Bug 1391304 - Inline IsCallable when called with MIRType::Value. r=jandem

This commit is contained in:
André Bargull 2017-08-17 18:31:33 +02:00
parent fecbd1f9b8
commit 537d49e004
7 changed files with 77 additions and 26 deletions

View File

@ -11902,18 +11902,22 @@ CodeGenerator::visitSetDOMProperty(LSetDOMProperty* ins)
class OutOfLineIsCallable : public OutOfLineCodeBase<CodeGenerator>
{
LIsCallable* ins_;
Register object_;
Register output_;
public:
explicit OutOfLineIsCallable(LIsCallable* ins)
: ins_(ins)
OutOfLineIsCallable(Register object, Register output)
: object_(object), output_(output)
{ }
void accept(CodeGenerator* codegen) {
codegen->visitOutOfLineIsCallable(this);
}
LIsCallable* ins() const {
return ins_;
Register object() const {
return object_;
}
Register output() const {
return output_;
}
};
@ -11966,12 +11970,12 @@ CodeGenerator::emitIsCallableOrConstructor(Register object, Register output, Lab
}
void
CodeGenerator::visitIsCallable(LIsCallable* ins)
CodeGenerator::visitIsCallableO(LIsCallableO* ins)
{
Register object = ToRegister(ins->object());
Register output = ToRegister(ins->output());
OutOfLineIsCallable* ool = new(alloc()) OutOfLineIsCallable(ins);
OutOfLineIsCallable* ool = new(alloc()) OutOfLineIsCallable(object, output);
addOutOfLineCode(ool, ins->mir());
emitIsCallableOrConstructor<Callable>(object, output, ool->entry());
@ -11979,12 +11983,34 @@ CodeGenerator::visitIsCallable(LIsCallable* ins)
masm.bind(ool->rejoin());
}
void
CodeGenerator::visitIsCallableV(LIsCallableV* ins)
{
ValueOperand val = ToValue(ins, LIsCallableV::Value);
Register output = ToRegister(ins->output());
Register temp = ToRegister(ins->temp());
Label notObject;
masm.branchTestObject(Assembler::NotEqual, val, &notObject);
masm.unboxObject(val, temp);
OutOfLineIsCallable* ool = new(alloc()) OutOfLineIsCallable(temp, output);
addOutOfLineCode(ool, ins->mir());
emitIsCallableOrConstructor<Callable>(temp, output, ool->entry());
masm.jump(ool->rejoin());
masm.bind(&notObject);
masm.move32(Imm32(0), output);
masm.bind(ool->rejoin());
}
void
CodeGenerator::visitOutOfLineIsCallable(OutOfLineIsCallable* ool)
{
LIsCallable* ins = ool->ins();
Register object = ToRegister(ins->object());
Register output = ToRegister(ins->output());
Register object = ool->object();
Register output = ool->output();
saveVolatile(output);
masm.setupUnalignedABICall(output);

View File

@ -386,7 +386,8 @@ class CodeGenerator final : public CodeGeneratorSpecific
};
template <CallableOrConstructor mode>
void emitIsCallableOrConstructor(Register object, Register output, Label* failure);
void visitIsCallable(LIsCallable* lir);
void visitIsCallableO(LIsCallableO* lir);
void visitIsCallableV(LIsCallableV* lir);
void visitOutOfLineIsCallable(OutOfLineIsCallable* ool);
void visitIsConstructor(LIsConstructor* lir);
void visitOutOfLineIsConstructor(OutOfLineIsConstructor* ool);

View File

@ -4359,9 +4359,14 @@ LIRGenerator::visitIsTypedArray(MIsTypedArray* ins)
void
LIRGenerator::visitIsCallable(MIsCallable* ins)
{
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
MOZ_ASSERT(ins->type() == MIRType::Boolean);
define(new(alloc()) LIsCallable(useRegister(ins->object())), ins);
if (ins->object()->type() == MIRType::Object) {
define(new(alloc()) LIsCallableO(useRegister(ins->object())), ins);
} else {
MOZ_ASSERT(ins->object()->type() == MIRType::Value);
define(new(alloc()) LIsCallableV(useBox(ins->object()), temp()), ins);
}
}
void

View File

@ -2982,25 +2982,24 @@ IonBuilder::inlineIsCallable(CallInfo& callInfo)
return InliningStatus_NotInlined;
MDefinition* arg = callInfo.getArg(0);
// Do not inline if the type of arg is neither primitive nor object.
if (arg->type() > MIRType::Object)
return InliningStatus_NotInlined;
// Try inlining with constant true/false: only objects may be callable at
// all, and if we know the class check if it is callable.
bool isCallableKnown = false;
bool isCallableConstant;
if (arg->type() != MIRType::Object) {
// Primitive (including undefined and null).
isCallableKnown = true;
isCallableConstant = false;
} else {
if (arg->type() == MIRType::Object) {
TemporaryTypeSet* types = arg->resultTypeSet();
const Class* clasp = types ? types->getKnownClass(constraints()) : nullptr;
if (clasp && !clasp->isProxy()) {
isCallableKnown = true;
isCallableConstant = clasp->nonProxyCallable();
}
} else if (!arg->mightBeType(MIRType::Object)) {
// Primitive (including undefined and null).
isCallableKnown = true;
isCallableConstant = false;
} else if (arg->type() != MIRType::Value) {
return InliningStatus_NotInlined;
}
callInfo.setImplicitlyUsedUnchecked();

View File

@ -13444,11 +13444,12 @@ class MResumePoint final :
class MIsCallable
: public MUnaryInstruction,
public SingleObjectPolicy::Data
public BoxExceptPolicy<0, MIRType::Object>::Data
{
explicit MIsCallable(MDefinition* object)
: MUnaryInstruction(object)
{
MOZ_ASSERT(object->type() == MIRType::Object || object->type() == MIRType::Value);
setResultType(MIRType::Boolean);
setMovable();
}

View File

@ -8008,11 +8008,11 @@ class LCallInstanceOf : public LCallInstructionHelper<1, BOX_PIECES+1, 0>
static const size_t RHS = BOX_PIECES;
};
class LIsCallable : public LInstructionHelper<1, 1, 0>
class LIsCallableO : public LInstructionHelper<1, 1, 0>
{
public:
LIR_HEADER(IsCallable);
explicit LIsCallable(const LAllocation& object) {
LIR_HEADER(IsCallableO);
explicit LIsCallableO(const LAllocation& object) {
setOperand(0, object);
}
@ -8024,6 +8024,24 @@ class LIsCallable : public LInstructionHelper<1, 1, 0>
}
};
class LIsCallableV : public LInstructionHelper<1, BOX_PIECES, 1>
{
public:
LIR_HEADER(IsCallableV);
static const size_t Value = 0;
LIsCallableV(const LBoxAllocation& value, const LDefinition& temp) {
setBoxOperand(0, value);
setTemp(0, temp);
}
const LDefinition* temp() {
return getTemp(0);
}
MIsCallable* mir() const {
return mir_->toIsCallable();
}
};
class LIsConstructor : public LInstructionHelper<1, 1, 0>
{
public:

View File

@ -390,7 +390,8 @@
_(GetDOMMemberT) \
_(SetDOMProperty) \
_(CallDOMNative) \
_(IsCallable) \
_(IsCallableO) \
_(IsCallableV) \
_(IsConstructor) \
_(IsArrayO) \
_(IsArrayV) \