1998-03-28 05:44:41 +03:00
|
|
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
*
|
1999-09-29 03:12:09 +04:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1998-03-28 05:44:41 +03:00
|
|
|
*
|
1999-09-29 03:12:09 +04:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1998-03-28 05:44:41 +03:00
|
|
|
*
|
1999-09-29 03:12:09 +04:00
|
|
|
* The Original Code is Mozilla Communicator client code, released
|
|
|
|
* March 31, 1998.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-03-28 05:44:41 +03:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-09-29 03:12:09 +04:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
2000-08-26 06:30:22 +04:00
|
|
|
* Contributor(s):
|
1999-09-29 03:12:09 +04:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the
|
|
|
|
* terms of the GNU Public License (the "GPL"), in which case the
|
|
|
|
* provisions of the GPL are applicable instead of those above.
|
|
|
|
* If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of the GPL and not to allow others to use your
|
|
|
|
* version of this file under the NPL, indicate your decision by
|
|
|
|
* deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this
|
|
|
|
* file under either the NPL or the GPL.
|
1998-03-28 05:44:41 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef jsgc_h___
|
|
|
|
#define jsgc_h___
|
|
|
|
/*
|
|
|
|
* JS Garbage Collector.
|
|
|
|
*/
|
2000-08-26 06:30:22 +04:00
|
|
|
#include "jsprvtd.h"
|
1998-03-28 05:44:41 +03:00
|
|
|
#include "jspubtd.h"
|
2001-04-04 09:53:58 +04:00
|
|
|
#include "jsdhash.h"
|
1998-03-28 05:44:41 +03:00
|
|
|
|
1998-10-14 14:22:38 +04:00
|
|
|
JS_BEGIN_EXTERN_C
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
/* GC thing type indexes. */
|
2000-09-03 00:37:37 +04:00
|
|
|
#define GCX_OBJECT 0 /* JSObject */
|
|
|
|
#define GCX_STRING 1 /* JSString */
|
|
|
|
#define GCX_DOUBLE 2 /* jsdouble */
|
|
|
|
#define GCX_EXTERNAL_STRING 3 /* JSString w/ external chars */
|
Fixes to make JS GC truly exact:
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
2000-09-14 10:14:45 +04:00
|
|
|
#define GCX_NTYPES_LOG2 3 /* type index bits */
|
2000-09-03 00:37:37 +04:00
|
|
|
#define GCX_NTYPES JS_BIT(GCX_NTYPES_LOG2)
|
1998-03-28 05:44:41 +03:00
|
|
|
|
Fixes to make JS GC truly exact:
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
2000-09-14 10:14:45 +04:00
|
|
|
/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */
|
2000-09-03 00:37:37 +04:00
|
|
|
#define GCF_TYPEMASK JS_BITMASK(GCX_NTYPES_LOG2)
|
|
|
|
#define GCF_MARK JS_BIT(GCX_NTYPES_LOG2)
|
|
|
|
#define GCF_FINAL JS_BIT(GCX_NTYPES_LOG2 + 1)
|
|
|
|
#define GCF_LOCKSHIFT (GCX_NTYPES_LOG2 + 2) /* lock bit shift and mask */
|
|
|
|
#define GCF_LOCKMASK (JS_BITMASK(8 - GCF_LOCKSHIFT) << GCF_LOCKSHIFT)
|
|
|
|
#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */
|
1998-03-28 05:44:41 +03:00
|
|
|
|
2001-08-21 06:53:19 +04:00
|
|
|
extern uint8 *
|
|
|
|
js_GetGCThingFlags(void *thing);
|
|
|
|
|
2001-04-04 08:30:41 +04:00
|
|
|
/* These are compatible with JSDHashEntryStub. */
|
|
|
|
struct JSGCRootHashEntry {
|
|
|
|
JSDHashEntryHdr hdr;
|
|
|
|
void *root;
|
|
|
|
const char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct JSGCLockHashEntry {
|
|
|
|
JSDHashEntryHdr hdr;
|
|
|
|
const JSGCThing *thing;
|
|
|
|
uint32 count;
|
|
|
|
};
|
|
|
|
|
1998-03-28 05:44:41 +03:00
|
|
|
#if 1
|
|
|
|
/*
|
|
|
|
* Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
|
Fixes to make JS GC truly exact:
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
2000-09-14 10:14:45 +04:00
|
|
|
* loading oldval. XXX remove implied force, fix jsinterp.c's "second arg
|
|
|
|
* ignored", etc.
|
1998-03-28 05:44:41 +03:00
|
|
|
*/
|
|
|
|
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
|
|
|
|
#else
|
|
|
|
#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
|
|
|
|
#endif
|
|
|
|
|
2000-09-03 00:37:37 +04:00
|
|
|
extern intN
|
|
|
|
js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
|
|
|
|
JSStringFinalizeOp newop);
|
|
|
|
|
1998-03-28 05:44:41 +03:00
|
|
|
extern JSBool
|
|
|
|
js_InitGC(JSRuntime *rt, uint32 maxbytes);
|
|
|
|
|
|
|
|
extern void
|
|
|
|
js_FinishGC(JSRuntime *rt);
|
|
|
|
|
|
|
|
extern JSBool
|
1998-04-24 04:31:11 +04:00
|
|
|
js_AddRoot(JSContext *cx, void *rp, const char *name);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
2001-03-27 10:04:44 +04:00
|
|
|
extern JSBool
|
|
|
|
js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
|
|
|
|
|
1998-03-28 05:44:41 +03:00
|
|
|
extern JSBool
|
1999-06-23 18:18:56 +04:00
|
|
|
js_RemoveRoot(JSRuntime *rt, void *rp);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
extern void *
|
|
|
|
js_AllocGCThing(JSContext *cx, uintN flags);
|
|
|
|
|
|
|
|
extern JSBool
|
|
|
|
js_LockGCThing(JSContext *cx, void *thing);
|
|
|
|
|
|
|
|
extern JSBool
|
|
|
|
js_UnlockGCThing(JSContext *cx, void *thing);
|
|
|
|
|
2001-02-02 11:44:24 +03:00
|
|
|
extern JSBool
|
|
|
|
js_IsAboutToBeFinalized(JSContext *cx, void *thing);
|
|
|
|
|
2000-08-26 06:30:22 +04:00
|
|
|
extern void
|
|
|
|
js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg);
|
|
|
|
|
2000-12-06 09:03:30 +03:00
|
|
|
/* We avoid a large number of unnecessary calls by doing the flag check first */
|
|
|
|
#define GC_MARK_ATOM(cx, atom, arg) \
|
|
|
|
JS_BEGIN_MACRO \
|
|
|
|
if (!((atom)->flags & ATOM_MARK)) \
|
|
|
|
js_MarkAtom(cx, atom, arg); \
|
|
|
|
JS_END_MACRO
|
|
|
|
|
2000-08-26 06:30:22 +04:00
|
|
|
extern void
|
|
|
|
js_MarkGCThing(JSContext *cx, void *thing, void *arg);
|
|
|
|
|
|
|
|
#ifdef GC_MARK_DEBUG
|
|
|
|
|
|
|
|
typedef struct GCMarkNode GCMarkNode;
|
|
|
|
|
|
|
|
struct GCMarkNode {
|
|
|
|
void *thing;
|
|
|
|
const char *name;
|
|
|
|
GCMarkNode *next;
|
|
|
|
GCMarkNode *prev;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define GC_MARK(_cx, _thing, _name, _prev) \
|
|
|
|
JS_BEGIN_MACRO \
|
|
|
|
GCMarkNode _node; \
|
|
|
|
_node.thing = _thing; \
|
|
|
|
_node.name = _name; \
|
|
|
|
_node.next = NULL; \
|
|
|
|
_node.prev = _prev; \
|
|
|
|
if (_prev) ((GCMarkNode *)(_prev))->next = &_node; \
|
|
|
|
js_MarkGCThing(_cx, _thing, &_node); \
|
|
|
|
JS_END_MACRO
|
|
|
|
|
|
|
|
#else /* !GC_MARK_DEBUG */
|
|
|
|
|
|
|
|
#define GC_MARK(cx, thing, name, prev) js_MarkGCThing(cx, thing, NULL)
|
|
|
|
|
|
|
|
#endif /* !GC_MARK_DEBUG */
|
|
|
|
|
1998-04-24 04:31:11 +04:00
|
|
|
extern JS_FRIEND_API(void)
|
1998-03-28 05:44:41 +03:00
|
|
|
js_ForceGC(JSContext *cx);
|
|
|
|
|
2000-07-08 06:06:01 +04:00
|
|
|
/*
|
|
|
|
* Flags to modify how a GC marks and sweeps:
|
|
|
|
* GC_KEEP_ATOMS Don't sweep unmarked atoms, they may be in use by the
|
|
|
|
* compiler, or by an API function that calls js_Atomize,
|
|
|
|
* when the GC is called from js_AllocGCThing, due to a
|
|
|
|
* malloc failure or runtime GC-thing limit.
|
|
|
|
* GC_LAST_CONTEXT Called from js_DestroyContext for last JSContext in a
|
|
|
|
* JSRuntime, when it is imperative that rt->gcPoke gets
|
|
|
|
* cleared early in js_GC, if it is set.
|
|
|
|
*/
|
|
|
|
#define GC_KEEP_ATOMS 0x1
|
|
|
|
#define GC_LAST_CONTEXT 0x2
|
|
|
|
|
1998-03-28 05:44:41 +03:00
|
|
|
extern void
|
2000-07-08 06:06:01 +04:00
|
|
|
js_GC(JSContext *cx, uintN gcflags);
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
#ifdef JS_GCMETER
|
|
|
|
|
|
|
|
typedef struct JSGCStats {
|
|
|
|
uint32 alloc; /* number of allocation attempts */
|
|
|
|
uint32 freelen; /* gcFreeList length */
|
|
|
|
uint32 recycle; /* number of things recycled through gcFreeList */
|
|
|
|
uint32 retry; /* allocation attempt retries after running the GC */
|
|
|
|
uint32 fail; /* allocation failures */
|
Fixes to make JS GC truly exact:
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
2000-09-14 10:14:45 +04:00
|
|
|
uint32 finalfail; /* finalizer calls allocator failures */
|
1998-03-28 05:44:41 +03:00
|
|
|
uint32 lock; /* valid lock calls */
|
|
|
|
uint32 unlock; /* valid unlock calls */
|
|
|
|
uint32 stuck; /* stuck reference counts seen by lock calls */
|
|
|
|
uint32 unstuck; /* unlock calls that saw a stuck lock count */
|
|
|
|
uint32 depth; /* mark recursion depth */
|
|
|
|
uint32 maxdepth; /* maximum mark recursion depth */
|
|
|
|
uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */
|
|
|
|
uint32 poke; /* number of potentially useful GC calls */
|
|
|
|
uint32 nopoke; /* useless GC calls where js_PokeGC was not set */
|
|
|
|
uint32 afree; /* thing arenas freed so far */
|
Fixes to make JS GC truly exact:
- All jsvals for which JSVAL_IS_GCTHING evaluates to true must contain tagged
pointers into the GC heap -- therefore jsapi.c's JS_DefineConstDoubles cannot
"cheat" by tagging addresses of static jsdoubles to avoid js_NewNumberValue.
- Finalization is now interleaved with the Sweep phase, to avoid allocating
memory for finalization records while sweeping. Instead, the JSRuntime holds a
preallocated JSGCThing vector (gcFinalVec) that the Sweep phase fills and
flushes via gc_finalize_phase, repeatedly.
This means that finalizers cannot allocate a new GC thing, an incompatible but
plausible change. js_AllocGCThing asserts and then checks whether it is called
while rt->gcLevel is non-zero, and fails the allocation attempt if so. But this
fixes bug 38942, where the old sweep-then-finalize with a sweep => malloc
dependency could lead to memory exhaustion.
- Instead of scanning whole stackPool arenas, which led to UMRs (bug 27924) and
sometimes to gross over-scanning that depended on the GC bounds-checking all
thing pointers against its heap, we scan exactly those stack slots in use:
- arguments reachable from fp->argv;
- variables reachable from fp->vars;
- operands now reachable from fp->spbase, bounded above by the lesser of
fp->sp or fp->spbase + fp->script->depth for an interpreted frame; if the
latter, fp->sp has advanced logically above the operand budget, in order to
call a native method, and all unused slots from fp->sp up to depth slots
above fp->spbase must be set to JSVAL_VOID;
- stack segments pushed when calling native methods, prefixed by JSStackHeader
structs and linked from cx->stackSegments through each header.
The stack segment headers help the GC avoid scanning unused portions of the
stack: the generating pc slots running depth slots below fp->spbase, and slots
at the end of an arena that aren't sufficient to satisfy a contiguous allocation
for more args, vars, or operands.
- Exact GC means the stack pointer must remain above live operands until the
interpreter is done with them, so jsinterp.c got heavily whacked. Instead of
POPs of various kinds followed by a PUSH for binary operators (e.g.), we use
FETCH and STORE macros that index by -1 and -2 from sp, and minimize adjustments
to sp. When sp is homed to fp->sp, this allows js_DecompileValueGenerator to
find the value reliably, and if possible its generating pc.
- Finally, the O(n**2) growth rate of gc_find_flags has been fixed, using the
scheme sketched in bug 49816 and documented in a new major comment in jsgc.c.
Briefly, by allocating flags and things from one arena, we can align things on
1024-byte "thing page" boundaries, and use JSGCPageInfo headers in each page to
find a given thing's flags in O(1) time.
/be
2000-09-14 10:14:45 +04:00
|
|
|
uint32 stackseg; /* total extraordinary stack segments scanned */
|
|
|
|
uint32 segslots; /* total stack segment jsval slots scanned */
|
1998-03-28 05:44:41 +03:00
|
|
|
} JSGCStats;
|
|
|
|
|
|
|
|
extern void
|
|
|
|
js_DumpGCStats(JSRuntime *rt, FILE *fp);
|
|
|
|
|
|
|
|
#endif /* JS_GCMETER */
|
|
|
|
|
1998-10-14 14:22:38 +04:00
|
|
|
JS_END_EXTERN_C
|
1998-03-28 05:44:41 +03:00
|
|
|
|
|
|
|
#endif /* jsgc_h___ */
|