Index: src/compiler/arm64/code-generator-arm64.cc |
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc |
index c240156f00386237ab99cd63fbc80772e9dd5e8a..448c7e608a7b98e9049dab37d46db6ff2ca8264f 100644 |
--- a/src/compiler/arm64/code-generator-arm64.cc |
+++ b/src/compiler/arm64/code-generator-arm64.cc |
@@ -255,6 +255,48 @@ class OutOfLineLoadZero final : public OutOfLineCode { |
}; |
+class OutOfLineRecordWrite final : public OutOfLineCode { |
+ public: |
+ OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, |
+ Register value, Register scratch0, Register scratch1, |
+ RecordWriteMode mode) |
+ : OutOfLineCode(gen), |
+ object_(object), |
+ index_(index), |
+ value_(value), |
+ scratch0_(scratch0), |
+ scratch1_(scratch1), |
+ mode_(mode) {} |
+ |
+ void Generate() final { |
+ if (mode_ > RecordWriteMode::kValueIsPointer) { |
+ __ JumpIfSmi(value_, exit()); |
+ } |
+ if (mode_ > RecordWriteMode::kValueIsMap) { |
+ __ CheckPageFlagClear(value_, scratch0_, |
+ MemoryChunk::kPointersToHereAreInterestingMask, |
+ 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_, index_); |
+ __ CallStub(&stub); |
+ } |
+ |
+ private: |
+ Register const object_; |
+ Register const index_; |
+ Register const value_; |
+ Register const scratch0_; |
+ Register const scratch1_; |
+ RecordWriteMode const mode_; |
+}; |
+ |
+ |
Condition FlagsConditionToCondition(FlagsCondition condition) { |
switch (condition) { |
case kEqual: |
@@ -529,6 +571,23 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kArchTruncateDoubleToI: |
__ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
break; |
+ case kArchStoreWithWriteBarrier: { |
+ RecordWriteMode mode = |
+ static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
+ Register object = i.InputRegister(0); |
+ Register index = 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, index, value, |
+ scratch0, scratch1, mode); |
+ __ Str(value, MemOperand(object, index)); |
+ __ CheckPageFlagSet(object, scratch0, |
+ MemoryChunk::kPointersFromHereAreInterestingMask, |
+ ool->entry()); |
+ __ Bind(ool->exit()); |
+ break; |
+ } |
case kArm64Float64RoundDown: |
__ Frintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
break; |
@@ -995,29 +1054,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kArm64StrD: |
__ Str(i.InputDoubleRegister(2), i.MemoryOperand()); |
break; |
- case kArm64StoreWriteBarrier: { |
- Register object = i.InputRegister(0); |
- Register index = i.InputRegister(1); |
- Register value = i.InputRegister(2); |
- __ Add(index, object, index); |
- __ Str(value, MemOperand(index)); |
- SaveFPRegsMode mode = |
- frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
- // TODO(dcarney): we shouldn't test write barriers from c calls. |
- LinkRegisterStatus lr_status = kLRHasNotBeenSaved; |
- UseScratchRegisterScope scope(masm()); |
- Register temp = no_reg; |
- if (csp.is(masm()->StackPointer())) { |
- temp = scope.AcquireX(); |
- lr_status = kLRHasBeenSaved; |
- __ Push(lr, temp); // Need to push a pair |
- } |
- __ RecordWrite(object, index, value, lr_status, mode); |
- if (csp.is(masm()->StackPointer())) { |
- __ Pop(temp, lr); |
- } |
- break; |
- } |
case kCheckedLoadInt8: |
ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb); |
break; |