Bug 742562 - Inline allocation for JSOP_NEWARRAY. r=dvander

This commit is contained in:
Sean Stangl 2012-04-04 21:10:42 -07:00
parent 7931737218
commit 34f045f407
5 changed files with 80 additions and 13 deletions

View File

@ -830,16 +830,84 @@ CodeGenerator::generateBody()
return true;
}
bool
CodeGenerator::visitNewArray(LNewArray *lir)
// Out-of-line object allocation for LNewArray.
class OutOfLineNewArray : public OutOfLineCodeBase<CodeGenerator>
{
LNewArray *lir_;
public:
OutOfLineNewArray(LNewArray *lir)
: lir_(lir)
{ }
bool accept(CodeGenerator *codegen) {
return codegen->visitOutOfLineNewArray(this);
}
LNewArray *lir() const {
return lir_;
}
};
bool
CodeGenerator::visitNewArrayCallVM(LNewArray *lir)
{
Register objReg = ToRegister(lir->output());
typedef JSObject *(*pf)(JSContext *, uint32, types::TypeObject *);
static const VMFunction NewInitArrayInfo = FunctionInfo<pf>(NewInitArray);
JS_ASSERT(!lir->isCall());
saveLive(lir);
pushArg(ImmGCPtr(lir->mir()->type()));
pushArg(Imm32(lir->mir()->count()));
if (!callVM(NewInitArrayInfo, lir))
return false;
if (ReturnReg != objReg)
masm.movePtr(ReturnReg, objReg);
restoreLive(lir);
return true;
}
bool
CodeGenerator::visitNewArray(LNewArray *lir)
{
Register objReg = ToRegister(lir->output());
types::TypeObject *typeObj = lir->mir()->type();
uint32 count = lir->mir()->count();
size_t maxArraySlots =
gc::GetGCKindSlots(gc::FINALIZE_OBJECT_LAST) - ObjectElements::VALUES_PER_HEADER;
if (!gen->cx->typeInferenceEnabled() || !typeObj || count > maxArraySlots)
return visitNewArrayCallVM(lir);
OutOfLineNewArray *ool = new OutOfLineNewArray(lir);
if (!addOutOfLineCode(ool))
return false;
JSObject *templateObject = NewDenseUnallocatedArray(gen->cx, count);
if (!templateObject)
return false;
templateObject->setType(typeObj);
masm.getNewObject(gen->cx, objReg, templateObject, ool->entry());
masm.bind(ool->rejoin());
return true;
}
bool
CodeGenerator::visitOutOfLineNewArray(OutOfLineNewArray *ool)
{
if (!visitNewArrayCallVM(ool->lir()))
return false;
masm.jump(ool->rejoin());
return true;
}

View File

@ -55,6 +55,7 @@
namespace js {
namespace ion {
class OutOfLineNewArray;
class OutOfLineNewObject;
class OutOfLineCreateThis;
class CheckOverRecursedFailure;
@ -105,7 +106,9 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitCallGeneric(LCallGeneric *call);
bool visitCallConstructor(LCallConstructor *call);
bool visitDoubleToInt32(LDoubleToInt32 *lir);
bool visitNewArrayCallVM(LNewArray *lir);
bool visitNewArray(LNewArray *lir);
bool visitOutOfLineNewArray(OutOfLineNewArray *ool);
bool visitNewObjectVMCall(LNewObject *lir);
bool visitNewObject(LNewObject *lir);
bool visitOutOfLineNewObject(OutOfLineNewObject *ool);

View File

@ -2772,9 +2772,7 @@ IonBuilder::jsop_newarray(uint32 count)
current->add(ins);
current->push(ins);
if (!resumeAfter(ins))
return false;
return true;
return resumeAfter(ins);
}
bool

View File

@ -225,11 +225,15 @@ class LGoto : public LInstructionHelper<0, 0, 0>
}
};
class LNewArray : public LCallInstructionHelper<1, 0, 0>
class LNewArray : public LInstructionHelper<1, 0, 0>
{
public:
LIR_HEADER(NewArray);
const LDefinition *output() {
return getDef(0);
}
MNewArray *mir() const {
return mir_->toNewArray();
}

View File

@ -134,13 +134,7 @@ bool
LIRGenerator::visitNewArray(MNewArray *ins)
{
LNewArray *lir = new LNewArray();
if (!defineVMReturn(lir, ins))
return false;
if (!assignSafepoint(lir, ins))
return false;
return true;
return define(lir, ins) && assignSafepoint(lir, ins);
}
bool