author | Brian Hackett <bhackett1024@gmail.com> |
Tue, 04 Nov 2014 18:44:03 -0700 | |
changeset 214044 | fd04ca4a868dbc364906ea59fdf3ee784bfcb86f |
parent 214043 | 38ca6211d1d4ae7571b1cbc26ae4371b960006c1 |
child 214045 | fca5cc8130369e86140bb9f9715a1a2bcaa95250 |
push id | 27771 |
push user | ryanvm@gmail.com |
push date | Wed, 05 Nov 2014 19:04:24 +0000 |
treeherder | mozilla-central@305b4fecce99 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | billm |
bugs | 1089665 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jsobj.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsobj.h | file | annotate | diff | comparison | revisions |
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2382,16 +2382,25 @@ NativeObject::fillInAfterSwap(JSContext if (!slots_) CrashAtUnhandlableOOM("fillInAfterSwap"); Debug_SetSlotRangeToCrashOnTouch(slots_, ndynamic); } initSlotRange(0, values.begin(), values.length()); } +void +JSObject::fixDictionaryShapeAfterSwap() +{ + // Dictionary shapes can point back to their containing objects, so after + // swapping the guts of those objects fix the pointers up. + if (isNative() && as<NativeObject>().inDictionaryMode()) + shape_->listp = &shape_; +} + /* Use this method with extreme caution. It trades the guts of two objects. */ bool JSObject::swap(JSContext *cx, HandleObject a, HandleObject b) { // Ensure swap doesn't cause a finalizer to not be run. MOZ_ASSERT(IsBackgroundFinalized(a->asTenured().getAllocKind()) == IsBackgroundFinalized(b->asTenured().getAllocKind())); MOZ_ASSERT(a->compartment() == b->compartment()); @@ -2436,16 +2445,19 @@ JSObject::swap(JSContext *cx, HandleObje size_t size = a->tenuredSizeOfThis(); char tmp[mozilla::tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::value]; MOZ_ASSERT(size <= sizeof(tmp)); js_memcpy(tmp, a, size); js_memcpy(a, b, size); js_memcpy(b, tmp, size); + + a->fixDictionaryShapeAfterSwap(); + b->fixDictionaryShapeAfterSwap(); } else { // Avoid GC in here to avoid confusing the tracing code with our // intermediate state. AutoSuppressGC suppress(cx); // When the objects have different sizes, they will have different // numbers of fixed slots before and after the swap, so the slots for // native objects will need to be rearranged. @@ -2473,29 +2485,25 @@ JSObject::swap(JSContext *cx, HandleObje } // Swap the main fields of the objects, whether they are native objects or proxies. char tmp[sizeof(JSObject_Slots0)]; js_memcpy(&tmp, a, sizeof tmp); js_memcpy(a, b, sizeof tmp); js_memcpy(b, &tmp, sizeof tmp); + a->fixDictionaryShapeAfterSwap(); + b->fixDictionaryShapeAfterSwap(); + if (na) b->as<NativeObject>().fillInAfterSwap(cx, avals, apriv); if (nb) a->as<NativeObject>().fillInAfterSwap(cx, bvals, bpriv); } - // Dictionary shapes can point back to their containing objects, so fix - // those pointers up. - if (a->isNative() && a->as<NativeObject>().inDictionaryMode()) - a->lastProperty()->listp = &a->shape_; - if (b->isNative() && b->as<NativeObject>().inDictionaryMode()) - b->lastProperty()->listp = &b->shape_; - // Swapping the contents of two objects invalidates type sets which contain // either of the objects, so mark all such sets as unknown. MarkTypeObjectUnknownProperties(cx, a->type(), !a->hasSingletonType()); MarkTypeObjectUnknownProperties(cx, b->type(), !b->hasSingletonType()); #ifdef JSGC_INCREMENTAL /* * We need a write barrier here. If |a| was marked and |b| was not, then
--- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -700,16 +700,20 @@ class JSObject : public js::gc::Cell return op(cx, obj); return obj; } static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp); static bool swap(JSContext *cx, JS::HandleObject a, JS::HandleObject b); + private: + void fixDictionaryShapeAfterSwap(); + + public: inline void initArrayClass(); /* * In addition to the generic object interface provided by JSObject, * specific types of objects may provide additional operations. To access, * these addition operations, callers should use the pattern: * * if (obj.is<XObject>()) {