Bug 969012 - Use a second register for object allocation; r=jandem

--HG--
extra : rebase_source : 2cbc07d17ed3cf84fbc2590745a4c22a62ee573c
This commit is contained in:
Terrence Cole 2014-02-17 17:39:14 -08:00
Родитель 17f4a32d8b
Коммит 944db060be
10 изменённых файлов: 245 добавлений и 136 удалений

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

@ -964,6 +964,7 @@ CodeGenerator::visitLambda(LLambda *lir)
{
Register scopeChain = ToRegister(lir->scopeChain());
Register output = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
const LambdaFunctionInfo &info = lir->mir()->info();
OutOfLineCode *ool = oolCallVM(LambdaInfo, lir, (ArgList(), ImmGCPtr(info.fun), scopeChain),
@ -973,8 +974,8 @@ CodeGenerator::visitLambda(LLambda *lir)
JS_ASSERT(!info.singletonType);
masm.newGCThing(output, info.fun, ool->entry(), gc::DefaultHeap);
masm.initGCThing(output, info.fun);
masm.newGCThing(output, tempReg, info.fun, ool->entry(), gc::DefaultHeap);
masm.initGCThing(output, tempReg, info.fun);
emitLambdaInit(output, scopeChain, info);
@ -983,7 +984,7 @@ CodeGenerator::visitLambda(LLambda *lir)
}
void
CodeGenerator::emitLambdaInit(const Register &output, const Register &scopeChain,
CodeGenerator::emitLambdaInit(Register output, Register scopeChain,
const LambdaFunctionInfo &info)
{
// Initialize nargs and flags. We do this with a single uint32 to avoid
@ -3396,6 +3397,7 @@ CodeGenerator::visitNewArray(LNewArray *lir)
{
JS_ASSERT(gen->info().executionMode() == SequentialExecution);
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObject = lir->mir()->templateObject();
DebugOnly<uint32_t> count = lir->mir()->count();
@ -3408,8 +3410,8 @@ CodeGenerator::visitNewArray(LNewArray *lir)
if (!addOutOfLineCode(ool))
return false;
masm.newGCThing(objReg, templateObject, ool->entry(), lir->mir()->initialHeap());
masm.initGCThing(objReg, templateObject);
masm.newGCThing(objReg, tempReg, templateObject, ool->entry(), lir->mir()->initialHeap());
masm.initGCThing(objReg, tempReg, templateObject);
masm.bind(ool->rejoin());
return true;
@ -3485,6 +3487,7 @@ CodeGenerator::visitNewObject(LNewObject *lir)
{
JS_ASSERT(gen->info().executionMode() == SequentialExecution);
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObject = lir->mir()->templateObject();
if (lir->mir()->shouldUseVM())
@ -3494,8 +3497,8 @@ CodeGenerator::visitNewObject(LNewObject *lir)
if (!addOutOfLineCode(ool))
return false;
masm.newGCThing(objReg, templateObject, ool->entry(), lir->mir()->initialHeap());
masm.initGCThing(objReg, templateObject);
masm.newGCThing(objReg, tempReg, templateObject, ool->entry(), lir->mir()->initialHeap());
masm.initGCThing(objReg, tempReg, templateObject);
masm.bind(ool->rejoin());
return true;
@ -3517,7 +3520,8 @@ static const VMFunction NewDeclEnvObjectInfo =
bool
CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
{
Register obj = ToRegister(lir->output());
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObj = lir->mir()->templateObj();
CompileInfo &info = lir->mir()->block()->info();
@ -3525,12 +3529,12 @@ CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
OutOfLineCode *ool = oolCallVM(NewDeclEnvObjectInfo, lir,
(ArgList(), ImmGCPtr(info.funMaybeLazy()),
Imm32(gc::DefaultHeap)),
StoreRegisterTo(obj));
StoreRegisterTo(objReg));
if (!ool)
return false;
masm.newGCThing(obj, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(obj, templateObj);
masm.newGCThing(objReg, tempReg, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(objReg, tempReg, templateObj);
masm.bind(ool->rejoin());
return true;
}
@ -3543,7 +3547,8 @@ static const VMFunction NewCallObjectInfo =
bool
CodeGenerator::visitNewCallObject(LNewCallObject *lir)
{
Register obj = ToRegister(lir->output());
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
JSObject *templateObj = lir->mir()->templateObject();
@ -3555,14 +3560,14 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
ImmGCPtr(templateObj->lastProperty()),
ImmGCPtr(templateObj->hasSingletonType() ? nullptr : templateObj->type()),
ToRegister(lir->slots())),
StoreRegisterTo(obj));
StoreRegisterTo(objReg));
} else {
ool = oolCallVM(NewCallObjectInfo, lir,
(ArgList(), ImmGCPtr(lir->mir()->block()->info().script()),
ImmGCPtr(templateObj->lastProperty()),
ImmGCPtr(templateObj->hasSingletonType() ? nullptr : templateObj->type()),
ImmPtr(nullptr)),
StoreRegisterTo(obj));
StoreRegisterTo(objReg));
}
if (!ool)
return false;
@ -3571,11 +3576,11 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
// Objects can only be given singleton types in VM calls.
masm.jump(ool->entry());
} else {
masm.newGCThing(obj, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(obj, templateObj);
masm.newGCThing(objReg, tempReg, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(objReg, tempReg, templateObj);
if (lir->slots()->isRegister())
masm.storePtr(ToRegister(lir->slots()), Address(obj, JSObject::offsetOfSlots()));
masm.storePtr(ToRegister(lir->slots()), Address(objReg, JSObject::offsetOfSlots()));
}
masm.bind(ool->rejoin());
@ -3661,8 +3666,8 @@ CodeGenerator::visitNewStringObject(LNewStringObject *lir)
if (!ool)
return false;
masm.newGCThing(output, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(output, templateObj);
masm.newGCThing(output, temp, templateObj, ool->entry(), gc::DefaultHeap);
masm.initGCThing(output, temp, templateObj);
masm.loadStringLength(input, temp);
@ -3704,9 +3709,8 @@ public:
};
bool
CodeGenerator::emitAllocateGCThingPar(LInstruction *lir, const Register &objReg,
const Register &cxReg, const Register &tempReg1,
const Register &tempReg2, JSObject *templateObj)
CodeGenerator::emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg,
Register tempReg1, Register tempReg2, JSObject *templateObj)
{
gc::AllocKind allocKind = templateObj->tenuredGetAllocKind();
OutOfLineNewGCThingPar *ool = new(alloc()) OutOfLineNewGCThingPar(lir, allocKind, objReg, cxReg);
@ -3715,7 +3719,7 @@ CodeGenerator::emitAllocateGCThingPar(LInstruction *lir, const Register &objReg,
masm.newGCThingPar(objReg, cxReg, tempReg1, tempReg2, templateObj, ool->entry());
masm.bind(ool->rejoin());
masm.initGCThing(objReg, templateObj);
masm.initGCThing(objReg, tempReg1, templateObj);
return true;
}
@ -3899,6 +3903,7 @@ CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
gc::AllocKind allocKind = templateObject->tenuredGetAllocKind();
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
Register objReg = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
OutOfLineCode *ool = oolCallVM(NewGCObjectInfo, lir,
(ArgList(), Imm32(allocKind), Imm32(initialHeap)),
@ -3907,11 +3912,11 @@ CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
return false;
// Allocate. If the FreeList is empty, call to VM, which may GC.
masm.newGCThing(objReg, templateObject, ool->entry(), lir->mir()->initialHeap());
masm.newGCThing(objReg, tempReg, templateObject, ool->entry(), lir->mir()->initialHeap());
// Initialize based on the templateObject.
masm.bind(ool->rejoin());
masm.initGCThing(objReg, templateObject);
masm.initGCThing(objReg, tempReg, templateObject);
return true;
}
@ -4865,7 +4870,7 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode)
// Allocate a new rope.
switch (mode) {
case SequentialExecution:
masm.newGCString(output, &failure);
masm.newGCString(output, temp3, &failure);
break;
case ParallelExecution:
masm.push(temp1);
@ -4910,7 +4915,7 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode)
// Allocate a JSShortString.
switch (mode) {
case SequentialExecution:
masm.newGCShortString(output, &failure);
masm.newGCShortString(output, temp3, &failure);
break;
case ParallelExecution:
masm.push(temp1);
@ -5630,8 +5635,8 @@ CodeGenerator::visitArrayConcat(LArrayConcat *lir)
// Try to allocate an object.
JSObject *templateObj = lir->mir()->templateObj();
masm.newGCThing(temp1, templateObj, &fail, lir->mir()->initialHeap());
masm.initGCThing(temp1, templateObj);
masm.newGCThing(temp1, temp2, templateObj, &fail, lir->mir()->initialHeap());
masm.initGCThing(temp1, temp2, templateObj);
masm.jump(&call);
{
masm.bind(&fail);
@ -6002,8 +6007,8 @@ CodeGenerator::visitRest(LRest *lir)
JSObject *templateObject = lir->mir()->templateObject();
Label joinAlloc, failAlloc;
masm.newGCThing(temp2, templateObject, &failAlloc, gc::DefaultHeap);
masm.initGCThing(temp2, templateObject);
masm.newGCThing(temp2, temp0, templateObject, &failAlloc, gc::DefaultHeap);
masm.initGCThing(temp2, temp0, templateObject);
masm.jump(&joinAlloc);
{
masm.bind(&failAlloc);

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

@ -366,13 +366,13 @@ class CodeGenerator : public CodeGeneratorSpecific
bool generateBranchV(const ValueOperand &value, Label *ifTrue, Label *ifFalse, FloatRegister fr);
bool emitAllocateGCThingPar(LInstruction *lir, const Register &objReg, const Register &cxReg,
const Register &tempReg1, const Register &tempReg2,
bool emitAllocateGCThingPar(LInstruction *lir, Register objReg, Register cxReg,
Register tempReg1, Register tempReg2,
JSObject *templateObj);
bool emitCallToUncompiledScriptPar(LInstruction *lir, Register calleeReg);
void emitLambdaInit(const Register &resultReg, const Register &scopeChainReg,
void emitLambdaInit(Register resultReg, Register scopeChainReg,
const LambdaFunctionInfo &info);
bool emitFilterArgumentsOrEval(LInstruction *lir, Register string, Register temp1,

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

@ -7928,7 +7928,7 @@ IonBuilder::jsop_rest()
// Unroll the argument copy loop. We don't need to do any bounds or hole
// checking here.
MConstant *index;
MConstant *index = nullptr;
for (unsigned i = numFormals; i < numActuals; i++) {
index = MConstant::New(alloc(), Int32Value(i - numFormals));
current->add(index);

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

@ -361,7 +361,7 @@ MacroAssembler::branchNurseryPtr(Condition cond, const Address &ptr1, const ImmM
}
void
MacroAssembler::moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, const Register &reg)
MacroAssembler::moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, Register reg)
{
#ifdef JSGC_GENERATIONAL
if (ptr.value && gc::IsInsideNursery(GetIonContext()->cx->runtime(), (void *)ptr.value))
@ -634,7 +634,7 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
}
void
MacroAssembler::newGCThing(const Register &result, gc::AllocKind allocKind, Label *fail,
MacroAssembler::newGCThing(Register result, Register temp, gc::AllocKind allocKind, Label *fail,
gc::InitialHeap initialHeap /* = gc::DefaultHeap */)
{
// Inlined equivalent of js::gc::NewGCThing() without failure case handling.
@ -662,10 +662,9 @@ MacroAssembler::newGCThing(const Register &result, gc::AllocKind allocKind, Labe
// in such cases.
const Nursery &nursery = GetIonContext()->runtime->gcNursery();
loadPtr(AbsoluteAddress(nursery.addressOfPosition()), result);
addPtr(Imm32(thingSize), result);
branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(nursery.addressOfCurrentEnd()), result, fail);
storePtr(result, AbsoluteAddress(nursery.addressOfPosition()));
subPtr(Imm32(thingSize), result);
computeEffectiveAddress(Address(result, thingSize), temp);
branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(nursery.addressOfCurrentEnd()), temp, fail);
storePtr(temp, AbsoluteAddress(nursery.addressOfPosition()));
return;
}
#endif // JSGC_GENERATIONAL
@ -678,37 +677,34 @@ MacroAssembler::newGCThing(const Register &result, gc::AllocKind allocKind, Labe
// which the code below always re-reads.
loadPtr(AbsoluteAddress(zone->addressOfFreeListFirst(allocKind)), result);
branchPtr(Assembler::BelowOrEqual, AbsoluteAddress(zone->addressOfFreeListLast(allocKind)), result, fail);
addPtr(Imm32(thingSize), result);
storePtr(result, AbsoluteAddress(zone->addressOfFreeListFirst(allocKind)));
subPtr(Imm32(thingSize), result);
computeEffectiveAddress(Address(result, thingSize), temp);
storePtr(temp, AbsoluteAddress(zone->addressOfFreeListFirst(allocKind)));
}
void
MacroAssembler::newGCThing(const Register &result, JSObject *templateObject,
Label *fail, gc::InitialHeap initialHeap)
MacroAssembler::newGCThing(Register result, Register temp, JSObject *templateObject, Label *fail,
gc::InitialHeap initialHeap)
{
gc::AllocKind allocKind = templateObject->tenuredGetAllocKind();
JS_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST);
newGCThing(result, allocKind, fail, initialHeap);
newGCThing(result, temp, allocKind, fail, initialHeap);
}
void
MacroAssembler::newGCString(const Register &result, Label *fail)
MacroAssembler::newGCString(Register result, Register temp, Label *fail)
{
newGCThing(result, js::gc::FINALIZE_STRING, fail);
newGCThing(result, temp, js::gc::FINALIZE_STRING, fail);
}
void
MacroAssembler::newGCShortString(const Register &result, Label *fail)
MacroAssembler::newGCShortString(Register result, Register temp, Label *fail)
{
newGCThing(result, js::gc::FINALIZE_SHORT_STRING, fail);
newGCThing(result, temp, js::gc::FINALIZE_SHORT_STRING, fail);
}
void
MacroAssembler::newGCThingPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
MacroAssembler::newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
gc::AllocKind allocKind, Label *fail)
{
// Similar to ::newGCThing(), except that it allocates from a custom
@ -755,8 +751,7 @@ MacroAssembler::newGCThingPar(const Register &result, const Register &cx,
}
void
MacroAssembler::newGCThingPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
MacroAssembler::newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
JSObject *templateObject, Label *fail)
{
gc::AllocKind allocKind = templateObject->tenuredGetAllocKind();
@ -766,69 +761,127 @@ MacroAssembler::newGCThingPar(const Register &result, const Register &cx,
}
void
MacroAssembler::newGCStringPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
MacroAssembler::newGCStringPar(Register result, Register cx, Register tempReg1, Register tempReg2,
Label *fail)
{
newGCThingPar(result, cx, tempReg1, tempReg2, js::gc::FINALIZE_STRING, fail);
}
void
MacroAssembler::newGCShortStringPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
Label *fail)
MacroAssembler::newGCShortStringPar(Register result, Register cx, Register tempReg1,
Register tempReg2, Label *fail)
{
newGCThingPar(result, cx, tempReg1, tempReg2, js::gc::FINALIZE_SHORT_STRING, fail);
}
void
MacroAssembler::initGCThing(const Register &obj, JSObject *templateObject)
MacroAssembler::copySlotsFromTemplate(Register obj, Register temp, const JSObject *templateObj,
uint32_t start, uint32_t end)
{
uint32_t nfixed = Min(templateObj->numFixedSlots(), end);
for (unsigned i = start; i < nfixed; i++)
storeValue(templateObj->getFixedSlot(i), Address(obj, JSObject::getFixedSlotOffset(i)));
}
void
MacroAssembler::fillSlotsWithUndefined(Register obj, Register temp, const JSObject *templateObj,
uint32_t start, uint32_t end)
{
#ifdef JS_NUNBOX32
// We only have a single spare register, so do the initialization as two
// strided writes of the tag and body.
jsval_layout jv = JSVAL_TO_IMPL(UndefinedValue());
uint32_t nfixed = Min(templateObj->numFixedSlots(), end);
mov(ImmWord(jv.s.tag), temp);
for (unsigned i = start; i < nfixed; i++)
store32(temp, ToType(Address(obj, JSObject::getFixedSlotOffset(i))));
mov(ImmWord(jv.s.payload.i32), temp);
for (unsigned i = start; i < nfixed; i++)
store32(temp, ToPayload(Address(obj, JSObject::getFixedSlotOffset(i))));
#else
moveValue(UndefinedValue(), temp);
uint32_t nfixed = Min(templateObj->numFixedSlots(), end);
for (unsigned i = start; i < nfixed; i++)
storePtr(temp, Address(obj, JSObject::getFixedSlotOffset(i)));
#endif
}
static uint32_t
FindStartOfUndefinedSlots(JSObject *templateObj, uint32_t nslots)
{
JS_ASSERT(nslots == templateObj->lastProperty()->slotSpan(templateObj->getClass()));
JS_ASSERT(nslots > 0);
for (uint32_t first = nslots; first != 0; --first) {
if (templateObj->getSlot(first - 1) != UndefinedValue())
return first;
}
return 0;
}
void
MacroAssembler::initGCSlots(Register obj, Register temp, JSObject *templateObj)
{
// Slots of non-array objects are required to be initialized.
// Use the values currently in the template object.
uint32_t nslots = templateObj->lastProperty()->slotSpan(templateObj->getClass());
if (nslots == 0)
return;
// Attempt to group slot writes such that we minimize the amount of
// duplicated data we need to embed in code and load into registers. In
// general, most template object slots will be undefined except for any
// reserved slots. Since reserved slots come first, we split the object
// logically into independent non-UndefinedValue writes to the head and
// duplicated writes of UndefinedValue to the tail. For the majority of
// objects, the "tail" will be the entire slot range.
uint32_t startOfUndefined = FindStartOfUndefinedSlots(templateObj, nslots);
copySlotsFromTemplate(obj, temp, templateObj, 0, startOfUndefined);
fillSlotsWithUndefined(obj, temp, templateObj, startOfUndefined, nslots);
}
void
MacroAssembler::initGCThing(Register obj, Register temp, JSObject *templateObj)
{
// Fast initialization of an empty object returned by NewGCThing().
JS_ASSERT(!templateObject->hasDynamicElements());
JS_ASSERT(!templateObj->hasDynamicElements());
storePtr(ImmGCPtr(templateObject->lastProperty()), Address(obj, JSObject::offsetOfShape()));
storePtr(ImmGCPtr(templateObject->type()), Address(obj, JSObject::offsetOfType()));
storePtr(ImmGCPtr(templateObj->lastProperty()), Address(obj, JSObject::offsetOfShape()));
storePtr(ImmGCPtr(templateObj->type()), Address(obj, JSObject::offsetOfType()));
storePtr(ImmPtr(nullptr), Address(obj, JSObject::offsetOfSlots()));
if (templateObject->is<ArrayObject>()) {
JS_ASSERT(!templateObject->getDenseInitializedLength());
if (templateObj->is<ArrayObject>()) {
JS_ASSERT(!templateObj->getDenseInitializedLength());
int elementsOffset = JSObject::offsetOfFixedElements();
addPtr(Imm32(elementsOffset), obj);
storePtr(obj, Address(obj, -elementsOffset + JSObject::offsetOfElements()));
addPtr(Imm32(-elementsOffset), obj);
computeEffectiveAddress(Address(obj, elementsOffset), temp);
storePtr(temp, Address(obj, JSObject::offsetOfElements()));
// Fill in the elements header.
store32(Imm32(templateObject->getDenseCapacity()),
store32(Imm32(templateObj->getDenseCapacity()),
Address(obj, elementsOffset + ObjectElements::offsetOfCapacity()));
store32(Imm32(templateObject->getDenseInitializedLength()),
store32(Imm32(templateObj->getDenseInitializedLength()),
Address(obj, elementsOffset + ObjectElements::offsetOfInitializedLength()));
store32(Imm32(templateObject->as<ArrayObject>().length()),
store32(Imm32(templateObj->as<ArrayObject>().length()),
Address(obj, elementsOffset + ObjectElements::offsetOfLength()));
store32(Imm32(templateObject->shouldConvertDoubleElements()
store32(Imm32(templateObj->shouldConvertDoubleElements()
? ObjectElements::CONVERT_DOUBLE_ELEMENTS
: 0),
Address(obj, elementsOffset + ObjectElements::offsetOfFlags()));
JS_ASSERT(!templateObj->hasPrivate());
} else {
storePtr(ImmPtr(emptyObjectElements), Address(obj, JSObject::offsetOfElements()));
// Fixed slots of non-array objects are required to be initialized.
// Use the values currently in the template object.
size_t nslots = Min(templateObject->numFixedSlots(),
templateObject->lastProperty()->slotSpan(templateObject->getClass()));
for (unsigned i = 0; i < nslots; i++) {
storeValue(templateObject->getFixedSlot(i),
Address(obj, JSObject::getFixedSlotOffset(i)));
}
}
initGCSlots(obj, temp, templateObj);
if (templateObject->hasPrivate()) {
uint32_t nfixed = templateObject->numFixedSlots();
storePtr(ImmPtr(templateObject->getPrivate()),
Address(obj, JSObject::getPrivateDataOffset(nfixed)));
if (templateObj->hasPrivate()) {
uint32_t nfixed = templateObj->numFixedSlots();
storePtr(ImmPtr(templateObj->getPrivate()),
Address(obj, JSObject::getPrivateDataOffset(nfixed)));
}
}
}
@ -870,7 +923,7 @@ MacroAssembler::compareStrings(JSOp op, Register left, Register right, Register
}
void
MacroAssembler::checkInterruptFlagPar(const Register &tempReg, Label *fail)
MacroAssembler::checkInterruptFlagPar(Register tempReg, Label *fail)
{
#ifdef JS_THREADSAFE
movePtr(ImmPtr(GetIonContext()->runtime->addressOfInterruptPar()), tempReg);
@ -1819,7 +1872,7 @@ MacroAssembler::branchIfNotInterpretedConstructor(Register fun, Register scratch
}
void
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, const Register &tag,
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, Register tag,
Label *label)
{
if (!maybeDef || maybeDef->mightBeType(type)) {

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

@ -352,13 +352,13 @@ class MacroAssembler : public MacroAssemblerSpecific
}
// Branches to |label| if |reg| is false. |reg| should be a C++ bool.
void branchIfFalseBool(const Register &reg, Label *label) {
void branchIfFalseBool(Register reg, Label *label) {
// Note that C++ bool is only 1 byte, so ignore the higher-order bits.
branchTest32(Assembler::Zero, reg, Imm32(0xFF), label);
}
// Branches to |label| if |reg| is true. |reg| should be a C++ bool.
void branchIfTrueBool(const Register &reg, Label *label) {
void branchIfTrueBool(Register reg, Label *label) {
// Note that C++ bool is only 1 byte, so ignore the higher-order bits.
branchTest32(Assembler::NonZero, reg, Imm32(0xFF), label);
}
@ -381,10 +381,10 @@ class MacroAssembler : public MacroAssemblerSpecific
loadPtr(Address(worker, ThreadPoolWorker::offsetOfSliceBounds()), dest);
}
void loadJSContext(const Register &dest) {
void loadJSContext(Register dest) {
loadPtr(AbsoluteAddress(GetIonContext()->runtime->addressOfJSContext()), dest);
}
void loadJitActivation(const Register &dest) {
void loadJitActivation(Register dest) {
loadPtr(AbsoluteAddress(GetIonContext()->runtime->addressOfActivation()), dest);
}
@ -634,7 +634,7 @@ class MacroAssembler : public MacroAssemblerSpecific
branch32(cond, length, Imm32(key.constant()), label);
}
void branchTestNeedsBarrier(Condition cond, const Register &scratch, Label *label) {
void branchTestNeedsBarrier(Condition cond, Register scratch, Label *label) {
JS_ASSERT(cond == Zero || cond == NonZero);
CompileZone *zone = GetIonContext()->compartment->zone();
movePtr(ImmPtr(zone->addressOfNeedsBarrier()), scratch);
@ -690,7 +690,7 @@ class MacroAssembler : public MacroAssemblerSpecific
void branchNurseryPtr(Condition cond, const Address &ptr1, const ImmMaybeNurseryPtr &ptr2,
Label *label);
void moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, const Register &reg);
void moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, Register reg);
void canonicalizeDouble(FloatRegister reg) {
Label notNaN;
@ -783,30 +783,31 @@ class MacroAssembler : public MacroAssemblerSpecific
// Emit type case branch on tag matching if the type tag in the definition
// might actually be that type.
void branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, const Register &tag,
Label *label);
void branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, Register tag, Label *label);
// Inline allocation.
void newGCThing(const Register &result, gc::AllocKind allocKind, Label *fail,
void newGCThing(Register result, Register temp, gc::AllocKind allocKind, Label *fail,
gc::InitialHeap initialHeap = gc::DefaultHeap);
void newGCThing(const Register &result, JSObject *templateObject, Label *fail,
void newGCThing(Register result, Register temp, JSObject *templateObject, Label *fail,
gc::InitialHeap initialHeap);
void newGCString(const Register &result, Label *fail);
void newGCShortString(const Register &result, Label *fail);
void newGCString(Register result, Register temp, Label *fail);
void newGCShortString(Register result, Register temp, Label *fail);
void newGCThingPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
void newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
gc::AllocKind allocKind, Label *fail);
void newGCThingPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
void newGCThingPar(Register result, Register cx, Register tempReg1, Register tempReg2,
JSObject *templateObject, Label *fail);
void newGCStringPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
void newGCStringPar(Register result, Register cx, Register tempReg1, Register tempReg2,
Label *fail);
void newGCShortStringPar(const Register &result, const Register &cx,
const Register &tempReg1, const Register &tempReg2,
void newGCShortStringPar(Register result, Register cx, Register tempReg1, Register tempReg2,
Label *fail);
void initGCThing(const Register &obj, JSObject *templateObject);
void copySlotsFromTemplate(Register obj, Register temp, const JSObject *templateObj,
uint32_t start, uint32_t end);
void fillSlotsWithUndefined(Register obj, Register temp, const JSObject *templateObj,
uint32_t start, uint32_t end);
void initGCSlots(Register obj, Register temp, JSObject *templateObj);
void initGCThing(Register obj, Register temp, JSObject *templateObj);
// Compares two strings for equality based on the JSOP.
// This checks for identical pointers, atoms and length and fails for everything else.
@ -815,7 +816,7 @@ class MacroAssembler : public MacroAssemblerSpecific
// Checks the flags that signal that parallel code may need to interrupt or
// abort. Branches to fail in that case.
void checkInterruptFlagPar(const Register &tempReg, Label *fail);
void checkInterruptFlagPar(Register tempReg, Label *fail);
// If the JitCode that created this assembler needs to transition into the VM,
// we want to store the JitCode on the stack in order to mark it during a GC.
@ -903,7 +904,7 @@ class MacroAssembler : public MacroAssemblerSpecific
}
// see above comment for what is returned
uint32_t callIon(const Register &callee) {
uint32_t callIon(Register callee) {
leaveSPSFrame();
MacroAssemblerSpecific::callIon(callee);
uint32_t ret = currentOffset();

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

@ -328,29 +328,45 @@ class LNewSlots : public LCallInstructionHelper<1, 0, 3>
}
};
class LNewArray : public LInstructionHelper<1, 0, 0>
class LNewArray : public LInstructionHelper<1, 0, 1>
{
public:
LIR_HEADER(NewArray)
LNewArray(const LDefinition &temp) {
setTemp(0, temp);
}
const char *extraName() const {
return mir()->shouldUseVM() ? "VMCall" : nullptr;
}
const LDefinition *temp() {
return getTemp(0);
}
MNewArray *mir() const {
return mir_->toNewArray();
}
};
class LNewObject : public LInstructionHelper<1, 0, 0>
class LNewObject : public LInstructionHelper<1, 0, 1>
{
public:
LIR_HEADER(NewObject)
LNewObject(const LDefinition &temp) {
setTemp(0, temp);
}
const char *extraName() const {
return mir()->shouldUseVM() ? "VMCall" : nullptr;
}
const LDefinition *temp() {
return getTemp(0);
}
MNewObject *mir() const {
return mir_->toNewObject();
}
@ -430,11 +446,19 @@ class LNewDenseArrayPar : public LCallInstructionHelper<1, 2, 3>
// (1) An inline allocation of the call object is attempted.
// (2) Otherwise, a callVM create a new object.
//
class LNewDeclEnvObject : public LInstructionHelper<1, 0, 0>
class LNewDeclEnvObject : public LInstructionHelper<1, 0, 1>
{
public:
LIR_HEADER(NewDeclEnvObject);
LNewDeclEnvObject(const LDefinition &temp) {
setTemp(0, temp);
}
const LDefinition *temp() {
return getTemp(0);
}
MNewDeclEnvObject *mir() const {
return mir_->toNewDeclEnvObject();
}
@ -449,13 +473,18 @@ class LNewDeclEnvObject : public LInstructionHelper<1, 0, 0>
// call object.
// (2) Otherwise, an inline allocation of the call object is attempted.
//
class LNewCallObject : public LInstructionHelper<1, 1, 0>
class LNewCallObject : public LInstructionHelper<1, 1, 1>
{
public:
LIR_HEADER(NewCallObject)
LNewCallObject(const LAllocation &slots) {
LNewCallObject(const LAllocation &slots, const LDefinition &temp) {
setOperand(0, slots);
setTemp(0, temp);
}
const LDefinition *temp() {
return getTemp(0);
}
const LAllocation *slots() {
@ -883,17 +912,22 @@ class LCreateThisWithProto : public LCallInstructionHelper<1, 2, 0>
// Allocate an object for |new| on the caller-side.
// Always performs object initialization with a fast path.
class LCreateThisWithTemplate : public LInstructionHelper<1, 0, 0>
class LCreateThisWithTemplate : public LInstructionHelper<1, 0, 1>
{
public:
LIR_HEADER(CreateThisWithTemplate)
LCreateThisWithTemplate()
{ }
LCreateThisWithTemplate(const LDefinition &temp) {
setTemp(0, temp);
}
MCreateThisWithTemplate *mir() const {
return mir_->toCreateThisWithTemplate();
}
const LDefinition *temp() {
return getTemp(0);
}
};
// Allocate a new arguments object for the frame.
@ -3396,17 +3430,21 @@ class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
}
};
class LLambda : public LInstructionHelper<1, 1, 0>
class LLambda : public LInstructionHelper<1, 1, 1>
{
public:
LIR_HEADER(Lambda)
LLambda(const LAllocation &scopeChain) {
LLambda(const LAllocation &scopeChain, const LDefinition &temp) {
setOperand(0, scopeChain);
setTemp(0, temp);
}
const LAllocation *scopeChain() {
return getOperand(0);
}
const LDefinition *temp() {
return getTemp(0);
}
const MLambda *mir() const {
return mir_->toLambda();
}

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

@ -174,21 +174,21 @@ LIRGenerator::visitNewSlots(MNewSlots *ins)
bool
LIRGenerator::visitNewArray(MNewArray *ins)
{
LNewArray *lir = new(alloc()) LNewArray();
LNewArray *lir = new(alloc()) LNewArray(temp());
return define(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitNewObject(MNewObject *ins)
{
LNewObject *lir = new(alloc()) LNewObject();
LNewObject *lir = new(alloc()) LNewObject(temp());
return define(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitNewDeclEnvObject(MNewDeclEnvObject *ins)
{
LNewDeclEnvObject *lir = new(alloc()) LNewDeclEnvObject();
LNewDeclEnvObject *lir = new(alloc()) LNewDeclEnvObject(temp());
return define(lir, ins) && assignSafepoint(lir, ins);
}
@ -201,7 +201,7 @@ LIRGenerator::visitNewCallObject(MNewCallObject *ins)
else
slots = LConstantIndex::Bogus();
LNewCallObject *lir = new(alloc()) LNewCallObject(slots);
LNewCallObject *lir = new(alloc()) LNewCallObject(slots, temp());
if (!define(lir, ins))
return false;
@ -311,7 +311,7 @@ LIRGenerator::visitInitPropGetterSetter(MInitPropGetterSetter *ins)
bool
LIRGenerator::visitCreateThisWithTemplate(MCreateThisWithTemplate *ins)
{
LCreateThisWithTemplate *lir = new(alloc()) LCreateThisWithTemplate();
LCreateThisWithTemplate *lir = new(alloc()) LCreateThisWithTemplate(temp());
return define(lir, ins) && assignSafepoint(lir, ins);
}
@ -2026,7 +2026,7 @@ LIRGenerator::visitLambda(MLambda *ins)
return defineReturn(lir, ins) && assignSafepoint(lir, ins);
}
LLambda *lir = new(alloc()) LLambda(useRegister(ins->scopeChain()));
LLambda *lir = new(alloc()) LLambda(useRegister(ins->scopeChain()), temp());
return define(lir, ins) && assignSafepoint(lir, ins);
}

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

@ -2531,14 +2531,6 @@ MacroAssemblerARMCompat::branchFloat(DoubleCondition cond, const FloatRegister &
ma_b(label, ConditionFromDoubleCondition(cond));
}
// higher level tag testing code
Operand ToPayload(Operand base) {
return Operand(Register::FromCode(base.base()), base.disp());
}
Operand ToType(Operand base) {
return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void *));
}
Assembler::Condition
MacroAssemblerARMCompat::testInt32(Assembler::Condition cond, const ValueOperand &value)
{

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

@ -35,6 +35,20 @@ class MacroAssemblerARM : public Assembler
// baseline IC stubs rely on lr holding the return address.
Register secondScratchReg_;
// higher level tag testing code
Operand ToPayload(Operand base) {
return Operand(Register::FromCode(base.base()), base.disp());
}
Address ToPayload(Address base) {
return ToPayload(Operand(base)).toAddress();
}
Operand ToType(Operand base) {
return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void *));
}
Address ToType(Address base) {
return ToType(Operand(base)).toAddress();
}
public:
MacroAssemblerARM()
: secondScratchReg_(lr)

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

@ -91,6 +91,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
Operand ToPayload(Operand base) {
return base;
}
Address ToPayload(Address base) {
return base;
}
Operand ToType(Operand base) {
switch (base.kind()) {
case Operand::MEM_REG_DISP:
@ -104,6 +107,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
MOZ_ASSUME_UNREACHABLE("unexpected operand kind");
}
}
Address ToType(Address base) {
return ToType(Operand(base)).toAddress();
}
void moveValue(const Value &val, Register type, Register data) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movl(Imm32(jv.s.tag), type);