LCOV - code coverage report
Current view: directory - js/src - jsgcinlines.h (source / functions) Found Hit Coverage
Test: app.info Lines: 208 202 97.1 %
Date: 2012-04-07 Functions: 56 51 91.1 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is SpiderMonkey code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Mozilla Corporation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifndef jsgcinlines_h___
      41                 : #define jsgcinlines_h___
      42                 : 
      43                 : #include "jsgc.h"
      44                 : #include "jscntxt.h"
      45                 : #include "jscompartment.h"
      46                 : #include "jslock.h"
      47                 : #include "jsscope.h"
      48                 : #include "jsxml.h"
      49                 : 
      50                 : #include "js/TemplateLib.h"
      51                 : 
      52                 : namespace js {
      53                 : 
      54                 : struct Shape;
      55                 : 
      56                 : namespace gc {
      57                 : 
      58                 : inline JSGCTraceKind
      59        68696813 : GetGCThingTraceKind(const void *thing)
      60                 : {
      61        68696813 :     JS_ASSERT(thing);
      62        68696813 :     const Cell *cell = reinterpret_cast<const Cell *>(thing);
      63        68696813 :     return MapAllocToTraceKind(cell->getAllocKind());
      64                 : }
      65                 : 
      66                 : /* Capacity for slotsToThingKind */
      67                 : const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
      68                 : 
      69                 : /* Get the best kind to use when making an object with the given slot count. */
      70                 : static inline AllocKind
      71        11147671 : GetGCObjectKind(size_t numSlots)
      72                 : {
      73                 :     extern AllocKind slotsToThingKind[];
      74                 : 
      75        11147671 :     if (numSlots >= SLOTS_TO_THING_KIND_LIMIT)
      76          249154 :         return FINALIZE_OBJECT16;
      77        10898517 :     return slotsToThingKind[numSlots];
      78                 : }
      79                 : 
      80                 : static inline AllocKind
      81         8818707 : GetGCObjectKind(Class *clasp)
      82                 : {
      83         8818707 :     if (clasp == &FunctionClass)
      84           70887 :         return JSFunction::FinalizeKind;
      85         8747820 :     uint32_t nslots = JSCLASS_RESERVED_SLOTS(clasp);
      86         8747820 :     if (clasp->flags & JSCLASS_HAS_PRIVATE)
      87          589502 :         nslots++;
      88         8747820 :     return GetGCObjectKind(nslots);
      89                 : }
      90                 : 
      91                 : /* As for GetGCObjectKind, but for dense array allocation. */
      92                 : static inline AllocKind
      93         2124663 : GetGCArrayKind(size_t numSlots)
      94                 : {
      95                 :     extern AllocKind slotsToThingKind[];
      96                 : 
      97                 :     /*
      98                 :      * Dense arrays can use their fixed slots to hold their elements array
      99                 :      * (less two Values worth of ObjectElements header), but if more than the
     100                 :      * maximum number of fixed slots is needed then the fixed slots will be
     101                 :      * unused.
     102                 :      */
     103                 :     JS_STATIC_ASSERT(ObjectElements::VALUES_PER_HEADER == 2);
     104         2124663 :     if (numSlots > JSObject::NELEMENTS_LIMIT || numSlots + 2 >= SLOTS_TO_THING_KIND_LIMIT)
     105           28853 :         return FINALIZE_OBJECT2;
     106         2095810 :     return slotsToThingKind[numSlots + 2];
     107                 : }
     108                 : 
     109                 : static inline AllocKind
     110         2614024 : GetGCObjectFixedSlotsKind(size_t numFixedSlots)
     111                 : {
     112                 :     extern AllocKind slotsToThingKind[];
     113                 : 
     114         2614024 :     JS_ASSERT(numFixedSlots < SLOTS_TO_THING_KIND_LIMIT);
     115         2614024 :     return slotsToThingKind[numFixedSlots];
     116                 : }
     117                 : 
     118                 : static inline bool
     119        39375651 : IsBackgroundAllocKind(AllocKind kind)
     120                 : {
     121        39375651 :     JS_ASSERT(kind <= FINALIZE_LAST);
     122        39375651 :     return kind <= FINALIZE_OBJECT_LAST && kind % 2 == 1;
     123                 : }
     124                 : 
     125                 : static inline AllocKind
     126        15101080 : GetBackgroundAllocKind(AllocKind kind)
     127                 : {
     128        15101080 :     JS_ASSERT(!IsBackgroundAllocKind(kind));
     129        15101080 :     return (AllocKind) (kind + 1);
     130                 : }
     131                 : 
     132                 : /*
     133                 :  * Try to get the next larger size for an object, keeping BACKGROUND
     134                 :  * consistent.
     135                 :  */
     136                 : static inline bool
     137              17 : TryIncrementAllocKind(AllocKind *kindp)
     138                 : {
     139              17 :     size_t next = size_t(*kindp) + 2;
     140              17 :     if (next >= size_t(FINALIZE_OBJECT_LIMIT))
     141               0 :         return false;
     142              17 :     *kindp = AllocKind(next);
     143              17 :     return true;
     144                 : }
     145                 : 
     146                 : /* Get the number of fixed slots and initial capacity associated with a kind. */
     147                 : static inline size_t
     148        17354293 : GetGCKindSlots(AllocKind thingKind)
     149                 : {
     150                 :     /* Using a switch in hopes that thingKind will usually be a compile-time constant. */
     151        17354293 :     switch (thingKind) {
     152                 :       case FINALIZE_OBJECT0:
     153                 :       case FINALIZE_OBJECT0_BACKGROUND:
     154          797009 :         return 0;
     155                 :       case FINALIZE_OBJECT2:
     156                 :       case FINALIZE_OBJECT2_BACKGROUND:
     157         9763801 :         return 2;
     158                 :       case FINALIZE_OBJECT4:
     159                 :       case FINALIZE_OBJECT4_BACKGROUND:
     160         3852578 :         return 4;
     161                 :       case FINALIZE_OBJECT8:
     162                 :       case FINALIZE_OBJECT8_BACKGROUND:
     163          699466 :         return 8;
     164                 :       case FINALIZE_OBJECT12:
     165                 :       case FINALIZE_OBJECT12_BACKGROUND:
     166         1664084 :         return 12;
     167                 :       case FINALIZE_OBJECT16:
     168                 :       case FINALIZE_OBJECT16_BACKGROUND:
     169          577355 :         return 16;
     170                 :       default:
     171               0 :         JS_NOT_REACHED("Bad object finalize kind");
     172                 :         return 0;
     173                 :     }
     174                 : }
     175                 : 
     176                 : static inline size_t
     177        15166497 : GetGCKindSlots(AllocKind thingKind, Class *clasp)
     178                 : {
     179        15166497 :     size_t nslots = GetGCKindSlots(thingKind);
     180                 : 
     181                 :     /* An object's private data uses the space taken by its last fixed slot. */
     182        15166497 :     if (clasp->flags & JSCLASS_HAS_PRIVATE) {
     183         2829874 :         JS_ASSERT(nslots > 0);
     184         2829874 :         nslots--;
     185                 :     }
     186                 : 
     187                 :     /*
     188                 :      * Functions have a larger finalize kind than FINALIZE_OBJECT to reserve
     189                 :      * space for the extra fields in JSFunction, but have no fixed slots.
     190                 :      */
     191        15166497 :     if (clasp == &FunctionClass)
     192         8631365 :         nslots = 0;
     193                 : 
     194        15166497 :     return nslots;
     195                 : }
     196                 : 
     197                 : static inline void
     198            2709 : GCPoke(JSRuntime *rt, Value oldval)
     199                 : {
     200                 :     /*
     201                 :      * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
     202                 :      * loading oldval.  XXX remove implied force, fix jsinterp.c's "second arg
     203                 :      * ignored", etc.
     204                 :      */
     205                 : #if 1
     206            2709 :     rt->gcPoke = true;
     207                 : #else
     208                 :     rt->gcPoke = oldval.isGCThing();
     209                 : #endif
     210                 : 
     211                 : #ifdef JS_GC_ZEAL
     212                 :     /* Schedule a GC to happen "soon" after a GC poke. */
     213            2709 :     if (rt->gcZeal() == js::gc::ZealPokeValue)
     214               0 :         rt->gcNextScheduled = 1;
     215                 : #endif
     216            2709 : }
     217                 : 
     218                 : /*
     219                 :  * Invoke ArenaOp and CellOp on every arena and cell in a compartment which
     220                 :  * have the specified thing kind.
     221                 :  */
     222                 : template <class ArenaOp, class CellOp>
     223                 : void
     224           83677 : ForEachArenaAndCell(JSCompartment *compartment, AllocKind thingKind,
     225                 :                     ArenaOp arenaOp, CellOp cellOp)
     226                 : {
     227           83677 :     size_t thingSize = Arena::thingSize(thingKind);
     228           83677 :     ArenaHeader *aheader = compartment->arenas.getFirstArena(thingKind);
     229                 : 
     230          128983 :     for (; aheader; aheader = aheader->next) {
     231           45306 :         Arena *arena = aheader->getArena();
     232           45306 :         arenaOp(arena);
     233           45306 :         FreeSpan firstSpan(aheader->getFirstFreeSpan());
     234           45306 :         const FreeSpan *span = &firstSpan;
     235                 : 
     236          827014 :         for (uintptr_t thing = arena->thingsStart(thingKind); ; thing += thingSize) {
     237          827014 :             JS_ASSERT(thing <= arena->thingsEnd());
     238          827014 :             if (thing == span->first) {
     239           59115 :                 if (!span->hasNext())
     240                 :                     break;
     241           13809 :                 thing = span->last;
     242           13809 :                 span = span->nextSpan();
     243                 :             } else {
     244          767899 :                 Cell *t = reinterpret_cast<Cell *>(thing);
     245          767899 :                 cellOp(t);
     246                 :             }
     247                 :         }
     248                 :     }
     249           83677 : }
     250                 : 
     251                 : class CellIterImpl
     252                 : {
     253                 :     size_t firstThingOffset;
     254                 :     size_t thingSize;
     255                 :     ArenaHeader *aheader;
     256                 :     FreeSpan firstSpan;
     257                 :     const FreeSpan *span;
     258                 :     uintptr_t thing;
     259                 :     Cell *cell;
     260                 : 
     261                 :   protected:
     262          268346 :     CellIterImpl() {
     263          268346 :     }
     264                 : 
     265          268346 :     void initSpan(JSCompartment *comp, AllocKind kind) {
     266          268346 :         JS_ASSERT(comp->arenas.isSynchronizedFreeList(kind));
     267          268346 :         firstThingOffset = Arena::firstThingOffset(kind);
     268          268346 :         thingSize = Arena::thingSize(kind);
     269          268346 :         firstSpan.initAsEmpty();
     270          268346 :         span = &firstSpan;
     271          268346 :         thing = span->first;
     272          268346 :     }
     273                 : 
     274               9 :     void init(ArenaHeader *singleAheader) {
     275               9 :         aheader = singleAheader;
     276               9 :         initSpan(aheader->compartment, aheader->getAllocKind());
     277               9 :         next();
     278               9 :         aheader = NULL;
     279               9 :     }
     280                 : 
     281          268337 :     void init(JSCompartment *comp, AllocKind kind) {
     282          268337 :         initSpan(comp, kind);
     283          268337 :         aheader = comp->arenas.getFirstArena(kind);
     284          268337 :         next();
     285          268337 :     }
     286                 : 
     287                 :   public:
     288         3216883 :     bool done() const {
     289         3216883 :         return !cell;
     290                 :     }
     291                 : 
     292         1477930 :     template<typename T> T *get() const {
     293         1477930 :         JS_ASSERT(!done());
     294         1477930 :         return static_cast<T *>(cell);
     295                 :     }
     296                 : 
     297               0 :     Cell *getCell() const {
     298               0 :         JS_ASSERT(!done());
     299               0 :         return cell;
     300                 :     }
     301                 : 
     302         1910576 :     void next() {
     303          171623 :         for (;;) {
     304         1910576 :             if (thing != span->first)
     305         1407124 :                 break;
     306          503452 :             if (JS_LIKELY(span->hasNext())) {
     307           63483 :                 thing = span->last + thingSize;
     308           63483 :                 span = span->nextSpan();
     309           63483 :                 break;
     310                 :             }
     311          439969 :             if (!aheader) {
     312          268346 :                 cell = NULL;
     313          268346 :                 return;
     314                 :             }
     315          171623 :             firstSpan = aheader->getFirstFreeSpan();
     316          171623 :             span = &firstSpan;
     317          171623 :             thing = aheader->arenaAddress() | firstThingOffset;
     318          171623 :             aheader = aheader->next;
     319                 :         }
     320         1470607 :         cell = reinterpret_cast<Cell *>(thing);
     321         1470607 :         thing += thingSize;
     322                 :     }
     323                 : };
     324                 : 
     325                 : class CellIterUnderGC : public CellIterImpl
     326                 : {
     327                 :   public:
     328          215018 :     CellIterUnderGC(JSCompartment *comp, AllocKind kind) {
     329          215018 :         JS_ASSERT(comp->rt->gcRunning);
     330          215018 :         init(comp, kind);
     331          215018 :     }
     332                 : 
     333               9 :     CellIterUnderGC(ArenaHeader *aheader) {
     334               9 :         JS_ASSERT(aheader->compartment->rt->gcRunning);
     335               9 :         init(aheader);
     336               9 :     }
     337                 : };
     338                 : 
     339                 : /*
     340                 :  * When using the iterator outside the GC the caller must ensure that no GC or
     341                 :  * allocations of GC things are possible and that the background finalization
     342                 :  * for the given thing kind is not enabled or is done.
     343                 :  */
     344                 : class CellIter : public CellIterImpl
     345                 : {
     346                 :     ArenaLists *lists;
     347                 :     AllocKind kind;
     348                 : #ifdef DEBUG
     349                 :     size_t *counter;
     350                 : #endif
     351                 :   public:
     352           53319 :     CellIter(JSCompartment *comp, AllocKind kind)
     353                 :       : lists(&comp->arenas),
     354           53319 :         kind(kind)
     355                 :     {
     356                 :         /*
     357                 :          * We have a single-threaded runtime, so there's no need to protect
     358                 :          * against other threads iterating or allocating. However, we do have
     359                 :          * background finalization; make sure people aren't using CellIter to
     360                 :          * walk such allocation kinds.
     361                 :          */
     362           53319 :         JS_ASSERT(!IsBackgroundAllocKind(kind));
     363           53319 :         if (lists->isSynchronizedFreeList(kind)) {
     364           22606 :             lists = NULL;
     365                 :         } else {
     366           30713 :             JS_ASSERT(!comp->rt->gcRunning);
     367           30713 :             lists->copyFreeListToArena(kind);
     368                 :         }
     369                 : #ifdef DEBUG
     370           53319 :         counter = &comp->rt->noGCOrAllocationCheck;
     371           53319 :         ++*counter;
     372                 : #endif
     373           53319 :         init(comp, kind);
     374           53319 :     }
     375                 : 
     376           53319 :     ~CellIter() {
     377                 : #ifdef DEBUG
     378           53319 :         JS_ASSERT(*counter > 0);
     379           53319 :         --*counter;
     380                 : #endif
     381           53319 :         if (lists)
     382           30713 :             lists->clearFreeListInArena(kind);
     383           53319 :     }
     384                 : };
     385                 : 
     386                 : /* Signatures for ArenaOp and CellOp above. */
     387                 : 
     388           45306 : inline void EmptyArenaOp(Arena *arena) {}
     389                 : inline void EmptyCellOp(Cell *t) {}
     390                 : 
     391                 : class GCCompartmentsIter {
     392                 :   private:
     393                 :     JSCompartment **it, **end;
     394                 : 
     395                 :   public:
     396          423251 :     GCCompartmentsIter(JSRuntime *rt) {
     397          423251 :         JS_ASSERT(rt->gcRunning);
     398          423251 :         it = rt->compartments.begin();
     399          423251 :         end = rt->compartments.end();
     400          423251 :         if (!(*it)->isCollecting())
     401            1773 :             next();
     402          423251 :         JS_ASSERT(it < end);
     403          423251 :     }
     404                 : 
     405         3125087 :     bool done() const { return it == end; }
     406                 : 
     407          901605 :     void next() {
     408          901605 :         JS_ASSERT(!done());
     409         1382983 :         do {
     410          903117 :             it++;
     411          479866 :         } while (it != end && !(*it)->isCollecting());
     412          901605 :     }
     413                 : 
     414          900399 :     JSCompartment *get() const {
     415          900399 :         JS_ASSERT(!done());
     416          900399 :         return *it;
     417                 :     }
     418                 : 
     419           83697 :     operator JSCompartment *() const { return get(); }
     420          816702 :     JSCompartment *operator->() const { return get(); }
     421                 : };
     422                 : 
     423                 : /*
     424                 :  * Allocates a new GC thing. After a successful allocation the caller must
     425                 :  * fully initialize the thing before calling any function that can potentially
     426                 :  * trigger GC. This will ensure that GC tracing never sees junk values stored
     427                 :  * in the partially initialized thing.
     428                 :  */
     429                 : 
     430                 : template <typename T>
     431                 : inline T *
     432       194981538 : NewGCThing(JSContext *cx, js::gc::AllocKind kind, size_t thingSize)
     433                 : {
     434       194981538 :     JS_ASSERT(thingSize == js::gc::Arena::thingSize(kind));
     435                 : #ifdef JS_THREADSAFE
     436       194981538 :     JS_ASSERT_IF((cx->compartment == cx->runtime->atomsCompartment),
     437                 :                  kind == js::gc::FINALIZE_STRING || kind == js::gc::FINALIZE_SHORT_STRING);
     438                 : #endif
     439       194981538 :     JS_ASSERT(!cx->runtime->gcRunning);
     440       194981538 :     JS_ASSERT(!cx->runtime->noGCOrAllocationCheck);
     441                 : 
     442                 :     /* For testing out of memory conditions */
     443       194981538 :     JS_OOM_POSSIBLY_FAIL();
     444                 : 
     445                 : #ifdef JS_GC_ZEAL
     446       194981538 :     if (cx->runtime->needZealousGC())
     447           10664 :         js::gc::RunDebugGC(cx);
     448                 : #endif
     449                 : 
     450       194981538 :     js::gc::MaybeCheckStackRoots(cx);
     451                 : 
     452       194981538 :     JSCompartment *comp = cx->compartment;
     453       194981538 :     void *t = comp->arenas.allocateFromFreeList(kind, thingSize);
     454       194981538 :     if (!t)
     455         1768475 :         t = js::gc::ArenaLists::refillFreeList(cx, kind);
     456                 : 
     457       194981538 :     JS_ASSERT_IF(t && comp->needsBarrier(),
     458                 :                  static_cast<T *>(t)->arenaHeader()->allocatedDuringIncremental);
     459       194981538 :     return static_cast<T *>(t);
     460                 : }
     461                 : 
     462                 : /* Alternate form which allocates a GC thing if doing so cannot trigger a GC. */
     463                 : template <typename T>
     464                 : inline T *
     465        19052050 : TryNewGCThing(JSContext *cx, js::gc::AllocKind kind, size_t thingSize)
     466                 : {
     467        19052050 :     JS_ASSERT(thingSize == js::gc::Arena::thingSize(kind));
     468                 : #ifdef JS_THREADSAFE
     469        19052050 :     JS_ASSERT_IF((cx->compartment == cx->runtime->atomsCompartment),
     470                 :                  kind == js::gc::FINALIZE_STRING || kind == js::gc::FINALIZE_SHORT_STRING);
     471                 : #endif
     472        19052050 :     JS_ASSERT(!cx->runtime->gcRunning);
     473        19052050 :     JS_ASSERT(!cx->runtime->noGCOrAllocationCheck);
     474                 : 
     475                 : #ifdef JS_GC_ZEAL
     476        19052050 :     if (cx->runtime->needZealousGC())
     477            1570 :         return NULL;
     478                 : #endif
     479                 : 
     480        19050480 :     void *t = cx->compartment->arenas.allocateFromFreeList(kind, thingSize);
     481        19050480 :     JS_ASSERT_IF(t && cx->compartment->needsBarrier(),
     482                 :                  static_cast<T *>(t)->arenaHeader()->allocatedDuringIncremental);
     483        19050480 :     return static_cast<T *>(t);
     484                 : }
     485                 : 
     486                 : } /* namespace gc */
     487                 : } /* namespace js */
     488                 : 
     489                 : inline JSObject *
     490         7024695 : js_NewGCObject(JSContext *cx, js::gc::AllocKind kind)
     491                 : {
     492         7024695 :     JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST);
     493         7024695 :     return js::gc::NewGCThing<JSObject>(cx, kind, js::gc::Arena::thingSize(kind));
     494                 : }
     495                 : 
     496                 : inline JSObject *
     497        19052050 : js_TryNewGCObject(JSContext *cx, js::gc::AllocKind kind)
     498                 : {
     499        19052050 :     JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST);
     500        19052050 :     return js::gc::TryNewGCThing<JSObject>(cx, kind, js::gc::Arena::thingSize(kind));
     501                 : }
     502                 : 
     503                 : inline JSString *
     504       112031904 : js_NewGCString(JSContext *cx)
     505                 : {
     506       112031904 :     return js::gc::NewGCThing<JSString>(cx, js::gc::FINALIZE_STRING, sizeof(JSString));
     507                 : }
     508                 : 
     509                 : inline JSShortString *
     510        46323244 : js_NewGCShortString(JSContext *cx)
     511                 : {
     512        46323244 :     return js::gc::NewGCThing<JSShortString>(cx, js::gc::FINALIZE_SHORT_STRING, sizeof(JSShortString));
     513                 : }
     514                 : 
     515                 : inline JSExternalString *
     516            2000 : js_NewGCExternalString(JSContext *cx)
     517                 : {
     518                 :     return js::gc::NewGCThing<JSExternalString>(cx, js::gc::FINALIZE_EXTERNAL_STRING,
     519            2000 :                                                 sizeof(JSExternalString));
     520                 : }
     521                 : 
     522                 : inline JSScript *
     523          285135 : js_NewGCScript(JSContext *cx)
     524                 : {
     525          285135 :     return js::gc::NewGCThing<JSScript>(cx, js::gc::FINALIZE_SCRIPT, sizeof(JSScript));
     526                 : }
     527                 : 
     528                 : inline js::Shape *
     529        20149251 : js_NewGCShape(JSContext *cx)
     530                 : {
     531        20149251 :     return js::gc::NewGCThing<js::Shape>(cx, js::gc::FINALIZE_SHAPE, sizeof(js::Shape));
     532                 : }
     533                 : 
     534                 : inline js::BaseShape *
     535         4089976 : js_NewGCBaseShape(JSContext *cx)
     536                 : {
     537         4089976 :     return js::gc::NewGCThing<js::BaseShape>(cx, js::gc::FINALIZE_BASE_SHAPE, sizeof(js::BaseShape));
     538                 : }
     539                 : 
     540                 : #if JS_HAS_XML_SUPPORT
     541                 : extern JSXML *
     542                 : js_NewGCXML(JSContext *cx);
     543                 : #endif
     544                 : 
     545                 : #endif /* jsgcinlines_h___ */

Generated by: LCOV version 1.7