Bug 586358: make imacpc flagged. (r=lw)
[mozilla-central.git] / js / src / jsgc.h
blob11dbe793c5599d777f108170942bb584daffd577
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is Mozilla Communicator client code, released
17 * March 31, 1998.
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 1998
22 * the Initial Developer. All Rights Reserved.
24 * Contributor(s):
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.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef jsgc_h___
41 #define jsgc_h___
43 * JS Garbage Collector.
45 #include <setjmp.h>
47 #include "jstypes.h"
48 #include "jsprvtd.h"
49 #include "jspubtd.h"
50 #include "jsdhash.h"
51 #include "jsbit.h"
52 #include "jsgcchunk.h"
53 #include "jsutil.h"
54 #include "jstask.h"
55 #include "jsvector.h"
56 #include "jsversion.h"
57 #include "jsobj.h"
58 #include "jsfun.h"
60 #if !defined JS_DUMP_CONSERVATIVE_GC_ROOTS && defined DEBUG
61 # define JS_DUMP_CONSERVATIVE_GC_ROOTS 1
62 #endif
64 #if defined JS_GCMETER
65 const bool JS_WANT_GC_METER_PRINT = true;
66 #elif defined DEBUG
67 # define JS_GCMETER 1
68 const bool JS_WANT_GC_METER_PRINT = false;
69 #endif
71 #define JSTRACE_XML 2
74 * One past the maximum trace kind.
76 #define JSTRACE_LIMIT 3
78 const uintN JS_EXTERNAL_STRING_LIMIT = 8;
81 * Get the type of the external string or -1 if the string was not created
82 * with JS_NewExternalString.
84 extern intN
85 js_GetExternalStringGCType(JSString *str);
87 extern JS_FRIEND_API(uint32)
88 js_GetGCThingTraceKind(void *thing);
91 * The sole purpose of the function is to preserve public API compatibility
92 * in JS_GetStringBytes which takes only single JSString* argument.
94 JSRuntime *
95 js_GetGCThingRuntime(void *thing);
97 #if 1
99 * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
100 * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg
101 * ignored", etc.
103 #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
104 #else
105 #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
106 #endif
108 extern JSBool
109 js_InitGC(JSRuntime *rt, uint32 maxbytes);
111 extern void
112 js_FinishGC(JSRuntime *rt);
114 extern intN
115 js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
116 JSStringFinalizeOp newop);
118 extern JSBool
119 js_AddRoot(JSContext *cx, js::Value *vp, const char *name);
121 extern JSBool
122 js_AddGCThingRoot(JSContext *cx, void **rp, const char *name);
124 #ifdef DEBUG
125 extern void
126 js_DumpNamedRoots(JSRuntime *rt,
127 void (*dump)(const char *name, void *rp, JSGCRootType type, void *data),
128 void *data);
129 #endif
131 extern uint32
132 js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
134 /* Table of pointers with count valid members. */
135 typedef struct JSPtrTable {
136 size_t count;
137 void **array;
138 } JSPtrTable;
140 extern JSBool
141 js_RegisterCloseableIterator(JSContext *cx, JSObject *obj);
143 #ifdef JS_TRACER
144 extern JSBool
145 js_ReserveObjects(JSContext *cx, size_t nobjects);
146 #endif
148 extern JSBool
149 js_LockGCThingRT(JSRuntime *rt, void *thing);
151 extern void
152 js_UnlockGCThingRT(JSRuntime *rt, void *thing);
154 extern JS_FRIEND_API(bool)
155 js_IsAboutToBeFinalized(void *thing);
157 extern JS_FRIEND_API(bool)
158 js_GCThingIsMarked(void *thing, uint32 color);
161 * Macro to test if a traversal is the marking phase of GC to avoid exposing
162 * ScriptFilenameEntry to traversal implementations.
164 #define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL)
166 #if JS_HAS_XML_SUPPORT
167 # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) < JSTRACE_LIMIT)
168 #else
169 # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING)
170 #endif
172 extern void
173 js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp);
175 extern JS_REQUIRES_STACK void
176 js_TraceRuntime(JSTracer *trc);
178 extern JS_REQUIRES_STACK JS_FRIEND_API(void)
179 js_TraceContext(JSTracer *trc, JSContext *acx);
182 * Schedule the GC call at a later safe point.
184 #ifndef JS_THREADSAFE
185 # define js_TriggerGC(cx, gcLocked) js_TriggerGC (cx)
186 #endif
188 extern void
189 js_TriggerGC(JSContext *cx, JSBool gcLocked);
192 * Kinds of js_GC invocation.
194 typedef enum JSGCInvocationKind {
195 /* Normal invocation. */
196 GC_NORMAL = 0,
199 * Called from js_DestroyContext for last JSContext in a JSRuntime, when
200 * it is imperative that rt->gcPoke gets cleared early in js_GC.
202 GC_LAST_CONTEXT = 1,
205 * Flag bit telling js_GC that the caller has already acquired rt->gcLock.
207 GC_LOCK_HELD = 0x10
208 } JSGCInvocationKind;
210 extern void
211 js_GC(JSContext *cx, JSGCInvocationKind gckind);
213 #ifdef JS_THREADSAFE
215 * This is a helper for code at can potentially run outside JS request to
216 * ensure that the GC is not running when the function returns.
218 * This function must be called with the GC lock held.
220 extern void
221 js_WaitForGC(JSRuntime *rt);
223 #else /* !JS_THREADSAFE */
225 # define js_WaitForGC(rt) ((void) 0)
227 #endif
230 * The kind of GC thing with a finalizer. The external strings follow the
231 * ordinary string to simplify js_GetExternalStringGCType.
233 enum JSFinalizeGCThingKind {
234 FINALIZE_OBJECT,
235 FINALIZE_FUNCTION,
236 #if JS_HAS_XML_SUPPORT
237 FINALIZE_XML,
238 #endif
239 FINALIZE_SHORT_STRING,
240 FINALIZE_STRING,
241 FINALIZE_EXTERNAL_STRING0,
242 FINALIZE_EXTERNAL_STRING1,
243 FINALIZE_EXTERNAL_STRING2,
244 FINALIZE_EXTERNAL_STRING3,
245 FINALIZE_EXTERNAL_STRING4,
246 FINALIZE_EXTERNAL_STRING5,
247 FINALIZE_EXTERNAL_STRING6,
248 FINALIZE_EXTERNAL_STRING7,
249 FINALIZE_EXTERNAL_STRING_LAST = FINALIZE_EXTERNAL_STRING7,
250 FINALIZE_LIMIT
253 static inline bool
254 IsFinalizableStringKind(unsigned thingKind)
256 return unsigned(FINALIZE_SHORT_STRING) <= thingKind &&
257 thingKind <= unsigned(FINALIZE_EXTERNAL_STRING_LAST);
261 * Allocates a new GC thing. After a successful allocation the caller must
262 * fully initialize the thing before calling any function that can potentially
263 * trigger GC. This will ensure that GC tracing never sees junk values stored
264 * in the partially initialized thing.
266 extern void *
267 js_NewFinalizableGCThing(JSContext *cx, unsigned thingKind);
269 static inline JSObject *
270 js_NewGCObject(JSContext *cx)
272 return (JSObject *) js_NewFinalizableGCThing(cx, FINALIZE_OBJECT);
275 static inline JSString *
276 js_NewGCString(JSContext *cx)
278 return (JSString *) js_NewFinalizableGCThing(cx, FINALIZE_STRING);
281 struct JSShortString;
283 static inline JSShortString *
284 js_NewGCShortString(JSContext *cx)
286 return (JSShortString *) js_NewFinalizableGCThing(cx, FINALIZE_SHORT_STRING);
289 static inline JSString *
290 js_NewGCExternalString(JSContext *cx, uintN type)
292 JS_ASSERT(type < JS_EXTERNAL_STRING_LIMIT);
293 type += FINALIZE_EXTERNAL_STRING0;
294 return (JSString *) js_NewFinalizableGCThing(cx, type);
297 static inline JSFunction*
298 js_NewGCFunction(JSContext *cx)
300 JSFunction* obj = (JSFunction *)js_NewFinalizableGCThing(cx, FINALIZE_FUNCTION);
302 #ifdef DEBUG
303 if (obj) {
304 memset((uint8 *) obj + sizeof(JSObject), JS_FREE_PATTERN,
305 sizeof(JSFunction) - sizeof(JSObject));
307 #endif
309 return obj;
312 #if JS_HAS_XML_SUPPORT
313 static inline JSXML *
314 js_NewGCXML(JSContext *cx)
316 return (JSXML *) js_NewFinalizableGCThing(cx, FINALIZE_XML);
318 #endif
320 struct JSGCArena;
322 struct JSGCArenaList {
323 JSGCArena *head; /* list start */
324 JSGCArena *cursor; /* arena with free things */
325 uint32 thingKind; /* one of JSFinalizeGCThingKind */
326 uint32 thingSize; /* size of things to allocate on this list
330 struct JSGCFreeLists {
331 JSGCThing *finalizables[FINALIZE_LIMIT];
333 void purge();
334 void moveTo(JSGCFreeLists * another);
336 #ifdef DEBUG
337 bool isEmpty() const {
338 for (size_t i = 0; i != JS_ARRAY_LENGTH(finalizables); ++i) {
339 if (finalizables[i])
340 return false;
342 return true;
344 #endif
347 extern void
348 js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data);
350 struct JSWeakRoots {
351 /* Most recently created things by type, members of the GC's root set. */
352 void *finalizableNewborns[FINALIZE_LIMIT];
354 /* Atom root for the last-looked-up atom on this context. */
355 JSAtom *lastAtom;
357 /* Root for the result of the most recent js_InternalInvoke call. */
358 void *lastInternalResult;
360 void mark(JSTracer *trc);
363 #define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots)))
365 namespace js {
367 #ifdef JS_THREADSAFE
370 * During the finalization we do not free immediately. Rather we add the
371 * corresponding pointers to a buffer which we later release on the
372 * background thread.
374 * The buffer is implemented as a vector of 64K arrays of pointers, not as a
375 * simple vector, to avoid realloc calls during the vector growth and to not
376 * bloat the binary size of the inlined freeLater method. Any OOM during
377 * buffer growth results in the pointer being freed immediately.
379 class BackgroundSweepTask : public JSBackgroundTask {
380 static const size_t FREE_ARRAY_SIZE = size_t(1) << 16;
381 static const size_t FREE_ARRAY_LENGTH = FREE_ARRAY_SIZE / sizeof(void *);
383 Vector<void **, 16, js::SystemAllocPolicy> freeVector;
384 void **freeCursor;
385 void **freeCursorEnd;
387 JS_FRIEND_API(void)
388 replenishAndFreeLater(void *ptr);
390 static void freeElementsAndArray(void **array, void **end) {
391 JS_ASSERT(array <= end);
392 for (void **p = array; p != end; ++p)
393 js_free(*p);
394 js_free(array);
397 public:
398 BackgroundSweepTask()
399 : freeCursor(NULL), freeCursorEnd(NULL) { }
401 void freeLater(void* ptr) {
402 if (freeCursor != freeCursorEnd)
403 *freeCursor++ = ptr;
404 else
405 replenishAndFreeLater(ptr);
408 virtual void run();
411 #endif /* JS_THREADSAFE */
414 struct GCChunkInfo;
416 struct GCChunkHasher {
417 typedef jsuword Lookup;
420 * Strip zeros for better distribution after multiplying by the golden
421 * ratio.
423 static HashNumber hash(jsuword chunk) {
424 JS_ASSERT(!(chunk & GC_CHUNK_MASK));
425 return HashNumber(chunk >> GC_CHUNK_SHIFT);
428 static bool match(jsuword k, jsuword l) {
429 JS_ASSERT(!(k & GC_CHUNK_MASK));
430 JS_ASSERT(!(l & GC_CHUNK_MASK));
431 return k == l;
435 typedef HashSet<jsuword, GCChunkHasher, SystemAllocPolicy> GCChunkSet;
436 typedef Vector<GCChunkInfo *, 32, SystemAllocPolicy> GCChunkInfoVector;
438 struct ConservativeGCThreadData {
441 * The GC scans conservatively between JSThreadData::nativeStackBase and
442 * nativeStackTop unless the latter is NULL.
444 jsuword *nativeStackTop;
446 union {
447 jmp_buf jmpbuf;
448 jsuword words[JS_HOWMANY(sizeof(jmp_buf), sizeof(jsuword))];
449 } registerSnapshot;
451 int enableCount;
453 JS_NEVER_INLINE JS_FRIEND_API(void) enable(bool knownStackBoundary = false);
454 JS_FRIEND_API(void) disable();
455 bool isEnabled() const { return enableCount > 0; }
459 * The conservative GC test for a word shows that it is either a valid GC
460 * thing or is not for one of the following reasons.
462 enum ConservativeGCTest {
463 CGCT_VALID,
464 CGCT_LOWBITSET, /* excluded because one of the low bits was set */
465 CGCT_NOTARENA, /* not within arena range in a chunk */
466 CGCT_NOTCHUNK, /* not within a valid chunk */
467 CGCT_FREEARENA, /* within arena containing only free things */
468 CGCT_WRONGTAG, /* tagged pointer but wrong type */
469 CGCT_NOTLIVE, /* gcthing is not allocated */
470 CGCT_END
473 struct ConservativeGCStats {
474 uint32 counter[CGCT_END]; /* ConservativeGCTest classification
475 counters */
477 void add(const ConservativeGCStats &another) {
478 for (size_t i = 0; i != JS_ARRAY_LENGTH(counter); ++i)
479 counter[i] += another.counter[i];
482 void dump(FILE *fp);
485 struct GCMarker : public JSTracer {
486 private:
487 /* The color is only applied to objects, functions and xml. */
488 uint32 color;
490 /* See comments before delayMarkingChildren is jsgc.cpp. */
491 JSGCArena *unmarkedArenaStackTop;
492 #ifdef DEBUG
493 size_t markLaterCount;
494 #endif
496 public:
497 #if defined(JS_DUMP_CONSERVATIVE_GC_ROOTS) || defined(JS_GCMETER)
498 ConservativeGCStats conservativeStats;
499 #endif
501 #ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS
502 struct ConservativeRoot { void *thing; uint32 traceKind; };
503 Vector<ConservativeRoot, 0, SystemAllocPolicy> conservativeRoots;
504 const char *conservativeDumpFileName;
506 void dumpConservativeRoots();
507 #endif
509 js::Vector<JSObject *, 0, js::SystemAllocPolicy> arraysToSlowify;
511 public:
512 explicit GCMarker(JSContext *cx);
513 ~GCMarker();
515 uint32 getMarkColor() const {
516 return color;
519 void setMarkColor(uint32 newColor) {
521 * We must process any delayed marking here, otherwise we confuse
522 * colors.
524 markDelayedChildren();
525 color = newColor;
528 void delayMarkingChildren(void *thing);
530 JS_FRIEND_API(void) markDelayedChildren();
532 void slowifyArrays();
535 } /* namespace js */
537 extern void
538 js_FinalizeStringRT(JSRuntime *rt, JSString *str);
540 #ifdef JS_GCMETER
542 struct JSGCArenaStats {
543 uint32 alloc; /* allocation attempts */
544 uint32 localalloc; /* allocations from local lists */
545 uint32 retry; /* allocation retries after running the GC */
546 uint32 fail; /* allocation failures */
547 uint32 nthings; /* live GC things */
548 uint32 maxthings; /* maximum of live GC cells */
549 double totalthings; /* live GC things the GC scanned so far */
550 uint32 narenas; /* number of arena in list before the GC */
551 uint32 newarenas; /* new arenas allocated before the last GC */
552 uint32 livearenas; /* number of live arenas after the last GC */
553 uint32 maxarenas; /* maximum of allocated arenas */
554 uint32 totalarenas; /* total number of arenas with live things that
555 GC scanned so far */
558 struct JSGCStats {
559 uint32 finalfail; /* finalizer calls allocator failures */
560 uint32 lockborn; /* things born locked */
561 uint32 lock; /* valid lock calls */
562 uint32 unlock; /* valid unlock calls */
563 uint32 depth; /* mark tail recursion depth */
564 uint32 maxdepth; /* maximum mark tail recursion depth */
565 uint32 cdepth; /* mark recursion depth of C functions */
566 uint32 maxcdepth; /* maximum mark recursion depth of C functions */
567 uint32 unmarked; /* number of times marking of GC thing's children were
568 delayed due to a low C stack */
569 #ifdef DEBUG
570 uint32 maxunmarked;/* maximum number of things with children to mark
571 later */
572 #endif
573 uint32 poke; /* number of potentially useful GC calls */
574 uint32 afree; /* thing arenas freed so far */
575 uint32 stackseg; /* total extraordinary stack segments scanned */
576 uint32 segslots; /* total stack segment value slots scanned */
577 uint32 nclose; /* number of objects with close hooks */
578 uint32 maxnclose; /* max number of objects with close hooks */
579 uint32 closelater; /* number of close hooks scheduled to run */
580 uint32 maxcloselater; /* max number of close hooks scheduled to run */
581 uint32 nallarenas; /* number of all allocated arenas */
582 uint32 maxnallarenas; /* maximum number of all allocated arenas */
583 uint32 nchunks; /* number of allocated chunks */
584 uint32 maxnchunks; /* maximum number of allocated chunks */
586 JSGCArenaStats arenaStats[FINALIZE_LIMIT];
588 js::ConservativeGCStats conservative;
591 extern JS_FRIEND_API(void)
592 js_DumpGCStats(JSRuntime *rt, FILE *fp);
594 #endif /* JS_GCMETER */
597 * This function is defined in jsdbgapi.cpp but is declared here to avoid
598 * polluting jsdbgapi.h, a public API header, with internal functions.
600 extern void
601 js_MarkTraps(JSTracer *trc);
603 namespace js {
606 * Set object's prototype while checking that doing so would not create
607 * a cycle in the proto chain. The cycle check and proto change are done
608 * only when all other requests are finished or suspended to ensure exclusive
609 * access to the chain. If there is a cycle, return false without reporting
610 * an error. Otherwise, set the proto and return true.
612 extern bool
613 SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto);
615 /* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
616 void
617 Mark(JSTracer *trc, void *thing, uint32 kind);
619 static inline void
620 Mark(JSTracer *trc, void *thing, uint32 kind, const char *name)
622 JS_ASSERT(thing);
623 JS_SET_TRACING_NAME(trc, name);
624 Mark(trc, thing, kind);
627 static inline void
628 MarkString(JSTracer *trc, JSString *str)
630 JS_ASSERT(str);
631 Mark(trc, str, JSTRACE_STRING);
634 static inline void
635 MarkString(JSTracer *trc, JSString *str, const char *name)
637 JS_ASSERT(str);
638 JS_SET_TRACING_NAME(trc, name);
639 Mark(trc, str, JSTRACE_STRING);
642 static inline void
643 MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name)
645 for (uint32 i = 0; i < len; i++) {
646 if (JSAtom *atom = vec[i]) {
647 JS_SET_TRACING_INDEX(trc, name, i);
648 Mark(trc, ATOM_TO_STRING(atom), JSTRACE_STRING);
653 static inline void
654 MarkObject(JSTracer *trc, JSObject *obj, const char *name)
656 JS_ASSERT(obj);
657 JS_SET_TRACING_NAME(trc, name);
658 Mark(trc, obj, JSTRACE_OBJECT);
661 static inline void
662 MarkObjectRange(JSTracer *trc, size_t len, JSObject **vec, const char *name)
664 for (uint32 i = 0; i < len; i++) {
665 if (JSObject *obj = vec[i]) {
666 JS_SET_TRACING_INDEX(trc, name, i);
667 Mark(trc, obj, JSTRACE_OBJECT);
672 /* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
673 static inline void
674 MarkValueRaw(JSTracer *trc, const js::Value &v)
676 if (v.isMarkable())
677 return Mark(trc, v.asGCThing(), v.gcKind());
680 static inline void
681 MarkValue(JSTracer *trc, const js::Value &v, const char *name)
683 JS_SET_TRACING_NAME(trc, name);
684 MarkValueRaw(trc, v);
687 static inline void
688 MarkValueRange(JSTracer *trc, Value *beg, Value *end, const char *name)
690 for (Value *vp = beg; vp < end; ++vp) {
691 JS_SET_TRACING_INDEX(trc, name, vp - beg);
692 MarkValueRaw(trc, *vp);
696 static inline void
697 MarkValueRange(JSTracer *trc, size_t len, Value *vec, const char *name)
699 MarkValueRange(trc, vec, vec + len, name);
702 static inline void
703 MarkId(JSTracer *trc, jsid id)
705 if (JSID_IS_STRING(id))
706 Mark(trc, JSID_TO_STRING(id), JSTRACE_STRING);
707 else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
708 Mark(trc, JSID_TO_OBJECT(id), JSTRACE_OBJECT);
711 static inline void
712 MarkId(JSTracer *trc, jsid id, const char *name)
714 JS_SET_TRACING_NAME(trc, name);
715 MarkId(trc, id);
718 static inline void
719 MarkIdRange(JSTracer *trc, jsid *beg, jsid *end, const char *name)
721 for (jsid *idp = beg; idp != end; ++idp) {
722 JS_SET_TRACING_INDEX(trc, name, (idp - beg));
723 MarkId(trc, *idp);
727 static inline void
728 MarkIdRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
730 MarkIdRange(trc, vec, vec + len, name);
733 /* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */
734 void
735 MarkGCThing(JSTracer *trc, void *thing);
737 static inline void
738 MarkGCThing(JSTracer *trc, void *thing, const char *name)
740 JS_SET_TRACING_NAME(trc, name);
741 MarkGCThing(trc, thing);
744 static inline void
745 MarkGCThing(JSTracer *trc, void *thing, const char *name, size_t index)
747 JS_SET_TRACING_INDEX(trc, name, index);
748 MarkGCThing(trc, thing);
751 JSCompartment *
752 NewCompartment(JSContext *cx, JSPrincipals *principals);
754 } /* namespace js */
756 #endif /* jsgc_h___ */