[x86] Support immediate indices for StoreWriteBarrier.
authorbmeurer <bmeurer@chromium.org>
Fri, 10 Apr 2015 06:16:23 +0000 (23:16 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 10 Apr 2015 06:16:28 +0000 (06:16 +0000)
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}

src/compiler/ia32/code-generator-ia32.cc
src/compiler/ia32/instruction-selector-ia32.cc
src/compiler/x64/code-generator-x64.cc
src/compiler/x64/instruction-selector-x64.cc

index 7ec7eba8111f51012561545c8547822258134412..586d5488e906c6c3777b8b2704b974671c32c205 100644 (file)
@@ -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:
index bf9316039447a2447312a99223c7ee87cdb0473d..93644a90be0b2f959bb39716ea92bb5c22430b1b 100644 (file)
@@ -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());
index 6377f5cae5a0e040a45d8654bfe25527e7022b22..c13e1697c442fc34b031b9f12a19e9f4b67e9cc2 100644 (file)
@@ -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:
index fea4e3f6235a8c7e88a62c9ae688669300cfae91..68bc0352270b283fef2a1a2dd7f691fa0064842c 100644 (file)
@@ -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: