OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 160 |
161 | 161 |
162 class OutOfLineRecordWrite final : public OutOfLineCode { | 162 class OutOfLineRecordWrite final : public OutOfLineCode { |
163 public: | 163 public: |
164 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset, | 164 OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset, |
165 Register value, Register scratch0, Register scratch1, | 165 Register value, Register scratch0, Register scratch1, |
166 RecordWriteMode mode) | 166 RecordWriteMode mode) |
167 : OutOfLineCode(gen), | 167 : OutOfLineCode(gen), |
168 object_(object), | 168 object_(object), |
169 offset_(offset), | 169 offset_(offset), |
| 170 offset_immediate_(0), |
170 value_(value), | 171 value_(value), |
171 scratch0_(scratch0), | 172 scratch0_(scratch0), |
172 scratch1_(scratch1), | 173 scratch1_(scratch1), |
| 174 mode_(mode) {} |
| 175 |
| 176 OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset, |
| 177 Register value, Register scratch0, Register scratch1, |
| 178 RecordWriteMode mode) |
| 179 : OutOfLineCode(gen), |
| 180 object_(object), |
| 181 offset_(no_reg), |
| 182 offset_immediate_(offset), |
| 183 value_(value), |
| 184 scratch0_(scratch0), |
| 185 scratch1_(scratch1), |
173 mode_(mode) {} | 186 mode_(mode) {} |
174 | 187 |
175 void Generate() final { | 188 void Generate() final { |
176 if (mode_ > RecordWriteMode::kValueIsPointer) { | 189 if (mode_ > RecordWriteMode::kValueIsPointer) { |
177 __ JumpIfSmi(value_, exit()); | 190 __ JumpIfSmi(value_, exit()); |
178 } | 191 } |
179 if (mode_ > RecordWriteMode::kValueIsMap) { | 192 if (mode_ > RecordWriteMode::kValueIsMap) { |
180 __ CheckPageFlag(value_, scratch0_, | 193 __ CheckPageFlag(value_, scratch0_, |
181 MemoryChunk::kPointersToHereAreInterestingMask, eq, | 194 MemoryChunk::kPointersToHereAreInterestingMask, eq, |
182 exit()); | 195 exit()); |
183 } | 196 } |
184 SaveFPRegsMode const save_fp_mode = | 197 SaveFPRegsMode const save_fp_mode = |
185 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; | 198 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
186 // TODO(turbofan): Once we get frame elision working, we need to save | 199 // TODO(turbofan): Once we get frame elision working, we need to save |
187 // and restore lr properly here if the frame was elided. | 200 // and restore lr properly here if the frame was elided. |
188 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, | 201 RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, |
189 EMIT_REMEMBERED_SET, save_fp_mode); | 202 EMIT_REMEMBERED_SET, save_fp_mode); |
190 __ add(scratch1_, object_, offset_); | 203 if (offset_.is(no_reg)) { |
| 204 __ addi(scratch1_, object_, Operand(offset_immediate_)); |
| 205 } else { |
| 206 DCHECK_EQ(0, offset_immediate_); |
| 207 __ add(scratch1_, object_, offset_); |
| 208 } |
191 __ CallStub(&stub); | 209 __ CallStub(&stub); |
192 } | 210 } |
193 | 211 |
194 private: | 212 private: |
195 Register const object_; | 213 Register const object_; |
196 Register const offset_; | 214 Register const offset_; |
| 215 int32_t const offset_immediate_; // Valid if offset_.is(no_reg). |
197 Register const value_; | 216 Register const value_; |
198 Register const scratch0_; | 217 Register const scratch0_; |
199 Register const scratch1_; | 218 Register const scratch1_; |
200 RecordWriteMode const mode_; | 219 RecordWriteMode const mode_; |
201 }; | 220 }; |
202 | 221 |
203 | 222 |
204 Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { | 223 Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { |
205 switch (condition) { | 224 switch (condition) { |
206 case kEqual: | 225 case kEqual: |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 break; | 822 break; |
804 case kArchTruncateDoubleToI: | 823 case kArchTruncateDoubleToI: |
805 // TODO(mbrandy): move slow call to stub out of line. | 824 // TODO(mbrandy): move slow call to stub out of line. |
806 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); | 825 __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |
807 DCHECK_EQ(LeaveRC, i.OutputRCBit()); | 826 DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
808 break; | 827 break; |
809 case kArchStoreWithWriteBarrier: { | 828 case kArchStoreWithWriteBarrier: { |
810 RecordWriteMode mode = | 829 RecordWriteMode mode = |
811 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); | 830 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
812 Register object = i.InputRegister(0); | 831 Register object = i.InputRegister(0); |
813 Register offset = i.InputRegister(1); | |
814 Register value = i.InputRegister(2); | 832 Register value = i.InputRegister(2); |
815 Register scratch0 = i.TempRegister(0); | 833 Register scratch0 = i.TempRegister(0); |
816 Register scratch1 = i.TempRegister(1); | 834 Register scratch1 = i.TempRegister(1); |
817 auto ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, | 835 OutOfLineRecordWrite* ool; |
818 scratch0, scratch1, mode); | 836 |
819 __ StorePX(value, MemOperand(object, offset)); | 837 AddressingMode addressing_mode = |
| 838 AddressingModeField::decode(instr->opcode()); |
| 839 if (addressing_mode == kMode_MRI) { |
| 840 int32_t offset = i.InputInt32(1); |
| 841 ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, |
| 842 scratch0, scratch1, mode); |
| 843 __ StoreP(value, MemOperand(object, offset)); |
| 844 } else { |
| 845 DCHECK_EQ(kMode_MRR, addressing_mode); |
| 846 Register offset(i.InputRegister(1)); |
| 847 ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, |
| 848 scratch0, scratch1, mode); |
| 849 __ StorePX(value, MemOperand(object, offset)); |
| 850 } |
820 __ CheckPageFlag(object, scratch0, | 851 __ CheckPageFlag(object, scratch0, |
821 MemoryChunk::kPointersFromHereAreInterestingMask, ne, | 852 MemoryChunk::kPointersFromHereAreInterestingMask, ne, |
822 ool->entry()); | 853 ool->entry()); |
823 __ bind(ool->exit()); | 854 __ bind(ool->exit()); |
824 break; | 855 break; |
825 } | 856 } |
826 case kArchStackSlot: { | 857 case kArchStackSlot: { |
827 FrameOffset offset = | 858 FrameOffset offset = |
828 frame_access_state()->GetFrameOffset(i.InputInt32(0)); | 859 frame_access_state()->GetFrameOffset(i.InputInt32(0)); |
829 __ addi(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp, | 860 __ addi(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp, |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 padding_size -= v8::internal::Assembler::kInstrSize; | 1884 padding_size -= v8::internal::Assembler::kInstrSize; |
1854 } | 1885 } |
1855 } | 1886 } |
1856 } | 1887 } |
1857 | 1888 |
1858 #undef __ | 1889 #undef __ |
1859 | 1890 |
1860 } // namespace compiler | 1891 } // namespace compiler |
1861 } // namespace internal | 1892 } // namespace internal |
1862 } // namespace v8 | 1893 } // namespace v8 |
OLD | NEW |