/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jsgc.h

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs · C++ Header · 427 lines · 205 code · 71 blank · 151 comment · 10 complexity · e4bd457fe5552d412dbabd0784fe63d9 MD5 · raw file

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