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

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

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/deopt_instructions.h ('k') | runtime/vm/isolate.h » ('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 #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 dest_frame_(NULL),
26 : object_table_(object_table), 26 dest_frame_size_(0),
27 to_frame_(to_frame_start), 27 source_frame_is_copy_(false),
28 to_frame_size_(to_frame_size), 28 source_frame_(NULL),
29 from_frame_(NULL), 29 source_frame_size_(0),
30 from_frame_size_(0), 30 cpu_registers_(NULL),
31 registers_copy_(NULL), 31 fpu_registers_(NULL),
32 fpu_registers_copy_(NULL),
33 num_args_(num_args), 32 num_args_(num_args),
34 deopt_reason_(deopt_reason), 33 deopt_reason_(deopt_reason),
35 isolate_(Isolate::Current()) { 34 isolate_(Isolate::Current()),
36 from_frame_ = isolate_->deopt_frame_copy(); 35 deferred_boxes_(NULL),
37 from_frame_size_ = isolate_->deopt_frame_copy_size(); 36 deferred_object_refs_(NULL),
38 registers_copy_ = isolate_->deopt_cpu_registers_copy(); 37 deferred_objects_count_(0),
39 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy(); 38 deferred_objects_(NULL) {
40 // The deoptimized frame is filled starting just below the sp of its caller
41 // down to kDartFrameFixedSize words below its own sp.
42 // The chain of frame pointers is recreated from the fp of the caller.
43 caller_fp_ = GetFromFp();
44 } 39 }
45 40
46 41
47 intptr_t DeoptimizationContext::GetFromFp() const { 42 DeoptContext::~DeoptContext() {
48 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp]; 43 // Delete memory for source frame and registers.
44 if (source_frame_is_copy_) {
45 delete[] source_frame_;
46 }
47 source_frame_ = NULL;
48 delete[] fpu_registers_;
49 delete[] cpu_registers_;
50 fpu_registers_ = NULL;
51 cpu_registers_ = NULL;
52
53 // Delete all deferred objects.
54 for (intptr_t i = 0; i < deferred_objects_count_; i++) {
55 delete deferred_objects_[i];
56 }
57 delete[] deferred_objects_;
58 deferred_objects_ = NULL;
59 deferred_objects_count_ = 0;
49 } 60 }
50 61
51 62
52 intptr_t DeoptimizationContext::GetFromPp() const { 63 void DeoptContext::SetSourceArgs(intptr_t* frame_start,
53 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp + 64 intptr_t frame_size,
54 StackFrame::SavedCallerPpSlotFromFp()]; 65 fpu_register_t* fpu_registers,
66 intptr_t* cpu_registers,
67 bool source_frame_is_copy) {
68 ASSERT(frame_start != NULL);
69 ASSERT(frame_size >= 0);
70 ASSERT(source_frame_ == NULL);
71 ASSERT(cpu_registers_ == NULL && fpu_registers_ == NULL);
72 source_frame_ = frame_start;
73 source_frame_size_ = frame_size;
74 caller_fp_ = GetSourceFp();
75 cpu_registers_ = cpu_registers;
76 fpu_registers_ = fpu_registers;
77 source_frame_is_copy_ = source_frame_is_copy;
55 } 78 }
56 79
57 80
58 intptr_t DeoptimizationContext::GetFromPc() const { 81 void DeoptContext::SetDestArgs(intptr_t* frame_start,
59 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; 82 intptr_t frame_size) {
83 ASSERT(frame_start != NULL);
84 ASSERT(frame_size >= 0);
85 ASSERT(dest_frame_ == NULL);
86 dest_frame_ = frame_start;
87 dest_frame_size_ = frame_size;
60 } 88 }
61 89
62 90
63 intptr_t DeoptimizationContext::GetCallerFp() const { 91 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
92 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_table_));
93 }
94
95
96 intptr_t DeoptContext::GetSourceFp() const {
97 return source_frame_[source_frame_size_ - 1 - num_args_ -
98 kParamEndSlotFromFp];
99 }
100
101
102 intptr_t DeoptContext::GetSourcePp() const {
103 return source_frame_[source_frame_size_ - 1 - num_args_ -
104 kParamEndSlotFromFp +
105 StackFrame::SavedCallerPpSlotFromFp()];
106 }
107
108
109 intptr_t DeoptContext::GetSourcePc() const {
110 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
111 }
112
113
114 intptr_t DeoptContext::GetCallerFp() const {
64 return caller_fp_; 115 return caller_fp_;
65 } 116 }
66 117
67 118
68 void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) { 119 void DeoptContext::SetCallerFp(intptr_t caller_fp) {
69 caller_fp_ = caller_fp; 120 caller_fp_ = caller_fp;
70 } 121 }
71 122
72 123
124 static void FillDeferredSlots(DeferredSlot** slot_list) {
125 DeferredSlot* slot = *slot_list;
126 *slot_list = NULL;
127
128 while (slot != NULL) {
129 DeferredSlot* current = slot;
130 slot = slot->next();
131
132 current->Materialize();
133
134 delete current;
135 }
136 }
137
138
139 // Materializes all deferred objects. Returns the total number of
140 // artificial arguments used during deoptimization.
141 intptr_t DeoptContext::MaterializeDeferredObjects() {
142 // First materialize all unboxed "primitive" values (doubles, mints, simd)
143 // then materialize objects. The order is important: objects might be
144 // referencing boxes allocated on the first step. At the same time
145 // objects can't be referencing other deferred objects because storing
146 // an object into a field is always conservatively treated as escaping by
147 // allocation sinking and load forwarding.
148 FillDeferredSlots(&deferred_boxes_);
149 FillDeferredSlots(&deferred_object_refs_);
150
151 // Compute total number of artificial arguments used during deoptimization.
152 intptr_t deopt_arguments = 0;
153 for (intptr_t i = 0; i < DeferredObjectsCount(); i++) {
154 deopt_arguments += GetDeferredObject(i)->ArgumentCount();
155 }
156 return deopt_arguments;
157 }
158
159
73 // Deoptimization instruction moving value from optimized frame at 160 // Deoptimization instruction moving value from optimized frame at
74 // 'from_index' to specified slots in the unoptimized frame. 161 // 'source_index' to specified slots in the unoptimized frame.
75 // 'from_index' represents the slot index of the frame (0 being first argument) 162 // 'source_index' represents the slot index of the frame (0 being
76 // and accounts for saved return address, frame pointer, pool pointer and pc 163 // first argument) and accounts for saved return address, frame
77 // marker. 164 // pointer, pool pointer and pc marker.
78 class DeoptStackSlotInstr : public DeoptInstr { 165 class DeoptStackSlotInstr : public DeoptInstr {
79 public: 166 public:
80 explicit DeoptStackSlotInstr(intptr_t from_index) 167 explicit DeoptStackSlotInstr(intptr_t source_index)
81 : stack_slot_index_(from_index) { 168 : stack_slot_index_(source_index) {
82 ASSERT(stack_slot_index_ >= 0); 169 ASSERT(stack_slot_index_ >= 0);
83 } 170 }
84 171
85 virtual intptr_t from_index() const { return stack_slot_index_; } 172 virtual intptr_t source_index() const { return stack_slot_index_; }
86 virtual DeoptInstr::Kind kind() const { return kStackSlot; } 173 virtual DeoptInstr::Kind kind() const { return kStackSlot; }
87 174
88 virtual const char* ToCString() const { 175 virtual const char* ToCString() const {
89 return Isolate::Current()->current_zone()->PrintToString( 176 return Isolate::Current()->current_zone()->PrintToString(
90 "s%" Pd "", stack_slot_index_); 177 "s%" Pd "", stack_slot_index_);
91 } 178 }
92 179
93 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 180 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
94 intptr_t from_index = 181 intptr_t source_index =
95 deopt_context->from_frame_size() - stack_slot_index_ - 1; 182 deopt_context->source_frame_size() - stack_slot_index_ - 1;
96 intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index); 183 intptr_t* source_addr =
97 *to_addr = *from_addr; 184 deopt_context->GetSourceFrameAddressAt(source_index);
185 *dest_addr = *source_addr;
98 } 186 }
99 187
100 private: 188 private:
101 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 189 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
102 190
103 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr); 191 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr);
104 }; 192 };
105 193
106 194
107 class DeoptDoubleStackSlotInstr : public DeoptInstr { 195 class DeoptDoubleStackSlotInstr : public DeoptInstr {
108 public: 196 public:
109 explicit DeoptDoubleStackSlotInstr(intptr_t from_index) 197 explicit DeoptDoubleStackSlotInstr(intptr_t source_index)
110 : stack_slot_index_(from_index) { 198 : stack_slot_index_(source_index) {
111 ASSERT(stack_slot_index_ >= 0); 199 ASSERT(stack_slot_index_ >= 0);
112 } 200 }
113 201
114 virtual intptr_t from_index() const { return stack_slot_index_; } 202 virtual intptr_t source_index() const { return stack_slot_index_; }
115 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; } 203 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; }
116 204
117 virtual const char* ToCString() const { 205 virtual const char* ToCString() const {
118 return Isolate::Current()->current_zone()->PrintToString( 206 return Isolate::Current()->current_zone()->PrintToString(
119 "ds%" Pd "", stack_slot_index_); 207 "ds%" Pd "", stack_slot_index_);
120 } 208 }
121 209
122 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 210 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
123 intptr_t from_index = 211 intptr_t source_index =
124 deopt_context->from_frame_size() - stack_slot_index_ - 1; 212 deopt_context->source_frame_size() - stack_slot_index_ - 1;
125 double* from_addr = reinterpret_cast<double*>( 213 double* source_addr = reinterpret_cast<double*>(
126 deopt_context->GetFromFrameAddressAt(from_index)); 214 deopt_context->GetSourceFrameAddressAt(source_index));
127 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 215 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
128 Isolate::Current()->DeferDoubleMaterialization( 216 deopt_context->DeferDoubleMaterialization(
129 *from_addr, reinterpret_cast<RawDouble**>(to_addr)); 217 *source_addr, reinterpret_cast<RawDouble**>(dest_addr));
130 } 218 }
131 219
132 private: 220 private:
133 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 221 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
134 222
135 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr); 223 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr);
136 }; 224 };
137 225
138 226
139 class DeoptInt64StackSlotInstr : public DeoptInstr { 227 class DeoptInt64StackSlotInstr : public DeoptInstr {
140 public: 228 public:
141 explicit DeoptInt64StackSlotInstr(intptr_t from_index) 229 explicit DeoptInt64StackSlotInstr(intptr_t source_index)
142 : stack_slot_index_(from_index) { 230 : stack_slot_index_(source_index) {
143 ASSERT(stack_slot_index_ >= 0); 231 ASSERT(stack_slot_index_ >= 0);
144 } 232 }
145 233
146 virtual intptr_t from_index() const { return stack_slot_index_; } 234 virtual intptr_t source_index() const { return stack_slot_index_; }
147 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; } 235 virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; }
148 236
149 virtual const char* ToCString() const { 237 virtual const char* ToCString() const {
150 return Isolate::Current()->current_zone()->PrintToString( 238 return Isolate::Current()->current_zone()->PrintToString(
151 "ms%" Pd "", stack_slot_index_); 239 "ms%" Pd "", stack_slot_index_);
152 } 240 }
153 241
154 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 242 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
155 intptr_t from_index = 243 intptr_t source_index =
156 deopt_context->from_frame_size() - stack_slot_index_ - 1; 244 deopt_context->source_frame_size() - stack_slot_index_ - 1;
157 int64_t* from_addr = reinterpret_cast<int64_t*>( 245 int64_t* source_addr = reinterpret_cast<int64_t*>(
158 deopt_context->GetFromFrameAddressAt(from_index)); 246 deopt_context->GetSourceFrameAddressAt(source_index));
159 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 247 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
160 if (Smi::IsValid64(*from_addr)) { 248 if (Smi::IsValid64(*source_addr)) {
161 *to_addr = reinterpret_cast<intptr_t>( 249 *dest_addr = reinterpret_cast<intptr_t>(
162 Smi::New(static_cast<intptr_t>(*from_addr))); 250 Smi::New(static_cast<intptr_t>(*source_addr)));
163 } else { 251 } else {
164 Isolate::Current()->DeferMintMaterialization( 252 deopt_context->DeferMintMaterialization(
165 *from_addr, reinterpret_cast<RawMint**>(to_addr)); 253 *source_addr, reinterpret_cast<RawMint**>(dest_addr));
166 } 254 }
167 } 255 }
168 256
169 private: 257 private:
170 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 258 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
171 259
172 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); 260 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr);
173 }; 261 };
174 262
175 263
176 class DeoptFloat32x4StackSlotInstr : public DeoptInstr { 264 class DeoptFloat32x4StackSlotInstr : public DeoptInstr {
177 public: 265 public:
178 explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index) 266 explicit DeoptFloat32x4StackSlotInstr(intptr_t source_index)
179 : stack_slot_index_(from_index) { 267 : stack_slot_index_(source_index) {
180 ASSERT(stack_slot_index_ >= 0); 268 ASSERT(stack_slot_index_ >= 0);
181 } 269 }
182 270
183 virtual intptr_t from_index() const { return stack_slot_index_; } 271 virtual intptr_t source_index() const { return stack_slot_index_; }
184 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; } 272 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; }
185 273
186 virtual const char* ToCString() const { 274 virtual const char* ToCString() const {
187 return Isolate::Current()->current_zone()->PrintToString( 275 return Isolate::Current()->current_zone()->PrintToString(
188 "f32x4s%" Pd "", stack_slot_index_); 276 "f32x4s%" Pd "", stack_slot_index_);
189 } 277 }
190 278
191 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 279 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
192 intptr_t from_index = 280 intptr_t source_index =
193 deopt_context->from_frame_size() - stack_slot_index_ - 1; 281 deopt_context->source_frame_size() - stack_slot_index_ - 1;
194 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( 282 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
195 deopt_context->GetFromFrameAddressAt(from_index)); 283 deopt_context->GetSourceFrameAddressAt(source_index));
196 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 284 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
197 Isolate::Current()->DeferFloat32x4Materialization( 285 deopt_context->DeferFloat32x4Materialization(
198 *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr)); 286 *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr));
199 } 287 }
200 288
201 private: 289 private:
202 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 290 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
203 291
204 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr); 292 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr);
205 }; 293 };
206 294
207 295
208 class DeoptUint32x4StackSlotInstr : public DeoptInstr { 296 class DeoptUint32x4StackSlotInstr : public DeoptInstr {
209 public: 297 public:
210 explicit DeoptUint32x4StackSlotInstr(intptr_t from_index) 298 explicit DeoptUint32x4StackSlotInstr(intptr_t source_index)
211 : stack_slot_index_(from_index) { 299 : stack_slot_index_(source_index) {
212 ASSERT(stack_slot_index_ >= 0); 300 ASSERT(stack_slot_index_ >= 0);
213 } 301 }
214 302
215 virtual intptr_t from_index() const { return stack_slot_index_; } 303 virtual intptr_t source_index() const { return stack_slot_index_; }
216 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; } 304 virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; }
217 305
218 virtual const char* ToCString() const { 306 virtual const char* ToCString() const {
219 return Isolate::Current()->current_zone()->PrintToString( 307 return Isolate::Current()->current_zone()->PrintToString(
220 "ui32x4s%" Pd "", stack_slot_index_); 308 "ui32x4s%" Pd "", stack_slot_index_);
221 } 309 }
222 310
223 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 311 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
224 intptr_t from_index = 312 intptr_t source_index =
225 deopt_context->from_frame_size() - stack_slot_index_ - 1; 313 deopt_context->source_frame_size() - stack_slot_index_ - 1;
226 simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>( 314 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
227 deopt_context->GetFromFrameAddressAt(from_index)); 315 deopt_context->GetSourceFrameAddressAt(source_index));
228 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 316 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
229 Isolate::Current()->DeferUint32x4Materialization( 317 deopt_context->DeferUint32x4Materialization(
230 *from_addr, reinterpret_cast<RawUint32x4**>(to_addr)); 318 *source_addr, reinterpret_cast<RawUint32x4**>(dest_addr));
231 } 319 }
232 320
233 private: 321 private:
234 const intptr_t stack_slot_index_; // First argument is 0, always >= 0. 322 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
235 323
236 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr); 324 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4StackSlotInstr);
237 }; 325 };
238 326
239 327
240 // Deoptimization instruction creating return address using function and 328 // Deoptimization instruction creating return address using function and
241 // deopt-id stored at 'object_table_index'. 329 // deopt-id stored at 'object_table_index'.
242 class DeoptRetAddressInstr : public DeoptInstr { 330 class DeoptRetAddressInstr : public DeoptInstr {
243 public: 331 public:
244 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) 332 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id)
245 : object_table_index_(object_table_index), deopt_id_(deopt_id) { 333 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
246 ASSERT(object_table_index >= 0); 334 ASSERT(object_table_index >= 0);
247 ASSERT(deopt_id >= 0); 335 ASSERT(deopt_id >= 0);
248 } 336 }
249 337
250 explicit DeoptRetAddressInstr(intptr_t from_index) 338 explicit DeoptRetAddressInstr(intptr_t source_index)
251 : object_table_index_(ObjectTableIndex::decode(from_index)), 339 : object_table_index_(ObjectTableIndex::decode(source_index)),
252 deopt_id_(DeoptId::decode(from_index)) { 340 deopt_id_(DeoptId::decode(source_index)) {
253 } 341 }
254 342
255 virtual intptr_t from_index() const { 343 virtual intptr_t source_index() const {
256 return ObjectTableIndex::encode(object_table_index_) | 344 return ObjectTableIndex::encode(object_table_index_) |
257 DeoptId::encode(deopt_id_); 345 DeoptId::encode(deopt_id_);
258 } 346 }
259 347
260 virtual DeoptInstr::Kind kind() const { return kRetAddress; } 348 virtual DeoptInstr::Kind kind() const { return kRetAddress; }
261 349
262 virtual const char* ToCString() const { 350 virtual const char* ToCString() const {
263 return Isolate::Current()->current_zone()->PrintToString( 351 return Isolate::Current()->current_zone()->PrintToString(
264 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); 352 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_);
265 } 353 }
266 354
267 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 355 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
268 Function& function = Function::Handle(deopt_context->isolate()); 356 Function& function = Function::Handle(deopt_context->isolate());
269 function ^= deopt_context->ObjectAt(object_table_index_); 357 function ^= deopt_context->ObjectAt(object_table_index_);
270 const Code& code = 358 const Code& code =
271 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 359 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
272 ASSERT(!code.IsNull()); 360 ASSERT(!code.IsNull());
273 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, 361 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
274 PcDescriptors::kDeopt); 362 PcDescriptors::kDeopt);
275 ASSERT(continue_at_pc != 0); 363 ASSERT(continue_at_pc != 0);
276 *to_addr = continue_at_pc; 364 *dest_addr = continue_at_pc;
277 365
278 uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall); 366 uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall);
279 if (pc != 0) { 367 if (pc != 0) {
280 // If the deoptimization happened at an IC call, update the IC data 368 // If the deoptimization happened at an IC call, update the IC data
281 // to avoid repeated deoptimization at the same site next time around. 369 // to avoid repeated deoptimization at the same site next time around.
282 ICData& ic_data = ICData::Handle(); 370 ICData& ic_data = ICData::Handle();
283 CodePatcher::GetInstanceCallAt(pc, code, &ic_data); 371 CodePatcher::GetInstanceCallAt(pc, code, &ic_data);
284 if (!ic_data.IsNull()) { 372 if (!ic_data.IsNull()) {
285 ic_data.set_deopt_reason(deopt_context->deopt_reason()); 373 ic_data.set_deopt_reason(deopt_context->deopt_reason());
286 } 374 }
(...skipping 16 matching lines...) Expand all
303 391
304 392
305 // Deoptimization instruction moving a constant stored at 'object_table_index'. 393 // Deoptimization instruction moving a constant stored at 'object_table_index'.
306 class DeoptConstantInstr : public DeoptInstr { 394 class DeoptConstantInstr : public DeoptInstr {
307 public: 395 public:
308 explicit DeoptConstantInstr(intptr_t object_table_index) 396 explicit DeoptConstantInstr(intptr_t object_table_index)
309 : object_table_index_(object_table_index) { 397 : object_table_index_(object_table_index) {
310 ASSERT(object_table_index >= 0); 398 ASSERT(object_table_index >= 0);
311 } 399 }
312 400
313 virtual intptr_t from_index() const { return object_table_index_; } 401 virtual intptr_t source_index() const { return object_table_index_; }
314 virtual DeoptInstr::Kind kind() const { return kConstant; } 402 virtual DeoptInstr::Kind kind() const { return kConstant; }
315 403
316 virtual const char* ToCString() const { 404 virtual const char* ToCString() const {
317 return Isolate::Current()->current_zone()->PrintToString( 405 return Isolate::Current()->current_zone()->PrintToString(
318 "const oti:%" Pd "", object_table_index_); 406 "const oti:%" Pd "", object_table_index_);
319 } 407 }
320 408
321 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 409 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
322 const Object& obj = Object::Handle( 410 const Object& obj = Object::Handle(
323 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); 411 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_));
324 *reinterpret_cast<RawObject**>(to_addr) = obj.raw(); 412 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
325 } 413 }
326 414
327 private: 415 private:
328 const intptr_t object_table_index_; 416 const intptr_t object_table_index_;
329 417
330 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); 418 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
331 }; 419 };
332 420
333 421
334 // Deoptimization instruction moving a CPU register. 422 // Deoptimization instruction moving a CPU register.
335 class DeoptRegisterInstr: public DeoptInstr { 423 class DeoptRegisterInstr: public DeoptInstr {
336 public: 424 public:
337 explicit DeoptRegisterInstr(intptr_t reg_as_int) 425 explicit DeoptRegisterInstr(intptr_t reg_as_int)
338 : reg_(static_cast<Register>(reg_as_int)) {} 426 : reg_(static_cast<Register>(reg_as_int)) {}
339 427
340 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 428 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
341 virtual DeoptInstr::Kind kind() const { return kRegister; } 429 virtual DeoptInstr::Kind kind() const { return kRegister; }
342 430
343 virtual const char* ToCString() const { 431 virtual const char* ToCString() const {
344 return Assembler::RegisterName(reg_); 432 return Assembler::RegisterName(reg_);
345 } 433 }
346 434
347 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 435 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
348 *to_addr = deopt_context->RegisterValue(reg_); 436 *dest_addr = deopt_context->RegisterValue(reg_);
349 } 437 }
350 438
351 private: 439 private:
352 const Register reg_; 440 const Register reg_;
353 441
354 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); 442 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr);
355 }; 443 };
356 444
357 445
358 // Deoptimization instruction moving an XMM register. 446 // Deoptimization instruction moving an XMM register.
359 class DeoptFpuRegisterInstr: public DeoptInstr { 447 class DeoptFpuRegisterInstr: public DeoptInstr {
360 public: 448 public:
361 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) 449 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int)
362 : reg_(static_cast<FpuRegister>(reg_as_int)) {} 450 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
363 451
364 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 452 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
365 virtual DeoptInstr::Kind kind() const { return kFpuRegister; } 453 virtual DeoptInstr::Kind kind() const { return kFpuRegister; }
366 454
367 virtual const char* ToCString() const { 455 virtual const char* ToCString() const {
368 return Assembler::FpuRegisterName(reg_); 456 return Assembler::FpuRegisterName(reg_);
369 } 457 }
370 458
371 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 459 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
372 double value = deopt_context->FpuRegisterValue(reg_); 460 double value = deopt_context->FpuRegisterValue(reg_);
373 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 461 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
374 Isolate::Current()->DeferDoubleMaterialization( 462 deopt_context->DeferDoubleMaterialization(
375 value, reinterpret_cast<RawDouble**>(to_addr)); 463 value, reinterpret_cast<RawDouble**>(dest_addr));
376 } 464 }
377 465
378 private: 466 private:
379 const FpuRegister reg_; 467 const FpuRegister reg_;
380 468
381 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr); 469 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr);
382 }; 470 };
383 471
384 472
385 class DeoptInt64FpuRegisterInstr: public DeoptInstr { 473 class DeoptInt64FpuRegisterInstr: public DeoptInstr {
386 public: 474 public:
387 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int) 475 explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int)
388 : reg_(static_cast<FpuRegister>(reg_as_int)) {} 476 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
389 477
390 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 478 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
391 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; } 479 virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; }
392 480
393 virtual const char* ToCString() const { 481 virtual const char* ToCString() const {
394 return Isolate::Current()->current_zone()->PrintToString( 482 return Isolate::Current()->current_zone()->PrintToString(
395 "%s(m)", Assembler::FpuRegisterName(reg_)); 483 "%s(m)", Assembler::FpuRegisterName(reg_));
396 } 484 }
397 485
398 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 486 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
399 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_); 487 int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_);
400 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 488 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
401 if (Smi::IsValid64(value)) { 489 if (Smi::IsValid64(value)) {
402 *to_addr = reinterpret_cast<intptr_t>( 490 *dest_addr = reinterpret_cast<intptr_t>(
403 Smi::New(static_cast<intptr_t>(value))); 491 Smi::New(static_cast<intptr_t>(value)));
404 } else { 492 } else {
405 Isolate::Current()->DeferMintMaterialization( 493 deopt_context->DeferMintMaterialization(
406 value, reinterpret_cast<RawMint**>(to_addr)); 494 value, reinterpret_cast<RawMint**>(dest_addr));
407 } 495 }
408 } 496 }
409 497
410 private: 498 private:
411 const FpuRegister reg_; 499 const FpuRegister reg_;
412 500
413 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr); 501 DISALLOW_COPY_AND_ASSIGN(DeoptInt64FpuRegisterInstr);
414 }; 502 };
415 503
416 504
417 // Deoptimization instruction moving an XMM register. 505 // Deoptimization instruction moving an XMM register.
418 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { 506 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr {
419 public: 507 public:
420 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int) 508 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int)
421 : reg_(static_cast<FpuRegister>(reg_as_int)) {} 509 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
422 510
423 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 511 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
424 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; } 512 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; }
425 513
426 virtual const char* ToCString() const { 514 virtual const char* ToCString() const {
427 return Isolate::Current()->current_zone()->PrintToString( 515 return Isolate::Current()->current_zone()->PrintToString(
428 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); 516 "%s(f32x4)", Assembler::FpuRegisterName(reg_));
429 } 517 }
430 518
431 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 519 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
432 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); 520 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
433 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 521 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
434 Isolate::Current()->DeferFloat32x4Materialization( 522 deopt_context->DeferFloat32x4Materialization(
435 value, reinterpret_cast<RawFloat32x4**>(to_addr)); 523 value, reinterpret_cast<RawFloat32x4**>(dest_addr));
436 } 524 }
437 525
438 private: 526 private:
439 const FpuRegister reg_; 527 const FpuRegister reg_;
440 528
441 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr); 529 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr);
442 }; 530 };
443 531
444 532
445 // Deoptimization instruction moving an XMM register. 533 // Deoptimization instruction moving an XMM register.
446 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr { 534 class DeoptUint32x4FpuRegisterInstr: public DeoptInstr {
447 public: 535 public:
448 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int) 536 explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int)
449 : reg_(static_cast<FpuRegister>(reg_as_int)) {} 537 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
450 538
451 virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } 539 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
452 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; } 540 virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; }
453 541
454 virtual const char* ToCString() const { 542 virtual const char* ToCString() const {
455 return Isolate::Current()->current_zone()->PrintToString( 543 return Isolate::Current()->current_zone()->PrintToString(
456 "%s(f32x4)", Assembler::FpuRegisterName(reg_)); 544 "%s(f32x4)", Assembler::FpuRegisterName(reg_));
457 } 545 }
458 546
459 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 547 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
460 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_); 548 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
461 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 549 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
462 Isolate::Current()->DeferUint32x4Materialization( 550 deopt_context->DeferUint32x4Materialization(
463 value, reinterpret_cast<RawUint32x4**>(to_addr)); 551 value, reinterpret_cast<RawUint32x4**>(dest_addr));
464 } 552 }
465 553
466 private: 554 private:
467 const FpuRegister reg_; 555 const FpuRegister reg_;
468 556
469 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr); 557 DISALLOW_COPY_AND_ASSIGN(DeoptUint32x4FpuRegisterInstr);
470 }; 558 };
471 559
472 560
473 // Deoptimization instruction creating a PC marker for the code of 561 // Deoptimization instruction creating a PC marker for the code of
474 // function at 'object_table_index'. 562 // function at 'object_table_index'.
475 class DeoptPcMarkerInstr : public DeoptInstr { 563 class DeoptPcMarkerInstr : public DeoptInstr {
476 public: 564 public:
477 explicit DeoptPcMarkerInstr(intptr_t object_table_index) 565 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
478 : object_table_index_(object_table_index) { 566 : object_table_index_(object_table_index) {
479 ASSERT(object_table_index >= 0); 567 ASSERT(object_table_index >= 0);
480 } 568 }
481 569
482 virtual intptr_t from_index() const { return object_table_index_; } 570 virtual intptr_t source_index() const { return object_table_index_; }
483 virtual DeoptInstr::Kind kind() const { return kPcMarker; } 571 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
484 572
485 virtual const char* ToCString() const { 573 virtual const char* ToCString() const {
486 return Isolate::Current()->current_zone()->PrintToString( 574 return Isolate::Current()->current_zone()->PrintToString(
487 "pcmark oti:%" Pd "", object_table_index_); 575 "pcmark oti:%" Pd "", object_table_index_);
488 } 576 }
489 577
490 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 578 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
491 Function& function = Function::Handle(deopt_context->isolate()); 579 Function& function = Function::Handle(deopt_context->isolate());
492 function ^= deopt_context->ObjectAt(object_table_index_); 580 function ^= deopt_context->ObjectAt(object_table_index_);
493 if (function.IsNull()) { 581 if (function.IsNull()) {
494 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. 582 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
495 *to_addr = 0; 583 *dest_addr = 0;
496 return; 584 return;
497 } 585 }
498 const Code& code = 586 const Code& code =
499 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 587 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
500 ASSERT(!code.IsNull()); 588 ASSERT(!code.IsNull());
501 const intptr_t pc_marker = 589 const intptr_t pc_marker =
502 code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset; 590 code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset;
503 *to_addr = pc_marker; 591 *dest_addr = pc_marker;
504 // Increment the deoptimization counter. This effectively increments each 592 // Increment the deoptimization counter. This effectively increments each
505 // function occurring in the optimized frame. 593 // function occurring in the optimized frame.
506 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 594 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
507 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { 595 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
508 OS::PrintErr("Deoptimizing %s (count %d)\n", 596 OS::PrintErr("Deoptimizing %s (count %d)\n",
509 function.ToFullyQualifiedCString(), 597 function.ToFullyQualifiedCString(),
510 function.deoptimization_counter()); 598 function.deoptimization_counter());
511 } 599 }
512 // Clear invocation counter so that hopefully the function gets reoptimized 600 // Clear invocation counter so that hopefully the function gets reoptimized
513 // only after more feedback has been collected. 601 // only after more feedback has been collected.
(...skipping 10 matching lines...) Expand all
524 612
525 // Deoptimization instruction creating a pool pointer for the code of 613 // Deoptimization instruction creating a pool pointer for the code of
526 // function at 'object_table_index'. 614 // function at 'object_table_index'.
527 class DeoptPpInstr : public DeoptInstr { 615 class DeoptPpInstr : public DeoptInstr {
528 public: 616 public:
529 explicit DeoptPpInstr(intptr_t object_table_index) 617 explicit DeoptPpInstr(intptr_t object_table_index)
530 : object_table_index_(object_table_index) { 618 : object_table_index_(object_table_index) {
531 ASSERT(object_table_index >= 0); 619 ASSERT(object_table_index >= 0);
532 } 620 }
533 621
534 virtual intptr_t from_index() const { return object_table_index_; } 622 virtual intptr_t source_index() const { return object_table_index_; }
535 virtual DeoptInstr::Kind kind() const { return kPp; } 623 virtual DeoptInstr::Kind kind() const { return kPp; }
536 624
537 virtual const char* ToCString() const { 625 virtual const char* ToCString() const {
538 return Isolate::Current()->current_zone()->PrintToString( 626 return Isolate::Current()->current_zone()->PrintToString(
539 "pp oti:%" Pd "", object_table_index_); 627 "pp oti:%" Pd "", object_table_index_);
540 } 628 }
541 629
542 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 630 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
543 Function& function = Function::Handle(deopt_context->isolate()); 631 Function& function = Function::Handle(deopt_context->isolate());
544 function ^= deopt_context->ObjectAt(object_table_index_); 632 function ^= deopt_context->ObjectAt(object_table_index_);
545 const Code& code = 633 const Code& code =
546 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 634 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
547 ASSERT(!code.IsNull()); 635 ASSERT(!code.IsNull());
548 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); 636 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
549 *to_addr = pp; 637 *dest_addr = pp;
550 } 638 }
551 639
552 private: 640 private:
553 intptr_t object_table_index_; 641 intptr_t object_table_index_;
554 642
555 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); 643 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
556 }; 644 };
557 645
558 646
559 // Deoptimization instruction copying the caller saved FP from optimized frame. 647 // Deoptimization instruction copying the caller saved FP from optimized frame.
560 class DeoptCallerFpInstr : public DeoptInstr { 648 class DeoptCallerFpInstr : public DeoptInstr {
561 public: 649 public:
562 DeoptCallerFpInstr() {} 650 DeoptCallerFpInstr() {}
563 651
564 virtual intptr_t from_index() const { return 0; } 652 virtual intptr_t source_index() const { return 0; }
565 virtual DeoptInstr::Kind kind() const { return kCallerFp; } 653 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
566 654
567 virtual const char* ToCString() const { 655 virtual const char* ToCString() const {
568 return "callerfp"; 656 return "callerfp";
569 } 657 }
570 658
571 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 659 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
572 *to_addr = deopt_context->GetCallerFp(); 660 *dest_addr = deopt_context->GetCallerFp();
573 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( 661 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
574 to_addr - (kSavedCallerFpSlotFromFp * kWordSize))); 662 dest_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
575 } 663 }
576 664
577 private: 665 private:
578 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 666 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
579 }; 667 };
580 668
581 669
582 // Deoptimization instruction copying the caller saved PP from optimized frame. 670 // Deoptimization instruction copying the caller saved PP from optimized frame.
583 class DeoptCallerPpInstr : public DeoptInstr { 671 class DeoptCallerPpInstr : public DeoptInstr {
584 public: 672 public:
585 DeoptCallerPpInstr() {} 673 DeoptCallerPpInstr() {}
586 674
587 virtual intptr_t from_index() const { return 0; } 675 virtual intptr_t source_index() const { return 0; }
588 virtual DeoptInstr::Kind kind() const { return kCallerPp; } 676 virtual DeoptInstr::Kind kind() const { return kCallerPp; }
589 677
590 virtual const char* ToCString() const { 678 virtual const char* ToCString() const {
591 return "callerpp"; 679 return "callerpp";
592 } 680 }
593 681
594 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 682 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
595 *to_addr = deopt_context->GetFromPp(); 683 *dest_addr = deopt_context->GetSourcePp();
596 } 684 }
597 685
598 private: 686 private:
599 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); 687 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr);
600 }; 688 };
601 689
602 690
603 // Deoptimization instruction copying the caller return address from optimized 691 // Deoptimization instruction copying the caller return address from optimized
604 // frame. 692 // frame.
605 class DeoptCallerPcInstr : public DeoptInstr { 693 class DeoptCallerPcInstr : public DeoptInstr {
606 public: 694 public:
607 DeoptCallerPcInstr() {} 695 DeoptCallerPcInstr() {}
608 696
609 virtual intptr_t from_index() const { return 0; } 697 virtual intptr_t source_index() const { return 0; }
610 virtual DeoptInstr::Kind kind() const { return kCallerPc; } 698 virtual DeoptInstr::Kind kind() const { return kCallerPc; }
611 699
612 virtual const char* ToCString() const { 700 virtual const char* ToCString() const {
613 return "callerpc"; 701 return "callerpc";
614 } 702 }
615 703
616 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 704 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
617 *to_addr = deopt_context->GetFromPc(); 705 *dest_addr = deopt_context->GetSourcePc();
618 } 706 }
619 707
620 private: 708 private:
621 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 709 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
622 }; 710 };
623 711
624 712
625 // Deoptimization instruction that indicates the rest of this DeoptInfo is a 713 // Deoptimization instruction that indicates the rest of this DeoptInfo is a
626 // suffix of another one. The suffix contains the info number (0 based 714 // suffix of another one. The suffix contains the info number (0 based
627 // index in the deopt table of the DeoptInfo to share) and the length of the 715 // index in the deopt table of the DeoptInfo to share) and the length of the
628 // suffix. 716 // suffix.
629 class DeoptSuffixInstr : public DeoptInstr { 717 class DeoptSuffixInstr : public DeoptInstr {
630 public: 718 public:
631 DeoptSuffixInstr(intptr_t info_number, intptr_t suffix_length) 719 DeoptSuffixInstr(intptr_t info_number, intptr_t suffix_length)
632 : info_number_(info_number), suffix_length_(suffix_length) { 720 : info_number_(info_number), suffix_length_(suffix_length) {
633 ASSERT(info_number >= 0); 721 ASSERT(info_number >= 0);
634 ASSERT(suffix_length >= 0); 722 ASSERT(suffix_length >= 0);
635 } 723 }
636 724
637 explicit DeoptSuffixInstr(intptr_t from_index) 725 explicit DeoptSuffixInstr(intptr_t source_index)
638 : info_number_(InfoNumber::decode(from_index)), 726 : info_number_(InfoNumber::decode(source_index)),
639 suffix_length_(SuffixLength::decode(from_index)) { 727 suffix_length_(SuffixLength::decode(source_index)) {
640 } 728 }
641 729
642 virtual intptr_t from_index() const { 730 virtual intptr_t source_index() const {
643 return InfoNumber::encode(info_number_) | 731 return InfoNumber::encode(info_number_) |
644 SuffixLength::encode(suffix_length_); 732 SuffixLength::encode(suffix_length_);
645 } 733 }
646 virtual DeoptInstr::Kind kind() const { return kSuffix; } 734 virtual DeoptInstr::Kind kind() const { return kSuffix; }
647 735
648 virtual const char* ToCString() const { 736 virtual const char* ToCString() const {
649 return Isolate::Current()->current_zone()->PrintToString( 737 return Isolate::Current()->current_zone()->PrintToString(
650 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); 738 "suffix %" Pd ":%" Pd, info_number_, suffix_length_);
651 } 739 }
652 740
653 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 741 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
654 // The deoptimization info is uncompressed by translating away suffixes 742 // The deoptimization info is uncompressed by translating away suffixes
655 // before executing the instructions. 743 // before executing the instructions.
656 UNREACHABLE(); 744 UNREACHABLE();
657 } 745 }
658 746
659 private: 747 private:
660 // Static decoder functions in DeoptInstr have access to the bitfield 748 // Static decoder functions in DeoptInstr have access to the bitfield
661 // definitions. 749 // definitions.
662 friend class DeoptInstr; 750 friend class DeoptInstr;
663 751
(...skipping 10 matching lines...) Expand all
674 762
675 // Write reference to a materialized object with the given index into the 763 // Write reference to a materialized object with the given index into the
676 // stack slot. 764 // stack slot.
677 class DeoptMaterializedObjectRefInstr : public DeoptInstr { 765 class DeoptMaterializedObjectRefInstr : public DeoptInstr {
678 public: 766 public:
679 explicit DeoptMaterializedObjectRefInstr(intptr_t index) 767 explicit DeoptMaterializedObjectRefInstr(intptr_t index)
680 : index_(index) { 768 : index_(index) {
681 ASSERT(index >= 0); 769 ASSERT(index >= 0);
682 } 770 }
683 771
684 virtual intptr_t from_index() const { return index_; } 772 virtual intptr_t source_index() const { return index_; }
685 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } 773 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
686 774
687 virtual const char* ToCString() const { 775 virtual const char* ToCString() const {
688 return Isolate::Current()->current_zone()->PrintToString( 776 return Isolate::Current()->current_zone()->PrintToString(
689 "mat ref #%" Pd "", index_); 777 "mat ref #%" Pd "", index_);
690 } 778 }
691 779
692 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 780 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
693 *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); 781 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
694 Isolate::Current()->DeferMaterializedObjectRef( 782 deopt_context->DeferMaterializedObjectRef(
695 index_, to_addr); 783 index_, dest_addr);
696 } 784 }
697 785
698 private: 786 private:
699 intptr_t index_; 787 intptr_t index_;
700 788
701 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); 789 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr);
702 }; 790 };
703 791
704 792
705 // Materialize object with the given number of fields. 793 // Materialize object with the given number of fields.
706 // Arguments for materialization (class and field-value pairs) are pushed 794 // Arguments for materialization (class and field-value pairs) are pushed
707 // to the expression stack of the bottom-most frame. 795 // to the expression stack of the bottom-most frame.
708 class DeoptMaterializeObjectInstr : public DeoptInstr { 796 class DeoptMaterializeObjectInstr : public DeoptInstr {
709 public: 797 public:
710 explicit DeoptMaterializeObjectInstr(intptr_t field_count) 798 explicit DeoptMaterializeObjectInstr(intptr_t field_count)
711 : field_count_(field_count) { 799 : field_count_(field_count) {
712 ASSERT(field_count >= 0); 800 ASSERT(field_count >= 0);
713 } 801 }
714 802
715 virtual intptr_t from_index() const { return field_count_; } 803 virtual intptr_t source_index() const { return field_count_; }
716 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } 804 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
717 805
718 virtual const char* ToCString() const { 806 virtual const char* ToCString() const {
719 return Isolate::Current()->current_zone()->PrintToString( 807 return Isolate::Current()->current_zone()->PrintToString(
720 "mat obj len:%" Pd "", field_count_); 808 "mat obj len:%" Pd "", field_count_);
721 } 809 }
722 810
723 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 811 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
724 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. 812 // This instructions are executed manually by the DeoptimizeWithDeoptInfo.
725 UNREACHABLE(); 813 UNREACHABLE();
726 } 814 }
727 815
728 private: 816 private:
729 intptr_t field_count_; 817 intptr_t field_count_;
730 818
731 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); 819 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr);
732 }; 820 };
733 821
734 822
735 intptr_t DeoptInstr::DecodeSuffix(intptr_t from_index, intptr_t* info_number) { 823 intptr_t DeoptInstr::DecodeSuffix(intptr_t source_index,
736 *info_number = DeoptSuffixInstr::InfoNumber::decode(from_index); 824 intptr_t* info_number) {
737 return DeoptSuffixInstr::SuffixLength::decode(from_index); 825 *info_number = DeoptSuffixInstr::InfoNumber::decode(source_index);
826 return DeoptSuffixInstr::SuffixLength::decode(source_index);
738 } 827 }
739 828
740 829
741 uword DeoptInstr::GetRetAddress(DeoptInstr* instr, 830 uword DeoptInstr::GetRetAddress(DeoptInstr* instr,
742 const Array& object_table, 831 const Array& object_table,
743 Function* func) { 832 Function* func) {
744 ASSERT(instr->kind() == kRetAddress); 833 ASSERT(instr->kind() == kRetAddress);
745 DeoptRetAddressInstr* ret_address_instr = 834 DeoptRetAddressInstr* ret_address_instr =
746 static_cast<DeoptRetAddressInstr*>(instr); 835 static_cast<DeoptRetAddressInstr*>(instr);
747 // The following assert may trigger when displaying a backtrace 836 // The following assert may trigger when displaying a backtrace
748 // from the simulator. 837 // from the simulator.
749 ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id())); 838 ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id()));
750 ASSERT(!object_table.IsNull()); 839 ASSERT(!object_table.IsNull());
751 ASSERT(func != NULL); 840 ASSERT(func != NULL);
752 *func ^= object_table.At(ret_address_instr->object_table_index()); 841 *func ^= object_table.At(ret_address_instr->object_table_index());
753 const Code& code = Code::Handle(func->unoptimized_code()); 842 const Code& code = Code::Handle(func->unoptimized_code());
754 ASSERT(!code.IsNull()); 843 ASSERT(!code.IsNull());
755 uword res = code.GetPcForDeoptId(ret_address_instr->deopt_id(), 844 uword res = code.GetPcForDeoptId(ret_address_instr->deopt_id(),
756 PcDescriptors::kDeopt); 845 PcDescriptors::kDeopt);
757 ASSERT(res != 0); 846 ASSERT(res != 0);
758 return res; 847 return res;
759 } 848 }
760 849
761 850
762 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { 851 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
763 Kind kind = static_cast<Kind>(kind_as_int); 852 Kind kind = static_cast<Kind>(kind_as_int);
764 switch (kind) { 853 switch (kind) {
765 case kStackSlot: return new DeoptStackSlotInstr(from_index); 854 case kStackSlot: return new DeoptStackSlotInstr(source_index);
766 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); 855 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index);
767 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); 856 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index);
768 case kFloat32x4StackSlot: 857 case kFloat32x4StackSlot:
769 return new DeoptFloat32x4StackSlotInstr(from_index); 858 return new DeoptFloat32x4StackSlotInstr(source_index);
770 case kUint32x4StackSlot: 859 case kUint32x4StackSlot:
771 return new DeoptUint32x4StackSlotInstr(from_index); 860 return new DeoptUint32x4StackSlotInstr(source_index);
772 case kRetAddress: return new DeoptRetAddressInstr(from_index); 861 case kRetAddress: return new DeoptRetAddressInstr(source_index);
773 case kConstant: return new DeoptConstantInstr(from_index); 862 case kConstant: return new DeoptConstantInstr(source_index);
774 case kRegister: return new DeoptRegisterInstr(from_index); 863 case kRegister: return new DeoptRegisterInstr(source_index);
775 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); 864 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index);
776 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); 865 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index);
777 case kFloat32x4FpuRegister: 866 case kFloat32x4FpuRegister:
778 return new DeoptFloat32x4FpuRegisterInstr(from_index); 867 return new DeoptFloat32x4FpuRegisterInstr(source_index);
779 case kUint32x4FpuRegister: 868 case kUint32x4FpuRegister:
780 return new DeoptUint32x4FpuRegisterInstr(from_index); 869 return new DeoptUint32x4FpuRegisterInstr(source_index);
781 case kPcMarker: return new DeoptPcMarkerInstr(from_index); 870 case kPcMarker: return new DeoptPcMarkerInstr(source_index);
782 case kPp: return new DeoptPpInstr(from_index); 871 case kPp: return new DeoptPpInstr(source_index);
783 case kCallerFp: return new DeoptCallerFpInstr(); 872 case kCallerFp: return new DeoptCallerFpInstr();
784 case kCallerPp: return new DeoptCallerPpInstr(); 873 case kCallerPp: return new DeoptCallerPpInstr();
785 case kCallerPc: return new DeoptCallerPcInstr(); 874 case kCallerPc: return new DeoptCallerPcInstr();
786 case kSuffix: return new DeoptSuffixInstr(from_index); 875 case kSuffix: return new DeoptSuffixInstr(source_index);
787 case kMaterializedObjectRef: 876 case kMaterializedObjectRef:
788 return new DeoptMaterializedObjectRefInstr(from_index); 877 return new DeoptMaterializedObjectRefInstr(source_index);
789 case kMaterializeObject: return new DeoptMaterializeObjectInstr(from_index); 878 case kMaterializeObject:
879 return new DeoptMaterializeObjectInstr(source_index);
790 } 880 }
791 UNREACHABLE(); 881 UNREACHABLE();
792 return NULL; 882 return NULL;
793 } 883 }
794 884
795 885
796 class DeoptInfoBuilder::TrieNode : public ZoneAllocated { 886 class DeoptInfoBuilder::TrieNode : public ZoneAllocated {
797 public: 887 public:
798 // Construct the root node representing the implicit "shared" terminator 888 // Construct the root node representing the implicit "shared" terminator
799 // at the end of each deopt info. 889 // at the end of each deopt info.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 return i; 933 return i;
844 } 934 }
845 } 935 }
846 // Add object. 936 // Add object.
847 const intptr_t result = object_table_.Length(); 937 const intptr_t result = object_table_.Length();
848 object_table_.Add(obj, Heap::kOld); 938 object_table_.Add(obj, Heap::kOld);
849 return result; 939 return result;
850 } 940 }
851 941
852 942
853 intptr_t DeoptInfoBuilder::CalculateStackIndex(const Location& from_loc) const { 943 intptr_t DeoptInfoBuilder::CalculateStackIndex(
854 return from_loc.stack_index() < 0 ? 944 const Location& source_loc) const {
855 from_loc.stack_index() + num_args_ : 945 return source_loc.stack_index() < 0 ?
856 from_loc.stack_index() + num_args_ + kDartFrameFixedSize; 946 source_loc.stack_index() + num_args_ :
947 source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
857 } 948 }
858 949
859 950
860 void DeoptInfoBuilder::AddReturnAddress(const Function& function, 951 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
861 intptr_t deopt_id, 952 intptr_t deopt_id,
862 intptr_t to_index) { 953 intptr_t dest_index) {
863 // Check that deopt_id exists. 954 // Check that deopt_id exists.
864 // TODO(vegorov): verify after deoptimization targets as well. 955 // TODO(vegorov): verify after deoptimization targets as well.
865 #ifdef DEBUG 956 #ifdef DEBUG
866 const Code& code = Code::Handle(function.unoptimized_code()); 957 const Code& code = Code::Handle(function.unoptimized_code());
867 ASSERT(Isolate::IsDeoptAfter(deopt_id) || 958 ASSERT(Isolate::IsDeoptAfter(deopt_id) ||
868 (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0)); 959 (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
869 #endif 960 #endif
870 const intptr_t object_table_index = FindOrAddObjectInTable(function); 961 const intptr_t object_table_index = FindOrAddObjectInTable(function);
871 ASSERT(to_index == FrameSize()); 962 ASSERT(dest_index == FrameSize());
872 instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id)); 963 instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id));
873 } 964 }
874 965
875 966
876 void DeoptInfoBuilder::AddPcMarker(const Function& function, 967 void DeoptInfoBuilder::AddPcMarker(const Function& function,
877 intptr_t to_index) { 968 intptr_t dest_index) {
878 intptr_t object_table_index = FindOrAddObjectInTable(function); 969 intptr_t object_table_index = FindOrAddObjectInTable(function);
879 ASSERT(to_index == FrameSize()); 970 ASSERT(dest_index == FrameSize());
880 instructions_.Add(new DeoptPcMarkerInstr(object_table_index)); 971 instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
881 } 972 }
882 973
883 974
884 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t to_index) { 975 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
885 intptr_t object_table_index = FindOrAddObjectInTable(function); 976 intptr_t object_table_index = FindOrAddObjectInTable(function);
886 ASSERT(to_index == FrameSize()); 977 ASSERT(dest_index == FrameSize());
887 instructions_.Add(new DeoptPpInstr(object_table_index)); 978 instructions_.Add(new DeoptPpInstr(object_table_index));
888 } 979 }
889 980
890 981
891 void DeoptInfoBuilder::AddCopy(Value* value, 982 void DeoptInfoBuilder::AddCopy(Value* value,
892 const Location& from_loc, 983 const Location& source_loc,
893 const intptr_t to_index) { 984 const intptr_t dest_index) {
894 DeoptInstr* deopt_instr = NULL; 985 DeoptInstr* deopt_instr = NULL;
895 if (from_loc.IsConstant()) { 986 if (source_loc.IsConstant()) {
896 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); 987 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
897 deopt_instr = new DeoptConstantInstr(object_table_index); 988 deopt_instr = new DeoptConstantInstr(object_table_index);
898 } else if (from_loc.IsRegister()) { 989 } else if (source_loc.IsRegister()) {
899 ASSERT(value->definition()->representation() == kTagged); 990 ASSERT(value->definition()->representation() == kTagged);
900 deopt_instr = new DeoptRegisterInstr(from_loc.reg()); 991 deopt_instr = new DeoptRegisterInstr(source_loc.reg());
901 } else if (from_loc.IsFpuRegister()) { 992 } else if (source_loc.IsFpuRegister()) {
902 if (value->definition()->representation() == kUnboxedDouble) { 993 if (value->definition()->representation() == kUnboxedDouble) {
903 deopt_instr = new DeoptFpuRegisterInstr(from_loc.fpu_reg()); 994 deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg());
904 } else if (value->definition()->representation() == kUnboxedMint) { 995 } else if (value->definition()->representation() == kUnboxedMint) {
905 deopt_instr = new DeoptInt64FpuRegisterInstr(from_loc.fpu_reg()); 996 deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg());
906 } else if (value->definition()->representation() == kUnboxedFloat32x4) { 997 } else if (value->definition()->representation() == kUnboxedFloat32x4) {
907 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(from_loc.fpu_reg()); 998 deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg());
908 } else { 999 } else {
909 ASSERT(value->definition()->representation() == kUnboxedUint32x4); 1000 ASSERT(value->definition()->representation() == kUnboxedUint32x4);
910 deopt_instr = new DeoptUint32x4FpuRegisterInstr(from_loc.fpu_reg()); 1001 deopt_instr = new DeoptUint32x4FpuRegisterInstr(source_loc.fpu_reg());
911 } 1002 }
912 } else if (from_loc.IsStackSlot()) { 1003 } else if (source_loc.IsStackSlot()) {
913 ASSERT(value->definition()->representation() == kTagged); 1004 ASSERT(value->definition()->representation() == kTagged);
914 intptr_t from_index = CalculateStackIndex(from_loc); 1005 intptr_t source_index = CalculateStackIndex(source_loc);
915 deopt_instr = new DeoptStackSlotInstr(from_index); 1006 deopt_instr = new DeoptStackSlotInstr(source_index);
916 } else if (from_loc.IsDoubleStackSlot()) { 1007 } else if (source_loc.IsDoubleStackSlot()) {
917 intptr_t from_index = CalculateStackIndex(from_loc); 1008 intptr_t source_index = CalculateStackIndex(source_loc);
918 if (value->definition()->representation() == kUnboxedDouble) { 1009 if (value->definition()->representation() == kUnboxedDouble) {
919 deopt_instr = new DeoptDoubleStackSlotInstr(from_index); 1010 deopt_instr = new DeoptDoubleStackSlotInstr(source_index);
920 } else { 1011 } else {
921 ASSERT(value->definition()->representation() == kUnboxedMint); 1012 ASSERT(value->definition()->representation() == kUnboxedMint);
922 deopt_instr = new DeoptInt64StackSlotInstr(from_index); 1013 deopt_instr = new DeoptInt64StackSlotInstr(source_index);
923 } 1014 }
924 } else if (from_loc.IsQuadStackSlot()) { 1015 } else if (source_loc.IsQuadStackSlot()) {
925 intptr_t from_index = CalculateStackIndex(from_loc); 1016 intptr_t source_index = CalculateStackIndex(source_loc);
926 if (value->definition()->representation() == kUnboxedFloat32x4) { 1017 if (value->definition()->representation() == kUnboxedFloat32x4) {
927 deopt_instr = new DeoptFloat32x4StackSlotInstr(from_index); 1018 deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index);
928 } else { 1019 } else {
929 ASSERT(value->definition()->representation() == kUnboxedUint32x4); 1020 ASSERT(value->definition()->representation() == kUnboxedUint32x4);
930 deopt_instr = new DeoptUint32x4StackSlotInstr(from_index); 1021 deopt_instr = new DeoptUint32x4StackSlotInstr(source_index);
931 } 1022 }
932 } else if (from_loc.IsInvalid() && 1023 } else if (source_loc.IsInvalid() &&
933 value->definition()->IsMaterializeObject()) { 1024 value->definition()->IsMaterializeObject()) {
934 const intptr_t index = FindMaterialization( 1025 const intptr_t index = FindMaterialization(
935 value->definition()->AsMaterializeObject()); 1026 value->definition()->AsMaterializeObject());
936 ASSERT(index >= 0); 1027 ASSERT(index >= 0);
937 deopt_instr = new DeoptMaterializedObjectRefInstr(index); 1028 deopt_instr = new DeoptMaterializedObjectRefInstr(index);
938 } else { 1029 } else {
939 UNREACHABLE(); 1030 UNREACHABLE();
940 } 1031 }
941 ASSERT(to_index == FrameSize()); 1032 ASSERT(dest_index == FrameSize());
942 ASSERT(deopt_instr != NULL); 1033 ASSERT(deopt_instr != NULL);
943 instructions_.Add(deopt_instr); 1034 instructions_.Add(deopt_instr);
944 } 1035 }
945 1036
946 1037
947 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) { 1038 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
948 ASSERT(to_index == FrameSize()); 1039 ASSERT(dest_index == FrameSize());
949 instructions_.Add(new DeoptCallerFpInstr()); 1040 instructions_.Add(new DeoptCallerFpInstr());
950 } 1041 }
951 1042
952 1043
953 void DeoptInfoBuilder::AddCallerPp(intptr_t to_index) { 1044 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
954 ASSERT(to_index == FrameSize()); 1045 ASSERT(dest_index == FrameSize());
955 instructions_.Add(new DeoptCallerPpInstr()); 1046 instructions_.Add(new DeoptCallerPpInstr());
956 } 1047 }
957 1048
958 1049
959 void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) { 1050 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
960 ASSERT(to_index == FrameSize()); 1051 ASSERT(dest_index == FrameSize());
961 instructions_.Add(new DeoptCallerPcInstr()); 1052 instructions_.Add(new DeoptCallerPcInstr());
962 } 1053 }
963 1054
964 1055
965 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t to_index) { 1056 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
966 ASSERT(to_index == FrameSize()); 1057 ASSERT(dest_index == FrameSize());
967 intptr_t object_table_index = FindOrAddObjectInTable(obj); 1058 intptr_t object_table_index = FindOrAddObjectInTable(obj);
968 instructions_.Add(new DeoptConstantInstr(object_table_index)); 1059 instructions_.Add(new DeoptConstantInstr(object_table_index));
969 } 1060 }
970 1061
971 1062
972 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) { 1063 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) {
973 const intptr_t index = FindMaterialization(mat); 1064 const intptr_t index = FindMaterialization(mat);
974 if (index >= 0) { 1065 if (index >= 0) {
975 return; // Already added. 1066 return; // Already added.
976 } 1067 }
977 materializations_.Add(mat); 1068 materializations_.Add(mat);
978 1069
979 // Count initialized fields and emit kMaterializeObject instruction. 1070 // Count initialized fields and emit kMaterializeObject instruction.
980 // There is no need to write nulls into fields because object is null 1071 // There is no need to write nulls into fields because object is null
981 // initialized by default. 1072 // initialized by default.
982 intptr_t non_null_fields = 0; 1073 intptr_t non_null_fields = 0;
983 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1074 for (intptr_t i = 0; i < mat->InputCount(); i++) {
984 if (!mat->InputAt(i)->BindsToConstantNull()) { 1075 if (!mat->InputAt(i)->BindsToConstantNull()) {
985 non_null_fields++; 1076 non_null_fields++;
986 } 1077 }
987 } 1078 }
988 1079
989 instructions_.Add(new DeoptMaterializeObjectInstr(non_null_fields)); 1080 instructions_.Add(new DeoptMaterializeObjectInstr(non_null_fields));
990 } 1081 }
991 1082
992 1083
993 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t to_index) { 1084 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) {
994 ASSERT(to_index == kDartFrameFixedSize); 1085 ASSERT(dest_index == kDartFrameFixedSize);
995 for (intptr_t i = 0; i < materializations_.length(); i++) { 1086 for (intptr_t i = 0; i < materializations_.length(); i++) {
996 MaterializeObjectInstr* mat = materializations_[i]; 1087 MaterializeObjectInstr* mat = materializations_[i];
997 AddConstant(mat->cls(), to_index++); // Class of the instance to allocate. 1088 // Class of the instance to allocate.
1089 AddConstant(mat->cls(), dest_index++);
998 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1090 for (intptr_t i = 0; i < mat->InputCount(); i++) {
999 if (!mat->InputAt(i)->BindsToConstantNull()) { 1091 if (!mat->InputAt(i)->BindsToConstantNull()) {
1000 // Emit field-value pair. 1092 // Emit field-value pair.
1001 AddConstant(mat->FieldAt(i), to_index++); 1093 AddConstant(mat->FieldAt(i), dest_index++);
1002 AddCopy(mat->InputAt(i), mat->LocationAt(i), to_index++); 1094 AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++);
1003 } 1095 }
1004 } 1096 }
1005 } 1097 }
1006 return to_index; 1098 return dest_index;
1007 } 1099 }
1008 1100
1009 1101
1010 intptr_t DeoptInfoBuilder::FindMaterialization( 1102 intptr_t DeoptInfoBuilder::FindMaterialization(
1011 MaterializeObjectInstr* mat) const { 1103 MaterializeObjectInstr* mat) const {
1012 for (intptr_t i = 0; i < materializations_.length(); i++) { 1104 for (intptr_t i = 0; i < materializations_.length(); i++) {
1013 if (materializations_[i] == mat) { 1105 if (materializations_[i] == mat) {
1014 return i; 1106 return i;
1015 } 1107 }
1016 } 1108 }
(...skipping 25 matching lines...) Expand all
1042 // Allocate space for the translation. If the shared suffix is longer 1134 // Allocate space for the translation. If the shared suffix is longer
1043 // than one instruction, we replace it with a single suffix instruction. 1135 // than one instruction, we replace it with a single suffix instruction.
1044 if (suffix_length > 1) length -= (suffix_length - 1); 1136 if (suffix_length > 1) length -= (suffix_length - 1);
1045 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(length)); 1137 const DeoptInfo& deopt_info = DeoptInfo::Handle(DeoptInfo::New(length));
1046 1138
1047 // Write the unshared instructions and build their sub-tree. 1139 // Write the unshared instructions and build their sub-tree.
1048 TrieNode* node = NULL; 1140 TrieNode* node = NULL;
1049 intptr_t write_count = (suffix_length > 1) ? length - 1 : length; 1141 intptr_t write_count = (suffix_length > 1) ? length - 1 : length;
1050 for (intptr_t i = 0; i < write_count; ++i) { 1142 for (intptr_t i = 0; i < write_count; ++i) {
1051 DeoptInstr* instr = instructions_[i]; 1143 DeoptInstr* instr = instructions_[i];
1052 deopt_info.SetAt(i, instr->kind(), instr->from_index()); 1144 deopt_info.SetAt(i, instr->kind(), instr->source_index());
1053 TrieNode* child = node; 1145 TrieNode* child = node;
1054 node = new TrieNode(instr, current_info_number_); 1146 node = new TrieNode(instr, current_info_number_);
1055 node->AddChild(child); 1147 node->AddChild(child);
1056 } 1148 }
1057 1149
1058 if (suffix_length > 1) { 1150 if (suffix_length > 1) {
1059 suffix->AddChild(node); 1151 suffix->AddChild(node);
1060 DeoptInstr* instr = 1152 DeoptInstr* instr =
1061 new DeoptSuffixInstr(suffix->info_number(), suffix_length); 1153 new DeoptSuffixInstr(suffix->info_number(), suffix_length);
1062 deopt_info.SetAt(length - 1, instr->kind(), instr->from_index()); 1154 deopt_info.SetAt(length - 1, instr->kind(), instr->source_index());
1063 } else { 1155 } else {
1064 trie_root_->AddChild(node); 1156 trie_root_->AddChild(node);
1065 } 1157 }
1066 1158
1067 ASSERT(deopt_info.VerifyDecompression(instructions_, deopt_table)); 1159 ASSERT(deopt_info.VerifyDecompression(instructions_, deopt_table));
1068 instructions_.Clear(); 1160 instructions_.Clear();
1069 materializations_.Clear(); 1161 materializations_.Clear();
1070 frame_start_ = -1; 1162 frame_start_ = -1;
1071 1163
1072 ++current_info_number_; 1164 ++current_info_number_;
(...skipping 29 matching lines...) Expand all
1102 Smi* offset, 1194 Smi* offset,
1103 DeoptInfo* info, 1195 DeoptInfo* info,
1104 Smi* reason) { 1196 Smi* reason) {
1105 intptr_t i = index * kEntrySize; 1197 intptr_t i = index * kEntrySize;
1106 *offset ^= table.At(i); 1198 *offset ^= table.At(i);
1107 *info ^= table.At(i + 1); 1199 *info ^= table.At(i + 1);
1108 *reason ^= table.At(i + 2); 1200 *reason ^= table.At(i + 2);
1109 } 1201 }
1110 1202
1111 } // namespace dart 1203 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/deopt_instructions.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698