OLD | NEW |
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 #include "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
11 #include "vm/parser.h" | 11 #include "vm/parser.h" |
12 #include "vm/stack_frame.h" | 12 #include "vm/stack_frame.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 DEFINE_FLAG(bool, compress_deopt_info, true, | 16 DEFINE_FLAG(bool, compress_deopt_info, true, |
17 "Compress the size of the deoptimization info for optimized code."); | 17 "Compress the size of the deoptimization info for optimized code."); |
18 DECLARE_FLAG(bool, trace_deoptimization); | 18 DECLARE_FLAG(bool, trace_deoptimization); |
19 DECLARE_FLAG(bool, trace_deoptimization_verbose); | 19 DECLARE_FLAG(bool, trace_deoptimization_verbose); |
20 | 20 |
21 DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start, | 21 DeoptContext::DeoptContext(const Array& object_table, |
22 intptr_t to_frame_size, | 22 intptr_t num_args, |
23 const Array& object_table, | 23 DeoptReasonId deopt_reason) |
24 intptr_t num_args, | 24 : object_table_(object_table.raw()), |
25 DeoptReasonId deopt_reason) | 25 to_frame_(NULL), |
26 : object_table_(object_table), | 26 to_frame_size_(0), |
27 to_frame_(to_frame_start), | |
28 to_frame_size_(to_frame_size), | |
29 from_frame_(NULL), | 27 from_frame_(NULL), |
30 from_frame_size_(0), | 28 from_frame_size_(0), |
31 registers_copy_(NULL), | 29 cpu_registers_(NULL), |
32 fpu_registers_copy_(NULL), | 30 fpu_registers_(NULL), |
33 num_args_(num_args), | 31 num_args_(num_args), |
34 deopt_reason_(deopt_reason), | 32 deopt_reason_(deopt_reason), |
35 isolate_(Isolate::Current()) { | 33 isolate_(Isolate::Current()), |
36 from_frame_ = isolate_->deopt_frame_copy(); | 34 deferred_boxes_(NULL), |
37 from_frame_size_ = isolate_->deopt_frame_copy_size(); | 35 deferred_object_refs_(NULL), |
38 registers_copy_ = isolate_->deopt_cpu_registers_copy(); | 36 deferred_objects_count_(0), |
39 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy(); | 37 deferred_objects_(NULL) { |
40 // The deoptimized frame is filled starting just below the sp of its caller | 38 } |
41 // down to kDartFrameFixedSize words below its own sp. | 39 |
42 // The chain of frame pointers is recreated from the fp of the caller. | 40 |
| 41 DeoptContext::~DeoptContext() { |
| 42 // Delete all deferred objects. |
| 43 for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
| 44 delete deferred_objects_[i]; |
| 45 } |
| 46 delete[] deferred_objects_; |
| 47 deferred_objects_ = NULL; |
| 48 deferred_objects_count_ = 0; |
| 49 } |
| 50 |
| 51 |
| 52 void DeoptContext::SetToFrame(intptr_t* start, |
| 53 intptr_t size) { |
| 54 ASSERT(start != NULL); |
| 55 ASSERT(size >= 0); |
| 56 ASSERT(to_frame_ == NULL); |
| 57 to_frame_ = start; |
| 58 to_frame_size_ = size; |
| 59 } |
| 60 |
| 61 |
| 62 void DeoptContext::SetFromFrame(intptr_t* start, |
| 63 intptr_t size) { |
| 64 ASSERT(start != NULL); |
| 65 ASSERT(size >= 0); |
| 66 ASSERT(from_frame_ == NULL); |
| 67 from_frame_ = start; |
| 68 from_frame_size_ = size; |
43 caller_fp_ = GetFromFp(); | 69 caller_fp_ = GetFromFp(); |
44 } | 70 } |
45 | 71 |
46 | 72 |
47 intptr_t DeoptimizationContext::GetFromFp() const { | 73 void DeoptContext::SetSavedRegisters(fpu_register_t* fpu_registers, |
| 74 intptr_t* cpu_registers) { |
| 75 ASSERT(cpu_registers_ == NULL && fpu_registers_ == NULL); |
| 76 cpu_registers_ = cpu_registers; |
| 77 fpu_registers_ = fpu_registers; |
| 78 } |
| 79 |
| 80 |
| 81 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 82 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_table_)); |
| 83 } |
| 84 |
| 85 |
| 86 intptr_t DeoptContext::GetFromFp() const { |
48 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp]; | 87 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp]; |
49 } | 88 } |
50 | 89 |
51 | 90 |
52 intptr_t DeoptimizationContext::GetFromPp() const { | 91 intptr_t DeoptContext::GetFromPp() const { |
53 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp + | 92 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp + |
54 StackFrame::SavedCallerPpSlotFromFp()]; | 93 StackFrame::SavedCallerPpSlotFromFp()]; |
55 } | 94 } |
56 | 95 |
57 | 96 |
58 intptr_t DeoptimizationContext::GetFromPc() const { | 97 intptr_t DeoptContext::GetFromPc() const { |
59 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; | 98 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; |
60 } | 99 } |
61 | 100 |
62 | 101 |
63 intptr_t DeoptimizationContext::GetCallerFp() const { | 102 intptr_t DeoptContext::GetCallerFp() const { |
64 return caller_fp_; | 103 return caller_fp_; |
65 } | 104 } |
66 | 105 |
67 | 106 |
68 void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) { | 107 void DeoptContext::SetCallerFp(intptr_t caller_fp) { |
69 caller_fp_ = caller_fp; | 108 caller_fp_ = caller_fp; |
70 } | 109 } |
71 | 110 |
72 | 111 |
| 112 static void FillDeferredSlots(DeferredSlot** slot_list) { |
| 113 DeferredSlot* slot = *slot_list; |
| 114 *slot_list = NULL; |
| 115 |
| 116 while (slot != NULL) { |
| 117 DeferredSlot* current = slot; |
| 118 slot = slot->next(); |
| 119 |
| 120 current->Materialize(); |
| 121 |
| 122 delete current; |
| 123 } |
| 124 } |
| 125 |
| 126 |
| 127 // Materializes all deferred objects. Returns the total number of |
| 128 // artificial arguments used during deoptimization. |
| 129 intptr_t DeoptContext::MaterializeDeferredObjects() { |
| 130 // First materialize all unboxed "primitive" values (doubles, mints, simd) |
| 131 // then materialize objects. The order is important: objects might be |
| 132 // referencing boxes allocated on the first step. At the same time |
| 133 // objects can't be referencing other deferred objects because storing |
| 134 // an object into a field is always conservatively treated as escaping by |
| 135 // allocation sinking and load forwarding. |
| 136 FillDeferredSlots(&deferred_boxes_); |
| 137 FillDeferredSlots(&deferred_object_refs_); |
| 138 |
| 139 // Compute total number of artificial arguments used during deoptimization. |
| 140 intptr_t deopt_arguments = 0; |
| 141 for (intptr_t i = 0; i < DeferredObjectsCount(); i++) { |
| 142 deopt_arguments += GetDeferredObject(i)->ArgumentCount(); |
| 143 } |
| 144 return deopt_arguments; |
| 145 } |
| 146 |
| 147 |
73 // Deoptimization instruction moving value from optimized frame at | 148 // Deoptimization instruction moving value from optimized frame at |
74 // 'from_index' to specified slots in the unoptimized frame. | 149 // 'from_index' to specified slots in the unoptimized frame. |
75 // 'from_index' represents the slot index of the frame (0 being first argument) | 150 // 'from_index' represents the slot index of the frame (0 being first argument) |
76 // and accounts for saved return address, frame pointer, pool pointer and pc | 151 // and accounts for saved return address, frame pointer, pool pointer and pc |
77 // marker. | 152 // marker. |
78 class DeoptStackSlotInstr : public DeoptInstr { | 153 class DeoptStackSlotInstr : public DeoptInstr { |
79 public: | 154 public: |
80 explicit DeoptStackSlotInstr(intptr_t from_index) | 155 explicit DeoptStackSlotInstr(intptr_t from_index) |
81 : stack_slot_index_(from_index) { | 156 : stack_slot_index_(from_index) { |
82 ASSERT(stack_slot_index_ >= 0); | 157 ASSERT(stack_slot_index_ >= 0); |
83 } | 158 } |
84 | 159 |
85 virtual intptr_t from_index() const { return stack_slot_index_; } | 160 virtual intptr_t from_index() const { return stack_slot_index_; } |
86 virtual DeoptInstr::Kind kind() const { return kStackSlot; } | 161 virtual DeoptInstr::Kind kind() const { return kStackSlot; } |
87 | 162 |
88 virtual const char* ToCString() const { | 163 virtual const char* ToCString() const { |
89 return Isolate::Current()->current_zone()->PrintToString( | 164 return Isolate::Current()->current_zone()->PrintToString( |
90 "s%" Pd "", stack_slot_index_); | 165 "s%" Pd "", stack_slot_index_); |
91 } | 166 } |
92 | 167 |
93 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 168 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
94 intptr_t from_index = | 169 intptr_t from_index = |
95 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 170 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
96 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index); | 171 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index); |
97 *to_addr = *from_addr; | 172 *to_addr = *from_addr; |
98 } | 173 } |
99 | 174 |
100 private: | 175 private: |
101 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 176 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
102 | 177 |
103 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); | 178 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); |
104 }; | 179 }; |
105 | 180 |
106 | 181 |
107 class DeoptDoubleStackSlotInstr : public DeoptInstr { | 182 class DeoptDoubleStackSlotInstr : public DeoptInstr { |
108 public: | 183 public: |
109 explicit DeoptDoubleStackSlotInstr(intptr_t from_index) | 184 explicit DeoptDoubleStackSlotInstr(intptr_t from_index) |
110 : stack_slot_index_(from_index) { | 185 : stack_slot_index_(from_index) { |
111 ASSERT(stack_slot_index_ >= 0); | 186 ASSERT(stack_slot_index_ >= 0); |
112 } | 187 } |
113 | 188 |
114 virtual intptr_t from_index() const { return stack_slot_index_; } | 189 virtual intptr_t from_index() const { return stack_slot_index_; } |
115 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; } | 190 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; } |
116 | 191 |
117 virtual const char* ToCString() const { | 192 virtual const char* ToCString() const { |
118 return Isolate::Current()->current_zone()->PrintToString( | 193 return Isolate::Current()->current_zone()->PrintToString( |
119 "ds%" Pd "", stack_slot_index_); | 194 "ds%" Pd "", stack_slot_index_); |
120 } | 195 } |
121 | 196 |
122 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 197 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
123 intptr_t from_index = | 198 intptr_t from_index = |
124 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 199 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
125 double* from_addr = reinterpret_cast<double*>( | 200 double* from_addr = reinterpret_cast<double*>( |
126 deopt_context->GetFromFrameAddressAt(from_index)); | 201 deopt_context->GetFromFrameAddressAt(from_index)); |
127 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 202 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
128 Isolate::Current()->DeferDoubleMaterialization( | 203 deopt_context->DeferDoubleMaterialization( |
129 *from_addr, reinterpret_cast<RawDouble**>(to_addr)); | 204 *from_addr, reinterpret_cast<RawDouble**>(to_addr)); |
130 } | 205 } |
131 | 206 |
132 private: | 207 private: |
133 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 208 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
134 | 209 |
135 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); | 210 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); |
136 }; | 211 }; |
137 | 212 |
138 | 213 |
139 class DeoptInt64StackSlotInstr : public DeoptInstr { | 214 class DeoptInt64StackSlotInstr : public DeoptInstr { |
140 public: | 215 public: |
141 explicit DeoptInt64StackSlotInstr(intptr_t from_index) | 216 explicit DeoptInt64StackSlotInstr(intptr_t from_index) |
142 : stack_slot_index_(from_index) { | 217 : stack_slot_index_(from_index) { |
143 ASSERT(stack_slot_index_ >= 0); | 218 ASSERT(stack_slot_index_ >= 0); |
144 } | 219 } |
145 | 220 |
146 virtual intptr_t from_index() const { return stack_slot_index_; } | 221 virtual intptr_t from_index() const { return stack_slot_index_; } |
147 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } | 222 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } |
148 | 223 |
149 virtual const char* ToCString() const { | 224 virtual const char* ToCString() const { |
150 return Isolate::Current()->current_zone()->PrintToString( | 225 return Isolate::Current()->current_zone()->PrintToString( |
151 "ms%" Pd "", stack_slot_index_); | 226 "ms%" Pd "", stack_slot_index_); |
152 } | 227 } |
153 | 228 |
154 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 229 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
155 intptr_t from_index = | 230 intptr_t from_index = |
156 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 231 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
157 int64_t* from_addr = reinterpret_cast<int64_t*>( | 232 int64_t* from_addr = reinterpret_cast<int64_t*>( |
158 deopt_context->GetFromFrameAddressAt(from_index)); | 233 deopt_context->GetFromFrameAddressAt(from_index)); |
159 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 234 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
160 if (Smi::IsValid64(*from_addr)) { | 235 if (Smi::IsValid64(*from_addr)) { |
161 *to_addr = reinterpret_cast<intptr_t>( | 236 *to_addr = reinterpret_cast<intptr_t>( |
162 Smi::New(static_cast<intptr_t>(*from_addr))); | 237 Smi::New(static_cast<intptr_t>(*from_addr))); |
163 } else { | 238 } else { |
164 Isolate::Current()->DeferMintMaterialization( | 239 deopt_context->DeferMintMaterialization( |
165 *from_addr, reinterpret_cast<RawMint**>(to_addr)); | 240 *from_addr, reinterpret_cast<RawMint**>(to_addr)); |
166 } | 241 } |
167 } | 242 } |
168 | 243 |
169 private: | 244 private: |
170 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 245 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
171 | 246 |
172 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); | 247 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); |
173 }; | 248 }; |
174 | 249 |
175 | 250 |
176 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { | 251 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { |
177 public: | 252 public: |
178 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) | 253 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) |
179 : stack_slot_index_(from_index) { | 254 : stack_slot_index_(from_index) { |
180 ASSERT(stack_slot_index_ >= 0); | 255 ASSERT(stack_slot_index_ >= 0); |
181 } | 256 } |
182 | 257 |
183 virtual intptr_t from_index() const { return stack_slot_index_; } | 258 virtual intptr_t from_index() const { return stack_slot_index_; } |
184 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } | 259 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } |
185 | 260 |
186 virtual const char* ToCString() const { | 261 virtual const char* ToCString() const { |
187 return Isolate::Current()->current_zone()->PrintToString( | 262 return Isolate::Current()->current_zone()->PrintToString( |
188 "f32x4s%" Pd "", stack_slot_index_); | 263 "f32x4s%" Pd "", stack_slot_index_); |
189 } | 264 } |
190 | 265 |
191 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 266 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
192 intptr_t from_index = | 267 intptr_t from_index = |
193 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 268 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
194 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( | 269 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
195 deopt_context->GetFromFrameAddressAt(from_index)); | 270 deopt_context->GetFromFrameAddressAt(from_index)); |
196 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 271 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
197 Isolate::Current()->DeferFloat32x4Materialization( | 272 deopt_context->DeferFloat32x4Materialization( |
198 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); | 273 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); |
199 } | 274 } |
200 | 275 |
201 private: | 276 private: |
202 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 277 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
203 | 278 |
204 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); | 279 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); |
205 }; | 280 }; |
206 | 281 |
207 | 282 |
208 class DeoptUint32x4StackSlotInstr : public DeoptInstr { | 283 class DeoptUint32x4StackSlotInstr : public DeoptInstr { |
209 public: | 284 public: |
210 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) | 285 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) |
211 : stack_slot_index_(from_index) { | 286 : stack_slot_index_(from_index) { |
212 ASSERT(stack_slot_index_ >= 0); | 287 ASSERT(stack_slot_index_ >= 0); |
213 } | 288 } |
214 | 289 |
215 virtual intptr_t from_index() const { return stack_slot_index_; } | 290 virtual intptr_t from_index() const { return stack_slot_index_; } |
216 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } | 291 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } |
217 | 292 |
218 virtual const char* ToCString() const { | 293 virtual const char* ToCString() const { |
219 return Isolate::Current()->current_zone()->PrintToString( | 294 return Isolate::Current()->current_zone()->PrintToString( |
220 "ui32x4s%" Pd "", stack_slot_index_); | 295 "ui32x4s%" Pd "", stack_slot_index_); |
221 } | 296 } |
222 | 297 |
223 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 298 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
224 intptr_t from_index = | 299 intptr_t from_index = |
225 deopt_context->from_frame_size() - stack_slot_index_ - 1; | 300 deopt_context->from_frame_size() - stack_slot_index_ - 1; |
226 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( | 301 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( |
227 deopt_context->GetFromFrameAddressAt(from_index)); | 302 deopt_context->GetFromFrameAddressAt(from_index)); |
228 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 303 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
229 Isolate::Current()->DeferUint32x4Materialization( | 304 deopt_context->DeferUint32x4Materialization( |
230 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); | 305 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); |
231 } | 306 } |
232 | 307 |
233 private: | 308 private: |
234 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. | 309 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
235 | 310 |
236 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); | 311 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); |
237 }; | 312 }; |
238 | 313 |
239 | 314 |
(...skipping 17 matching lines...) Expand all Loading... |
257 DeoptId::encode(deopt_id_); | 332 DeoptId::encode(deopt_id_); |
258 } | 333 } |
259 | 334 |
260 virtual DeoptInstr::Kind kind() const { return kRetAddress; } | 335 virtual DeoptInstr::Kind kind() const { return kRetAddress; } |
261 | 336 |
262 virtual const char* ToCString() const { | 337 virtual const char* ToCString() const { |
263 return Isolate::Current()->current_zone()->PrintToString( | 338 return Isolate::Current()->current_zone()->PrintToString( |
264 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); | 339 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); |
265 } | 340 } |
266 | 341 |
267 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 342 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
268 Function& function = Function::Handle(deopt_context->isolate()); | 343 Function& function = Function::Handle(deopt_context->isolate()); |
269 function ^= deopt_context->ObjectAt(object_table_index_); | 344 function ^= deopt_context->ObjectAt(object_table_index_); |
270 const Code& code = | 345 const Code& code = |
271 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 346 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
272 ASSERT(!code.IsNull()); | 347 ASSERT(!code.IsNull()); |
273 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, | 348 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, |
274 PcDescriptors::kDeopt); | 349 PcDescriptors::kDeopt); |
275 ASSERT(continue_at_pc != 0); | 350 ASSERT(continue_at_pc != 0); |
276 *to_addr = continue_at_pc; | 351 *to_addr = continue_at_pc; |
277 | 352 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 } | 386 } |
312 | 387 |
313 virtual intptr_t from_index() const { return object_table_index_; } | 388 virtual intptr_t from_index() const { return object_table_index_; } |
314 virtual DeoptInstr::Kind kind() const { return kConstant; } | 389 virtual DeoptInstr::Kind kind() const { return kConstant; } |
315 | 390 |
316 virtual const char* ToCString() const { | 391 virtual const char* ToCString() const { |
317 return Isolate::Current()->current_zone()->PrintToString( | 392 return Isolate::Current()->current_zone()->PrintToString( |
318 "const oti:%" Pd "", object_table_index_); | 393 "const oti:%" Pd "", object_table_index_); |
319 } | 394 } |
320 | 395 |
321 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 396 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
322 const Object& obj = Object::Handle( | 397 const Object& obj = Object::Handle( |
323 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); | 398 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); |
324 *reinterpret_cast<RawObject**>(to_addr) = obj.raw(); | 399 *reinterpret_cast<RawObject**>(to_addr) = obj.raw(); |
325 } | 400 } |
326 | 401 |
327 private: | 402 private: |
328 const intptr_t object_table_index_; | 403 const intptr_t object_table_index_; |
329 | 404 |
330 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); | 405 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); |
331 }; | 406 }; |
332 | 407 |
333 | 408 |
334 // Deoptimization instruction moving a CPU register. | 409 // Deoptimization instruction moving a CPU register. |
335 class DeoptRegisterInstr: public DeoptInstr { | 410 class DeoptRegisterInstr: public DeoptInstr { |
336 public: | 411 public: |
337 explicit DeoptRegisterInstr(intptr_t reg_as_int) | 412 explicit DeoptRegisterInstr(intptr_t reg_as_int) |
338 : reg_(static_cast<Register>(reg_as_int)) {} | 413 : reg_(static_cast<Register>(reg_as_int)) {} |
339 | 414 |
340 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 415 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
341 virtual DeoptInstr::Kind kind() const { return kRegister; } | 416 virtual DeoptInstr::Kind kind() const { return kRegister; } |
342 | 417 |
343 virtual const char* ToCString() const { | 418 virtual const char* ToCString() const { |
344 return Assembler::RegisterName(reg_); | 419 return Assembler::RegisterName(reg_); |
345 } | 420 } |
346 | 421 |
347 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 422 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
348 *to_addr = deopt_context->RegisterValue(reg_); | 423 *to_addr = deopt_context->RegisterValue(reg_); |
349 } | 424 } |
350 | 425 |
351 private: | 426 private: |
352 const Register reg_; | 427 const Register reg_; |
353 | 428 |
354 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); | 429 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); |
355 }; | 430 }; |
356 | 431 |
357 | 432 |
358 // Deoptimization instruction moving an XMM register. | 433 // Deoptimization instruction moving an XMM register. |
359 class DeoptFpuRegisterInstr: public DeoptInstr { | 434 class DeoptFpuRegisterInstr: public DeoptInstr { |
360 public: | 435 public: |
361 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) | 436 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) |
362 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 437 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
363 | 438 |
364 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 439 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
365 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } | 440 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } |
366 | 441 |
367 virtual const char* ToCString() const { | 442 virtual const char* ToCString() const { |
368 return Assembler::FpuRegisterName(reg_); | 443 return Assembler::FpuRegisterName(reg_); |
369 } | 444 } |
370 | 445 |
371 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 446 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
372 double value = deopt_context->FpuRegisterValue(reg_); | 447 double value = deopt_context->FpuRegisterValue(reg_); |
373 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 448 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
374 Isolate::Current()->DeferDoubleMaterialization( | 449 deopt_context->DeferDoubleMaterialization( |
375 value, reinterpret_cast<RawDouble**>(to_addr)); | 450 value, reinterpret_cast<RawDouble**>(to_addr)); |
376 } | 451 } |
377 | 452 |
378 private: | 453 private: |
379 const FpuRegister reg_; | 454 const FpuRegister reg_; |
380 | 455 |
381 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); | 456 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); |
382 }; | 457 }; |
383 | 458 |
384 | 459 |
385 class DeoptInt64FpuRegisterInstr: public DeoptInstr { | 460 class DeoptInt64FpuRegisterInstr: public DeoptInstr { |
386 public: | 461 public: |
387 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) | 462 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) |
388 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 463 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
389 | 464 |
390 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 465 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
391 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } | 466 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } |
392 | 467 |
393 virtual const char* ToCString() const { | 468 virtual const char* ToCString() const { |
394 return Isolate::Current()->current_zone()->PrintToString( | 469 return Isolate::Current()->current_zone()->PrintToString( |
395 "%s(m)", Assembler::FpuRegisterName(reg_)); | 470 "%s(m)", Assembler::FpuRegisterName(reg_)); |
396 } | 471 } |
397 | 472 |
398 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 473 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
399 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); | 474 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); |
400 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 475 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
401 if (Smi::IsValid64(value)) { | 476 if (Smi::IsValid64(value)) { |
402 *to_addr = reinterpret_cast<intptr_t>( | 477 *to_addr = reinterpret_cast<intptr_t>( |
403 Smi::New(static_cast<intptr_t>(value))); | 478 Smi::New(static_cast<intptr_t>(value))); |
404 } else { | 479 } else { |
405 Isolate::Current()->DeferMintMaterialization( | 480 deopt_context->DeferMintMaterialization( |
406 value, reinterpret_cast<RawMint**>(to_addr)); | 481 value, reinterpret_cast<RawMint**>(to_addr)); |
407 } | 482 } |
408 } | 483 } |
409 | 484 |
410 private: | 485 private: |
411 const FpuRegister reg_; | 486 const FpuRegister reg_; |
412 | 487 |
413 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); | 488 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); |
414 }; | 489 }; |
415 | 490 |
416 | 491 |
417 // Deoptimization instruction moving an XMM register. | 492 // Deoptimization instruction moving an XMM register. |
418 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { | 493 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
419 public: | 494 public: |
420 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) | 495 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) |
421 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 496 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
422 | 497 |
423 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 498 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
424 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } | 499 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } |
425 | 500 |
426 virtual const char* ToCString() const { | 501 virtual const char* ToCString() const { |
427 return Isolate::Current()->current_zone()->PrintToString( | 502 return Isolate::Current()->current_zone()->PrintToString( |
428 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); | 503 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); |
429 } | 504 } |
430 | 505 |
431 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 506 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
432 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); | 507 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
433 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 508 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
434 Isolate::Current()->DeferFloat32x4Materialization( | 509 deopt_context->DeferFloat32x4Materialization( |
435 value, reinterpret_cast<RawFloat32x4**>(to_addr)); | 510 value, reinterpret_cast<RawFloat32x4**>(to_addr)); |
436 } | 511 } |
437 | 512 |
438 private: | 513 private: |
439 const FpuRegister reg_; | 514 const FpuRegister reg_; |
440 | 515 |
441 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); | 516 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); |
442 }; | 517 }; |
443 | 518 |
444 | 519 |
445 // Deoptimization instruction moving an XMM register. | 520 // Deoptimization instruction moving an XMM register. |
446 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { | 521 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { |
447 public: | 522 public: |
448 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) | 523 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) |
449 : reg_(static_cast<FpuRegister>(reg_as_int)) {} | 524 : reg_(static_cast<FpuRegister>(reg_as_int)) {} |
450 | 525 |
451 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } | 526 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
452 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } | 527 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } |
453 | 528 |
454 virtual const char* ToCString() const { | 529 virtual const char* ToCString() const { |
455 return Isolate::Current()->current_zone()->PrintToString( | 530 return Isolate::Current()->current_zone()->PrintToString( |
456 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); | 531 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); |
457 } | 532 } |
458 | 533 |
459 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 534 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
460 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); | 535 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); |
461 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 536 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
462 Isolate::Current()->DeferUint32x4Materialization( | 537 deopt_context->DeferUint32x4Materialization( |
463 value, reinterpret_cast<RawUint32x4**>(to_addr)); | 538 value, reinterpret_cast<RawUint32x4**>(to_addr)); |
464 } | 539 } |
465 | 540 |
466 private: | 541 private: |
467 const FpuRegister reg_; | 542 const FpuRegister reg_; |
468 | 543 |
469 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); | 544 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); |
470 }; | 545 }; |
471 | 546 |
472 | 547 |
473 // Deoptimization instruction creating a PC marker for the code of | 548 // Deoptimization instruction creating a PC marker for the code of |
474 // function at 'object_table_index'. | 549 // function at 'object_table_index'. |
475 class DeoptPcMarkerInstr : public DeoptInstr { | 550 class DeoptPcMarkerInstr : public DeoptInstr { |
476 public: | 551 public: |
477 explicit DeoptPcMarkerInstr(intptr_t object_table_index) | 552 explicit DeoptPcMarkerInstr(intptr_t object_table_index) |
478 : object_table_index_(object_table_index) { | 553 : object_table_index_(object_table_index) { |
479 ASSERT(object_table_index >= 0); | 554 ASSERT(object_table_index >= 0); |
480 } | 555 } |
481 | 556 |
482 virtual intptr_t from_index() const { return object_table_index_; } | 557 virtual intptr_t from_index() const { return object_table_index_; } |
483 virtual DeoptInstr::Kind kind() const { return kPcMarker; } | 558 virtual DeoptInstr::Kind kind() const { return kPcMarker; } |
484 | 559 |
485 virtual const char* ToCString() const { | 560 virtual const char* ToCString() const { |
486 return Isolate::Current()->current_zone()->PrintToString( | 561 return Isolate::Current()->current_zone()->PrintToString( |
487 "pcmark oti:%" Pd "", object_table_index_); | 562 "pcmark oti:%" Pd "", object_table_index_); |
488 } | 563 } |
489 | 564 |
490 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 565 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
491 Function& function = Function::Handle(deopt_context->isolate()); | 566 Function& function = Function::Handle(deopt_context->isolate()); |
492 function ^= deopt_context->ObjectAt(object_table_index_); | 567 function ^= deopt_context->ObjectAt(object_table_index_); |
493 if (function.IsNull()) { | 568 if (function.IsNull()) { |
494 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. | 569 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. |
495 *to_addr = 0; | 570 *to_addr = 0; |
496 return; | 571 return; |
497 } | 572 } |
498 const Code& code = | 573 const Code& code = |
499 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 574 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
500 ASSERT(!code.IsNull()); | 575 ASSERT(!code.IsNull()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 } | 607 } |
533 | 608 |
534 virtual intptr_t from_index() const { return object_table_index_; } | 609 virtual intptr_t from_index() const { return object_table_index_; } |
535 virtual DeoptInstr::Kind kind() const { return kPp; } | 610 virtual DeoptInstr::Kind kind() const { return kPp; } |
536 | 611 |
537 virtual const char* ToCString() const { | 612 virtual const char* ToCString() const { |
538 return Isolate::Current()->current_zone()->PrintToString( | 613 return Isolate::Current()->current_zone()->PrintToString( |
539 "pp oti:%" Pd "", object_table_index_); | 614 "pp oti:%" Pd "", object_table_index_); |
540 } | 615 } |
541 | 616 |
542 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 617 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
543 Function& function = Function::Handle(deopt_context->isolate()); | 618 Function& function = Function::Handle(deopt_context->isolate()); |
544 function ^= deopt_context->ObjectAt(object_table_index_); | 619 function ^= deopt_context->ObjectAt(object_table_index_); |
545 const Code& code = | 620 const Code& code = |
546 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 621 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
547 ASSERT(!code.IsNull()); | 622 ASSERT(!code.IsNull()); |
548 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); | 623 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); |
549 *to_addr = pp; | 624 *to_addr = pp; |
550 } | 625 } |
551 | 626 |
552 private: | 627 private: |
553 intptr_t object_table_index_; | 628 intptr_t object_table_index_; |
554 | 629 |
555 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); | 630 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); |
556 }; | 631 }; |
557 | 632 |
558 | 633 |
559 // Deoptimization instruction copying the caller saved FP from optimized frame. | 634 // Deoptimization instruction copying the caller saved FP from optimized frame. |
560 class DeoptCallerFpInstr : public DeoptInstr { | 635 class DeoptCallerFpInstr : public DeoptInstr { |
561 public: | 636 public: |
562 DeoptCallerFpInstr() {} | 637 DeoptCallerFpInstr() {} |
563 | 638 |
564 virtual intptr_t from_index() const { return 0; } | 639 virtual intptr_t from_index() const { return 0; } |
565 virtual DeoptInstr::Kind kind() const { return kCallerFp; } | 640 virtual DeoptInstr::Kind kind() const { return kCallerFp; } |
566 | 641 |
567 virtual const char* ToCString() const { | 642 virtual const char* ToCString() const { |
568 return "callerfp"; | 643 return "callerfp"; |
569 } | 644 } |
570 | 645 |
571 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 646 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
572 *to_addr = deopt_context->GetCallerFp(); | 647 *to_addr = deopt_context->GetCallerFp(); |
573 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( | 648 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( |
574 to_addr - (kSavedCallerFpSlotFromFp * kWordSize))); | 649 to_addr - (kSavedCallerFpSlotFromFp * kWordSize))); |
575 } | 650 } |
576 | 651 |
577 private: | 652 private: |
578 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); | 653 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); |
579 }; | 654 }; |
580 | 655 |
581 | 656 |
582 // Deoptimization instruction copying the caller saved PP from optimized frame. | 657 // Deoptimization instruction copying the caller saved PP from optimized frame. |
583 class DeoptCallerPpInstr : public DeoptInstr { | 658 class DeoptCallerPpInstr : public DeoptInstr { |
584 public: | 659 public: |
585 DeoptCallerPpInstr() {} | 660 DeoptCallerPpInstr() {} |
586 | 661 |
587 virtual intptr_t from_index() const { return 0; } | 662 virtual intptr_t from_index() const { return 0; } |
588 virtual DeoptInstr::Kind kind() const { return kCallerPp; } | 663 virtual DeoptInstr::Kind kind() const { return kCallerPp; } |
589 | 664 |
590 virtual const char* ToCString() const { | 665 virtual const char* ToCString() const { |
591 return "callerpp"; | 666 return "callerpp"; |
592 } | 667 } |
593 | 668 |
594 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 669 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
595 *to_addr = deopt_context->GetFromPp(); | 670 *to_addr = deopt_context->GetFromPp(); |
596 } | 671 } |
597 | 672 |
598 private: | 673 private: |
599 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); | 674 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); |
600 }; | 675 }; |
601 | 676 |
602 | 677 |
603 // Deoptimization instruction copying the caller return address from optimized | 678 // Deoptimization instruction copying the caller return address from optimized |
604 // frame. | 679 // frame. |
605 class DeoptCallerPcInstr : public DeoptInstr { | 680 class DeoptCallerPcInstr : public DeoptInstr { |
606 public: | 681 public: |
607 DeoptCallerPcInstr() {} | 682 DeoptCallerPcInstr() {} |
608 | 683 |
609 virtual intptr_t from_index() const { return 0; } | 684 virtual intptr_t from_index() const { return 0; } |
610 virtual DeoptInstr::Kind kind() const { return kCallerPc; } | 685 virtual DeoptInstr::Kind kind() const { return kCallerPc; } |
611 | 686 |
612 virtual const char* ToCString() const { | 687 virtual const char* ToCString() const { |
613 return "callerpc"; | 688 return "callerpc"; |
614 } | 689 } |
615 | 690 |
616 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 691 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
617 *to_addr = deopt_context->GetFromPc(); | 692 *to_addr = deopt_context->GetFromPc(); |
618 } | 693 } |
619 | 694 |
620 private: | 695 private: |
621 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); | 696 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); |
622 }; | 697 }; |
623 | 698 |
624 | 699 |
625 // Deoptimization instruction that indicates the rest of this DeoptInfo is a | 700 // Deoptimization instruction that indicates the rest of this DeoptInfo is a |
626 // suffix of another one. The suffix contains the info number (0 based | 701 // suffix of another one. The suffix contains the info number (0 based |
(...skipping 16 matching lines...) Expand all Loading... |
643 return InfoNumber::encode(info_number_) | | 718 return InfoNumber::encode(info_number_) | |
644 SuffixLength::encode(suffix_length_); | 719 SuffixLength::encode(suffix_length_); |
645 } | 720 } |
646 virtual DeoptInstr::Kind kind() const { return kSuffix; } | 721 virtual DeoptInstr::Kind kind() const { return kSuffix; } |
647 | 722 |
648 virtual const char* ToCString() const { | 723 virtual const char* ToCString() const { |
649 return Isolate::Current()->current_zone()->PrintToString( | 724 return Isolate::Current()->current_zone()->PrintToString( |
650 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); | 725 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); |
651 } | 726 } |
652 | 727 |
653 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 728 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
654 // The deoptimization info is uncompressed by translating away suffixes | 729 // The deoptimization info is uncompressed by translating away suffixes |
655 // before executing the instructions. | 730 // before executing the instructions. |
656 UNREACHABLE(); | 731 UNREACHABLE(); |
657 } | 732 } |
658 | 733 |
659 private: | 734 private: |
660 // Static decoder functions in DeoptInstr have access to the bitfield | 735 // Static decoder functions in DeoptInstr have access to the bitfield |
661 // definitions. | 736 // definitions. |
662 friend class DeoptInstr; | 737 friend class DeoptInstr; |
663 | 738 |
(...skipping 18 matching lines...) Expand all Loading... |
682 } | 757 } |
683 | 758 |
684 virtual intptr_t from_index() const { return index_; } | 759 virtual intptr_t from_index() const { return index_; } |
685 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } | 760 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } |
686 | 761 |
687 virtual const char* ToCString() const { | 762 virtual const char* ToCString() const { |
688 return Isolate::Current()->current_zone()->PrintToString( | 763 return Isolate::Current()->current_zone()->PrintToString( |
689 "mat ref #%" Pd "", index_); | 764 "mat ref #%" Pd "", index_); |
690 } | 765 } |
691 | 766 |
692 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 767 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
693 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); | 768 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
694 Isolate::Current()->DeferMaterializedObjectRef( | 769 deopt_context->DeferMaterializedObjectRef( |
695 index_, to_addr); | 770 index_, to_addr); |
696 } | 771 } |
697 | 772 |
698 private: | 773 private: |
699 intptr_t index_; | 774 intptr_t index_; |
700 | 775 |
701 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); | 776 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); |
702 }; | 777 }; |
703 | 778 |
704 | 779 |
705 // Materialize object with the given number of fields. | 780 // Materialize object with the given number of fields. |
706 // Arguments for materialization (class and field-value pairs) are pushed | 781 // Arguments for materialization (class and field-value pairs) are pushed |
707 // to the expression stack of the bottom-most frame. | 782 // to the expression stack of the bottom-most frame. |
708 class DeoptMaterializeObjectInstr : public DeoptInstr { | 783 class DeoptMaterializeObjectInstr : public DeoptInstr { |
709 public: | 784 public: |
710 explicit DeoptMaterializeObjectInstr(intptr_t field_count) | 785 explicit DeoptMaterializeObjectInstr(intptr_t field_count) |
711 : field_count_(field_count) { | 786 : field_count_(field_count) { |
712 ASSERT(field_count >= 0); | 787 ASSERT(field_count >= 0); |
713 } | 788 } |
714 | 789 |
715 virtual intptr_t from_index() const { return field_count_; } | 790 virtual intptr_t from_index() const { return field_count_; } |
716 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } | 791 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } |
717 | 792 |
718 virtual const char* ToCString() const { | 793 virtual const char* ToCString() const { |
719 return Isolate::Current()->current_zone()->PrintToString( | 794 return Isolate::Current()->current_zone()->PrintToString( |
720 "mat obj len:%" Pd "", field_count_); | 795 "mat obj len:%" Pd "", field_count_); |
721 } | 796 } |
722 | 797 |
723 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { | 798 void Execute(DeoptContext* deopt_context, intptr_t* to_addr) { |
724 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. | 799 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. |
725 UNREACHABLE(); | 800 UNREACHABLE(); |
726 } | 801 } |
727 | 802 |
728 private: | 803 private: |
729 intptr_t field_count_; | 804 intptr_t field_count_; |
730 | 805 |
731 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); | 806 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); |
732 }; | 807 }; |
733 | 808 |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 Smi* offset, | 1177 Smi* offset, |
1103 DeoptInfo* info, | 1178 DeoptInfo* info, |
1104 Smi* reason) { | 1179 Smi* reason) { |
1105 intptr_t i = index * kEntrySize; | 1180 intptr_t i = index * kEntrySize; |
1106 *offset ^= table.At(i); | 1181 *offset ^= table.At(i); |
1107 *info ^= table.At(i + 1); | 1182 *info ^= table.At(i + 1); |
1108 *reason ^= table.At(i + 2); | 1183 *reason ^= table.At(i + 2); |
1109 } | 1184 } |
1110 | 1185 |
1111 } // namespace dart | 1186 } // namespace dart |
OLD | NEW |