Bug 1141865 - Part 1: Make two ICCall_Fallback, one for constructing invocations. (r=jandem)

This commit is contained in:
Eric Faust 2015-06-03 02:01:14 -07:00
parent 555676c060
commit bccf4effd7
5 changed files with 35 additions and 40 deletions

View File

@ -454,7 +454,7 @@ GetStubReturnAddress(JSContext* cx, jsbytecode* pc)
return cx->compartment()->jitCompartment()->baselineSetPropReturnAddr();
// This should be a call op of some kind, now.
MOZ_ASSERT(IsCallPC(pc));
return cx->compartment()->jitCompartment()->baselineCallReturnAddr();
return cx->compartment()->jitCompartment()->baselineCallReturnAddr(JSOp(*pc) == JSOP_NEW);
}
static inline jsbytecode*

View File

@ -10835,24 +10835,20 @@ ICCall_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
leaveStubFrame(masm, true);
// R1 and R0 are taken.
regs = availableGeneralRegs(2);
Register scratch = regs.takeAny();
// If this is a |constructing| call, if the callee returns a non-object, we replace it with
// the |this| object passed in.
MOZ_ASSERT(JSReturnOperand == R0);
Label skipThisReplace;
masm.load16ZeroExtend(Address(BaselineStubReg, ICStub::offsetOfExtra()), scratch);
masm.branchTest32(Assembler::Zero, scratch, Imm32(ICCall_Fallback::CONSTRUCTING_FLAG),
&skipThisReplace);
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
masm.moveValue(R1, R0);
if (isConstructing_) {
MOZ_ASSERT(JSReturnOperand == R0);
Label skipThisReplace;
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
masm.moveValue(R1, R0);
#ifdef DEBUG
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
masm.assumeUnreachable("Failed to return object in constructing call.");
masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace);
masm.assumeUnreachable("Failed to return object in constructing call.");
#endif
masm.bind(&skipThisReplace);
masm.bind(&skipThisReplace);
}
// At this point, BaselineStubReg points to the ICCall_Fallback stub, which is NOT
// a MonitoredStub, but rather a MonitoredFallbackStub. To use EmitEnterTypeMonitorIC,
@ -10873,7 +10869,8 @@ ICCall_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle<Jit
CodeOffsetLabel offset(returnOffset_);
offset.fixup(&masm);
cx->compartment()->jitCompartment()->initBaselineCallReturnAddr(code->raw() + offset.offset());
cx->compartment()->jitCompartment()->initBaselineCallReturnAddr(code->raw() + offset.offset(),
isConstructing_);
return true;
}

View File

@ -5538,27 +5538,18 @@ class ICCall_Fallback : public ICMonitoredFallbackStub
{
friend class ICStubSpace;
public:
static const unsigned CONSTRUCTING_FLAG = 0x1;
static const unsigned UNOPTIMIZABLE_CALL_FLAG = 0x2;
static const unsigned UNOPTIMIZABLE_CALL_FLAG = 0x1;
static const uint32_t MAX_OPTIMIZED_STUBS = 16;
static const uint32_t MAX_SCRIPTED_STUBS = 7;
static const uint32_t MAX_NATIVE_STUBS = 7;
private:
ICCall_Fallback(JitCode* stubCode, bool isConstructing)
explicit ICCall_Fallback(JitCode* stubCode)
: ICMonitoredFallbackStub(ICStub::Call_Fallback, stubCode)
{
extra_ = 0;
if (isConstructing)
extra_ |= CONSTRUCTING_FLAG;
}
{ }
public:
bool isConstructing() const {
return extra_ & CONSTRUCTING_FLAG;
}
void noteUnoptimizableCall() {
extra_ |= UNOPTIMIZABLE_CALL_FLAG;
}
@ -5583,6 +5574,9 @@ class ICCall_Fallback : public ICMonitoredFallbackStub
// Compiler for this stub kind.
class Compiler : public ICCallStubCompiler {
public:
static const int32_t CALL_KEY = static_cast<int32_t>(ICStub::Call_Fallback);
static const int32_t CONSTRUCT_KEY = static_cast<int32_t>(ICStub::Call_Fallback) | (1 << 17);
protected:
bool isConstructing_;
bool isSpread_;
@ -5591,7 +5585,8 @@ class ICCall_Fallback : public ICMonitoredFallbackStub
bool postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code);
virtual int32_t getKey() const {
return static_cast<int32_t>(kind) | (static_cast<int32_t>(isSpread_) << 16);
return static_cast<int32_t>(kind) | (static_cast<int32_t>(isSpread_) << 16) |
(static_cast<int32_t>(isConstructing_) << 17);
}
public:
@ -5602,7 +5597,7 @@ class ICCall_Fallback : public ICMonitoredFallbackStub
{ }
ICStub* getStub(ICStubSpace* space) {
ICCall_Fallback* stub = newStub<ICCall_Fallback>(space, getStubCode(), isConstructing_);
ICCall_Fallback* stub = newStub<ICCall_Fallback>(space, getStubCode());
if (!stub || !stub->initMonitoringChain(cx, space))
return nullptr;
return stub;

View File

@ -362,13 +362,13 @@ JitRuntime::patchIonBackedges(JSRuntime* rt, BackedgeTarget target)
JitCompartment::JitCompartment()
: stubCodes_(nullptr),
baselineCallReturnAddr_(nullptr),
baselineGetPropReturnAddr_(nullptr),
baselineSetPropReturnAddr_(nullptr),
stringConcatStub_(nullptr),
regExpExecStub_(nullptr),
regExpTestStub_(nullptr)
{
baselineCallReturnAddrs_[0] = baselineCallReturnAddrs_[1] = nullptr;
}
JitCompartment::~JitCompartment()
@ -652,8 +652,11 @@ JitCompartment::sweep(FreeOp* fop, JSCompartment* compartment)
stubCodes_->sweep(fop);
// If the sweep removed the ICCall_Fallback stub, nullptr the baselineCallReturnAddr_ field.
if (!stubCodes_->lookup(static_cast<uint32_t>(ICStub::Call_Fallback)))
baselineCallReturnAddr_ = nullptr;
if (!stubCodes_->lookup(ICCall_Fallback::Compiler::CALL_KEY))
baselineCallReturnAddrs_[0] = nullptr;
if (!stubCodes_->lookup(ICCall_Fallback::Compiler::CONSTRUCT_KEY))
baselineCallReturnAddrs_[1] = nullptr;
// Similarly for the ICGetProp_Fallback stub.
if (!stubCodes_->lookup(static_cast<uint32_t>(ICStub::GetProp_Fallback)))
baselineGetPropReturnAddr_ = nullptr;

View File

@ -422,7 +422,7 @@ class JitCompartment
// Keep track of offset into various baseline stubs' code at return
// point from called script.
void* baselineCallReturnAddr_;
void* baselineCallReturnAddrs_[2];
void* baselineGetPropReturnAddr_;
void* baselineSetPropReturnAddr_;
@ -481,13 +481,13 @@ class JitCompartment
ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
return stubCodes_->add(p, key, stubCode.get());
}
void initBaselineCallReturnAddr(void* addr) {
MOZ_ASSERT(baselineCallReturnAddr_ == nullptr);
baselineCallReturnAddr_ = addr;
void initBaselineCallReturnAddr(void* addr, bool constructing) {
MOZ_ASSERT(baselineCallReturnAddrs_[constructing] == nullptr);
baselineCallReturnAddrs_[constructing] = addr;
}
void* baselineCallReturnAddr() {
MOZ_ASSERT(baselineCallReturnAddr_ != nullptr);
return baselineCallReturnAddr_;
void* baselineCallReturnAddr(bool constructing) {
MOZ_ASSERT(baselineCallReturnAddrs_[constructing] != nullptr);
return baselineCallReturnAddrs_[constructing];
}
void initBaselineGetPropReturnAddr(void* addr) {
MOZ_ASSERT(baselineGetPropReturnAddr_ == nullptr);