Bug 1060342 - Optimize TypeOfV codegen. r=bhackett

This commit is contained in:
Jan de Mooij 2014-08-30 13:34:09 +02:00
Родитель c4cf1d93c6
Коммит 3bd8e95f82
1 изменённых файлов: 101 добавлений и 48 удалений

Просмотреть файл

@ -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, &notObject); bool testString = input->mightBeType(MIRType_String);
masm.movePtr(ImmGCPtr(names.object), output); bool testSymbol = input->mightBeType(MIRType_Symbol);
masm.jump(&done);
masm.bind(&notObject); 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, &notObject);
masm.movePtr(ImmGCPtr(names.object), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notObject);
}
numTests--;
} }
Label notNumber; if (testNumber) {
masm.branchTestNumber(Assembler::NotEqual, tag, &notNumber); Label notNumber;
masm.movePtr(ImmGCPtr(names.number), output); if (numTests > 1)
masm.jump(&done); masm.branchTestNumber(Assembler::NotEqual, tag, &notNumber);
masm.bind(&notNumber); masm.movePtr(ImmGCPtr(names.number), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notNumber);
numTests--;
}
Label notUndefined; if (testUndefined) {
masm.branchTestUndefined(Assembler::NotEqual, tag, &notUndefined); Label notUndefined;
masm.movePtr(ImmGCPtr(names.undefined), output); if (numTests > 1)
masm.jump(&done); masm.branchTestUndefined(Assembler::NotEqual, tag, &notUndefined);
masm.bind(&notUndefined); masm.movePtr(ImmGCPtr(names.undefined), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notUndefined);
numTests--;
}
Label notNull; if (testNull) {
masm.branchTestNull(Assembler::NotEqual, tag, &notNull); Label notNull;
masm.movePtr(ImmGCPtr(names.object), output); if (numTests > 1)
masm.jump(&done); masm.branchTestNull(Assembler::NotEqual, tag, &notNull);
masm.bind(&notNull); masm.movePtr(ImmGCPtr(names.object), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notNull);
numTests--;
}
Label notBoolean; if (testBoolean) {
masm.branchTestBoolean(Assembler::NotEqual, tag, &notBoolean); Label notBoolean;
masm.movePtr(ImmGCPtr(names.boolean), output); if (numTests > 1)
masm.jump(&done); masm.branchTestBoolean(Assembler::NotEqual, tag, &notBoolean);
masm.bind(&notBoolean); masm.movePtr(ImmGCPtr(names.boolean), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notBoolean);
numTests--;
}
Label notString; if (testString) {
masm.branchTestString(Assembler::NotEqual, tag, &notString); Label notString;
masm.movePtr(ImmGCPtr(names.string), output); if (numTests > 1)
masm.jump(&done); masm.branchTestString(Assembler::NotEqual, tag, &notString);
masm.bind(&notString); masm.movePtr(ImmGCPtr(names.string), output);
if (numTests > 1)
masm.jump(&done);
masm.bind(&notString);
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, &notSymbol);
masm.bind(&isSymbol); masm.movePtr(ImmGCPtr(names.symbol), output);
#endif if (numTests > 1)
masm.movePtr(ImmGCPtr(names.symbol), output); masm.jump(&done);
masm.bind(&notSymbol);
numTests--;
}
MOZ_ASSERT(numTests == 0);
masm.bind(&done); masm.bind(&done);
if (ool) if (ool)