PageRenderTime 50ms CodeModel.GetById 38ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 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___ */