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) { ...@@ -790,13 +790,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break; break;
case kIA32StoreWriteBarrier: { case kIA32StoreWriteBarrier: {
Register object = i.InputRegister(0); Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2); Register value = i.InputRegister(2);
__ mov(Operand(object, index, times_1, 0), value);
__ lea(index, Operand(object, index, times_1, 0));
SaveFPRegsMode mode = SaveFPRegsMode mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 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; break;
} }
case kCheckedLoadInt8: case kCheckedLoadInt8:
......
...@@ -208,11 +208,17 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -208,11 +208,17 @@ void InstructionSelector::VisitStore(Node* node) {
DCHECK_EQ(kRepTagged, rep); DCHECK_EQ(kRepTagged, rep);
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. if (g.CanBeImmediate(index)) {
InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister()};
Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), g.UseImmediate(index), g.UseFixed(value, ecx), arraysize(temps),
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; return;
} }
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
......
...@@ -1105,13 +1105,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1105,13 +1105,20 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break; break;
case kX64StoreWriteBarrier: { case kX64StoreWriteBarrier: {
Register object = i.InputRegister(0); Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2); Register value = i.InputRegister(2);
__ movq(Operand(object, index, times_1, 0), value);
__ leaq(index, Operand(object, index, times_1, 0));
SaveFPRegsMode mode = SaveFPRegsMode mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 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; break;
} }
case kCheckedLoadInt8: case kCheckedLoadInt8:
......
...@@ -154,17 +154,24 @@ void InstructionSelector::VisitStore(Node* node) { ...@@ -154,17 +154,24 @@ void InstructionSelector::VisitStore(Node* node) {
StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
MachineType rep = RepresentationOf(store_rep.machine_type()); MachineType rep = RepresentationOf(store_rep.machine_type());
if (store_rep.write_barrier_kind() == kFullWriteBarrier) { if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
DCHECK(rep == kRepTagged); DCHECK_EQ(kRepTagged, rep);
// TODO(dcarney): refactor RecordWrite function to take temp registers // TODO(dcarney): refactor RecordWrite function to take temp registers
// and pass them here instead of using fixed regs // and pass them here instead of using fixed regs
// TODO(dcarney): handle immediate indices. if (g.CanBeImmediate(index)) {
InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister()};
Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx), Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps), g.UseImmediate(index), g.UseFixed(value, rcx), arraysize(temps),
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; return;
} }
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
ArchOpcode opcode; ArchOpcode opcode;
switch (rep) { switch (rep) {
case kRepFloat32: 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