зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1060342 - Optimize TypeOfV codegen. r=bhackett
This commit is contained in:
Родитель
c4cf1d93c6
Коммит
3bd8e95f82
|
@ -7837,62 +7837,115 @@ CodeGenerator::visitTypeOfV(LTypeOfV *lir)
|
||||||
const JSAtomState &names = GetIonContext()->runtime->names();
|
const JSAtomState &names = GetIonContext()->runtime->names();
|
||||||
Label done;
|
Label done;
|
||||||
|
|
||||||
OutOfLineTypeOfV *ool = nullptr;
|
MDefinition *input = lir->mir()->input();
|
||||||
if (lir->mir()->inputMaybeCallableOrEmulatesUndefined()) {
|
|
||||||
// The input may be a callable object (result is "function") or may
|
|
||||||
// emulate undefined (result is "undefined"). Use an OOL path.
|
|
||||||
ool = new(alloc()) OutOfLineTypeOfV(lir);
|
|
||||||
if (!addOutOfLineCode(ool, lir->mir()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
masm.branchTestObject(Assembler::Equal, tag, ool->entry());
|
bool testObject = input->mightBeType(MIRType_Object);
|
||||||
} else {
|
bool testNumber = input->mightBeType(MIRType_Int32) || input->mightBeType(MIRType_Double);
|
||||||
// Input is not callable and does not emulate undefined, so if
|
bool testBoolean = input->mightBeType(MIRType_Boolean);
|
||||||
// it's an object the result is always "object".
|
bool testUndefined = input->mightBeType(MIRType_Undefined);
|
||||||
Label notObject;
|
bool testNull = input->mightBeType(MIRType_Null);
|
||||||
masm.branchTestObject(Assembler::NotEqual, tag, ¬Object);
|
bool testString = input->mightBeType(MIRType_String);
|
||||||
masm.movePtr(ImmGCPtr(names.object), output);
|
bool testSymbol = input->mightBeType(MIRType_Symbol);
|
||||||
masm.jump(&done);
|
|
||||||
masm.bind(¬Object);
|
unsigned numTests = unsigned(testObject) + unsigned(testNumber) + unsigned(testBoolean) +
|
||||||
|
unsigned(testUndefined) + unsigned(testNull) + unsigned(testString) + unsigned(testSymbol);
|
||||||
|
|
||||||
|
MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0);
|
||||||
|
|
||||||
|
OutOfLineTypeOfV *ool = nullptr;
|
||||||
|
if (testObject) {
|
||||||
|
if (lir->mir()->inputMaybeCallableOrEmulatesUndefined()) {
|
||||||
|
// The input may be a callable object (result is "function") or may
|
||||||
|
// emulate undefined (result is "undefined"). Use an OOL path.
|
||||||
|
ool = new(alloc()) OutOfLineTypeOfV(lir);
|
||||||
|
if (!addOutOfLineCode(ool, lir->mir()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.branchTestObject(Assembler::Equal, tag, ool->entry());
|
||||||
|
else
|
||||||
|
masm.jump(ool->entry());
|
||||||
|
} else {
|
||||||
|
// Input is not callable and does not emulate undefined, so if
|
||||||
|
// it's an object the result is always "object".
|
||||||
|
Label notObject;
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.branchTestObject(Assembler::NotEqual, tag, ¬Object);
|
||||||
|
masm.movePtr(ImmGCPtr(names.object), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Object);
|
||||||
|
}
|
||||||
|
numTests--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Label notNumber;
|
if (testNumber) {
|
||||||
masm.branchTestNumber(Assembler::NotEqual, tag, ¬Number);
|
Label notNumber;
|
||||||
masm.movePtr(ImmGCPtr(names.number), output);
|
if (numTests > 1)
|
||||||
masm.jump(&done);
|
masm.branchTestNumber(Assembler::NotEqual, tag, ¬Number);
|
||||||
masm.bind(¬Number);
|
masm.movePtr(ImmGCPtr(names.number), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Number);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
Label notUndefined;
|
if (testUndefined) {
|
||||||
masm.branchTestUndefined(Assembler::NotEqual, tag, ¬Undefined);
|
Label notUndefined;
|
||||||
masm.movePtr(ImmGCPtr(names.undefined), output);
|
if (numTests > 1)
|
||||||
masm.jump(&done);
|
masm.branchTestUndefined(Assembler::NotEqual, tag, ¬Undefined);
|
||||||
masm.bind(¬Undefined);
|
masm.movePtr(ImmGCPtr(names.undefined), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Undefined);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
Label notNull;
|
if (testNull) {
|
||||||
masm.branchTestNull(Assembler::NotEqual, tag, ¬Null);
|
Label notNull;
|
||||||
masm.movePtr(ImmGCPtr(names.object), output);
|
if (numTests > 1)
|
||||||
masm.jump(&done);
|
masm.branchTestNull(Assembler::NotEqual, tag, ¬Null);
|
||||||
masm.bind(¬Null);
|
masm.movePtr(ImmGCPtr(names.object), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Null);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
Label notBoolean;
|
if (testBoolean) {
|
||||||
masm.branchTestBoolean(Assembler::NotEqual, tag, ¬Boolean);
|
Label notBoolean;
|
||||||
masm.movePtr(ImmGCPtr(names.boolean), output);
|
if (numTests > 1)
|
||||||
masm.jump(&done);
|
masm.branchTestBoolean(Assembler::NotEqual, tag, ¬Boolean);
|
||||||
masm.bind(¬Boolean);
|
masm.movePtr(ImmGCPtr(names.boolean), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Boolean);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
Label notString;
|
if (testString) {
|
||||||
masm.branchTestString(Assembler::NotEqual, tag, ¬String);
|
Label notString;
|
||||||
masm.movePtr(ImmGCPtr(names.string), output);
|
if (numTests > 1)
|
||||||
masm.jump(&done);
|
masm.branchTestString(Assembler::NotEqual, tag, ¬String);
|
||||||
masm.bind(¬String);
|
masm.movePtr(ImmGCPtr(names.string), output);
|
||||||
|
if (numTests > 1)
|
||||||
|
masm.jump(&done);
|
||||||
|
masm.bind(¬String);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
if (testSymbol) {
|
||||||
Label isSymbol;
|
Label notSymbol;
|
||||||
masm.branchTestSymbol(Assembler::Equal, tag, &isSymbol);
|
if (numTests > 1)
|
||||||
masm.assumeUnreachable("Unexpected type for TypeOfV");
|
masm.branchTestSymbol(Assembler::NotEqual, tag, ¬Symbol);
|
||||||
masm.bind(&isSymbol);
|
masm.movePtr(ImmGCPtr(names.symbol), output);
|
||||||
#endif
|
if (numTests > 1)
|
||||||
masm.movePtr(ImmGCPtr(names.symbol), output);
|
masm.jump(&done);
|
||||||
|
masm.bind(¬Symbol);
|
||||||
|
numTests--;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(numTests == 0);
|
||||||
|
|
||||||
masm.bind(&done);
|
masm.bind(&done);
|
||||||
if (ool)
|
if (ool)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче