Improve loading elements from arrays with holes on x86, bug 727857. r=sstangl

This commit is contained in:
Brian Hackett 2012-12-10 06:18:43 -07:00
parent a22a51aacf
commit 44ff0d6f9c
6 changed files with 34 additions and 5 deletions

View File

@ -7,6 +7,7 @@
#include "IonAnalysis.h"
#include "IonBuilder.h"
#include "Lowering.h"
#include "MIRGraph.h"
#include "Ion.h"
#include "IonAnalysis.h"
@ -5243,7 +5244,7 @@ IonBuilder::jsop_getelem_dense()
MDefinition *obj = current->pop();
JSValueType knownType = JSVAL_TYPE_UNKNOWN;
if (!needsHoleCheck && !barrier) {
if (!barrier) {
knownType = types->getKnownTypeTag();
// Null and undefined have no payload so they can't be specialized.
@ -5253,6 +5254,11 @@ IonBuilder::jsop_getelem_dense()
// constant.
if (knownType == JSVAL_TYPE_UNDEFINED || knownType == JSVAL_TYPE_NULL)
knownType = JSVAL_TYPE_UNKNOWN;
// Different architectures may want typed element reads which require
// hole checks to be done as either value or typed reads.
if (needsHoleCheck && !LIRGenerator::allowTypedElementHoleCheck())
knownType = JSVAL_TYPE_UNKNOWN;
}
// Ensure id is an integer.

View File

@ -1488,9 +1488,13 @@ LIRGenerator::visitLoadElement(MLoadElement *ins)
return false;
default:
JS_ASSERT(!ins->fallible());
return define(new LLoadElementT(useRegister(ins->elements()),
useRegisterOrConstant(ins->index())), ins);
{
LLoadElementT *lir = new LLoadElementT(useRegister(ins->elements()),
useRegisterOrConstant(ins->index()));
if (ins->fallible() && !assignSnapshot(lir))
return false;
return define(lir, ins);
}
}
}

View File

@ -166,6 +166,11 @@ class LIRGeneratorShared : public MInstructionVisitor
public:
bool visitConstant(MConstant *ins);
// Whether to generate typed reads for element accesses with hole checks.
static bool allowTypedElementHoleCheck() {
return false;
}
};
} // namespace ion

View File

@ -230,12 +230,17 @@ CodeGeneratorX86::visitLoadElementT(LLoadElementT *load)
{
Operand source = createArrayElementOperand(ToRegister(load->elements()), load->index());
if (load->mir()->needsHoleCheck()) {
Assembler::Condition cond = masm.testMagic(Assembler::Equal, source);
if (!bailoutIf(cond, load->snapshot()))
return false;
}
if (load->mir()->type() == MIRType_Double)
masm.loadInt32OrDouble(source, ToFloatRegister(load->output()));
else
masm.movl(masm.ToPayload(source), ToRegister(load->output()));
JS_ASSERT(!load->mir()->needsHoleCheck());
return true;
}

View File

@ -49,6 +49,10 @@ class LIRGeneratorX86 : public LIRGeneratorX86Shared
bool visitReturn(MReturn *ret);
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
bool lowerPhi(MPhi *phi);
static bool allowTypedElementHoleCheck() {
return true;
}
};
typedef LIRGeneratorX86 LIRGeneratorSpecific;

View File

@ -272,6 +272,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmpl(tag, ImmTag(JSVAL_TAG_MAGIC));
return cond;
}
Condition testMagic(Condition cond, const Operand &operand) {
JS_ASSERT(cond == Equal || cond == NotEqual);
cmpl(ToType(operand), ImmTag(JSVAL_TAG_MAGIC));
return cond;
}
Condition testPrimitive(Condition cond, const Register &tag) {
JS_ASSERT(cond == Equal || cond == NotEqual);
cmpl(tag, ImmTag(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET));