From ce4483243e6c012de84815c2b769db99d7c917de Mon Sep 17 00:00:00 2001 From: Igor Bukanov Date: Sat, 31 Jul 2010 11:54:01 +0200 Subject: [PATCH] bug 579957 - parent as a field in JSObject (relanding after wixing bug 583404). r=lw --- js/src/jsarray.cpp | 1 - js/src/jscntxt.h | 2 +- js/src/jsgc.cpp | 4 ++++ js/src/jsobj.cpp | 2 -- js/src/jsobj.h | 41 +++++++++++++---------------------------- js/src/jsproxy.cpp | 9 --------- js/src/jsscope.h | 4 ++-- js/src/jstracer.cpp | 2 +- js/src/jstypedarray.cpp | 3 --- 9 files changed, 21 insertions(+), 47 deletions(-) diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 176783b5741b..0b397eabc94a 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -983,7 +983,6 @@ static void array_trace(JSTracer *trc, JSObject *obj) { JS_ASSERT(obj->isDenseArray()); - obj->traceProtoAndParent(trc); if (!obj->dslots) return; diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index a20ef95896f2..b60aaa784745 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -3073,7 +3073,7 @@ LeaveTrace(JSContext *cx) static JS_INLINE void LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj) { - if (obj->fslots[JSSLOT_PARENT].isNull()) + if (!obj->parent) LeaveTrace(cx); } diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 0b6fa9c75e08..af0d2d63c979 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1917,6 +1917,10 @@ JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind) JSObject *obj = (JSObject *) thing; if (!obj->map) break; + if (JSObject *proto = obj->getProto()) + JS_CALL_OBJECT_TRACER(trc, proto, "proto"); + if (JSObject *parent = obj->getParent()) + JS_CALL_OBJECT_TRACER(trc, parent, "parent"); JSTraceOp op = obj->getOps()->trace; (op ? op : js_TraceObject)(trc, obj); break; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 25a0dbe11b5c..c3e3d52ae7c3 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -5926,8 +5926,6 @@ js_TraceObject(JSTracer *trc, JSObject *obj) compartment->marked = true; } - obj->traceProtoAndParent(trc); - /* * An unmutated object that shares a prototype object's scope. We can't * tell how many slots are in use in obj by looking at its scope, so we diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 323dae09c3f2..a75c1fc56f95 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -228,9 +228,7 @@ js_TypeOf(JSContext *cx, JSObject *obj); struct NativeIterator; -const uint32 JS_INITIAL_NSLOTS = 4; - -const uint32 JSSLOT_PARENT = 0; +const uint32 JS_INITIAL_NSLOTS = 3; /* * The first available slot to store generic value. For JSCLASS_HAS_PRIVATE @@ -239,7 +237,7 @@ const uint32 JSSLOT_PARENT = 0; * tagging and should be accessed using the (get|set)Private methods of * JSObject. */ -const uint32 JSSLOT_PRIVATE = 1; +const uint32 JSSLOT_PRIVATE = 0; struct JSFunction; @@ -248,13 +246,13 @@ struct JSFunction; * 64 bytes on 64-bit systems. The JSFunction struct is an extension of this * struct allocated from a larger GC size-class. * - * An object is a delegate if it is on another object's prototype (linked by - * JSSLOT_PROTO) or scope (JSSLOT_PARENT) chain, and therefore the delegate - * might be asked implicitly to get or set a property on behalf of another - * object. Delegates may be accessed directly too, as may any object, but only - * those objects linked after the head of any prototype or scope chain are - * flagged as delegates. This definition helps to optimize shape-based property - * cache invalidation (see Purge{Scope,Proto}Chain in jsobj.cpp). + * An object is a delegate if it is on another object's prototype (the proto + * field) or scope chain (the parent field), and therefore the delegate might + * be asked implicitly to get or set a property on behalf of another object. + * Delegates may be accessed directly too, as may any object, but only those + * objects linked after the head of any prototype or scope chain are flagged + * as delegates. This definition helps to optimize shape-based property cache + * invalidation (see Purge{Scope,Proto}Chain in jsobj.cpp). * * The meaning of the system object bit is defined by the API client. It is * set in JS_NewSystemObject and is queried by JS_IsSystemObject (jsdbgapi.h), @@ -281,14 +279,8 @@ struct JSObject { js::Class *clasp; /* class pointer */ jsuword flags; /* see above */ JSObject *proto; /* object's prototype */ + JSObject *parent; /* object's parent */ js::Value *dslots; /* dynamically allocated slots */ -#if JS_BITS_PER_WORD == 32 - // TODO: this is needed to pad out fslots. alternatively, clasp could be - // merged with flags and the padding removed, but I think the upcoming - // removal of JSScope will change this all anyway so I will leave this - // here for now. - uint32 padding; -#endif js::Value fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */ bool isNative() const { @@ -410,11 +402,11 @@ struct JSObject { } JSObject *getParent() const { - return fslots[JSSLOT_PARENT].toObjectOrNull(); + return parent; } void clearParent() { - fslots[JSSLOT_PARENT].setNull(); + parent = NULL; } void setParent(JSObject *newParent) { @@ -423,14 +415,7 @@ struct JSObject { JS_ASSERT(obj != this); #endif setDelegateNullSafe(newParent); - fslots[JSSLOT_PARENT].setObjectOrNull(newParent); - } - - void traceProtoAndParent(JSTracer *trc) const { - if (JSObject *proto = getProto()) - JS_CALL_OBJECT_TRACER(trc, proto, "__proto__"); - if (JSObject *parent = getParent()) - JS_CALL_OBJECT_TRACER(trc, parent, "parent"); + parent = newParent; } JSObject *getGlobal(); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index cf457ad3e426..5beac6f14b9d 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -888,15 +888,6 @@ proxy_TraceObject(JSTracer *trc, JSObject *obj) if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList)) js_TraceWatchPoints(trc, obj); - Class *clasp = obj->getClass(); - if (clasp->mark) { - if (clasp->flags & JSCLASS_MARK_IS_TRACE) - ((JSTraceOp) clasp->mark)(trc, obj); - else if (IS_GC_MARKING_TRACER(trc)) - (void) clasp->mark(cx, obj, trc); - } - - obj->traceProtoAndParent(trc); obj->getProxyHandler()->trace(trc, obj); MarkValue(trc, obj->getProxyPrivate(), "private"); if (obj->isFunctionProxy()) { diff --git a/js/src/jsscope.h b/js/src/jsscope.h index 83b3e8178273..6988d007ade8 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -456,8 +456,8 @@ struct JSScope : public JSObjectMap /* * A scope has a method barrier when some compiler-created "null closure" - * function objects (functions that do not use lexical bindings above their - * scope, only free variable names) that have a correct JSSLOT_PARENT value + * function objects (functions that do not use lexical bindings above + * their scope, only free variable names) that have a correct parent value * thanks to the COMPILE_N_GO optimization are stored as newly added direct * property values of the scope's object. * diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index d3e639642f89..a2b0b6392458 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -9989,7 +9989,7 @@ TraceRecorder::box_value_into_alloc(const Value &v, LIns *v_ins) LIns* TraceRecorder::stobj_get_parent(nanojit::LIns* obj_ins) { - return stobj_get_fslot_ptr(obj_ins, JSSLOT_PARENT); + return lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, parent), ACCSET_OTHER); } LIns* diff --git a/js/src/jstypedarray.cpp b/js/src/jstypedarray.cpp index f884685621a4..8dc480739fe8 100644 --- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -318,9 +318,6 @@ TypedArray::obj_trace(JSTracer *trc, JSObject *obj) { TypedArray *tarray = fromJSObject(obj); JS_ASSERT(tarray); - - obj->traceProtoAndParent(trc); - JS_CALL_OBJECT_TRACER(trc, tarray->bufferJS, "typedarray.buffer"); }