Closed Bug 579957 Opened 15 years ago Closed 15 years ago

parent as a field in JSObject

Categories

(Core :: JavaScript Engine, enhancement)

Other Branch
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: igor, Assigned: igor)

References

Details

(Whiteboard: fixed-in-tracemonkey)

Attachments

(1 file, 1 obsolete file)

Currently the parent link is stored in the first fixed slot of JSObject *. With fat values on 32-bit CPU this results in bloating the object size by 8 bytes, 4 unused bytes to store the parent object pointer in a value slot and 4 bytes to pad fixed slots so they starts on 8-bytes boundary. The attached patch avoids that by storing the parent as JSObject* field.
Attached patch v1 (obsolete) — Splinter Review
Attachment #458390 - Flags: review?(lw)
Comment on attachment 458390 [details] [diff] [review] v1 Awesome! This also makes setting/getting the parent faster (on both x86 and x64)! I don't know why I assumed that JSObject*-ifying JSSLOT_PARENT would be hard... superstitious belief that somehow code wanted it to be an fslot or something... I would be interested to see the effect on SS/V8.
Attachment #458390 - Flags: review?(lw) → review+
Could you hold off until bug 558451 is rebased at least? I will repack JSObject as a "last patch in mq" step there. Also, this seems to go against the bug 508357 comment 1 idea (which may have its own bug, I couldn't find it) of making the parent fslot optional (by class). /be
I was curious, so I measured. SS showed no change, but V8 showed: 1.010x as fast 5289.0ms +/- 0.4% 5237.4ms +/- 0.4% significant
(In reply to comment #3) > Could you hold off until bug 558451 is rebased at least? I will repack JSObject > as a "last patch in mq" step there. I will wait. > Also, this seems to go against the bug 508357 comment 1 idea (which may have > its own bug, I couldn't find it) of making the parent fslot optional (by > class). This is orthogonal to this bug which which is about quick recovering of 8 wasted byets per object on 32 bit. Elimination of the parent can be done both for its jsval and JSObject* forms.
Brendan - is it OK to land this now?
I'm close to landing bug 558451 modulo review. I can rebase if you land this, though. But apart from 32-bit packing, why is this good? If we want to make parent optional but declared, we'll need C++ subtypes -- that is for a later bug but I wonder if it would work out. Would it be the case that every scope object and all the DOM objects would derive from the new JSObjectWithParent? How would the API for this look? I suspect it would be too complicated to be worth the benefits. If we use an fslot instead, we can decide based on JSCLASS_HAS_PARENT (and assert that as needed). We need runtime type information anyway, not just C++ type info (_sans_ RTTI). /be
Decoding the parent becomes easier on x64 but evidence suggests this doesn't matter.
I think we should land this. I will probably make a patch to obsolete parent in most objects, but until then this is a strict improvement.
(In reply to comment #9) > I think we should land this. I will probably make a patch to obsolete parent in > most objects, but until then this is a strict improvement. Please respond to comment 7. /be
In an ideal world, only a very small set of objects needs a parent. The vast majority of them are functions, which have extra storage we can move the parent into. Aside from that we just need parent in With and a few other oddballs, which we can make work. I don't think we need a common case for "stuff with parents". There are very few, and they are not touched in related places so we don't save anything by having a common interface.
(In reply to comment #11) > In an ideal world, only a very small set of objects needs a parent. The vast > majority of them are functions, which have extra storage we can move the parent > into. Aside from that we just need parent in With and a few other oddballs, > which we can make work. Wrong. It's not "a few", it is the DOM elements that can have event handlers, which is all of them. > I don't think we need a common case for "stuff with > parents". There are very few, and they are not touched in related places so we > don't save anything by having a common interface. I repeat: how are you going to factor JSObject *parent; so it is in a C++ type used by all of the DOM types as well as the JS core-language scope objects? As the JS API allows objects to be on the scope chain precisely so the DOM can put its elements there, how will you tell at runtime that you have a parent-full object? Both TM and JM need to know, and we can't use RTTI. /be
(In reply to comment #12) > (In reply to comment #11) > > In an ideal world, only a very small set of objects needs a parent. The vast > > majority of them are functions, which have extra storage we can move the parent > > into. Aside from that we just need parent in With and a few other oddballs, > > which we can make work. > > Wrong. It's not "a few", it is the DOM elements that can have event handlers, > which is all of them. We currently (ab)use parent of DOM elements for this purpose. In my reworked experimental proxy-based DOM bindings DOM elements will be non-native, and very different rules apply. I can store the parent wherever I want. > > > I don't think we need a common case for "stuff with > > parents". There are very few, and they are not touched in related places so we > > don't save anything by having a common interface. > > I repeat: how are you going to factor JSObject *parent; so it is in a C++ type > used by all of the DOM types as well as the JS core-language scope objects? As > the JS API allows objects to be on the scope chain precisely so the DOM can put > its elements there, how will you tell at runtime that you have a parent-full > object? Both TM and JM need to know, and we can't use RTTI. As indicated above I think in the engine there are only a few things that have parents, and DOM objects might become non-native and special potentially. > > /be
Ok, but the JS API would need changes. Igor just landing a JSObject *parent; change is one step along a path. Is it important to do just this step right now instead of doing the work to make parent rare? /be
I can take the rebase (I've had worse lately), so that is not the main issue. It is doing something to pack JSObject on 32 bits that I'll repack anyway soon after rebasing, and not doing the work that matters: factoring parent out of JSObject. /be
This is a really small patch. I have no strong preferences. Your call.
Comment on attachment 458390 [details] [diff] [review] v1 > void traceProtoAndParent(JSTracer *trc) const { > if (JSObject *proto = getProto()) >- JS_CALL_OBJECT_TRACER(trc, proto, "__proto__"); >+ JS_CALL_OBJECT_TRACER(trc, proto, "proto"); > if (JSObject *parent = getParent()) > JS_CALL_OBJECT_TRACER(trc, parent, "parent"); > } Good patch, let's get it in -- but since you are touching one line here, why not get rid of the temporaries and getProto()/getParent() layering and just test proto and parent? /be
Sorry, I should have looked harder. The patch is a strict improvement over the fslot approach. /be
Attached patch v2Splinter Review
This version removes traceProtoAndParent and just inlines the corresponding code in jsgc.cpp.
Attachment #458390 - Attachment is obsolete: true
Attachment #461254 - Flags: review+
Whiteboard: fixed-in-tracemonkey
I backed this out because it appeared to cause a crash in crashtest on all platforms.
Whiteboard: fixed-in-tracemonkey
Depends on: 583404
Whiteboard: fixed-in-tracemonkey
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: