bug 579957 - parent as a field in JSObject (relanding after wixing bug 583404). r=lw

This commit is contained in:
Igor Bukanov 2010-07-31 11:54:01 +02:00
Родитель f627d24fb9
Коммит ce4483243e
9 изменённых файлов: 21 добавлений и 47 удалений

Просмотреть файл

@ -983,7 +983,6 @@ static void
array_trace(JSTracer *trc, JSObject *obj)
{
JS_ASSERT(obj->isDenseArray());
obj->traceProtoAndParent(trc);
if (!obj->dslots)
return;

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -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();

Просмотреть файл

@ -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()) {

Просмотреть файл

@ -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.
*

Просмотреть файл

@ -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*

Просмотреть файл

@ -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");
}