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

Side by Side Diff: runtime/vm/deopt_instructions.h

Issue 462403004: Refactor deopt_instructions.cc to minimize boilerplate and duplication. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/deopt_instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_DEOPT_INSTRUCTIONS_H_ 5 #ifndef VM_DEOPT_INSTRUCTIONS_H_
6 #define VM_DEOPT_INSTRUCTIONS_H_ 6 #define VM_DEOPT_INSTRUCTIONS_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
11 #include "vm/deferred_objects.h" 11 #include "vm/deferred_objects.h"
12 #include "vm/growable_array.h" 12 #include "vm/growable_array.h"
13 #include "vm/locations.h"
13 #include "vm/object.h" 14 #include "vm/object.h"
14 15
15 namespace dart { 16 namespace dart {
16 17
17 class Location; 18 class Location;
18 class Value; 19 class Value;
19 class MaterializeObjectInstr; 20 class MaterializeObjectInstr;
20 class StackFrame; 21 class StackFrame;
21 22
22 // Holds all data relevant for execution of deoptimization instructions. 23 // Holds all data relevant for execution of deoptimization instructions.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 return cpu_registers_[reg]; 64 return cpu_registers_[reg];
64 } 65 }
65 66
66 double FpuRegisterValue(FpuRegister reg) const { 67 double FpuRegisterValue(FpuRegister reg) const {
67 ASSERT(fpu_registers_ != NULL); 68 ASSERT(fpu_registers_ != NULL);
68 ASSERT(reg >= 0); 69 ASSERT(reg >= 0);
69 ASSERT(reg < kNumberOfFpuRegisters); 70 ASSERT(reg < kNumberOfFpuRegisters);
70 return *reinterpret_cast<double*>(&fpu_registers_[reg]); 71 return *reinterpret_cast<double*>(&fpu_registers_[reg]);
71 } 72 }
72 73
73 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const {
74 ASSERT(fpu_registers_ != NULL);
75 ASSERT(reg >= 0);
76 ASSERT(reg < kNumberOfFpuRegisters);
77 return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]);
78 }
79
80 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { 74 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
81 ASSERT(fpu_registers_ != NULL); 75 ASSERT(fpu_registers_ != NULL);
82 ASSERT(reg >= 0); 76 ASSERT(reg >= 0);
83 ASSERT(reg < kNumberOfFpuRegisters); 77 ASSERT(reg < kNumberOfFpuRegisters);
84 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); 78 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]);
85 return simd128_value_t().readFrom(address); 79 return simd128_value_t().readFrom(address);
86 } 80 }
87 81
88 void set_dest_frame(intptr_t* dest_frame) { 82 void set_dest_frame(intptr_t* dest_frame) {
89 ASSERT(dest_frame != NULL && dest_frame_ == NULL); 83 ASSERT(dest_frame != NULL && dest_frame_ == NULL);
(...skipping 23 matching lines...) Expand all
113 107
114 void VisitObjectPointers(ObjectPointerVisitor* visitor); 108 void VisitObjectPointers(ObjectPointerVisitor* visitor);
115 109
116 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { 110 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
117 deferred_slots_ = new DeferredObjectRef( 111 deferred_slots_ = new DeferredObjectRef(
118 idx, 112 idx,
119 reinterpret_cast<RawInstance**>(slot), 113 reinterpret_cast<RawInstance**>(slot),
120 deferred_slots_); 114 deferred_slots_);
121 } 115 }
122 116
123 void DeferDoubleMaterialization(double value, RawDouble** slot) { 117 void DeferMaterialization(double value, RawDouble** slot) {
124 deferred_slots_ = new DeferredDouble( 118 deferred_slots_ = new DeferredDouble(
125 value, 119 value,
126 reinterpret_cast<RawInstance**>(slot), 120 reinterpret_cast<RawInstance**>(slot),
127 deferred_slots_); 121 deferred_slots_);
128 } 122 }
129 123
130 void DeferMintMaterialization(int64_t value, RawMint** slot) { 124 void DeferMintMaterialization(int64_t value, RawMint** slot) {
131 deferred_slots_ = new DeferredMint( 125 deferred_slots_ = new DeferredMint(
132 value, 126 value,
133 reinterpret_cast<RawInstance**>(slot), 127 reinterpret_cast<RawInstance**>(slot),
134 deferred_slots_); 128 deferred_slots_);
135 } 129 }
136 130
137 void DeferFloat32x4Materialization(simd128_value_t value, 131 void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) {
138 RawFloat32x4** slot) {
139 deferred_slots_ = new DeferredFloat32x4( 132 deferred_slots_ = new DeferredFloat32x4(
140 value, 133 value,
141 reinterpret_cast<RawInstance**>(slot), 134 reinterpret_cast<RawInstance**>(slot),
142 deferred_slots_); 135 deferred_slots_);
143 } 136 }
144 137
145 void DeferFloat64x2Materialization(simd128_value_t value, 138 void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) {
146 RawFloat64x2** slot) {
147 deferred_slots_ = new DeferredFloat64x2( 139 deferred_slots_ = new DeferredFloat64x2(
148 value, 140 value,
149 reinterpret_cast<RawInstance**>(slot), 141 reinterpret_cast<RawInstance**>(slot),
150 deferred_slots_); 142 deferred_slots_);
151 } 143 }
152 144
153 void DeferInt32x4Materialization(simd128_value_t value, 145 void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) {
154 RawInt32x4** slot) {
155 deferred_slots_ = new DeferredInt32x4( 146 deferred_slots_ = new DeferredInt32x4(
156 value, 147 value,
157 reinterpret_cast<RawInstance**>(slot), 148 reinterpret_cast<RawInstance**>(slot),
158 deferred_slots_); 149 deferred_slots_);
159 } 150 }
160 151
161 DeferredObject* GetDeferredObject(intptr_t idx) const { 152 DeferredObject* GetDeferredObject(intptr_t idx) const {
162 return deferred_objects_[idx]; 153 return deferred_objects_[idx];
163 } 154 }
164 155
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 205
215 206
216 // Represents one deopt instruction, e.g, setup return address, store object, 207 // Represents one deopt instruction, e.g, setup return address, store object,
217 // store register, etc. The target is defined by instruction's position in 208 // store register, etc. The target is defined by instruction's position in
218 // the deopt-info array. 209 // the deopt-info array.
219 class DeoptInstr : public ZoneAllocated { 210 class DeoptInstr : public ZoneAllocated {
220 public: 211 public:
221 enum Kind { 212 enum Kind {
222 kRetAddress, 213 kRetAddress,
223 kConstant, 214 kConstant,
224 kRegister, 215 kWord,
225 kFpuRegister, 216 kDouble,
226 kFloat32x4FpuRegister, 217 kFloat32x4,
227 kFloat64x2FpuRegister, 218 kFloat64x2,
228 kInt32x4FpuRegister, 219 kInt32x4,
229 kStackSlot,
230 kDoubleStackSlot,
231 kFloat32x4StackSlot,
232 kFloat64x2StackSlot,
233 kInt32x4StackSlot,
234 // Mints are split into low and high words. Each word can be in a register 220 // Mints are split into low and high words. Each word can be in a register
235 // or stack slot. Note Mints are only used on 32-bit architectures. 221 // or stack slot. Note Mints are only used on 32-bit architectures.
236 kMintRegisterPair, 222 kMintPair,
237 kMintStackSlotPair, 223 kUint32,
238 kMintStackSlotRegister,
239 kUint32Register,
240 kUint32StackSlot,
241 kPcMarker, 224 kPcMarker,
242 kPp, 225 kPp,
243 kCallerFp, 226 kCallerFp,
244 kCallerPp, 227 kCallerPp,
245 kCallerPc, 228 kCallerPc,
246 kSuffix, 229 kSuffix,
247 kMaterializedObjectRef, 230 kMaterializedObjectRef,
248 kMaterializeObject 231 kMaterializeObject
249 }; 232 };
250 233
251 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index); 234 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index);
252 235
253 DeoptInstr() {} 236 DeoptInstr() {}
254 virtual ~DeoptInstr() {} 237 virtual ~DeoptInstr() {}
255 238
256 virtual const char* ToCString() const = 0; 239 virtual const char* ToCString() const {
240 const char* args = ArgumentsToCString();
241 if (args != NULL) {
242 return Isolate::Current()->current_zone()->PrintToString(
243 "%s(%s)", KindToCString(kind()), args);
244 } else {
245 return KindToCString(kind());
246 }
247 }
257 248
258 virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0; 249 virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
259 250
260 virtual DeoptInstr::Kind kind() const = 0; 251 virtual DeoptInstr::Kind kind() const = 0;
261 252
262 bool Equals(const DeoptInstr& other) const { 253 bool Equals(const DeoptInstr& other) const {
263 return (kind() == other.kind()) && (source_index() == other.source_index()); 254 return (kind() == other.kind()) && (source_index() == other.source_index());
264 } 255 }
265 256
266 // Decode the payload of a suffix command. Return the suffix length and 257 // Decode the payload of a suffix command. Return the suffix length and
(...skipping 11 matching lines...) Expand all
278 static intptr_t GetFieldCount(DeoptInstr* instr) { 269 static intptr_t GetFieldCount(DeoptInstr* instr) {
279 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); 270 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject);
280 return instr->source_index(); 271 return instr->source_index();
281 } 272 }
282 273
283 protected: 274 protected:
284 friend class DeoptInfoBuilder; 275 friend class DeoptInfoBuilder;
285 276
286 virtual intptr_t source_index() const = 0; 277 virtual intptr_t source_index() const = 0;
287 278
279 virtual const char* ArgumentsToCString() const {
280 return NULL;
281 }
282
288 private: 283 private:
284 static const char* KindToCString(Kind kind);
285
289 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); 286 DISALLOW_COPY_AND_ASSIGN(DeoptInstr);
290 }; 287 };
291 288
292 289
290 template<typename RegisterType, typename DestinationType> struct SourceReader;
291
292 template<typename T>
293 struct SourceReader<Register, T> {
294 static intptr_t Read(DeoptContext* context, Register reg) {
295 return context->RegisterValue(reg);
296 }
297 };
298
299 template<>
300 struct SourceReader<FpuRegister, double> {
301 static double Read(DeoptContext* context, FpuRegister reg) {
302 return context->FpuRegisterValue(reg);
303 }
304 };
305
306
307 template<>
308 struct SourceReader<FpuRegister, simd128_value_t> {
309 static simd128_value_t Read(DeoptContext* context, FpuRegister reg) {
310 return context->FpuRegisterValueAsSimd128(reg);
311 }
312 };
313
314
315 template<typename RegisterType>
316 class GenericDeoptSource {
317 public:
318 enum Kind {
319 kStackSlot = 0,
320 kRegister = 1
321 };
322
323 explicit GenericDeoptSource(intptr_t source_index)
Florian Schneider 2014/08/22 17:05:45 Is this constructor used at all, or is is dead cod
Vyacheslav Egorov (Google) 2014/08/23 00:26:45 It is used when deserializing deopt instructions.
324 : source_index_(source_index) { }
325
326 GenericDeoptSource(Kind kind, intptr_t index)
327 : source_index_(IsRegister::encode(kind) | RawIndex::encode(index)) {
328 }
329
330 template<typename T>
331 T Value(DeoptContext* context) const {
332 if (is_register()) {
333 return static_cast<T>(SourceReader<RegisterType, T>::Read(
334 context, reg()));
335 } else {
336 return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt(
337 context->source_frame_size() - raw_index() - 1));
338 }
339 }
340
341 intptr_t source_index() const { return source_index_; }
342
343 const char* ToCString() const {
344 if (is_register()) {
345 return Name(reg());
346 } else {
347 return Isolate::Current()->current_zone()->PrintToString(
348 "s%" Pd "", raw_index());
349 }
350 }
351
352 private:
353 class IsRegister : public BitField<intptr_t, 0, 1> { };
354 class RawIndex : public BitField<intptr_t, 1, kBitsPerWord - 1> { };
355
356 bool is_register() const {
357 return IsRegister::decode(source_index_) == kRegister;
358 }
359 intptr_t raw_index() const { return RawIndex::decode(source_index_); }
360
361 RegisterType reg() const { return static_cast<RegisterType>(raw_index()); }
362
363 static const char* Name(Register reg) {
364 return Assembler::RegisterName(reg);
365 }
366
367 static const char* Name(FpuRegister fpu_reg) {
368 return Assembler::FpuRegisterName(fpu_reg);
369 }
370
371 const intptr_t source_index_;
372 };
373
374
375 typedef GenericDeoptSource<Register> MachineWordSource;
376 typedef GenericDeoptSource<FpuRegister> MachineFpuSource;
377
378
293 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX 379 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX
294 // methods in the order of their target, starting wih deoptimized code 380 // methods in the order of their target, starting wih deoptimized code
295 // continuation pc and ending with the first argument of the deoptimized 381 // continuation pc and ending with the first argument of the deoptimized
296 // code. Call CreateDeoptInfo to write the accumulated instructions into 382 // code. Call CreateDeoptInfo to write the accumulated instructions into
297 // the heap and reset the builder's internal state for the next DeoptInfo. 383 // the heap and reset the builder's internal state for the next DeoptInfo.
298 class DeoptInfoBuilder : public ValueObject { 384 class DeoptInfoBuilder : public ValueObject {
299 public: 385 public:
300 DeoptInfoBuilder(Isolate* isolate, const intptr_t num_args); 386 DeoptInfoBuilder(Isolate* isolate, const intptr_t num_args);
301 387
302 // 'object_table' holds all objects referred to by DeoptInstr in 388 // 'object_table' holds all objects referred to by DeoptInstr in
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 // Mark the actual start of the frame description after all materialization 421 // Mark the actual start of the frame description after all materialization
336 // instructions were emitted. Used for verification purposes. 422 // instructions were emitted. Used for verification purposes.
337 void MarkFrameStart() { 423 void MarkFrameStart() {
338 ASSERT(frame_start_ == -1); 424 ASSERT(frame_start_ == -1);
339 frame_start_ = instructions_.length(); 425 frame_start_ = instructions_.length();
340 } 426 }
341 427
342 private: 428 private:
343 class TrieNode; 429 class TrieNode;
344 430
431 MachineWordSource ToMachineWordSource(const Location& loc);
432 MachineFpuSource ToMachineFpuSource(const Location& loc,
433 Location::Kind expected_stack_slot_kind);
434
345 intptr_t FindOrAddObjectInTable(const Object& obj) const; 435 intptr_t FindOrAddObjectInTable(const Object& obj) const;
346 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; 436 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const;
347 intptr_t CalculateStackIndex(const Location& source_loc) const; 437 intptr_t CalculateStackIndex(const Location& source_loc) const;
348 438
349 intptr_t FrameSize() const { 439 intptr_t FrameSize() const {
350 return instructions_.length() - frame_start_; 440 return instructions_.length() - frame_start_;
351 } 441 }
352 442
353 void AddConstant(const Object& obj, intptr_t dest_index); 443 void AddConstant(const Object& obj, intptr_t dest_index);
354 444
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 DeoptInfo* info, 488 DeoptInfo* info,
399 Smi* reason); 489 Smi* reason);
400 490
401 private: 491 private:
402 static const intptr_t kEntrySize = 3; 492 static const intptr_t kEntrySize = 3;
403 }; 493 };
404 494
405 } // namespace dart 495 } // namespace dart
406 496
407 #endif // VM_DEOPT_INSTRUCTIONS_H_ 497 #endif // VM_DEOPT_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/deopt_instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698