Index: src/compiler/ppc/code-generator-ppc.cc |
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc |
index dbc776ef9efbd3ee83060658eddd35211e328f90..fa973544be01613e00c54c393199cb2cc7c48a4c 100644 |
--- a/src/compiler/ppc/code-generator-ppc.cc |
+++ b/src/compiler/ppc/code-generator-ppc.cc |
@@ -157,6 +157,48 @@ class OutOfLineLoadZero final : public OutOfLineCode { |
}; |
+class OutOfLineRecordWrite final : public OutOfLineCode { |
+ public: |
+ OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset, |
+ Register value, Register scratch0, Register scratch1, |
+ RecordWriteMode mode) |
+ : OutOfLineCode(gen), |
+ object_(object), |
+ offset_(offset), |
+ value_(value), |
+ scratch0_(scratch0), |
+ scratch1_(scratch1), |
+ mode_(mode) {} |
+ |
+ void Generate() final { |
+ if (mode_ > RecordWriteMode::kValueIsPointer) { |
+ __ JumpIfSmi(value_, exit()); |
+ } |
+ if (mode_ > RecordWriteMode::kValueIsMap) { |
+ __ CheckPageFlag(value_, scratch0_, |
+ MemoryChunk::kPointersToHereAreInterestingMask, eq, |
+ exit()); |
+ } |
+ SaveFPRegsMode const save_fp_mode = |
+ frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
+ // TODO(turbofan): Once we get frame elision working, we need to save |
+ // and restore lr properly here if the frame was elided. |
+ RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
+ EMIT_REMEMBERED_SET, save_fp_mode); |
+ __ add(scratch1_, object_, offset_); |
+ __ CallStub(&stub); |
+ } |
+ |
+ private: |
+ Register const object_; |
+ Register const offset_; |
+ Register const value_; |
+ Register const scratch0_; |
+ Register const scratch1_; |
+ RecordWriteMode const mode_; |
+}; |
+ |
+ |
Condition FlagsConditionToCondition(FlagsCondition condition) { |
switch (condition) { |
case kEqual: |
@@ -563,21 +605,6 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { |
} while (0) |
-#define ASSEMBLE_STORE_WRITE_BARRIER() \ |
- do { \ |
- Register object = i.InputRegister(0); \ |
- Register index = i.InputRegister(1); \ |
- Register value = i.InputRegister(2); \ |
- __ add(index, object, index); \ |
- __ StoreP(value, MemOperand(index)); \ |
- SaveFPRegsMode mode = \ |
- frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; \ |
- LinkRegisterStatus lr_status = kLRHasNotBeenSaved; \ |
- __ RecordWrite(object, index, value, lr_status, mode); \ |
- DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ |
- } while (0) |
- |
- |
void CodeGenerator::AssembleDeconstructActivationRecord() { |
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
int stack_slots = frame()->GetSpillSlotCount(); |
@@ -714,6 +741,23 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
break; |
+ case kArchStoreWithWriteBarrier: { |
+ RecordWriteMode mode = |
+ static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
+ Register object = i.InputRegister(0); |
+ Register offset = i.InputRegister(1); |
+ Register value = i.InputRegister(2); |
+ Register scratch0 = i.TempRegister(0); |
+ Register scratch1 = i.TempRegister(1); |
+ auto ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, |
+ scratch0, scratch1, mode); |
+ __ StorePX(value, MemOperand(object, offset)); |
+ __ CheckPageFlag(object, scratch0, |
+ MemoryChunk::kPointersFromHereAreInterestingMask, ne, |
+ ool->entry()); |
+ __ bind(ool->exit()); |
+ break; |
+ } |
case kPPC_And: |
if (HasRegisterInput(instr, 1)) { |
__ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), |
@@ -1155,9 +1199,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kPPC_StoreDouble: |
ASSEMBLE_STORE_DOUBLE(); |
break; |
- case kPPC_StoreWriteBarrier: |
- ASSEMBLE_STORE_WRITE_BARRIER(); |
- break; |
case kCheckedLoadInt8: |
ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); |
__ extsb(i.OutputRegister(), i.OutputRegister()); |