Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 1414183006: [turbofan] Avoid unnecessary write barriers and improve code generation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 5 #include <algorithm>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/compiler/instruction-selector-impl.h" 8 #include "src/compiler/instruction-selector-impl.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 151
152 152
153 void InstructionSelector::VisitStore(Node* node) { 153 void InstructionSelector::VisitStore(Node* node) {
154 X64OperandGenerator g(this); 154 X64OperandGenerator g(this);
155 Node* base = node->InputAt(0); 155 Node* base = node->InputAt(0);
156 Node* index = node->InputAt(1); 156 Node* index = node->InputAt(1);
157 Node* value = node->InputAt(2); 157 Node* value = node->InputAt(2);
158 158
159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
160 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
160 MachineType rep = RepresentationOf(store_rep.machine_type()); 161 MachineType rep = RepresentationOf(store_rep.machine_type());
161 if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
162 DCHECK_EQ(kRepTagged, rep);
163 // TODO(dcarney): refactor RecordWrite function to take temp registers
164 // and pass them here instead of using fixed regs
165 if (g.CanBeImmediate(index)) {
166 InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister()};
167 Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
168 g.UseImmediate(index), g.UseFixed(value, rcx), arraysize(temps),
169 temps);
170 } else {
171 InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
172 Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx),
173 g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
174 temps);
175 }
176 return;
177 }
178 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
179 162
180 ArchOpcode opcode; 163 ArchOpcode opcode;
181 switch (rep) { 164 switch (rep) {
182 case kRepFloat32: 165 case kRepFloat32:
183 opcode = kX64Movss; 166 opcode = kX64Movss;
184 break; 167 break;
185 case kRepFloat64: 168 case kRepFloat64:
186 opcode = kX64Movsd; 169 opcode = kX64Movsd;
187 break; 170 break;
188 case kRepBit: // Fall through. 171 case kRepBit: // Fall through.
189 case kRepWord8: 172 case kRepWord8:
190 opcode = kX64Movb; 173 opcode = kX64Movb;
191 break; 174 break;
192 case kRepWord16: 175 case kRepWord16:
193 opcode = kX64Movw; 176 opcode = kX64Movw;
194 break; 177 break;
195 case kRepWord32: 178 case kRepWord32:
196 opcode = kX64Movl; 179 opcode = kX64Movl;
197 break; 180 break;
198 case kRepTagged: // Fall through. 181 case kRepTagged: // Fall through.
199 case kRepWord64: 182 case kRepWord64:
200 opcode = kX64Movq; 183 opcode = kX64Movq;
201 break; 184 break;
202 default: 185 default:
203 UNREACHABLE(); 186 UNREACHABLE();
204 return; 187 return;
205 } 188 }
206 InstructionOperand inputs[4]; 189 InstructionOperand inputs[4];
207 size_t input_count = 0; 190 size_t input_count = 0;
208 AddressingMode mode = 191 AddressingMode addressing_mode =
209 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 192 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
210 InstructionCode code = opcode | AddressingModeField::encode(mode); 193 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode);
211 InstructionOperand value_operand = 194 InstructionOperand value_operand =
212 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 195 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
213 inputs[input_count++] = value_operand; 196 inputs[input_count++] = value_operand;
214 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); 197 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
198
199 if (write_barrier_kind != kNoWriteBarrier) {
200 DCHECK_EQ(kRepTagged, rep);
201 input_count = 0;
202 inputs[input_count++] = g.UseUniqueRegister(base);
203 if (g.CanBeImmediate(index)) {
204 inputs[input_count++] = g.UseImmediate(index);
205 addressing_mode = kMode_MRI;
206 } else {
207 inputs[input_count++] = g.UseUniqueRegister(index);
208 addressing_mode = kMode_MR1;
209 }
210 RecordWriteMode record_write_mode;
211 switch (write_barrier_kind) {
212 case kNoWriteBarrier:
213 UNREACHABLE();
214 break;
215 case kMapWriteBarrier:
216 record_write_mode = RecordWriteMode::kValueIsMap;
217 break;
218 case kPointerWriteBarrier:
219 inputs[input_count++] = g.UseUniqueRegister(value);
220 record_write_mode = RecordWriteMode::kValueIsPointer;
221 break;
222 case kFullWriteBarrier:
223 inputs[input_count++] = g.UseUniqueRegister(value);
224 record_write_mode = RecordWriteMode::kValueIsAny;
225 break;
226 }
227 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
228 size_t const temp_count = arraysize(temps);
229 InstructionCode code = kArchRecordWrite;
230 code |= AddressingModeField::encode(addressing_mode);
231 code |= MiscField::encode(static_cast<int>(record_write_mode));
232 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
233 }
215 } 234 }
216 235
217 236
218 void InstructionSelector::VisitCheckedLoad(Node* node) { 237 void InstructionSelector::VisitCheckedLoad(Node* node) {
219 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 238 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
220 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 239 MachineType typ = TypeOf(OpParameter<MachineType>(node));
221 X64OperandGenerator g(this); 240 X64OperandGenerator g(this);
222 Node* const buffer = node->InputAt(0); 241 Node* const buffer = node->InputAt(0);
223 Node* const offset = node->InputAt(1); 242 Node* const offset = node->InputAt(1);
224 Node* const length = node->InputAt(2); 243 Node* const length = node->InputAt(2);
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 if (CpuFeatures::IsSupported(SSE4_1)) { 1632 if (CpuFeatures::IsSupported(SSE4_1)) {
1614 flags |= MachineOperatorBuilder::kFloat64RoundDown | 1633 flags |= MachineOperatorBuilder::kFloat64RoundDown |
1615 MachineOperatorBuilder::kFloat64RoundTruncate; 1634 MachineOperatorBuilder::kFloat64RoundTruncate;
1616 } 1635 }
1617 return flags; 1636 return flags;
1618 } 1637 }
1619 1638
1620 } // namespace compiler 1639 } // namespace compiler
1621 } // namespace internal 1640 } // namespace internal
1622 } // namespace v8 1641 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/instruction-codes-x64.h ('k') | src/heap/heap.cc » ('j') | src/heap/heap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698