/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jsgc.h
C++ Header | 427 lines | 205 code | 71 blank | 151 comment | 10 complexity | e4bd457fe5552d412dbabd0784fe63d9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
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 Mozilla Communicator client code, released 17 * March 31, 1998. 18 * 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. 23 * 24 * Contributor(s): 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 jsgc_h___ 41#define jsgc_h___ 42/* 43 * JS Garbage Collector. 44 */ 45#include "jsprvtd.h" 46#include "jspubtd.h" 47#include "jsdhash.h" 48#include "jsbit.h" 49#include "jsutil.h" 50 51JS_BEGIN_EXTERN_C 52 53JS_STATIC_ASSERT(JSTRACE_STRING == 2); 54 55#define JSTRACE_XML 3 56 57/* 58 * One past the maximum trace kind. 59 */ 60#define JSTRACE_LIMIT 4 61 62/* 63 * We use the trace kinds as the types for all GC things except external 64 * strings. 65 */ 66#define GCX_OBJECT JSTRACE_OBJECT /* JSObject */ 67#define GCX_DOUBLE JSTRACE_DOUBLE /* jsdouble */ 68#define GCX_STRING JSTRACE_STRING /* JSString */ 69#define GCX_XML JSTRACE_XML /* JSXML */ 70#define GCX_EXTERNAL_STRING JSTRACE_LIMIT /* JSString with external 71 chars */ 72/* 73 * The number of defined GC types. 74 */ 75#define GCX_NTYPES (GCX_EXTERNAL_STRING + 8) 76 77/* 78 * The maximum limit for the number of GC types. 79 */ 80#define GCX_LIMIT_LOG2 4 /* type index bits */ 81#define GCX_LIMIT JS_BIT(GCX_LIMIT_LOG2) 82 83JS_STATIC_ASSERT(GCX_NTYPES <= GCX_LIMIT); 84 85/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */ 86#define GCF_TYPEMASK JS_BITMASK(GCX_LIMIT_LOG2) 87#define GCF_MARK JS_BIT(GCX_LIMIT_LOG2) 88#define GCF_FINAL JS_BIT(GCX_LIMIT_LOG2 + 1) 89#define GCF_LOCKSHIFT (GCX_LIMIT_LOG2 + 2) /* lock bit shift */ 90#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */ 91 92/* 93 * Get the type of the external string or -1 if the string was not created 94 * with JS_NewExternalString. 95 */ 96extern intN 97js_GetExternalStringGCType(JSString *str); 98 99extern JS_FRIEND_API(uint32) 100js_GetGCThingTraceKind(void *thing); 101 102/* 103 * The sole purpose of the function is to preserve public API compatibility 104 * in JS_GetStringBytes which takes only single JSString* argument. 105 */ 106JSRuntime* 107js_GetGCStringRuntime(JSString *str); 108 109#if 1 110/* 111 * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles 112 * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg 113 * ignored", etc. 114 */ 115#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE) 116#else 117#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval)) 118#endif 119 120/* 121 * Write barrier macro monitoring property update from oldval to newval in 122 * scope->object. 123 * 124 * Since oldval is used only for the branded scope case, and the oldval actual 125 * argument expression is typically not used otherwise by callers, performance 126 * benefits if oldval is *not* evaluated into a callsite temporary variable, 127 * and instead passed to GC_WRITE_BARRIER for conditional evaluation (we rely 128 * on modern compilers to do a good CSE job). Yay, C macros. 129 */ 130#define GC_WRITE_BARRIER(cx,scope,oldval,newval) \ 131 JS_BEGIN_MACRO \ 132 if (SCOPE_IS_BRANDED(scope) && \ 133 (oldval) != (newval) && \ 134 (VALUE_IS_FUNCTION(cx,oldval) || VALUE_IS_FUNCTION(cx,newval))) { \ 135 SCOPE_MAKE_UNIQUE_SHAPE(cx, scope); \ 136 } \ 137 GC_POKE(cx, oldval); \ 138 JS_END_MACRO 139 140extern JSBool 141js_InitGC(JSRuntime *rt, uint32 maxbytes); 142 143extern void 144js_FinishGC(JSRuntime *rt); 145 146extern intN 147js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, 148 JSStringFinalizeOp newop); 149 150extern JSBool 151js_AddRoot(JSContext *cx, void *rp, const char *name); 152 153extern JSBool 154js_AddRootRT(JSRuntime *rt, void *rp, const char *name); 155 156extern JSBool 157js_RemoveRoot(JSRuntime *rt, void *rp); 158 159#ifdef DEBUG 160extern void 161js_DumpNamedRoots(JSRuntime *rt, 162 void (*dump)(const char *name, void *rp, void *data), 163 void *data); 164#endif 165 166extern uint32 167js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); 168 169/* Table of pointers with count valid members. */ 170typedef struct JSPtrTable { 171 size_t count; 172 void **array; 173} JSPtrTable; 174 175extern JSBool 176js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); 177 178/* 179 * The private JSGCThing struct, which describes a gcFreeList element. 180 */ 181struct JSGCThing { 182 JSGCThing *next; 183 uint8 *flagp; 184}; 185 186#define GC_NBYTES_MAX (10 * sizeof(JSGCThing)) 187#define GC_NUM_FREELISTS (GC_NBYTES_MAX / sizeof(JSGCThing)) 188#define GC_FREELIST_NBYTES(i) (((i) + 1) * sizeof(JSGCThing)) 189#define GC_FREELIST_INDEX(n) (((n) / sizeof(JSGCThing)) - 1) 190 191/* 192 * Allocates a new GC thing of the given size. After a successful allocation 193 * the caller must fully initialize the thing before calling any function that 194 * can potentially trigger GC. This will ensure that GC tracing never sees junk 195 * values stored in the partially initialized thing. 196 */ 197extern void * 198js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes); 199 200/* 201 * Allocate a new double jsval and store the result in *vp. vp must be a root. 202 * The function does not copy the result into any weak root. 203 */ 204extern JSBool 205js_NewDoubleInRootedValue(JSContext *cx, jsdouble d, jsval *vp); 206 207/* 208 * Return a pointer to a new GC-allocated and weakly-rooted jsdouble number, 209 * or null when the allocation fails. 210 */ 211extern jsdouble * 212js_NewWeaklyRootedDouble(JSContext *cx, jsdouble d); 213 214extern JSBool 215js_LockGCThingRT(JSRuntime *rt, void *thing); 216 217extern JSBool 218js_UnlockGCThingRT(JSRuntime *rt, void *thing); 219 220extern JSBool 221js_IsAboutToBeFinalized(JSContext *cx, void *thing); 222 223/* 224 * Macro to test if a traversal is the marking phase of GC to avoid exposing 225 * ScriptFilenameEntry to traversal implementations. 226 */ 227#define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL) 228 229#if JS_HAS_XML_SUPPORT 230# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) < JSTRACE_LIMIT) 231#else 232# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING) 233#endif 234 235/* 236 * JS_IS_VALID_TRACE_KIND assumes that JSTRACE_STRING is the last non-xml 237 * trace kind when JS_HAS_XML_SUPPORT is false. 238 */ 239JS_STATIC_ASSERT(JSTRACE_STRING + 1 == JSTRACE_XML); 240 241/* 242 * Trace jsval when JSVAL_IS_OBJECT(v) can be an arbitrary GC thing casted as 243 * JSVAL_OBJECT and js_GetGCThingTraceKind has to be used to find the real 244 * type behind v. 245 */ 246extern void 247js_CallValueTracerIfGCThing(JSTracer *trc, jsval v); 248 249extern void 250js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp); 251 252extern void 253js_TraceRuntime(JSTracer *trc, JSBool allAtoms); 254 255extern JS_FRIEND_API(void) 256js_TraceContext(JSTracer *trc, JSContext *acx); 257 258/* 259 * Kinds of js_GC invocation. 260 */ 261typedef enum JSGCInvocationKind { 262 /* Normal invocation. */ 263 GC_NORMAL = 0, 264 265 /* 266 * Called from js_DestroyContext for last JSContext in a JSRuntime, when 267 * it is imperative that rt->gcPoke gets cleared early in js_GC. 268 */ 269 GC_LAST_CONTEXT = 1, 270 271 /* 272 * Flag bit telling js_GC that the caller has already acquired rt->gcLock. 273 * Currently, this flag is set for the invocation kinds that also preserve 274 * atoms and weak roots, so we don't need another bit for GC_KEEP_ATOMS. 275 */ 276 GC_LOCK_HELD = 0x10, 277 GC_KEEP_ATOMS = GC_LOCK_HELD, 278 279 /* 280 * Called from js_SetProtoOrParent with a request to set an object's proto 281 * or parent slot inserted on rt->setSlotRequests. 282 */ 283 GC_SET_SLOT_REQUEST = GC_LOCK_HELD | 1, 284 285 /* 286 * Called from js_NewGCThing as a last-ditch GC attempt. See comments in 287 * jsgc.c just before js_GC's definition for details. 288 */ 289 GC_LAST_DITCH = GC_LOCK_HELD | 2 290} JSGCInvocationKind; 291 292extern void 293js_GC(JSContext *cx, JSGCInvocationKind gckind); 294 295/* Call this after succesful malloc of memory for GC-related things. */ 296extern void 297js_UpdateMallocCounter(JSContext *cx, size_t nbytes); 298 299typedef struct JSGCArenaInfo JSGCArenaInfo; 300typedef struct JSGCArenaList JSGCArenaList; 301typedef struct JSGCChunkInfo JSGCChunkInfo; 302 303struct JSGCArenaList { 304 JSGCArenaInfo *last; /* last allocated GC arena */ 305 uint16 lastCount; /* number of allocated things in the last 306 arena */ 307 uint16 thingSize; /* size of things to allocate on this list 308 */ 309 JSGCThing *freeList; /* list of free GC things */ 310}; 311 312typedef union JSGCDoubleCell JSGCDoubleCell; 313 314union JSGCDoubleCell { 315 double number; 316 JSGCDoubleCell *link; 317}; 318 319JS_STATIC_ASSERT(sizeof(JSGCDoubleCell) == sizeof(double)); 320 321typedef struct JSGCDoubleArenaList { 322 JSGCArenaInfo *first; /* first allocated GC arena */ 323 jsbitmap *nextDoubleFlags; /* bitmask with flags to check for free 324 things */ 325} JSGCDoubleArenaList; 326 327typedef struct JSGCFreeListSet JSGCFreeListSet; 328 329struct JSGCFreeListSet { 330 JSGCThing *array[GC_NUM_FREELISTS]; 331 JSGCFreeListSet *link; 332}; 333 334extern const JSGCFreeListSet js_GCEmptyFreeListSet; 335 336extern void 337js_RevokeGCLocalFreeLists(JSContext *cx); 338 339struct JSWeakRoots { 340 /* Most recently created things by type, members of the GC's root set. */ 341 void *newborn[GCX_NTYPES]; 342 343 /* Atom root for the last-looked-up atom on this context. */ 344 jsval lastAtom; 345 346 /* Root for the result of the most recent js_InternalInvoke call. */ 347 jsval lastInternalResult; 348}; 349 350JS_STATIC_ASSERT(JSVAL_NULL == 0); 351#define JS_CLEAR_WEAK_ROOTS(wr) (memset((wr), 0, sizeof(JSWeakRoots))) 352 353/* 354 * Increase runtime->gcBytes by sz bytes to account for an allocation outside 355 * the GC that will be freed only after the GC is run. The function may run 356 * the last ditch GC to ensure that gcBytes does not exceed gcMaxBytes. It will 357 * fail if the latter is not possible. 358 * 359 * This function requires that runtime->gcLock is held on entry. On successful 360 * return the lock is still held and on failure it will be released with 361 * the error reported. 362 */ 363extern JSBool 364js_AddAsGCBytes(JSContext *cx, size_t sz); 365 366extern void 367js_RemoveAsGCBytes(JSRuntime* rt, size_t sz); 368 369#ifdef DEBUG_notme 370#define JS_GCMETER 1 371#endif 372 373#ifdef JS_GCMETER 374 375typedef struct JSGCArenaStats { 376 uint32 alloc; /* allocation attempts */ 377 uint32 localalloc; /* allocations from local lists */ 378 uint32 retry; /* allocation retries after running the GC */ 379 uint32 fail; /* allocation failures */ 380 uint32 nthings; /* live GC things */ 381 uint32 maxthings; /* maximum of live GC cells */ 382 double totalthings; /* live GC things the GC scanned so far */ 383 uint32 narenas; /* number of arena in list before the GC */ 384 uint32 newarenas; /* new arenas allocated before the last GC */ 385 uint32 livearenas; /* number of live arenas after the last GC */ 386 uint32 maxarenas; /* maximum of allocated arenas */ 387 uint32 totalarenas; /* total number of arenas with live things that 388 GC scanned so far */ 389} JSGCArenaStats; 390 391typedef struct JSGCStats { 392 uint32 finalfail; /* finalizer calls allocator failures */ 393 uint32 lockborn; /* things born locked */ 394 uint32 lock; /* valid lock calls */ 395 uint32 unlock; /* valid unlock calls */ 396 uint32 depth; /* mark tail recursion depth */ 397 uint32 maxdepth; /* maximum mark tail recursion depth */ 398 uint32 cdepth; /* mark recursion depth of C functions */ 399 uint32 maxcdepth; /* maximum mark recursion depth of C functions */ 400 uint32 untraced; /* number of times tracing of GC thing's children were 401 delayed due to a low C stack */ 402#ifdef DEBUG 403 uint32 maxuntraced;/* maximum number of things with children to trace 404 later */ 405#endif 406 uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */ 407 uint32 poke; /* number of potentially useful GC calls */ 408 uint32 afree; /* thing arenas freed so far */ 409 uint32 stackseg; /* total extraordinary stack segments scanned */ 410 uint32 segslots; /* total stack segment jsval slots scanned */ 411 uint32 nclose; /* number of objects with close hooks */ 412 uint32 maxnclose; /* max number of objects with close hooks */ 413 uint32 closelater; /* number of close hooks scheduled to run */ 414 uint32 maxcloselater; /* max number of close hooks scheduled to run */ 415 416 JSGCArenaStats arenaStats[GC_NUM_FREELISTS]; 417 JSGCArenaStats doubleArenaStats; 418} JSGCStats; 419 420extern JS_FRIEND_API(void) 421js_DumpGCStats(JSRuntime *rt, FILE *fp); 422 423#endif /* JS_GCMETER */ 424 425JS_END_EXTERN_C 426 427#endif /* jsgc_h___ */