Bug 551763: Fix deletion of arguments ident. (r=Waldo)
[mozilla-central.git] / js / src / jsgc.h
blobd8167c5e5632970ba4d09774535d12d88c4eb697
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 "jsprvtd.h"
46 #include "jspubtd.h"
47 #include "jsdhash.h"
48 #include "jsbit.h"
49 #include "jsutil.h"
50 #include "jstask.h"
51 #include "jsvector.h"
52 #include "jsversion.h"
54 JS_BEGIN_EXTERN_C
56 #define JSTRACE_XML 3
59 * One past the maximum trace kind.
61 #define JSTRACE_LIMIT 4
63 const uintN JS_EXTERNAL_STRING_LIMIT = 8;
66 * Get the type of the external string or -1 if the string was not created
67 * with JS_NewExternalString.
69 extern intN
70 js_GetExternalStringGCType(JSString *str);
72 extern JS_FRIEND_API(uint32)
73 js_GetGCThingTraceKind(void *thing);
76 * The sole purpose of the function is to preserve public API compatibility
77 * in JS_GetStringBytes which takes only single JSString* argument.
79 JSRuntime *
80 js_GetGCThingRuntime(void *thing);
82 #if 1
84 * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
85 * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg
86 * ignored", etc.
88 #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
89 #else
90 #define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
91 #endif
93 extern JSBool
94 js_InitGC(JSRuntime *rt, uint32 maxbytes);
96 extern void
97 js_FinishGC(JSRuntime *rt);
99 extern intN
100 js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
101 JSStringFinalizeOp newop);
103 extern JSBool
104 js_AddRoot(JSContext *cx, void *rp, const char *name);
106 extern JSBool
107 js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
109 extern JSBool
110 js_RemoveRoot(JSRuntime *rt, void *rp);
112 #ifdef DEBUG
113 extern void
114 js_DumpNamedRoots(JSRuntime *rt,
115 void (*dump)(const char *name, void *rp, void *data),
116 void *data);
117 #endif
119 extern uint32
120 js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
122 /* Table of pointers with count valid members. */
123 typedef struct JSPtrTable {
124 size_t count;
125 void **array;
126 } JSPtrTable;
128 extern JSBool
129 js_RegisterCloseableIterator(JSContext *cx, JSObject *obj);
132 * Allocate a new double jsval and store the result in *vp. vp must be a root.
133 * The function does not copy the result into any weak root.
135 extern JSBool
136 js_NewDoubleInRootedValue(JSContext *cx, jsdouble d, jsval *vp);
139 * Return a pointer to a new GC-allocated and weakly-rooted jsdouble number,
140 * or null when the allocation fails.
142 extern jsdouble *
143 js_NewWeaklyRootedDouble(JSContext *cx, jsdouble d);
145 #ifdef JS_TRACER
146 extern JSBool
147 js_ReserveObjects(JSContext *cx, size_t nobjects);
148 #endif
150 extern JSBool
151 js_LockGCThingRT(JSRuntime *rt, void *thing);
153 extern void
154 js_UnlockGCThingRT(JSRuntime *rt, void *thing);
156 extern bool
157 js_IsAboutToBeFinalized(void *thing);
160 * Macro to test if a traversal is the marking phase of GC to avoid exposing
161 * ScriptFilenameEntry to traversal implementations.
163 #define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL)
165 #if JS_HAS_XML_SUPPORT
166 # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) < JSTRACE_LIMIT)
167 #else
168 # define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING)
169 #endif
172 * Trace jsval when JSVAL_IS_OBJECT(v) can be a GC thing pointer tagged as a
173 * jsval. NB: punning an arbitrary JSString * as an untagged (object-tagged)
174 * jsval no longer works due to static int and unit strings!
176 extern void
177 js_CallValueTracerIfGCThing(JSTracer *trc, jsval v);
179 extern void
180 js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp);
182 extern JS_REQUIRES_STACK void
183 js_TraceRuntime(JSTracer *trc);
185 extern JS_REQUIRES_STACK JS_FRIEND_API(void)
186 js_TraceContext(JSTracer *trc, JSContext *acx);
189 * Schedule the GC call at a later safe point.
191 #ifndef JS_THREADSAFE
192 # define js_TriggerGC(cx, gcLocked) js_TriggerGC (cx)
193 #endif
195 extern void
196 js_TriggerGC(JSContext *cx, JSBool gcLocked);
199 * Kinds of js_GC invocation.
201 typedef enum JSGCInvocationKind {
202 /* Normal invocation. */
203 GC_NORMAL = 0,
206 * Called from js_DestroyContext for last JSContext in a JSRuntime, when
207 * it is imperative that rt->gcPoke gets cleared early in js_GC.
209 GC_LAST_CONTEXT = 1,
212 * Flag bit telling js_GC that the caller has already acquired rt->gcLock.
214 GC_LOCK_HELD = 0x10,
217 * Called from js_SetProtoOrParent with a request to set an object's proto
218 * or parent slot inserted on rt->setSlotRequests.
220 GC_SET_SLOT_REQUEST = GC_LOCK_HELD | 1
221 } JSGCInvocationKind;
223 extern void
224 js_GC(JSContext *cx, JSGCInvocationKind gckind);
226 extern void
227 js_CallGCMarker(JSTracer *trc, void *thing, uint32 kind);
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_ITER,
236 FINALIZE_FUNCTION,
237 #if JS_HAS_XML_SUPPORT
238 FINALIZE_XML,
239 #endif
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_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 JSObject *
276 js_NewGCIter(JSContext *cx)
278 return (JSObject *) js_NewFinalizableGCThing(cx, FINALIZE_ITER);
281 static inline JSString *
282 js_NewGCString(JSContext *cx)
284 return (JSString *) js_NewFinalizableGCThing(cx, FINALIZE_STRING);
287 static inline JSString *
288 js_NewGCExternalString(JSContext *cx, uintN type)
290 JS_ASSERT(type < JS_EXTERNAL_STRING_LIMIT);
291 type += FINALIZE_EXTERNAL_STRING0;
292 return (JSString *) js_NewFinalizableGCThing(cx, type);
295 static inline JSFunction*
296 js_NewGCFunction(JSContext *cx)
298 return (JSFunction *) js_NewFinalizableGCThing(cx, FINALIZE_FUNCTION);
301 #if JS_HAS_XML_SUPPORT
302 static inline JSXML *
303 js_NewGCXML(JSContext *cx)
305 return (JSXML *) js_NewFinalizableGCThing(cx, FINALIZE_XML);
307 #endif
309 struct JSGCArena;
310 struct JSGCChunkInfo;
312 struct JSGCArenaList {
313 JSGCArena *head; /* list start */
314 JSGCArena *cursor; /* arena with free things */
315 uint32 thingKind; /* one of JSFinalizeGCThingKind */
316 uint32 thingSize; /* size of things to allocate on this list
320 struct JSGCDoubleArenaList {
321 JSGCArena *head; /* list start */
322 JSGCArena *cursor; /* next arena with free cells */
325 struct JSGCFreeLists {
326 JSGCThing *doubles;
327 JSGCThing *finalizables[FINALIZE_LIMIT];
329 void purge();
330 void moveTo(JSGCFreeLists * another);
332 #ifdef DEBUG
333 bool isEmpty() const {
334 if (doubles)
335 return false;
336 for (size_t i = 0; i != JS_ARRAY_LENGTH(finalizables); ++i) {
337 if (finalizables[i])
338 return false;
340 return true;
342 #endif
345 extern void
346 js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data);
348 struct JSWeakRoots {
349 /* Most recently created things by type, members of the GC's root set. */
350 void *finalizableNewborns[FINALIZE_LIMIT];
351 jsdouble *newbornDouble;
353 /* Atom root for the last-looked-up atom on this context. */
354 jsval lastAtom;
356 /* Root for the result of the most recent js_InternalInvoke call. */
357 jsval lastInternalResult;
359 void mark(JSTracer *trc);
362 #define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots)))
364 #ifdef JS_THREADSAFE
366 namespace js {
369 * During the finalization we do not free immediately. Rather we add the
370 * corresponding pointers to a buffer which we later release on the
371 * background thread.
373 * The buffer is implemented as a vector of 64K arrays of pointers, not as a
374 * simple vector, to avoid realloc calls during the vector growth and to not
375 * bloat the binary size of the inlined freeLater method. Any OOM during
376 * buffer growth results in the pointer being freed immediately.
378 class BackgroundSweepTask : public JSBackgroundTask {
379 static const size_t FREE_ARRAY_SIZE = size_t(1) << 16;
380 static const size_t FREE_ARRAY_LENGTH = FREE_ARRAY_SIZE / sizeof(void *);
382 Vector<void **, 16, js::SystemAllocPolicy> freeVector;
383 void **freeCursor;
384 void **freeCursorEnd;
386 JS_FRIEND_API(void)
387 replenishAndFreeLater(void *ptr);
389 static void freeElementsAndArray(void **array, void **end) {
390 JS_ASSERT(array <= end);
391 for (void **p = array; p != end; ++p)
392 js_free(*p);
393 js_free(array);
396 public:
397 BackgroundSweepTask()
398 : freeCursor(NULL), freeCursorEnd(NULL) { }
400 void freeLater(void* ptr) {
401 if (freeCursor != freeCursorEnd)
402 *freeCursor++ = ptr;
403 else
404 replenishAndFreeLater(ptr);
407 virtual void run();
411 #endif
413 extern void
414 js_FinalizeStringRT(JSRuntime *rt, JSString *str);
416 #if defined JS_GCMETER
417 const bool JS_WANT_GC_METER_PRINT = true;
418 #elif defined DEBUG
419 # define JS_GCMETER 1
420 const bool JS_WANT_GC_METER_PRINT = false;
421 #endif
423 #ifdef JS_GCMETER
425 struct JSGCArenaStats {
426 uint32 alloc; /* allocation attempts */
427 uint32 localalloc; /* allocations from local lists */
428 uint32 retry; /* allocation retries after running the GC */
429 uint32 fail; /* allocation failures */
430 uint32 nthings; /* live GC things */
431 uint32 maxthings; /* maximum of live GC cells */
432 double totalthings; /* live GC things the GC scanned so far */
433 uint32 narenas; /* number of arena in list before the GC */
434 uint32 newarenas; /* new arenas allocated before the last GC */
435 uint32 livearenas; /* number of live arenas after the last GC */
436 uint32 maxarenas; /* maximum of allocated arenas */
437 uint32 totalarenas; /* total number of arenas with live things that
438 GC scanned so far */
441 struct JSGCStats {
442 uint32 finalfail; /* finalizer calls allocator failures */
443 uint32 lockborn; /* things born locked */
444 uint32 lock; /* valid lock calls */
445 uint32 unlock; /* valid unlock calls */
446 uint32 depth; /* mark tail recursion depth */
447 uint32 maxdepth; /* maximum mark tail recursion depth */
448 uint32 cdepth; /* mark recursion depth of C functions */
449 uint32 maxcdepth; /* maximum mark recursion depth of C functions */
450 uint32 unmarked; /* number of times marking of GC thing's children were
451 delayed due to a low C stack */
452 #ifdef DEBUG
453 uint32 maxunmarked;/* maximum number of things with children to mark
454 later */
455 #endif
456 uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */
457 uint32 poke; /* number of potentially useful GC calls */
458 uint32 afree; /* thing arenas freed so far */
459 uint32 stackseg; /* total extraordinary stack segments scanned */
460 uint32 segslots; /* total stack segment jsval slots scanned */
461 uint32 nclose; /* number of objects with close hooks */
462 uint32 maxnclose; /* max number of objects with close hooks */
463 uint32 closelater; /* number of close hooks scheduled to run */
464 uint32 maxcloselater; /* max number of close hooks scheduled to run */
465 uint32 nallarenas; /* number of all allocated arenas */
466 uint32 maxnallarenas; /* maximum number of all allocated arenas */
467 uint32 nchunks; /* number of allocated chunks */
468 uint32 maxnchunks; /* maximum number of allocated chunks */
470 JSGCArenaStats arenaStats[FINALIZE_LIMIT];
471 JSGCArenaStats doubleArenaStats;
474 extern JS_FRIEND_API(void)
475 js_DumpGCStats(JSRuntime *rt, FILE *fp);
477 #endif /* JS_GCMETER */
480 * This function is defined in jsdbgapi.cpp but is declared here to avoid
481 * polluting jsdbgapi.h, a public API header, with internal functions.
483 extern void
484 js_MarkTraps(JSTracer *trc);
486 JS_END_EXTERN_C
488 namespace js {
490 void
491 TraceObjectVector(JSTracer *trc, JSObject **vec, uint32 len);
493 inline void
494 #ifdef DEBUG
495 TraceValues(JSTracer *trc, size_t len, jsval *vec, const char *name)
496 #else
497 TraceValues(JSTracer *trc, size_t len, jsval *vec, const char *) /* last arg unused in release. kill unreferenced formal param warnings */
498 #endif
500 for (jsval *vp = vec, *end = vp + len; vp < end; vp++) {
501 jsval v = *vp;
502 if (JSVAL_IS_TRACEABLE(v)) {
503 JS_SET_TRACING_INDEX(trc, name, vp - vec);
504 js_CallGCMarker(trc, JSVAL_TO_TRACEABLE(v), JSVAL_TRACE_KIND(v));
511 #endif /* jsgc_h___ */