From d3a3926b3446f75e79e28de7747003e58a46dc68 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Tue, 18 May 2010 17:25:12 -0700 Subject: [PATCH] Fix bugs --- js/src/jsapi.cpp | 8 +-- js/src/jsapi.h | 27 ++++++++- js/src/jsarray.cpp | 2 +- js/src/jsatom.cpp | 6 +- js/src/jscntxt.cpp | 11 ++-- js/src/jscntxtinlines.h | 33 +++++------ js/src/jsdbgapi.cpp | 2 +- js/src/jsfun.cpp | 4 +- js/src/jsfun.h | 2 +- js/src/jsgc.cpp | 38 ++++-------- js/src/jsgc.h | 126 ++++++++++++++++++++++------------------ js/src/jsinterp.cpp | 1 + js/src/jsinterp.h | 2 +- js/src/jsiter.cpp | 6 +- js/src/jsobj.cpp | 10 +--- js/src/jsobj.h | 6 +- js/src/jsops.cpp | 10 +++- js/src/jspubtd.h | 33 +++++++---- js/src/jsscope.cpp | 14 ++--- js/src/jsscope.h | 3 - js/src/jsscript.cpp | 8 +-- js/src/jsxml.cpp | 8 +-- js/src/jsxml.h | 6 +- 23 files changed, 189 insertions(+), 177 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 951e5f888d4..f5f3a9deb0d 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1897,7 +1897,7 @@ JS_TraceRuntime(JSTracer *trc) JS_PUBLIC_API(void) JS_CallTracer(JSTracer *trc, void *thing, uint32 kind) { - CallGCMarker(trc, thing, kind); + MarkRaw(trc, thing, kind); } #ifdef DEBUG @@ -2289,8 +2289,7 @@ JS_MarkGCThing(JSContext *cx, jsval v, const char *name, void *arg) #ifdef JS_THREADSAFE JS_ASSERT(cx->runtime->gcThread == trc->context->thread); #endif - JS_SET_TRACING_NAME(trc, name ? name : "unknown"); - CallGCMarkerIfGCThing(trc, Valueify(v)); + MarkValue(trc, Valueify(v), name ? name : "unknown"); } extern JS_PUBLIC_API(JSBool) @@ -3880,8 +3879,7 @@ prop_iter_trace(JSTracer *trc, JSObject *obj) } else { /* Non-native case: mark each id in the JSIdArray private. */ JSIdArray *ida = (JSIdArray *) pdata; - for (jsint i = 0, n = ida->length; i < n; i++) - js_TraceId(trc, ida->vector[i]); + MarkBoxedWordRange(trc, ida->length, ida->vector, "prop iter"); } } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 66dc6713fc1..1b62ff59abb 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3001,7 +3001,7 @@ struct FunObjOrUndefinedTag { }; struct NonFunObjTag { - explicit NonFunObjTag(JSObject &o) : obj(obj) {} + explicit NonFunObjTag(JSObject &obj) : obj(obj) {} JSObject &obj; }; @@ -3072,8 +3072,29 @@ class Value #endif struct { int32 first; int32 second; } bits; }; + JS_STATIC_ASSERT(sizeof(Data) == sizeof(double)); - MaskType mask; + enum TypeNames { + NullMask = JSVAL_NULL_MASK, + UndefinedMask = JSVAL_UNDEFINED_MASK, + Int32Mask = JSVAL_INT32_MASK, + DoubleMask = JSVAL_DOUBLE_MASK, + StringMask = JSVAL_STRING_MASK, + NonFunObjMask = JSVAL_NONFUNOBJ_MASK, + FunObjMask = JSVAL_FUNOBJ_MASK, + BooleanMask = JSVAL_BOOLEAN_MASK, + MagicMask = JSVAL_MAGIC_MASK, + + ObjectMask = JSVAL_OBJECT_MASK, + NumberMask = JSVAL_NUMBER_MASK, + GCThingMask = JSVAL_GCTHING_MASK + }; + JS_STATIC_ASSERT(sizeof(TypeNames) <= sizeof(MaskType)); + + union { + MaskType mask; + TypeNames typeName; + }; JS_INSERT_VALUE_PADDING() Data data; @@ -3455,7 +3476,7 @@ class Value JS_ASSERT(mask == JSVAL_INT32_MASK); return data.u32; } -}; +} VALUE_ALIGNMENT; struct AssertLayoutCompatible { diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 8d9e7ee0522..f7088db1bce 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1072,7 +1072,7 @@ array_trace(JSTracer *trc, JSObject *obj) uint32 capacity = obj->getDenseArrayCapacity(); for (uint32 i = 0; i < capacity; i++) - CallGCMarkerIfGCThing(trc, obj->getDenseArrayElement(i), "dense_array_elems"); + MarkValue(trc, obj->getDenseArrayElement(i), "dense_array_elems"); } extern JSObjectOps js_ArrayObjectOps; diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index 693d91573ce..03f5f577906 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -542,8 +542,8 @@ js_locked_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr, return JS_DHASH_NEXT; } JS_SET_TRACING_INDEX(trc, "locked_atom", (size_t)number); - CallGCMarker(trc, ATOM_ENTRY_KEY(entry), - IS_STRING_TABLE(table) ? JSTRACE_STRING : JSTRACE_DOUBLE); + MarkRaw(trc, ATOM_ENTRY_KEY(entry), + IS_STRING_TABLE(table) ? JSTRACE_STRING : JSTRACE_DOUBLE); return JS_DHASH_NEXT; } @@ -562,7 +562,7 @@ js_pinned_atom_tracer(JSDHashTable *table, JSDHashEntryHdr *hdr, ? "pinned_atom" : "interned_atom", (size_t)number); - CallGCMarker(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING); + MarkRaw(trc, ATOM_ENTRY_KEY(entry), JSTRACE_STRING); } return JS_DHASH_NEXT; } diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index d8e07b2252e..92a65addfbf 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -217,22 +217,22 @@ StackSpace::mark(JSTracer *trc) /* Mark slots/args trailing off of the last stack frame. */ JSStackFrame *fp = cs->getCurrentFrame(); - TraceValues(trc, fp->slots(), end, "stack"); + MarkValueRange(trc, fp->slots(), end, "stack"); /* Mark stack frames and slots/args between stack frames. */ JSStackFrame *initialFrame = cs->getInitialFrame(); for (JSStackFrame *f = fp; f != initialFrame; f = f->down) { js_TraceStackFrame(trc, f); - TraceValues(trc, f->down->slots(), f->argEnd(), "stack"); + MarkValueRange(trc, f->down->slots(), f->argEnd(), "stack"); } /* Mark initialFrame stack frame and leading args. */ js_TraceStackFrame(trc, initialFrame); - TraceValues(trc, cs->getInitialArgBegin(), initialFrame->argEnd(), "stack"); + MarkValueRange(trc, cs->getInitialArgBegin(), initialFrame->argEnd(), "stack"); } else { /* Mark slots/args trailing off callstack. */ JS_ASSERT(end == cs->getInitialArgEnd()); - TraceValues(trc, cs->getInitialArgBegin(), cs->getInitialArgEnd(), "stack"); + MarkValueRange(trc, cs->getInitialArgBegin(), cs->getInitialArgEnd(), "stack"); } end = cs->previousCallStackEnd(); } @@ -1678,8 +1678,7 @@ MarkLocalRoots(JSTracer *trc, JSLocalRootStack *lrs) m = n & JSLRS_CHUNK_MASK; void *thing = lrc->roots[m]; JS_ASSERT(thing != NULL); - JS_SET_TRACING_INDEX(trc, "local_root", n); - CallGCMarkerForGCThing(trc, thing); + MarkGCThing(trc, thing, "local_root", n); if (m == 0) lrc = lrc->down; } diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 08ba46b9ce6..762846d8f89 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -170,7 +170,7 @@ StackSpace::popInlineFrame(JSContext *cx, JSStackFrame *up, JSStackFrame *down) void AutoIdArray::trace(JSTracer *trc) { JS_ASSERT(tag == IDARRAY); - TraceBoxedWords(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray"); + MarkBoxedWordRange(trc, idArray->length, idArray->vector, "JSAutoIdArray.idArray"); } class AutoNamespaces : protected AutoGCRooter { @@ -189,8 +189,7 @@ AutoGCRooter::trace(JSTracer *trc) { switch (tag) { case JSVAL: - JS_SET_TRACING_NAME(trc, "js::AutoValueRooter.val"); - CallGCMarkerIfGCThing(trc, static_cast(this)->val); + MarkValue(trc, static_cast(this)->val, "js::AutoValueRooter.val"); return; case SPROP: @@ -216,7 +215,7 @@ AutoGCRooter::trace(JSTracer *trc) case IDARRAY: { JSIdArray *ida = static_cast(this)->idArray; - TraceBoxedWords(trc, ida->length, ida->vector, "js::AutoIdArray.idArray"); + MarkBoxedWordRange(trc, ida->length, ida->vector, "js::AutoIdArray.idArray"); return; } @@ -226,17 +225,18 @@ AutoGCRooter::trace(JSTracer *trc) for (size_t i = 0, len = descriptors.length(); i < len; i++) { PropertyDescriptor &desc = descriptors[i]; - CallGCMarkerIfGCThing(trc, desc.value, "PropertyDescriptor::value"); - CallGCMarkerIfGCThing(trc, desc.get, "PropertyDescriptor::get"); - CallGCMarkerIfGCThing(trc, desc.set, "PropertyDescriptor::set"); - js_TraceId(trc, desc.id); + MarkValue(trc, desc.value, "PropertyDescriptor::value"); + MarkValue(trc, desc.get, "PropertyDescriptor::get"); + MarkValue(trc, desc.set, "PropertyDescriptor::set"); + MarkBoxedWord(trc, desc.id, "desc.id"); } return; } case NAMESPACES: { JSXMLArray &array = static_cast(this)->array; - TraceObjectVector(trc, reinterpret_cast(array.vector), array.length); + MarkObjectVector(trc, array.length, reinterpret_cast(array.vector), + "JSXMLArray"); array.cursors->trace(trc); return; } @@ -246,32 +246,29 @@ AutoGCRooter::trace(JSTracer *trc) return; case OBJECT: - if (JSObject *obj = static_cast(this)->obj) { - JS_SET_TRACING_NAME(trc, "js::AutoObjectRooter.obj"); - CallGCMarker(trc, obj, JSTRACE_OBJECT); - } + if (JSObject *obj = static_cast(this)->obj) + MarkObject(trc, obj, "js::AutoObjectRooter.obj"); return; case ID: - JS_SET_TRACING_NAME(trc, "js::AutoIdRooter.val"); - CallGCMarkerIfGCThing(trc, static_cast(this)->idval); + MarkBoxedWord(trc, static_cast(this)->idval, "js::AutoIdRooter.val"); return; case VALVECTOR: { Vector &vector = static_cast(this)->vector; - TraceValues(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector"); + MarkValueRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector"); return; } case BOXEDVECTOR: { Vector &vector = static_cast(this)->vector; - TraceBoxedWords(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector"); + MarkBoxedWordRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector"); return; } } JS_ASSERT(tag >= 0); - TraceValues(trc, tag, static_cast(this)->array, "js::AutoArrayRooter.array"); + MarkValueRange(trc, tag, static_cast(this)->array, "js::AutoArrayRooter.array"); } } /* namespace js */ diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index 41f617ce516..08f2fd99e46 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -297,7 +297,7 @@ js_MarkTraps(JSTracer *trc) for (JSTrap *trap = (JSTrap *) rt->trapList.next; &trap->links != &rt->trapList; trap = (JSTrap *) trap->links.next) { - CallGCMarkerIfGCThing(trc, Valueify(trap->closure), "trap->closure"); + MarkValue(trc, Valueify(trap->closure), "trap->closure"); } } diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 98c438d6c61..36277d37e77 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -2992,7 +2992,7 @@ trace_local_names_enumerator(JSDHashTable *table, JSDHashEntryHdr *hdr, JS_SET_TRACING_INDEX(trc, entry->localKind == JSLOCAL_ARG ? "arg" : "var", entry->index); - CallGCMarker(trc, ATOM_TO_STRING(entry->name), JSTRACE_STRING); + MarkRaw(trc, ATOM_TO_STRING(entry->name), JSTRACE_STRING); return JS_DHASH_NEXT; } @@ -3017,7 +3017,7 @@ TraceLocalNames(JSTracer *trc, JSFunction *fun) JS_SET_TRACING_INDEX(trc, i < fun->nargs ? "arg" : "var", i < fun->nargs ? i : i - fun->nargs); - CallGCMarker(trc, ATOM_TO_STRING(atom), JSTRACE_STRING); + MarkRaw(trc, ATOM_TO_STRING(atom), JSTRACE_STRING); } } while (i != 0); } else { diff --git a/js/src/jsfun.h b/js/src/jsfun.h index fd556d7eb08..4f5187fd044 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -312,7 +312,7 @@ js_TraceFunction(JSTracer *trc, JSFunction *fun); extern void js_FinalizeFunction(JSContext *cx, JSFunction *fun); -extern JSObject * +extern JSObject * JS_FASTCALL js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, JSObject *proto); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index a052a085d81..01e6e79dc68 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1983,7 +1983,7 @@ MarkDelayedChildren(JSTracer *trc) namespace js { void -CallGCMarker(JSTracer *trc, void *thing, uint32 kind) +MarkRaw(JSTracer *trc, void *thing, uint32 kind) { JSContext *cx; JSRuntime *rt; @@ -2083,7 +2083,7 @@ CallGCMarker(JSTracer *trc, void *thing, uint32 kind) } void -CallGCMarkerForGCThing(JSTracer *trc, void *thing) +MarkGCThingRaw(JSTracer *trc, void *thing) { #ifdef DEBUG /* @@ -2098,7 +2098,7 @@ CallGCMarkerForGCThing(JSTracer *trc, void *thing) return; uint32 kind = js_GetGCThingTraceKind(thing); - CallGCMarker(trc, thing, kind); + MarkRaw(trc, thing, kind); } } /* namespace js */ @@ -2158,9 +2158,9 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry) JS_SET_TRACING_NAME(trc, entry.value.name ? entry.value.name : "root"); if (entry.value.type == JS_GC_ROOT_GCTHING_PTR) - CallGCMarkerForGCThing(trc, entry.key); + MarkGCThingRaw(trc, entry.key); else - CallGCMarkerIfGCThing(trc, *static_cast(entry.key)); + MarkValueRaw(trc, *static_cast(entry.key)); } static JSDHashOperator @@ -2178,21 +2178,6 @@ gc_lock_traversal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, return JS_DHASH_NEXT; } -namespace js { - -void -TraceObjectVector(JSTracer *trc, JSObject **vec, uint32 len) -{ - for (uint32 i = 0; i < len; i++) { - if (JSObject *obj = vec[i]) { - JS_SET_TRACING_INDEX(trc, "vector", i); - CallGCMarker(trc, obj, JSTRACE_OBJECT); - } - } -} - -} - void js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp) { @@ -2205,8 +2190,8 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp) js_TraceScript(trc, fp->script); /* Allow for primitive this parameter due to JSFUN_THISP_* flags. */ - CallGCMarkerIfGCThing(trc, fp->thisv, "this"); - CallGCMarkerIfGCThing(trc, fp->rval, "rval"); + MarkValue(trc, fp->thisv, "this"); + MarkValue(trc, fp->rval, "rval"); if (fp->scopeChain) JS_CALL_OBJECT_TRACER(trc, fp->scopeChain, "scope chain"); } @@ -2241,8 +2226,9 @@ JSWeakRoots::mark(JSTracer *trc) } if (newbornDouble) JS_CALL_DOUBLE_TRACER(trc, newbornDouble, "newborn_double"); - CallGCMarkerIfGCThing(trc, ATOM_TO_JSID(lastAtom), "lastAtom"); - CallGCMarkerForGCThing(trc, lastInternalResult, "lastInternalResult"); + if (lastAtom) + MarkBoxedWord(trc, ATOM_TO_JSID(lastAtom), "lastAtom"); + MarkGCThing(trc, lastInternalResult, "lastInternalResult"); } void @@ -2255,7 +2241,7 @@ js_TraceContext(JSTracer *trc, JSContext *acx) JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object"); acx->weakRoots.mark(trc); if (acx->throwing) { - CallGCMarkerIfGCThing(trc, acx->exception, "exception"); + MarkValue(trc, acx->exception, "exception"); } else { /* Avoid keeping GC-ed junk stored in JSContext.exception. */ acx->exception.setNull(); @@ -2269,7 +2255,7 @@ js_TraceContext(JSTracer *trc, JSContext *acx) js_TraceRegExpStatics(trc, acx); - CallGCMarkerIfGCThing(trc, acx->iterValue, "iterValue"); + MarkValue(trc, acx->iterValue, "iterValue"); #ifdef JS_TRACER TracerState* state = acx->tracerState; diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 36442ac2ef8..d3a045df9df 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -464,90 +464,100 @@ js_MarkTraps(JSTracer *trc); namespace js { +/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */ void -CallGCMarker(JSTracer *trc, void *thing, uint32 kind); +MarkRaw(JSTracer *trc, void *thing, uint32 kind); static inline void -CallGCMarkerForGCThing(JSTracer *trc, const js::Value &v) -{ - CallGCMarker(trc, v.asGCThing(), v.traceKind()); -} - -void -CallGCMarkerForGCThing(JSTracer *trc, void *thing); - -static inline void -CallGCMarkerForGCThing(JSTracer *trc, void *thing, const char *name) +MarkObject(JSTracer *trc, JSObject *obj, const char *name) { JS_SET_TRACING_NAME(trc, name); - CallGCMarkerForGCThing(trc, thing); + return MarkRaw(trc, obj, JSTRACE_OBJECT); } static inline void -CallGCMarkerIfGCThing(JSTracer *trc, const js::Value &v) +MarkObjectVector(JSTracer *trc, uint32 len, JSObject **vec, const char *name) { - if (v.isGCThing()) - CallGCMarkerForGCThing(trc, v); -} - -static inline void -CallGCMarkerIfGCThing(JSTracer *trc, const js::Value &v, const char *name) -{ - JS_SET_TRACING_NAME(trc, name); - if (v.isGCThing()) - CallGCMarkerForGCThing(trc, v); -} - -static inline void -CallGCMarkerIfGCThing(JSTracer *trc, jsid id) -{ - if (JSID_IS_GCTHING(id)) - CallGCMarker(trc, JSID_TO_GCTHING(id), JSID_TRACE_KIND(id)); -} - -static inline void -CallGCMarkerIfGCThing(JSTracer *trc, jsid id, const char *name) -{ - JS_SET_TRACING_NAME(trc, name); - if (JSID_IS_GCTHING(id)) - CallGCMarker(trc, JSID_TO_GCTHING(id), JSID_TRACE_KIND(id)); -} - -void -TraceObjectVector(JSTracer *trc, JSObject **vec, uint32 len); - -JS_ALWAYS_INLINE void -TraceValues(JSTracer *trc, Value *beg, Value *end, const char *name) -{ - for (Value *vp = beg; vp < end; ++vp) { - if (vp->isGCThing()) { - JS_SET_TRACING_INDEX(trc, name, vp - beg); - CallGCMarker(trc, vp->asGCThing(), vp->traceKind()); + for (uint32 i = 0; i < len; i++) { + if (JSObject *obj = vec[i]) { + JS_SET_TRACING_INDEX(trc, name, i); + MarkRaw(trc, obj, JSTRACE_OBJECT); } } } -JS_ALWAYS_INLINE void -TraceValues(JSTracer *trc, size_t len, Value *vec, const char *name) +/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */ +static inline void +MarkValueRaw(JSTracer *trc, const js::Value &v) { - TraceValues(trc, vec, vec + len, name); + if (v.isGCThing()) + return MarkRaw(trc, v.asGCThing(), v.traceKind()); } -JS_ALWAYS_INLINE void -TraceBoxedWords(JSTracer *trc, jsboxedword *beg, jsboxedword *end, const char *name) +static inline void +MarkValue(JSTracer *trc, const js::Value &v, const char *name) +{ + JS_SET_TRACING_NAME(trc, name); + MarkValueRaw(trc, v); +} + +static inline void +MarkValueRange(JSTracer *trc, Value *beg, Value *end, const char *name) +{ + for (Value *vp = beg; vp < end; ++vp) { + JS_SET_TRACING_INDEX(trc, name, vp - beg); + MarkValueRaw(trc, *vp); + } +} + +static inline void +MarkValueRange(JSTracer *trc, size_t len, Value *vec, const char *name) +{ + MarkValueRange(trc, vec, vec + len, name); +} + +static inline void +MarkBoxedWord(JSTracer *trc, jsboxedword w, const char *name) +{ + if (JSBOXEDWORD_IS_GCTHING(w)) { + JS_SET_TRACING_NAME(trc, name); + MarkRaw(trc, JSBOXEDWORD_TO_GCTHING(w), JSBOXEDWORD_TRACE_KIND(w)); + } +} + +static inline void +MarkBoxedWordRange(JSTracer *trc, jsboxedword *beg, jsboxedword *end, const char *name) { for (jsboxedword *wp = beg; wp < end; ++wp) { if (JSBOXEDWORD_IS_GCTHING(*wp)) { JS_SET_TRACING_INDEX(trc, name, wp - beg); - CallGCMarker(trc, JSBOXEDWORD_TO_GCTHING(*wp), JSBOXEDWORD_TRACE_KIND(*wp)); + MarkRaw(trc, JSBOXEDWORD_TO_GCTHING(*wp), JSBOXEDWORD_TRACE_KIND(*wp)); } } } inline void -TraceBoxedWords(JSTracer *trc, size_t len, jsboxedword *vec, const char *name) +MarkBoxedWordRange(JSTracer *trc, size_t len, jsboxedword *vec, const char *name) { - TraceBoxedWords(trc, vec, vec + len, name); + MarkBoxedWordRange(trc, vec, vec + len, name); +} + +/* N.B. Assumes JS_SET_TRACING_NAME/INDEX has already been called. */ +void +MarkGCThingRaw(JSTracer *trc, void *thing); + +static inline void +MarkGCThing(JSTracer *trc, void *thing, const char *name) +{ + JS_SET_TRACING_NAME(trc, name); + MarkGCThingRaw(trc, thing); +} + +static inline void +MarkGCThing(JSTracer *trc, void *thing, const char *name, size_t index) +{ + JS_SET_TRACING_INDEX(trc, name, index); + MarkGCThingRaw(trc, thing); } } /* namespace js */ diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index d7dd5bd746e..a34e3a6f383 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -1744,6 +1744,7 @@ namespace reprmeter { #define PUSH_NULL() regs.sp++->setNull() #define PUSH_UNDEFINED() regs.sp++->setUndefined() #define PUSH_BOOLEAN(b) regs.sp++->setBoolean(b) +#define PUSH_DOUBLE(d) regs.sp++->setDouble(d) #define PUSH_INT32(i) regs.sp++->setInt32(i) #define PUSH_STRING(s) regs.sp++->setString(s) #define PUSH_NONFUNOBJ(obj) regs.sp++->setNonFunObj(obj) diff --git a/js/src/jsinterp.h b/js/src/jsinterp.h index eefcc0c5193..c616f71fbfe 100644 --- a/js/src/jsinterp.h +++ b/js/src/jsinterp.h @@ -259,7 +259,7 @@ JS_ALWAYS_INLINE JSObject * ComputeThisObjectFromVp(JSContext *cx, js::Value *vp) { extern bool ComputeThisFromArgv(JSContext *, js::Value *); - return ComputeThisFromArgv(cx, vp + 2) ? &vp->asObject() : NULL; + return ComputeThisFromArgv(cx, vp + 2) ? &vp[1].asObject() : NULL; } JS_ALWAYS_INLINE bool diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 7e4ebca634a..30321f2c37d 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -103,7 +103,7 @@ ExtendedClass js_IteratorClass = { void NativeIterator::mark(JSTracer *trc) { - TraceBoxedWords(trc, props_array, props_end, "props"); + MarkBoxedWordRange(trc, props_array, props_end, "props"); } /* @@ -738,9 +738,9 @@ generator_trace(JSTracer *trc, JSObject *obj) JSStackFrame *fp = gen->getFloatingFrame(); JS_ASSERT(gen->getLiveFrame() == fp); - TraceValues(trc, gen->floatingStack, fp->argEnd(), "generator slots"); + MarkValueRange(trc, gen->floatingStack, fp->argEnd(), "generator slots"); js_TraceStackFrame(trc, fp); - TraceValues(trc, fp->slots(), gen->savedRegs.sp, "generator slots"); + MarkValueRange(trc, fp->slots(), gen->savedRegs.sp, "generator slots"); } ExtendedClass js_GeneratorClass = { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 70de5aaea0a..dfee1d7e51e 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -5992,10 +5992,8 @@ js_TraceObject(JSTracer *trc, JSObject *obj) for (uint32 i = JSSLOT_START(clasp); i != nslots; ++i) { const Value &v = obj->getSlot(i); - if (v.isGCThing()) { - JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); - CallGCMarkerForGCThing(trc, v); - } + JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i); + MarkValueRaw(trc, v); } } @@ -6291,10 +6289,6 @@ dumpValue(const Value &v) JS_FRIEND_API(void) DumpValue(const Value &val) { - JS_STATIC_ASSERT(sizeof(Value) >= 12); - JS_STATIC_ASSERT(sizeof(uint32_t) == sizeof(long)); - const uint32_t *p = reinterpret_cast(&val); - fprintf(stderr, "Value payload (%x %x) type mask (%x) = ", p[0], p[1], p[2]); dumpValue(val); fputc('\n', stderr); } diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 9530045e651..53141b096f4 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -580,12 +580,12 @@ struct JSObject { bool isCallable(); /* The map field is not initialized here and should be set separately. */ - void init(js::Class *clasp, const js::Value &proto, const js::Value &parent, + void init(js::Class *aclasp, const js::Value &proto, const js::Value &parent, const js::Value &privateSlotValue) { - JS_ASSERT(((jsuword) clasp & 3) == 0); JS_STATIC_ASSERT(JSSLOT_PRIVATE + 3 == JS_INITIAL_NSLOTS); - this->clasp = clasp; + clasp = aclasp; + flags = 0; JS_ASSERT(!isDelegate()); JS_ASSERT(!isSystem()); diff --git a/js/src/jsops.cpp b/js/src/jsops.cpp index ba205abed7d..107d4e63915 100644 --- a/js/src/jsops.cpp +++ b/js/src/jsops.cpp @@ -316,6 +316,7 @@ BEGIN_CASE(JSOP_STOP) } goto error; } + interpReturnOK = true; goto exit; } @@ -2541,9 +2542,14 @@ BEGIN_CASE(JSOP_RESETBASE) END_CASE(JSOP_RESETBASE) BEGIN_CASE(JSOP_DOUBLE) +{ JS_ASSERT(!fp->imacpc); JS_ASSERT(size_t(atoms - script->atomMap.vector) < script->atomMap.length); - /* FALL THROUGH */ + JSAtom *atom; + LOAD_ATOM(0, atom); + PUSH_DOUBLE(*ATOM_TO_DOUBLE(atom)); +} +END_CASE(JSOP_DOUBLE) BEGIN_CASE(JSOP_STRING) { @@ -2551,7 +2557,7 @@ BEGIN_CASE(JSOP_STRING) LOAD_ATOM(0, atom); PUSH_STRING(ATOM_TO_STRING(atom)); } -END_CASE(JSOP_DOUBLE) +END_CASE(JSOP_STRING) BEGIN_CASE(JSOP_OBJECT) { diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index ce9cece3528..033462fcd57 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -193,16 +193,21 @@ typedef JSUint64 JSValueMaskType; # error "Unsupported word size" #endif -#define JSVAL_NULL_MASK ((JSValueMaskType)0x00) -#define JSVAL_UNDEFINED_MASK ((JSValueMaskType)0x01) -#define JSVAL_INT32_MASK ((JSValueMaskType)0x02) -#define JSVAL_DOUBLE_MASK ((JSValueMaskType)0x04) -#define JSVAL_STRING_MASK ((JSValueMaskType)0x08) -#define JSVAL_NONFUNOBJ_MASK ((JSValueMaskType)0x10) -#define JSVAL_FUNOBJ_MASK ((JSValueMaskType)0x20) -#define JSVAL_BOOLEAN_MASK ((JSValueMaskType)0x40) -#define JSVAL_MAGIC_MASK ((JSValueMaskType)0x80) +#ifdef __GNUC__ +# define VALUE_ALIGNMENT __attribute__((aligned (8))) +#else +# error "TODO: do something for MSVC" +#endif +#define JSVAL_NULL_MASK 0x00 +#define JSVAL_UNDEFINED_MASK 0x01 +#define JSVAL_INT32_MASK 0x02 +#define JSVAL_DOUBLE_MASK 0x04 +#define JSVAL_STRING_MASK 0x08 +#define JSVAL_NONFUNOBJ_MASK 0x10 +#define JSVAL_FUNOBJ_MASK 0x20 +#define JSVAL_BOOLEAN_MASK 0x40 +#define JSVAL_MAGIC_MASK 0x80 #define JSVAL_OBJECT_MASK (JSVAL_NONFUNOBJ_MASK | JSVAL_FUNOBJ_MASK) #define JSVAL_NUMBER_MASK (JSVAL_INT32_MASK | JSVAL_DOUBLE_MASK) #define JSVAL_GCTHING_MASK (JSVAL_OBJECT_MASK | JSVAL_STRING_MASK) @@ -246,7 +251,7 @@ typedef struct jsval JSValueMaskType mask; JS_INSERT_VALUE_PADDING() jsval_data data; -} jsval; +} VALUE_ALIGNMENT jsval; /* * Boxed word macros (private engine detail) @@ -406,7 +411,11 @@ JSBOXEDWORD_TO_GCTHING(jsboxedword w) static JS_ALWAYS_INLINE uint32 JSBOXEDWORD_TRACE_KIND(jsboxedword w) { - JS_ASSERT(w == 0x0 || w == 0x2 || w == 0x4); +#ifdef DEBUG + unsigned tag = JSBOXEDWORD_TAG(w); + JS_ASSERT(tag == 0x0 || tag == 0x2 || tag == 0x4); +#endif + /* * We need to map: * XXXXXXXXXXXXXXXXXXXXXXXXXXXXX000 -> 00 (object) @@ -500,6 +509,8 @@ typedef jsboxedword jsid; #define JSID_TO_OBJECT(id) JSBOXEDWORD_TO_OBJECT((jsboxedword)(id)) #define OBJECT_TO_JSID(obj) ((jsid)OBJECT_TO_JSBOXEDWORD((obj))) +/* TODO: get JSID/JSBOXEDWORD story together. */ + /* Objects and strings (no doubles in jsids). */ #define JSID_IS_GCTHING(id) JSBOXEDWORD_IS_GCTHING(id) #define JSID_TO_GCTHING(id) (JS_ASSERT(JSID_IS_GCTHING((id))), \ diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index 52d1163d83a..703171ef8d3 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -1230,12 +1230,6 @@ JSScope::globalObjectOwnShapeChange(JSContext *cx) return !js_IsPropertyCacheDisabled(cx); } -void -js_TraceId(JSTracer *trc, jsid id) -{ - CallGCMarker(trc, JSBOXEDWORD_TO_GCTHING(id), JSBOXEDWORD_TRACE_KIND(id)); -} - #ifdef DEBUG static void PrintPropertyGetterOrSetter(JSTracer *trc, char *buf, size_t bufsize) @@ -1287,21 +1281,21 @@ JSScopeProperty::trace(JSTracer *trc) { if (IS_GC_MARKING_TRACER(trc)) mark(); - js_TraceId(trc, id); + MarkBoxedWord(trc, id, "id"); if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) { if ((attrs & JSPROP_GETTER) && rawGetter) { JS_SET_TRACING_DETAILS(trc, PrintPropertyGetterOrSetter, this, 0); - CallGCMarker(trc, getterObject(), JSTRACE_OBJECT); + MarkRaw(trc, getterObject(), JSTRACE_OBJECT); } if ((attrs & JSPROP_SETTER) && rawSetter) { JS_SET_TRACING_DETAILS(trc, PrintPropertyGetterOrSetter, this, 1); - CallGCMarker(trc, setterObject(), JSTRACE_OBJECT); + MarkRaw(trc, setterObject(), JSTRACE_OBJECT); } } if (isMethod()) { JS_SET_TRACING_DETAILS(trc, PrintPropertyMethod, this, 0); - CallGCMarker(trc, &methodFunObj(), JSTRACE_OBJECT); + MarkRaw(trc, &methodFunObj(), JSTRACE_OBJECT); } } diff --git a/js/src/jsscope.h b/js/src/jsscope.h index 4d3e5a6ad5a..e24ee8093e3 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -1006,9 +1006,6 @@ JSScopeProperty::isSharedPermanent() const extern JSScope * js_GetMutableScope(JSContext *cx, JSObject *obj); -extern void -js_TraceId(JSTracer *trc, jsid id); - #ifdef _MSC_VER #pragma warning(pop) #pragma warning(pop) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index cb64b078b98..3f8b7d7674b 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1176,7 +1176,7 @@ js_TraceScript(JSTracer *trc, JSScript *script) JSAtomMap *map = &script->atomMap; uintN length = map->length; jsboxedword *vector = (jsboxedword *)map->vector; - TraceBoxedWords(trc, length, vector, "atomMap"); + MarkBoxedWordRange(trc, length, vector, "atomMap"); if (script->objectsOffset != 0) { JSObjectArray *objarray = script->objects(); @@ -1185,7 +1185,7 @@ js_TraceScript(JSTracer *trc, JSScript *script) --i; if (objarray->vector[i]) { JS_SET_TRACING_INDEX(trc, "objects", i); - CallGCMarker(trc, objarray->vector[i], JSTRACE_OBJECT); + MarkRaw(trc, objarray->vector[i], JSTRACE_OBJECT); } } while (i != 0); } @@ -1197,14 +1197,14 @@ js_TraceScript(JSTracer *trc, JSScript *script) --i; if (objarray->vector[i]) { JS_SET_TRACING_INDEX(trc, "regexps", i); - CallGCMarker(trc, objarray->vector[i], JSTRACE_OBJECT); + MarkRaw(trc, objarray->vector[i], JSTRACE_OBJECT); } } while (i != 0); } if (script->u.object) { JS_SET_TRACING_NAME(trc, "object"); - CallGCMarker(trc, script->u.object, JSTRACE_OBJECT); + MarkRaw(trc, script->u.object, JSTRACE_OBJECT); } if (IS_GC_MARKING_TRACER(trc) && script->filename) diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp index 0291684662a..d390987ed02 100644 --- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -4749,7 +4749,7 @@ xml_trace_vector(JSTracer *trc, JSXML **vec, uint32 len) xml = vec[i]; if (xml) { JS_SET_TRACING_INDEX(trc, "xml_vector", i); - CallGCMarker(trc, xml, JSTRACE_XML); + MarkRaw(trc, xml, JSTRACE_XML); } } } @@ -7112,9 +7112,9 @@ js_TraceXML(JSTracer *trc, JSXML *xml) if (xml->xml_targetprop) JS_CALL_OBJECT_TRACER(trc, xml->xml_targetprop, "targetprop"); } else { - js::TraceObjectVector(trc, - (JSObject **) xml->xml_namespaces.vector, - xml->xml_namespaces.length); + MarkObjectVector(trc, xml->xml_namespaces.length, + (JSObject **) xml->xml_namespaces.vector, + "xml_namespaces"); XMLArrayCursorTrace(trc, xml->xml_namespaces.cursors); if (IS_GC_MARKING_TRACER(trc)) XMLArrayTrim(&xml->xml_namespaces); diff --git a/js/src/jsxml.h b/js/src/jsxml.h index 6f760183dad..12788e5f766 100644 --- a/js/src/jsxml.h +++ b/js/src/jsxml.h @@ -105,10 +105,8 @@ struct JSXMLArrayCursor #ifdef DEBUG size_t index = 0; #endif - for (JSXMLArrayCursor *cursor = this; cursor; cursor = cursor->next) { - JS_SET_TRACING_INDEX(trc, "cursor_root", index++); - js::CallGCMarkerForGCThing(trc, cursor->root); - } + for (JSXMLArrayCursor *cursor = this; cursor; cursor = cursor->next) + js::MarkGCThing(trc, cursor->root, "cursor_root", index++); } };