Commit 4eff883b authored by bmeurer's avatar bmeurer Committed by Commit bot

[x86] Support immediate indices for StoreWriteBarrier.

Ideally we would not need the StoreWriteBarrier instructions at all,
but represent the RecordWrite functionality as machine subgraph, but
that'll take some time to get there. In the mean time we can have a
shorter instruction sequence on Intel platforms by recognizing immediate
indices here.

R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/1075103002

Cr-Commit-Position: refs/heads/master@{#27731}
parent 4baa0aaf
......@@ -790,13 +790,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
case kIA32StoreWriteBarrier: {
Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2);
__ mov(Operand(object, index, times_1, 0), value);
__ lea(index, Operand(object, index, times_1, 0));
SaveFPRegsMode mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
__ RecordWrite(object, index, value, mode);
if (HasImmediateInput(instr, 1)) {
int index = i.InputInt32(1);
Register scratch = i.TempRegister(1);
__ mov(Operand(object, index), value);
__ RecordWriteContextSlot(object, index, value, scratch, mode);
} else {
Register index = i.InputRegister(1);
__ mov(Operand(object, index, times_1, 0), value);
__ lea(index, Operand(object, index, times_1, 0));
__ RecordWrite(object, index, value, mode);
}
break;
}
case kCheckedLoadInt8:
......
......@@ -208,11 +208,17 @@ void InstructionSelector::VisitStore(Node* node) {
DCHECK_EQ(kRepTagged, rep);
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
temps);
if (g.CanBeImmediate(index)) {
InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister()};
Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseImmediate(index), g.UseFixed(value, ecx), arraysize(temps),
temps);
} else {
InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
temps);
}
return;
}
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
......
......@@ -1105,13 +1105,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
case kX64StoreWriteBarrier: {
Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2);
__ movq(Operand(object, index, times_1, 0), value);
__ leaq(index, Operand(object, index, times_1, 0));
SaveFPRegsMode mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
__ RecordWrite(object, index, value, mode);
if (HasImmediateInput(instr, 1)) {
int index = i.InputInt32(1);
Register scratch = i.TempRegister(1);
__ movq(Operand(object, index), value);
__ RecordWriteContextSlot(object, index, value, scratch, mode);
} else {
Register index = i.InputRegister(1);
__ movq(Operand(object, index, times_1, 0), value);
__ leaq(index, Operand(object, index, times_1, 0));
__ RecordWrite(object, index, value, mode);
}
break;
}
case kCheckedLoadInt8:
......
......@@ -154,17 +154,24 @@ void InstructionSelector::VisitStore(Node* node) {
StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
MachineType rep = RepresentationOf(store_rep.machine_type());
if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
DCHECK(rep == kRepTagged);
DCHECK_EQ(kRepTagged, rep);
// TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices.
InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
temps);
if (g.CanBeImmediate(index)) {
InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister()};
Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseImmediate(index), g.UseFixed(value, rcx), arraysize(temps),
temps);
} else {
InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
temps);
}
return;
}
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
ArchOpcode opcode;
switch (rep) {
case kRepFloat32:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment