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

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

Issue 24834002: Refactor some deoptimization code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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 | « runtime/vm/deferred_objects.cc ('k') | 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/growable_array.h" 12 #include "vm/growable_array.h"
12 #include "vm/object.h" 13 #include "vm/object.h"
13 14
14 namespace dart { 15 namespace dart {
15 16
16 class Location; 17 class Location;
17 class Value; 18 class Value;
18 class MaterializeObjectInstr; 19 class MaterializeObjectInstr;
19 20
20 // Holds all data relevant for execution of deoptimization instructions. 21 // Holds all data relevant for execution of deoptimization instructions.
21 class DeoptimizationContext : public ValueObject { 22 class DeoptContext {
22 public: 23 public:
23 // 'to_frame_start' points to the fixed size portion of the frame under sp.
24 // 'num_args' is 0 if there are no arguments or if there are optional 24 // 'num_args' is 0 if there are no arguments or if there are optional
25 // arguments. 25 // arguments.
26 DeoptimizationContext(intptr_t* to_frame_start, 26 DeoptContext(const Array& object_table,
27 intptr_t to_frame_size, 27 intptr_t num_args,
28 const Array& object_table, 28 DeoptReasonId deopt_reason);
29 intptr_t num_args,
30 DeoptReasonId deopt_reason);
31 29
32 intptr_t* GetFromFrameAddressAt(intptr_t index) const { 30 virtual ~DeoptContext();
33 ASSERT((0 <= index) && (index < from_frame_size_)); 31
34 return &from_frame_[index]; 32 // Sets the sources (frame and registers) for this deoptimization.
33 //
34 // if 'frame_is_copy' is true, DeoptContext will delete the frame
35 // when it is done.
36 void SetSourceArgs(intptr_t* frame_start,
37 intptr_t frame_size,
38 fpu_register_t* fpu_registers,
39 intptr_t* cpu_registers,
40 bool frame_is_copy);
41
42 // Sets the destination fraem for this deoptimization.
43 //
44 // 'frame_start' oints to the fixed size portion of the frame under
45 // sp.
46 //
47 // DeoptContext does not claim ownership of the frame memory.
48 void SetDestArgs(intptr_t* frame_start, intptr_t frame_size);
49
50 intptr_t* GetSourceFrameAddressAt(intptr_t index) const {
51 ASSERT(source_frame_ != NULL);
52 ASSERT((0 <= index) && (index < source_frame_size_));
53 return &source_frame_[index];
35 } 54 }
36 55
37 intptr_t* GetToFrameAddressAt(intptr_t index) const { 56 intptr_t* GetDestFrameAddressAt(intptr_t index) const {
38 ASSERT((0 <= index) && (index < to_frame_size_)); 57 ASSERT(dest_frame_ != NULL);
39 return &to_frame_[index]; 58 ASSERT((0 <= index) && (index < dest_frame_size_));
59 return &dest_frame_[index];
40 } 60 }
41 61
42 intptr_t GetFromFp() const; 62 intptr_t GetSourceFp() const;
43 intptr_t GetFromPp() const; 63 intptr_t GetSourcePp() const;
44 intptr_t GetFromPc() const; 64 intptr_t GetSourcePc() const;
45 65
46 intptr_t GetCallerFp() const; 66 intptr_t GetCallerFp() const;
47 void SetCallerFp(intptr_t callers_fp); 67 void SetCallerFp(intptr_t callers_fp);
48 68
49 RawObject* ObjectAt(intptr_t index) const { 69 RawObject* ObjectAt(intptr_t index) const {
50 return object_table_.At(index); 70 const Array& object_table = Array::Handle(object_table_);
71 return object_table.At(index);
51 } 72 }
52 73
53 intptr_t RegisterValue(Register reg) const { 74 intptr_t RegisterValue(Register reg) const {
54 return registers_copy_[reg]; 75 return cpu_registers_[reg];
55 } 76 }
56 77
57 double FpuRegisterValue(FpuRegister reg) const { 78 double FpuRegisterValue(FpuRegister reg) const {
58 return *reinterpret_cast<double*>(&fpu_registers_copy_[reg]); 79 return *reinterpret_cast<double*>(&fpu_registers_[reg]);
59 } 80 }
60 81
61 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { 82 int64_t FpuRegisterValueAsInt64(FpuRegister reg) const {
62 return *reinterpret_cast<int64_t*>(&fpu_registers_copy_[reg]); 83 return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]);
63 } 84 }
64 85
65 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { 86 simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
66 const float* address = reinterpret_cast<float*>(&fpu_registers_copy_[reg]); 87 const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]);
67 return simd128_value_t().readFrom(address); 88 return simd128_value_t().readFrom(address);
68 } 89 }
69 90
70 Isolate* isolate() const { return isolate_; } 91 Isolate* isolate() const { return isolate_; }
71 92
72 intptr_t from_frame_size() const { return from_frame_size_; } 93 intptr_t source_frame_size() const { return source_frame_size_; }
73 94
74 DeoptReasonId deopt_reason() const { return deopt_reason_; } 95 DeoptReasonId deopt_reason() const { return deopt_reason_; }
75 96
97 void VisitObjectPointers(ObjectPointerVisitor* visitor);
98
99 void PrepareForDeferredMaterialization(intptr_t count) {
100 if (count > 0) {
101 deferred_objects_ = new DeferredObject*[count];
102 deferred_objects_count_ = count;
103 }
104 }
105
106 DeferredObject* GetDeferredObject(intptr_t idx) const {
107 return deferred_objects_[idx];
108 }
109
110 // Sets the materialized value for some deferred object.
111 //
112 // Claims ownership of the memory for 'object'.
113 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
114 deferred_objects_[idx] = object;
115 }
116
117 intptr_t DeferredObjectsCount() const {
118 return deferred_objects_count_;
119 }
120
121 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
122 deferred_object_refs_ = new DeferredObjectRef(
123 idx,
124 reinterpret_cast<RawInstance**>(slot),
125 deferred_object_refs_);
126 }
127
128 void DeferDoubleMaterialization(double value, RawDouble** slot) {
129 deferred_boxes_ = new DeferredDouble(
130 value,
131 reinterpret_cast<RawInstance**>(slot),
132 deferred_boxes_);
133 }
134
135 void DeferMintMaterialization(int64_t value, RawMint** slot) {
136 deferred_boxes_ = new DeferredMint(
137 value,
138 reinterpret_cast<RawInstance**>(slot),
139 deferred_boxes_);
140 }
141
142 void DeferFloat32x4Materialization(simd128_value_t value,
143 RawFloat32x4** slot) {
144 deferred_boxes_ = new DeferredFloat32x4(
145 value,
146 reinterpret_cast<RawInstance**>(slot),
147 deferred_boxes_);
148 }
149
150 void DeferUint32x4Materialization(simd128_value_t value,
151 RawUint32x4** slot) {
152 deferred_boxes_ = new DeferredUint32x4(
153 value,
154 reinterpret_cast<RawInstance**>(slot),
155 deferred_boxes_);
156 }
157
158 // Materializes all deferred objects. Returns the total number of
159 // artificial arguments used during deoptimization.
160 intptr_t MaterializeDeferredObjects();
161
76 private: 162 private:
77 const Array& object_table_; 163 RawArray* object_table_;
78 intptr_t* to_frame_; 164 intptr_t* dest_frame_;
79 const intptr_t to_frame_size_; 165 intptr_t dest_frame_size_;
80 intptr_t* from_frame_; 166 bool source_frame_is_copy_;
81 intptr_t from_frame_size_; 167 intptr_t* source_frame_;
82 intptr_t* registers_copy_; 168 intptr_t source_frame_size_;
83 fpu_register_t* fpu_registers_copy_; 169 intptr_t* cpu_registers_;
170 fpu_register_t* fpu_registers_;
84 const intptr_t num_args_; 171 const intptr_t num_args_;
85 const DeoptReasonId deopt_reason_; 172 const DeoptReasonId deopt_reason_;
86 intptr_t caller_fp_; 173 intptr_t caller_fp_;
87 Isolate* isolate_; 174 Isolate* isolate_;
88 175
89 DISALLOW_COPY_AND_ASSIGN(DeoptimizationContext); 176 DeferredSlot* deferred_boxes_;
177 DeferredSlot* deferred_object_refs_;
178
179 intptr_t deferred_objects_count_;
180 DeferredObject** deferred_objects_;
181
182 DISALLOW_COPY_AND_ASSIGN(DeoptContext);
90 }; 183 };
91 184
92 185
93 186
94 // Represents one deopt instruction, e.g, setup return address, store object, 187 // Represents one deopt instruction, e.g, setup return address, store object,
95 // store register, etc. The target is defined by instruction's position in 188 // store register, etc. The target is defined by instruction's position in
96 // the deopt-info array. 189 // the deopt-info array.
97 class DeoptInstr : public ZoneAllocated { 190 class DeoptInstr : public ZoneAllocated {
98 public: 191 public:
99 enum Kind { 192 enum Kind {
(...skipping 12 matching lines...) Expand all
112 kPcMarker, 205 kPcMarker,
113 kPp, 206 kPp,
114 kCallerFp, 207 kCallerFp,
115 kCallerPp, 208 kCallerPp,
116 kCallerPc, 209 kCallerPc,
117 kSuffix, 210 kSuffix,
118 kMaterializedObjectRef, 211 kMaterializedObjectRef,
119 kMaterializeObject 212 kMaterializeObject
120 }; 213 };
121 214
122 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); 215 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index);
123 216
124 DeoptInstr() {} 217 DeoptInstr() {}
125 virtual ~DeoptInstr() {} 218 virtual ~DeoptInstr() {}
126 219
127 virtual const char* ToCString() const = 0; 220 virtual const char* ToCString() const = 0;
128 221
129 virtual void Execute(DeoptimizationContext* deopt_context, 222 virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
130 intptr_t* to_addr) = 0;
131 223
132 virtual DeoptInstr::Kind kind() const = 0; 224 virtual DeoptInstr::Kind kind() const = 0;
133 225
134 bool Equals(const DeoptInstr& other) const { 226 bool Equals(const DeoptInstr& other) const {
135 return (kind() == other.kind()) && (from_index() == other.from_index()); 227 return (kind() == other.kind()) && (source_index() == other.source_index());
136 } 228 }
137 229
138 // Decode the payload of a suffix command. Return the suffix length and 230 // Decode the payload of a suffix command. Return the suffix length and
139 // set the output parameter info_number to the index of the shared suffix. 231 // set the output parameter info_number to the index of the shared suffix.
140 static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); 232 static intptr_t DecodeSuffix(intptr_t source_index, intptr_t* info_number);
141 233
142 // Get the function and return address which is encoded in this 234 // Get the function and return address which is encoded in this
143 // kRetAfterAddress deopt instruction. 235 // kRetAfterAddress deopt instruction.
144 static uword GetRetAddress(DeoptInstr* instr, 236 static uword GetRetAddress(DeoptInstr* instr,
145 const Array& object_table, 237 const Array& object_table,
146 Function* func); 238 Function* func);
147 239
148 // Return number of initialized fields in the object that will be 240 // Return number of initialized fields in the object that will be
149 // materialized by kMaterializeObject instruction. 241 // materialized by kMaterializeObject instruction.
150 static intptr_t GetFieldCount(DeoptInstr* instr) { 242 static intptr_t GetFieldCount(DeoptInstr* instr) {
151 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); 243 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject);
152 return instr->from_index(); 244 return instr->source_index();
153 } 245 }
154 246
155 protected: 247 protected:
156 friend class DeoptInfoBuilder; 248 friend class DeoptInfoBuilder;
157 249
158 virtual intptr_t from_index() const = 0; 250 virtual intptr_t source_index() const = 0;
159 251
160 private: 252 private:
161 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); 253 DISALLOW_COPY_AND_ASSIGN(DeoptInstr);
162 }; 254 };
163 255
164 256
165 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX 257 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX
166 // methods in the order of their target, starting wih deoptimized code 258 // methods in the order of their target, starting wih deoptimized code
167 // continuation pc and ending with the first argument of the deoptimized 259 // continuation pc and ending with the first argument of the deoptimized
168 // code. Call CreateDeoptInfo to write the accumulated instructions into 260 // code. Call CreateDeoptInfo to write the accumulated instructions into
169 // the heap and reset the builder's internal state for the next DeoptInfo. 261 // the heap and reset the builder's internal state for the next DeoptInfo.
170 class DeoptInfoBuilder : public ValueObject { 262 class DeoptInfoBuilder : public ValueObject {
171 public: 263 public:
172 explicit DeoptInfoBuilder(const intptr_t num_args); 264 explicit DeoptInfoBuilder(const intptr_t num_args);
173 265
174 // 'object_table' holds all objects referred to by DeoptInstr in 266 // 'object_table' holds all objects referred to by DeoptInstr in
175 // all DeoptInfo instances for a single Code object. 267 // all DeoptInfo instances for a single Code object.
176 const GrowableObjectArray& object_table() { return object_table_; } 268 const GrowableObjectArray& object_table() { return object_table_; }
177 269
178 // Return address before instruction. 270 // Return address before instruction.
179 void AddReturnAddress(const Function& function, 271 void AddReturnAddress(const Function& function,
180 intptr_t deopt_id, 272 intptr_t deopt_id,
181 intptr_t to_index); 273 intptr_t dest_index);
182 274
183 // Copy from optimized frame to unoptimized. 275 // Copy from optimized frame to unoptimized.
184 void AddCopy(Value* value, const Location& from_loc, intptr_t to_index); 276 void AddCopy(Value* value, const Location& source_loc, intptr_t dest_index);
185 void AddPcMarker(const Function& function, intptr_t to_index); 277 void AddPcMarker(const Function& function, intptr_t dest_index);
186 void AddPp(const Function& function, intptr_t to_index); 278 void AddPp(const Function& function, intptr_t dest_index);
187 void AddCallerFp(intptr_t to_index); 279 void AddCallerFp(intptr_t dest_index);
188 void AddCallerPp(intptr_t to_index); 280 void AddCallerPp(intptr_t dest_index);
189 void AddCallerPc(intptr_t to_index); 281 void AddCallerPc(intptr_t dest_index);
190 282
191 // Add object to be materialized. Emit kMaterializeObject instruction. 283 // Add object to be materialized. Emit kMaterializeObject instruction.
192 void AddMaterialization(MaterializeObjectInstr* mat); 284 void AddMaterialization(MaterializeObjectInstr* mat);
193 285
194 // For every materialized object emit instructions describing data required 286 // For every materialized object emit instructions describing data required
195 // for materialization: class of the instance to allocate and field-value 287 // for materialization: class of the instance to allocate and field-value
196 // pairs for initialization. 288 // pairs for initialization.
197 // Emitted instructions are expected to follow fixed size section of frame 289 // Emitted instructions are expected to follow fixed size section of frame
198 // emitted first. This way they become a part of the bottom-most deoptimized 290 // emitted first. This way they become a part of the bottom-most deoptimized
199 // frame and are discoverable by GC. 291 // frame and are discoverable by GC.
200 // At deoptimization they will be removed by the stub at the very end: 292 // At deoptimization they will be removed by the stub at the very end:
201 // after they were used to materialize objects. 293 // after they were used to materialize objects.
202 // Returns the index of the next stack slot. Used for verification. 294 // Returns the index of the next stack slot. Used for verification.
203 intptr_t EmitMaterializationArguments(intptr_t to_index); 295 intptr_t EmitMaterializationArguments(intptr_t dest_index);
204 296
205 RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table); 297 RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table);
206 298
207 // Mark the actual start of the frame description after all materialization 299 // Mark the actual start of the frame description after all materialization
208 // instructions were emitted. Used for verification purposes. 300 // instructions were emitted. Used for verification purposes.
209 void MarkFrameStart() { 301 void MarkFrameStart() {
210 ASSERT(frame_start_ == -1); 302 ASSERT(frame_start_ == -1);
211 frame_start_ = instructions_.length(); 303 frame_start_ = instructions_.length();
212 } 304 }
213 305
214 private: 306 private:
215 class TrieNode; 307 class TrieNode;
216 308
217 intptr_t FindOrAddObjectInTable(const Object& obj) const; 309 intptr_t FindOrAddObjectInTable(const Object& obj) const;
218 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; 310 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const;
219 intptr_t CalculateStackIndex(const Location& from_loc) const; 311 intptr_t CalculateStackIndex(const Location& source_loc) const;
220 312
221 intptr_t FrameSize() const { 313 intptr_t FrameSize() const {
222 return instructions_.length() - frame_start_; 314 return instructions_.length() - frame_start_;
223 } 315 }
224 316
225 void AddConstant(const Object& obj, intptr_t to_index); 317 void AddConstant(const Object& obj, intptr_t dest_index);
226 318
227 GrowableArray<DeoptInstr*> instructions_; 319 GrowableArray<DeoptInstr*> instructions_;
228 const GrowableObjectArray& object_table_; 320 const GrowableObjectArray& object_table_;
229 const intptr_t num_args_; 321 const intptr_t num_args_;
230 322
231 // Used to compress entries by sharing suffixes. 323 // Used to compress entries by sharing suffixes.
232 TrieNode* trie_root_; 324 TrieNode* trie_root_;
233 intptr_t current_info_number_; 325 intptr_t current_info_number_;
234 326
235 intptr_t frame_start_; 327 intptr_t frame_start_;
(...skipping 30 matching lines...) Expand all
266 DeoptInfo* info, 358 DeoptInfo* info,
267 Smi* reason); 359 Smi* reason);
268 360
269 private: 361 private:
270 static const intptr_t kEntrySize = 3; 362 static const intptr_t kEntrySize = 3;
271 }; 363 };
272 364
273 } // namespace dart 365 } // namespace dart
274 366
275 #endif // VM_DEOPT_INSTRUCTIONS_H_ 367 #endif // VM_DEOPT_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « runtime/vm/deferred_objects.cc ('k') | runtime/vm/deopt_instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698