author | David Anderson <danderson@mozilla.com> |
Fri, 14 Jan 2011 15:42:42 -0800 | |
changeset 60637 | 4275fce7591ba790bdfb2dc069759a492c2636b4 |
parent 60636 | 0f1fd87b570d08e9411eb06809440f0b2b738852 |
child 60638 | ea7bedcd069cea4e676deb43e5f788447269ed04 |
push id | 18053 |
push user | cleary@mozilla.com |
push date | Sat, 15 Jan 2011 03:38:42 +0000 |
treeherder | mozilla-central@4275fce7591b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cdleary, betaN |
bugs | 625757 |
milestone | 2.0b10pre |
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
|
--- a/js/src/assembler/assembler/AbstractMacroAssembler.h +++ b/js/src/assembler/assembler/AbstractMacroAssembler.h @@ -475,16 +475,21 @@ public: { return m_assembler.executableCopy(buffer); } Label label() { return Label(this); } + + DataLabel32 dataLabel32() + { + return DataLabel32(this); + } Label align() { m_assembler.align(16); return Label(this); } ptrdiff_t differenceBetween(Label from, Jump to)
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/jaeger/bug625757.js @@ -0,0 +1,4 @@ +for(var i=0; i<20; i++) { + var x = 5e-324; +} +/* Don't crash. */
--- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -484,17 +484,20 @@ mjit::Compiler::finishThisUp(JITScript * if (ic::MICInfo *scriptMICs = jit->mics) { for (size_t i = 0; i < mics.length(); i++) { scriptMICs[i].kind = mics[i].kind; scriptMICs[i].entry = fullCode.locationOf(mics[i].entry); switch (mics[i].kind) { case ic::MICInfo::GET: case ic::MICInfo::SET: - scriptMICs[i].load = fullCode.locationOf(mics[i].load); + if (mics[i].kind == ic::MICInfo::GET) + scriptMICs[i].load = fullCode.locationOf(mics[i].load); + else + scriptMICs[i].load = fullCode.locationOf(mics[i].store).labelAtOffset(0); scriptMICs[i].shape = fullCode.locationOf(mics[i].shape); scriptMICs[i].stubCall = stubCode.locationOf(mics[i].call); scriptMICs[i].stubEntry = stubCode.locationOf(mics[i].stubEntry); scriptMICs[i].u.name.typeConst = mics[i].u.name.typeConst; scriptMICs[i].u.name.dataConst = mics[i].u.name.dataConst; scriptMICs[i].u.name.usePropertyCache = mics[i].u.name.usePropertyCache; break; default: @@ -3444,17 +3447,17 @@ mjit::Compiler::jsop_setprop(JSAtom *ato } /* Load dslots. */ Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, offsetof(JSObject, slots)), objReg); /* Store RHS into object slot. */ Address slot(objReg, 1 << 24); - Label inlineValueStore = masm.storeValueWithAddressOffsetPatch(vr, slot); + DataLabel32 inlineValueStore = masm.storeValueWithAddressOffsetPatch(vr, slot); pic.fastPathRejoin = masm.label(); frame.freeReg(objReg); frame.freeReg(shapeReg); /* "Pop under", taking out object (LHS) and leaving RHS. */ frame.shimmy(1); @@ -4423,34 +4426,23 @@ mjit::Compiler::jsop_setgname(JSAtom *at } else { v = fe->getValue(); } masm.loadPtr(Address(objReg, offsetof(JSObject, slots)), objReg); Address address(objReg, slot); if (mic.u.name.dataConst) { - mic.load = masm.storeValueWithAddressOffsetPatch(v, address); + mic.store = masm.storeValueWithAddressOffsetPatch(v, address); } else if (mic.u.name.typeConst) { - mic.load = masm.storeValueWithAddressOffsetPatch(ImmType(typeTag), dataReg, address); + mic.store = masm.storeValueWithAddressOffsetPatch(ImmType(typeTag), dataReg, address); } else { - mic.load = masm.storeValueWithAddressOffsetPatch(typeReg, dataReg, address); + mic.store = masm.storeValueWithAddressOffsetPatch(typeReg, dataReg, address); } -#if defined JS_PUNBOX64 - /* - * Instructions on x86_64 can vary in size based on registers - * used. Since we only need to patch the last instruction in - * both paths above, remember the distance between the - * load label and after the instruction to be patched. - */ - mic.patchValueOffset = masm.differenceBetween(mic.load, masm.label()); - JS_ASSERT(mic.patchValueOffset == masm.differenceBetween(mic.load, masm.label())); -#endif - frame.freeReg(objReg); frame.popn(2); if (mic.u.name.dataConst) { frame.push(v); } else { if (mic.u.name.typeConst) frame.pushTypedPayload(typeTag, dataReg); else
--- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -69,20 +69,18 @@ class Compiler : public BaseCompiler #if defined JS_MONOIC struct MICGenInfo { MICGenInfo(ic::MICInfo::Kind kind) : kind(kind) { } Label entry; Label stubEntry; DataLabel32 shape; DataLabelPtr addrLabel; -#if defined JS_PUNBOX64 - uint32 patchValueOffset; -#endif Label load; + DataLabel32 store; Call call; ic::MICInfo::Kind kind; jsbytecode *jumpTarget; Jump traceHint; MaybeJump slowTraceHint; union { struct { bool typeConst;
--- a/js/src/methodjit/ICLabels.h +++ b/js/src/methodjit/ICLabels.h @@ -227,17 +227,17 @@ struct GetPropLabels : MacroAssemblerTyp int32 inlineTypeJumpOffset : 8; #endif }; /* SetPropCompiler */ struct SetPropLabels : MacroAssemblerTypedefs { friend class ::ICOffsetInitializer; - void setInlineValueStore(MacroAssembler &masm, Label fastPathRejoin, Label inlineValueStore, + void setInlineValueStore(MacroAssembler &masm, Label fastPathRejoin, DataLabel32 inlineValueStore, const ValueRemat &vr) { int offset = masm.differenceBetween(fastPathRejoin, inlineValueStore); setInlineValueStoreOffset(offset, vr.isConstant(), vr.isTypeKnown()); } CodeLocationLabel getInlineValueStore(CodeLocationLabel fastPathRejoin, const ValueRemat &vr) { return fastPathRejoin.labelAtOffset(getInlineValueStoreOffset(vr.isConstant(), vr.isTypeKnown()));
--- a/js/src/methodjit/MonoIC.h +++ b/js/src/methodjit/MonoIC.h @@ -99,18 +99,16 @@ struct MICInfo { GET, SET }; /* Used by multiple MICs. */ JSC::CodeLocationLabel entry; JSC::CodeLocationLabel stubEntry; - /* TODO: use a union-like structure for the below. */ - /* * - ARM and x64 always emit exactly one instruction which needs to be * patched. On ARM, the label points to the patched instruction, whilst * on x64 it points to the instruction after it. * - For x86, the label "load" points to the start of the load/store * sequence, which may consist of one or two "mov" instructions. Because * of this, x86 is the only platform which requires non-trivial patching * code.
--- a/js/src/methodjit/NunboxAssembler.h +++ b/js/src/methodjit/NunboxAssembler.h @@ -198,82 +198,73 @@ class NunboxAssembler : public JSC::Macr } /* * Store a (64b) js::Value from type |treg| and payload |dreg| into |address|, and * return a label which can be used by * ICRepatcher::patchAddressOffsetForValueStore to patch the address' * offset. */ - Label storeValueWithAddressOffsetPatch(RegisterID treg, RegisterID dreg, Address address) { - Label start = label(); + DataLabel32 storeValueWithAddressOffsetPatch(RegisterID treg, RegisterID dreg, Address address) { + DataLabel32 start = dataLabel32(); #if defined JS_CPU_X86 /* * On x86 there are two stores to patch and they both encode the offset * in-line. */ storeTypeTag(treg, address); DBGLABEL_NOMASM(endType); storePayload(dreg, address); DBGLABEL_NOMASM(endPayload); JS_ASSERT(differenceBetween(start, endType) == 6); JS_ASSERT(differenceBetween(endType, endPayload) == 6); return start; #elif defined JS_CPU_ARM - DataLabel32 store = store64WithAddressOffsetPatch(treg, dreg, address); - JS_ASSERT(differenceBetween(start, store) == 0); - (void) store; - return start; + return store64WithAddressOffsetPatch(treg, dreg, address); #endif } /* Overloaded for storing a constant type. */ - Label storeValueWithAddressOffsetPatch(ImmType type, RegisterID dreg, Address address) { - Label start = label(); + DataLabel32 storeValueWithAddressOffsetPatch(ImmType type, RegisterID dreg, Address address) { + DataLabel32 start = dataLabel32(); #if defined JS_CPU_X86 storeTypeTag(type, address); DBGLABEL_NOMASM(endType); storePayload(dreg, address); DBGLABEL_NOMASM(endPayload); JS_ASSERT(differenceBetween(start, endType) == 10); JS_ASSERT(differenceBetween(endType, endPayload) == 6); return start; #elif defined JS_CPU_ARM - DataLabel32 store = store64WithAddressOffsetPatch(type, dreg, address); - JS_ASSERT(differenceBetween(start, store) == 0); - (void) store; - return start; + return store64WithAddressOffsetPatch(type, dreg, address); #endif } /* Overloaded for storing constant type and data. */ - Label storeValueWithAddressOffsetPatch(const Value &v, Address address) { + DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) { jsval_layout jv; jv.asBits = JSVAL_BITS(Jsvalify(v)); ImmTag type(jv.s.tag); Imm32 payload(jv.s.payload.u32); - Label start = label(); + DataLabel32 start = dataLabel32(); #if defined JS_CPU_X86 store32(type, tagOf(address)); DBGLABEL_NOMASM(endType); store32(payload, payloadOf(address)); DBGLABEL_NOMASM(endPayload); JS_ASSERT(differenceBetween(start, endType) == 10); JS_ASSERT(differenceBetween(endType, endPayload) == 10); return start; #elif defined JS_CPU_ARM - DataLabel32 store = store64WithAddressOffsetPatch(type, payload, address); - JS_ASSERT(differenceBetween(start, store) == 0); - (void) store; - return start; + return store64WithAddressOffsetPatch(type, payload, address); #endif } /* Overloaded for store with value remat info. */ - Label storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) { + DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) { if (vr.isConstant()) { return storeValueWithAddressOffsetPatch(vr.value(), address); } else if (vr.isTypeKnown()) { ImmType type(vr.knownType()); RegisterID data(vr.dataReg()); return storeValueWithAddressOffsetPatch(type, data, address); } else { RegisterID type(vr.typeReg());
--- a/js/src/methodjit/PunboxAssembler.h +++ b/js/src/methodjit/PunboxAssembler.h @@ -154,35 +154,40 @@ class PunboxAssembler : public JSC::Macr storeValue(Registers::ValueReg, address); } /* * Store a (64b) js::Value from 'type' and 'payload' into 'address', and * return a label which can be used by * Repatcher::patchAddressOffsetForValueStore to patch the address offset. */ - Label storeValueWithAddressOffsetPatch(RegisterID type, RegisterID payload, Address address) { - storeValueFromComponents(type, payload, address); - return label(); + DataLabel32 storeValueWithAddressOffsetPatch(RegisterID type, RegisterID payload, Address address) { + move(type, Registers::ValueReg); + orPtr(payload, Registers::ValueReg); + return storePtrWithAddressOffsetPatch(Registers::ValueReg, address); } /* Overload for constant type. */ - Label storeValueWithAddressOffsetPatch(ImmTag type, RegisterID payload, Address address) { - storeValueFromComponents(type, payload, address); - return label(); + DataLabel32 storeValueWithAddressOffsetPatch(ImmTag type, RegisterID payload, Address address) { + move(type, Registers::ValueReg); + orPtr(payload, Registers::ValueReg); + return storePtrWithAddressOffsetPatch(Registers::ValueReg, address); } /* Overload for constant type and constant data. */ - Label storeValueWithAddressOffsetPatch(const Value &v, Address address) { - storeValue(v, address); - return label(); + DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) { + jsval_layout jv; + jv.asBits = JSVAL_BITS(Jsvalify(v)); + + move(ImmPtr(reinterpret_cast<void*>(jv.asBits)), Registers::ValueReg); + return storePtrWithAddressOffsetPatch(Registers::ValueReg, valueOf(address)); } /* Overloaded for store with value remat info. */ - Label storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) { + DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) { if (vr.isConstant()) { return storeValueWithAddressOffsetPatch(vr.value(), address); } else if (vr.isTypeKnown()) { ImmType type(vr.knownType()); RegisterID data(vr.dataReg()); return storeValueWithAddressOffsetPatch(type, data, address); } else { RegisterID type(vr.typeReg());