author | Wes Kocher <wkocher@mozilla.com> |
Tue, 04 Nov 2014 20:24:50 -0800 | |
changeset 214046 | 3c88f1fc617cf2079c3dcef41b35f306ecf39625 |
parent 214045 | fca5cc8130369e86140bb9f9715a1a2bcaa95250 |
child 214047 | 919fe1b47dbb01f114ccf18aa374fa9eb37fe341 |
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) |
bugs | 1092833 |
milestone | 36.0a1 |
backs out | 5e6d8b6023e32f464ac8595969531f40b5113c05 |
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/jit-test/tests/ion/bug1092833.js | file | annotate | diff | comparison | revisions | |
js/src/jit/IonMacroAssembler.cpp | file | annotate | diff | comparison | revisions | |
js/src/jit/IonMacroAssembler.h | file | annotate | diff | comparison | revisions |
deleted file mode 100644 --- a/js/src/jit-test/tests/ion/bug1092833.js +++ /dev/null @@ -1,49 +0,0 @@ -// Test that lexicals work with functions with many bindings. - -(function() { - var a01 - var b02 - var c03 - var d04 - var e05 - var f06 - var g07 - var h08 - let i09 - var j10 - var k11 - var l12 - var m13 - var n14 - var o15 - (function n14() { - assertEq(i09, undefined); - })() -})(); - -try { - (function() { - var a01 - var b02 - var c03 - var d04 - var e05 - var f06 - var g07 - var h08 - let i09 - var j10 - var k11 - var l12 - var m13 - var n14 - var o15 - (function n14() { - i12++ - })() - let i12 - })() -} catch (e) { - assertEq(e instanceof ReferenceError, true); - assertEq(e.message.indexOf("i12") > 0, true); -}
--- a/js/src/jit/IonMacroAssembler.cpp +++ b/js/src/jit/IonMacroAssembler.cpp @@ -22,17 +22,16 @@ #include "vm/ForkJoin.h" #include "vm/TraceLogging.h" #ifdef JSGC_GENERATIONAL # include "jsgcinlines.h" #endif #include "jsinferinlines.h" #include "jsobjinlines.h" -#include "vm/Interpreter-inl.h" using namespace js; using namespace js::jit; using JS::GenericNaN; namespace { @@ -952,76 +951,49 @@ MacroAssembler::copySlotsFromTemplate(Re uint32_t start, uint32_t end) { uint32_t nfixed = Min(templateObj->numFixedSlots(), end); for (unsigned i = start; i < nfixed; i++) storeValue(templateObj->getFixedSlot(i), Address(obj, NativeObject::getFixedSlotOffset(i))); } void -MacroAssembler::fillSlotsWithConstantValue(Address base, Register temp, - uint32_t start, uint32_t end, const Value &v) +MacroAssembler::fillSlotsWithUndefined(Address base, Register temp, uint32_t start, uint32_t end) { - MOZ_ASSERT(v.isUndefined() || IsUninitializedLexical(v)); - - if (start >= end) - return; - #ifdef JS_NUNBOX32 // We only have a single spare register, so do the initialization as two // strided writes of the tag and body. - jsval_layout jv = JSVAL_TO_IMPL(v); + jsval_layout jv = JSVAL_TO_IMPL(UndefinedValue()); Address addr = base; move32(Imm32(jv.s.payload.i32), temp); for (unsigned i = start; i < end; ++i, addr.offset += sizeof(HeapValue)) store32(temp, ToPayload(addr)); addr = base; move32(Imm32(jv.s.tag), temp); for (unsigned i = start; i < end; ++i, addr.offset += sizeof(HeapValue)) store32(temp, ToType(addr)); #else - moveValue(v, temp); + moveValue(UndefinedValue(), temp); for (uint32_t i = start; i < end; ++i, base.offset += sizeof(HeapValue)) storePtr(temp, base); #endif } -void -MacroAssembler::fillSlotsWithUndefined(Address base, Register temp, uint32_t start, uint32_t end) -{ - fillSlotsWithConstantValue(base, temp, start, end, UndefinedValue()); -} - -void -MacroAssembler::fillSlotsWithUninitialized(Address base, Register temp, uint32_t start, uint32_t end) -{ - fillSlotsWithConstantValue(base, temp, start, end, MagicValue(JS_UNINITIALIZED_LEXICAL)); -} - -static void -FindStartOfUndefinedAndUninitializedSlots(NativeObject *templateObj, uint32_t nslots, - uint32_t *startOfUndefined, uint32_t *startOfUninitialized) +static uint32_t +FindStartOfUndefinedSlots(NativeObject *templateObj, uint32_t nslots) { MOZ_ASSERT(nslots == templateObj->lastProperty()->slotSpan(templateObj->getClass())); MOZ_ASSERT(nslots > 0); - uint32_t first = nslots; - for (; first != 0; --first) { - if (!IsUninitializedLexical(templateObj->getSlot(first - 1))) - break; + for (uint32_t first = nslots; first != 0; --first) { + if (templateObj->getSlot(first - 1) != UndefinedValue()) + return first; } - *startOfUninitialized = first; - for (; first != 0; --first) { - if (templateObj->getSlot(first - 1) != UndefinedValue()) { - *startOfUndefined = first; - return; - } - } - *startOfUndefined = 0; + return 0; } void MacroAssembler::initGCSlots(Register obj, Register slots, NativeObject *templateObj, bool initFixedSlots) { // Slots of non-array objects are required to be initialized. // Use the values currently in the template object. @@ -1034,53 +1006,34 @@ MacroAssembler::initGCSlots(Register obj // Attempt to group slot writes such that we minimize the amount of // duplicated data we need to embed in code and load into registers. In // general, most template object slots will be undefined except for any // reserved slots. Since reserved slots come first, we split the object // logically into independent non-UndefinedValue writes to the head and // duplicated writes of UndefinedValue to the tail. For the majority of // objects, the "tail" will be the entire slot range. - // - // The template object may be a CallObject, in which case we need to - // account for uninitialized lexical slots as well as undefined - // slots. Unitialized lexical slots always appear at the very end of - // slots, after undefined. - uint32_t startOfUndefined = nslots; - uint32_t startOfUninitialized = nslots; - FindStartOfUndefinedAndUninitializedSlots(templateObj, nslots, - &startOfUndefined, &startOfUninitialized); + uint32_t startOfUndefined = FindStartOfUndefinedSlots(templateObj, nslots); MOZ_ASSERT(startOfUndefined <= nfixed); // Reserved slots must be fixed. - MOZ_ASSERT_IF(startOfUndefined != nfixed, startOfUndefined <= startOfUninitialized); - MOZ_ASSERT_IF(!templateObj->is<CallObject>(), startOfUninitialized == nslots); // Copy over any preserved reserved slots. copySlotsFromTemplate(obj, templateObj, 0, startOfUndefined); - // Fill the rest of the fixed slots with undefined and uninitialized. + // Fill the rest of the fixed slots with undefined. if (initFixedSlots) { fillSlotsWithUndefined(Address(obj, NativeObject::getFixedSlotOffset(startOfUndefined)), slots, - startOfUndefined, Min(startOfUninitialized, nfixed)); - size_t offset = NativeObject::getFixedSlotOffset(startOfUninitialized); - fillSlotsWithUninitialized(Address(obj, offset), slots, startOfUninitialized, nfixed); + startOfUndefined, nfixed); } if (ndynamic) { // We are short one register to do this elegantly. Borrow the obj // register briefly for our slots base address. push(obj); loadPtr(Address(obj, NativeObject::offsetOfSlots()), obj); - - // Initially fill all dynamic slots with undefined. fillSlotsWithUndefined(Address(obj, 0), slots, 0, ndynamic); - - // Fill uninitialized slots if necessary. - fillSlotsWithUninitialized(Address(obj, 0), slots, startOfUninitialized - nfixed, - nslots - startOfUninitialized); - pop(obj); } } void MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj, bool initFixedSlots) {
--- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -805,20 +805,17 @@ class MacroAssembler : public MacroAssem void nurseryAllocate(Register result, Register slots, gc::AllocKind allocKind, size_t nDynamicSlots, gc::InitialHeap initialHeap, Label *fail); void freeListAllocate(Register result, Register temp, gc::AllocKind allocKind, Label *fail); void allocateObject(Register result, Register slots, gc::AllocKind allocKind, uint32_t nDynamicSlots, gc::InitialHeap initialHeap, Label *fail); void allocateNonObject(Register result, Register temp, gc::AllocKind allocKind, Label *fail); void copySlotsFromTemplate(Register obj, const NativeObject *templateObj, uint32_t start, uint32_t end); - void fillSlotsWithConstantValue(Address addr, Register temp, uint32_t start, uint32_t end, - const Value &v); void fillSlotsWithUndefined(Address addr, Register temp, uint32_t start, uint32_t end); - void fillSlotsWithUninitialized(Address addr, Register temp, uint32_t start, uint32_t end); void initGCSlots(Register obj, Register temp, NativeObject *templateObj, bool initFixedSlots); public: void callMallocStub(size_t nbytes, Register result, Label *fail); void callFreeStub(Register slots); void createGCObject(Register result, Register temp, JSObject *templateObj, gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots = true);