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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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
« no previous file with comments | « runtime/vm/deopt_instructions.h ('k') | runtime/vm/disassembler.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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/disassembler.h" 10 #include "vm/disassembler.h"
11 #include "vm/intermediate_language.h" 11 #include "vm/intermediate_language.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/parser.h" 13 #include "vm/parser.h"
14 #include "vm/stack_frame.h" 14 #include "vm/stack_frame.h"
15 #include "vm/thread.h" 15 #include "vm/thread.h"
16 #include "vm/timeline.h" 16 #include "vm/timeline.h"
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DEFINE_FLAG(bool, 20 DEFINE_FLAG(bool,
21 compress_deopt_info, 21 compress_deopt_info,
22 true, 22 true,
23 "Compress the size of the deoptimization info for optimized code."); 23 "Compress the size of the deoptimization info for optimized code.");
24 DECLARE_FLAG(bool, trace_deoptimization); 24 DECLARE_FLAG(bool, trace_deoptimization);
25 DECLARE_FLAG(bool, trace_deoptimization_verbose); 25 DECLARE_FLAG(bool, trace_deoptimization_verbose);
26 26
27
28 DeoptContext::DeoptContext(const StackFrame* frame, 27 DeoptContext::DeoptContext(const StackFrame* frame,
29 const Code& code, 28 const Code& code,
30 DestFrameOptions dest_options, 29 DestFrameOptions dest_options,
31 fpu_register_t* fpu_registers, 30 fpu_register_t* fpu_registers,
32 intptr_t* cpu_registers, 31 intptr_t* cpu_registers,
33 bool is_lazy_deopt, 32 bool is_lazy_deopt,
34 bool deoptimizing_code) 33 bool deoptimizing_code)
35 : code_(code.raw()), 34 : code_(code.raw()),
36 object_pool_(code.GetObjectPool()), 35 object_pool_(code.GetObjectPool()),
37 deopt_info_(TypedData::null()), 36 deopt_info_(TypedData::null()),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) { 124 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
126 THR_Print( 125 THR_Print(
127 "Deoptimizing (reason %d '%s') at " 126 "Deoptimizing (reason %d '%s') at "
128 "pc=%" Pp " fp=%" Pp " '%s' (count %d)\n", 127 "pc=%" Pp " fp=%" Pp " '%s' (count %d)\n",
129 deopt_reason(), DeoptReasonToCString(deopt_reason()), frame->pc(), 128 deopt_reason(), DeoptReasonToCString(deopt_reason()), frame->pc(),
130 frame->fp(), function.ToFullyQualifiedCString(), 129 frame->fp(), function.ToFullyQualifiedCString(),
131 function.deoptimization_counter()); 130 function.deoptimization_counter());
132 } 131 }
133 } 132 }
134 133
135
136 DeoptContext::~DeoptContext() { 134 DeoptContext::~DeoptContext() {
137 // Delete memory for source frame and registers. 135 // Delete memory for source frame and registers.
138 if (source_frame_is_allocated_) { 136 if (source_frame_is_allocated_) {
139 delete[] source_frame_; 137 delete[] source_frame_;
140 } 138 }
141 source_frame_ = NULL; 139 source_frame_ = NULL;
142 delete[] fpu_registers_; 140 delete[] fpu_registers_;
143 delete[] cpu_registers_; 141 delete[] cpu_registers_;
144 fpu_registers_ = NULL; 142 fpu_registers_ = NULL;
145 cpu_registers_ = NULL; 143 cpu_registers_ = NULL;
(...skipping 30 matching lines...) Expand all
176 timeline_event->CopyArgument(0, "function", function_name.ToCString()); 174 timeline_event->CopyArgument(0, "function", function_name.ToCString());
177 timeline_event->CopyArgument(1, "reason", reason); 175 timeline_event->CopyArgument(1, "reason", reason);
178 timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter); 176 timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter);
179 timeline_event->Complete(); 177 timeline_event->Complete();
180 } 178 }
181 } 179 }
182 } 180 }
183 #endif // !PRODUCT 181 #endif // !PRODUCT
184 } 182 }
185 183
186
187 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) { 184 void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
188 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_)); 185 visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_pool_));
189 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_)); 186 visitor->VisitPointer(reinterpret_cast<RawObject**>(&deopt_info_));
190 187
191 // Visit any object pointers on the destination stack. 188 // Visit any object pointers on the destination stack.
192 if (dest_frame_is_allocated_) { 189 if (dest_frame_is_allocated_) {
193 for (intptr_t i = 0; i < dest_frame_size_; i++) { 190 for (intptr_t i = 0; i < dest_frame_size_; i++) {
194 if (dest_frame_[i] != 0) { 191 if (dest_frame_[i] != 0) {
195 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i])); 192 visitor->VisitPointer(reinterpret_cast<RawObject**>(&dest_frame_[i]));
196 } 193 }
197 } 194 }
198 } 195 }
199 } 196 }
200 197
201
202 intptr_t DeoptContext::DestStackAdjustment() const { 198 intptr_t DeoptContext::DestStackAdjustment() const {
203 return dest_frame_size_ - kDartFrameFixedSize - num_args_ 199 return dest_frame_size_ - kDartFrameFixedSize - num_args_
204 #if !defined(TARGET_ARCH_DBC) 200 #if !defined(TARGET_ARCH_DBC)
205 - 1 // For fp. 201 - 1 // For fp.
206 #endif 202 #endif
207 - kParamEndSlotFromFp; 203 - kParamEndSlotFromFp;
208 } 204 }
209 205
210
211 intptr_t DeoptContext::GetSourceFp() const { 206 intptr_t DeoptContext::GetSourceFp() const {
212 #if !defined(TARGET_ARCH_DBC) 207 #if !defined(TARGET_ARCH_DBC)
213 return source_frame_[source_frame_size_ - 1 - num_args_ - 208 return source_frame_[source_frame_size_ - 1 - num_args_ -
214 kParamEndSlotFromFp]; 209 kParamEndSlotFromFp];
215 #else 210 #else
216 return source_frame_[num_args_ + kDartFrameFixedSize + 211 return source_frame_[num_args_ + kDartFrameFixedSize +
217 kSavedCallerFpSlotFromFp]; 212 kSavedCallerFpSlotFromFp];
218 #endif 213 #endif
219 } 214 }
220 215
221
222 intptr_t DeoptContext::GetSourcePp() const { 216 intptr_t DeoptContext::GetSourcePp() const {
223 #if !defined(TARGET_ARCH_DBC) 217 #if !defined(TARGET_ARCH_DBC)
224 return source_frame_[source_frame_size_ - 1 - num_args_ - 218 return source_frame_[source_frame_size_ - 1 - num_args_ -
225 kParamEndSlotFromFp + 219 kParamEndSlotFromFp +
226 StackFrame::SavedCallerPpSlotFromFp()]; 220 StackFrame::SavedCallerPpSlotFromFp()];
227 #else 221 #else
228 UNREACHABLE(); 222 UNREACHABLE();
229 return 0; 223 return 0;
230 #endif 224 #endif
231 } 225 }
232 226
233
234 intptr_t DeoptContext::GetSourcePc() const { 227 intptr_t DeoptContext::GetSourcePc() const {
235 #if !defined(TARGET_ARCH_DBC) 228 #if !defined(TARGET_ARCH_DBC)
236 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp]; 229 return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
237 #else 230 #else
238 return source_frame_[num_args_ + kDartFrameFixedSize + 231 return source_frame_[num_args_ + kDartFrameFixedSize +
239 kSavedCallerPcSlotFromFp]; 232 kSavedCallerPcSlotFromFp];
240 #endif 233 #endif
241 } 234 }
242 235
243
244 intptr_t DeoptContext::GetCallerFp() const { 236 intptr_t DeoptContext::GetCallerFp() const {
245 return caller_fp_; 237 return caller_fp_;
246 } 238 }
247 239
248
249 void DeoptContext::SetCallerFp(intptr_t caller_fp) { 240 void DeoptContext::SetCallerFp(intptr_t caller_fp) {
250 caller_fp_ = caller_fp; 241 caller_fp_ = caller_fp;
251 } 242 }
252 243
253
254 static bool IsObjectInstruction(DeoptInstr::Kind kind) { 244 static bool IsObjectInstruction(DeoptInstr::Kind kind) {
255 switch (kind) { 245 switch (kind) {
256 case DeoptInstr::kConstant: 246 case DeoptInstr::kConstant:
257 case DeoptInstr::kPp: 247 case DeoptInstr::kPp:
258 case DeoptInstr::kCallerPp: 248 case DeoptInstr::kCallerPp:
259 case DeoptInstr::kMaterializedObjectRef: 249 case DeoptInstr::kMaterializedObjectRef:
260 case DeoptInstr::kFloat32x4: 250 case DeoptInstr::kFloat32x4:
261 case DeoptInstr::kInt32x4: 251 case DeoptInstr::kInt32x4:
262 case DeoptInstr::kFloat64x2: 252 case DeoptInstr::kFloat64x2:
263 case DeoptInstr::kWord: 253 case DeoptInstr::kWord:
(...skipping 13 matching lines...) Expand all
277 case DeoptInstr::kMaterializeObject: 267 case DeoptInstr::kMaterializeObject:
278 default: 268 default:
279 // We should not encounter these instructions when filling stack slots. 269 // We should not encounter these instructions when filling stack slots.
280 UNREACHABLE(); 270 UNREACHABLE();
281 return false; 271 return false;
282 } 272 }
283 UNREACHABLE(); 273 UNREACHABLE();
284 return false; 274 return false;
285 } 275 }
286 276
287
288 void DeoptContext::FillDestFrame() { 277 void DeoptContext::FillDestFrame() {
289 const Code& code = Code::Handle(code_); 278 const Code& code = Code::Handle(code_);
290 const TypedData& deopt_info = TypedData::Handle(deopt_info_); 279 const TypedData& deopt_info = TypedData::Handle(deopt_info_);
291 280
292 GrowableArray<DeoptInstr*> deopt_instructions; 281 GrowableArray<DeoptInstr*> deopt_instructions;
293 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 282 const Array& deopt_table = Array::Handle(code.deopt_info_array());
294 ASSERT(!deopt_table.IsNull()); 283 ASSERT(!deopt_table.IsNull());
295 DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions); 284 DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions);
296 285
297 const intptr_t len = deopt_instructions.length(); 286 const intptr_t len = deopt_instructions.length();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 326
338 if (FLAG_trace_deoptimization_verbose) { 327 if (FLAG_trace_deoptimization_verbose) {
339 for (intptr_t i = 0; i < frame_size; i++) { 328 for (intptr_t i = 0; i < frame_size; i++) {
340 intptr_t* to_addr = GetDestFrameAddressAt(i); 329 intptr_t* to_addr = GetDestFrameAddressAt(i);
341 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", i, to_addr, *to_addr, 330 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", i, to_addr, *to_addr,
342 deopt_instructions[i + (len - frame_size)]->ToCString()); 331 deopt_instructions[i + (len - frame_size)]->ToCString());
343 } 332 }
344 } 333 }
345 } 334 }
346 335
347
348 intptr_t* DeoptContext::CatchEntryState(intptr_t num_vars) { 336 intptr_t* DeoptContext::CatchEntryState(intptr_t num_vars) {
349 const Code& code = Code::Handle(code_); 337 const Code& code = Code::Handle(code_);
350 const TypedData& deopt_info = TypedData::Handle(deopt_info_); 338 const TypedData& deopt_info = TypedData::Handle(deopt_info_);
351 GrowableArray<DeoptInstr*> deopt_instructions; 339 GrowableArray<DeoptInstr*> deopt_instructions;
352 const Array& deopt_table = Array::Handle(code.deopt_info_array()); 340 const Array& deopt_table = Array::Handle(code.deopt_info_array());
353 ASSERT(!deopt_table.IsNull()); 341 ASSERT(!deopt_table.IsNull());
354 DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions); 342 DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions);
355 343
356 intptr_t* state = new intptr_t[2 * num_vars + 1]; 344 intptr_t* state = new intptr_t[2 * num_vars + 1];
357 state[0] = num_vars; 345 state[0] = num_vars;
(...skipping 15 matching lines...) Expand all
373 intptr_t dest_index = i - params; 361 intptr_t dest_index = i - params;
374 #endif 362 #endif
375 CatchEntryStatePair p = instr->ToCatchEntryStatePair(this, dest_index); 363 CatchEntryStatePair p = instr->ToCatchEntryStatePair(this, dest_index);
376 state[1 + 2 * i] = p.src; 364 state[1 + 2 * i] = p.src;
377 state[2 + 2 * i] = p.dest; 365 state[2 + 2 * i] = p.dest;
378 } 366 }
379 367
380 return state; 368 return state;
381 } 369 }
382 370
383
384 static void FillDeferredSlots(DeoptContext* deopt_context, 371 static void FillDeferredSlots(DeoptContext* deopt_context,
385 DeferredSlot** slot_list) { 372 DeferredSlot** slot_list) {
386 DeferredSlot* slot = *slot_list; 373 DeferredSlot* slot = *slot_list;
387 *slot_list = NULL; 374 *slot_list = NULL;
388 375
389 while (slot != NULL) { 376 while (slot != NULL) {
390 DeferredSlot* current = slot; 377 DeferredSlot* current = slot;
391 slot = slot->next(); 378 slot = slot->next();
392 379
393 current->Materialize(deopt_context); 380 current->Materialize(deopt_context);
394 381
395 delete current; 382 delete current;
396 } 383 }
397 } 384 }
398 385
399
400 // Materializes all deferred objects. Returns the total number of 386 // Materializes all deferred objects. Returns the total number of
401 // artificial arguments used during deoptimization. 387 // artificial arguments used during deoptimization.
402 intptr_t DeoptContext::MaterializeDeferredObjects() { 388 intptr_t DeoptContext::MaterializeDeferredObjects() {
403 // Populate slots with references to all unboxed "primitive" values (doubles, 389 // Populate slots with references to all unboxed "primitive" values (doubles,
404 // mints, simd) and deferred objects. Deferred objects are only allocated 390 // mints, simd) and deferred objects. Deferred objects are only allocated
405 // but not filled with data. This is done later because deferred objects 391 // but not filled with data. This is done later because deferred objects
406 // can references each other. 392 // can references each other.
407 FillDeferredSlots(this, &deferred_slots_); 393 FillDeferredSlots(this, &deferred_slots_);
408 394
409 // Compute total number of artificial arguments used during deoptimization. 395 // Compute total number of artificial arguments used during deoptimization.
(...skipping 21 matching lines...) Expand all
431 char line_buffer[80]; 417 char line_buffer[80];
432 OS::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'", line, 418 OS::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'", line,
433 line_string.ToCString()); 419 line_string.ToCString());
434 THR_Print("%s\n", line_buffer); 420 THR_Print("%s\n", line_buffer);
435 THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count); 421 THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count);
436 } 422 }
437 423
438 return deopt_arg_count; 424 return deopt_arg_count;
439 } 425 }
440 426
441
442 RawArray* DeoptContext::DestFrameAsArray() { 427 RawArray* DeoptContext::DestFrameAsArray() {
443 ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_); 428 ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_);
444 const Array& dest_array = Array::Handle(zone(), Array::New(dest_frame_size_)); 429 const Array& dest_array = Array::Handle(zone(), Array::New(dest_frame_size_));
445 PassiveObject& obj = PassiveObject::Handle(zone()); 430 PassiveObject& obj = PassiveObject::Handle(zone());
446 for (intptr_t i = 0; i < dest_frame_size_; i++) { 431 for (intptr_t i = 0; i < dest_frame_size_; i++) {
447 obj = reinterpret_cast<RawObject*>(dest_frame_[i]); 432 obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
448 dest_array.SetAt(i, obj); 433 dest_array.SetAt(i, obj);
449 } 434 }
450 return dest_array.raw(); 435 return dest_array.raw();
451 } 436 }
452 437
453
454 // Deoptimization instruction creating return address using function and 438 // Deoptimization instruction creating return address using function and
455 // deopt-id stored at 'object_table_index'. 439 // deopt-id stored at 'object_table_index'.
456 class DeoptRetAddressInstr : public DeoptInstr { 440 class DeoptRetAddressInstr : public DeoptInstr {
457 public: 441 public:
458 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) 442 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id)
459 : object_table_index_(object_table_index), deopt_id_(deopt_id) { 443 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
460 ASSERT(object_table_index >= 0); 444 ASSERT(object_table_index >= 0);
461 ASSERT(deopt_id >= 0); 445 ASSERT(deopt_id >= 0);
462 } 446 }
463 447
(...skipping 28 matching lines...) Expand all
492 }; 476 };
493 class DeoptId 477 class DeoptId
494 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {}; 478 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {};
495 479
496 const intptr_t object_table_index_; 480 const intptr_t object_table_index_;
497 const intptr_t deopt_id_; 481 const intptr_t deopt_id_;
498 482
499 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddressInstr); 483 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddressInstr);
500 }; 484 };
501 485
502
503 // Deoptimization instruction moving a constant stored at 'object_table_index'. 486 // Deoptimization instruction moving a constant stored at 'object_table_index'.
504 class DeoptConstantInstr : public DeoptInstr { 487 class DeoptConstantInstr : public DeoptInstr {
505 public: 488 public:
506 explicit DeoptConstantInstr(intptr_t object_table_index) 489 explicit DeoptConstantInstr(intptr_t object_table_index)
507 : object_table_index_(object_table_index) { 490 : object_table_index_(object_table_index) {
508 ASSERT(object_table_index >= 0); 491 ASSERT(object_table_index >= 0);
509 } 492 }
510 493
511 virtual intptr_t source_index() const { return object_table_index_; } 494 virtual intptr_t source_index() const { return object_table_index_; }
512 virtual DeoptInstr::Kind kind() const { return kConstant; } 495 virtual DeoptInstr::Kind kind() const { return kConstant; }
(...skipping 13 matching lines...) Expand all
526 intptr_t dest_slot) { 509 intptr_t dest_slot) {
527 return CatchEntryStatePair::FromConstant(object_table_index_, dest_slot); 510 return CatchEntryStatePair::FromConstant(object_table_index_, dest_slot);
528 } 511 }
529 512
530 private: 513 private:
531 const intptr_t object_table_index_; 514 const intptr_t object_table_index_;
532 515
533 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); 516 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
534 }; 517 };
535 518
536
537 // Deoptimization instruction moving value from optimized frame at 519 // Deoptimization instruction moving value from optimized frame at
538 // 'source_index' to specified slots in the unoptimized frame. 520 // 'source_index' to specified slots in the unoptimized frame.
539 // 'source_index' represents the slot index of the frame (0 being 521 // 'source_index' represents the slot index of the frame (0 being
540 // first argument) and accounts for saved return address, frame 522 // first argument) and accounts for saved return address, frame
541 // pointer, pool pointer and pc marker. 523 // pointer, pool pointer and pc marker.
542 // Deoptimization instruction moving a CPU register. 524 // Deoptimization instruction moving a CPU register.
543 class DeoptWordInstr : public DeoptInstr { 525 class DeoptWordInstr : public DeoptInstr {
544 public: 526 public:
545 explicit DeoptWordInstr(intptr_t source_index) : source_(source_index) {} 527 explicit DeoptWordInstr(intptr_t source_index) : source_(source_index) {}
546 528
(...skipping 13 matching lines...) Expand all
560 return CatchEntryStatePair::FromMove(source_.StackSlot(deopt_context), 542 return CatchEntryStatePair::FromMove(source_.StackSlot(deopt_context),
561 dest_slot); 543 dest_slot);
562 } 544 }
563 545
564 private: 546 private:
565 const CpuRegisterSource source_; 547 const CpuRegisterSource source_;
566 548
567 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr); 549 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr);
568 }; 550 };
569 551
570
571 class DeoptIntegerInstrBase : public DeoptInstr { 552 class DeoptIntegerInstrBase : public DeoptInstr {
572 public: 553 public:
573 DeoptIntegerInstrBase() {} 554 DeoptIntegerInstrBase() {}
574 555
575 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 556 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
576 const int64_t value = GetValue(deopt_context); 557 const int64_t value = GetValue(deopt_context);
577 if (Smi::IsValid(value)) { 558 if (Smi::IsValid(value)) {
578 *dest_addr = Smi::RawValue(static_cast<intptr_t>(value)); 559 *dest_addr = Smi::RawValue(static_cast<intptr_t>(value));
579 } else { 560 } else {
580 *dest_addr = Smi::RawValue(0); 561 *dest_addr = Smi::RawValue(0);
581 deopt_context->DeferMintMaterialization( 562 deopt_context->DeferMintMaterialization(
582 value, reinterpret_cast<RawMint**>(dest_addr)); 563 value, reinterpret_cast<RawMint**>(dest_addr));
583 } 564 }
584 } 565 }
585 566
586 virtual int64_t GetValue(DeoptContext* deopt_context) = 0; 567 virtual int64_t GetValue(DeoptContext* deopt_context) = 0;
587 568
588 private: 569 private:
589 DISALLOW_COPY_AND_ASSIGN(DeoptIntegerInstrBase); 570 DISALLOW_COPY_AND_ASSIGN(DeoptIntegerInstrBase);
590 }; 571 };
591 572
592
593 class DeoptMintPairInstr : public DeoptIntegerInstrBase { 573 class DeoptMintPairInstr : public DeoptIntegerInstrBase {
594 public: 574 public:
595 explicit DeoptMintPairInstr(intptr_t source_index) 575 explicit DeoptMintPairInstr(intptr_t source_index)
596 : DeoptIntegerInstrBase(), 576 : DeoptIntegerInstrBase(),
597 lo_(LoRegister::decode(source_index)), 577 lo_(LoRegister::decode(source_index)),
598 hi_(HiRegister::decode(source_index)) {} 578 hi_(HiRegister::decode(source_index)) {}
599 579
600 DeoptMintPairInstr(const CpuRegisterSource& lo, const CpuRegisterSource& hi) 580 DeoptMintPairInstr(const CpuRegisterSource& lo, const CpuRegisterSource& hi)
601 : DeoptIntegerInstrBase(), lo_(lo), hi_(hi) {} 581 : DeoptIntegerInstrBase(), lo_(lo), hi_(hi) {}
602 582
(...skipping 18 matching lines...) Expand all
621 class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> {}; 601 class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> {};
622 class HiRegister 602 class HiRegister
623 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {}; 603 : public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> {};
624 604
625 const CpuRegisterSource lo_; 605 const CpuRegisterSource lo_;
626 const CpuRegisterSource hi_; 606 const CpuRegisterSource hi_;
627 607
628 DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr); 608 DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr);
629 }; 609 };
630 610
631
632 template <DeoptInstr::Kind K, typename T> 611 template <DeoptInstr::Kind K, typename T>
633 class DeoptIntInstr : public DeoptIntegerInstrBase { 612 class DeoptIntInstr : public DeoptIntegerInstrBase {
634 public: 613 public:
635 explicit DeoptIntInstr(intptr_t source_index) 614 explicit DeoptIntInstr(intptr_t source_index)
636 : DeoptIntegerInstrBase(), source_(source_index) {} 615 : DeoptIntegerInstrBase(), source_(source_index) {}
637 616
638 explicit DeoptIntInstr(const CpuRegisterSource& source) 617 explicit DeoptIntInstr(const CpuRegisterSource& source)
639 : DeoptIntegerInstrBase(), source_(source) {} 618 : DeoptIntegerInstrBase(), source_(source) {}
640 619
641 virtual intptr_t source_index() const { return source_.source_index(); } 620 virtual intptr_t source_index() const { return source_.source_index(); }
642 virtual DeoptInstr::Kind kind() const { return K; } 621 virtual DeoptInstr::Kind kind() const { return K; }
643 622
644 virtual const char* ArgumentsToCString() const { return source_.ToCString(); } 623 virtual const char* ArgumentsToCString() const { return source_.ToCString(); }
645 624
646 virtual int64_t GetValue(DeoptContext* deopt_context) { 625 virtual int64_t GetValue(DeoptContext* deopt_context) {
647 return static_cast<int64_t>(source_.Value<T>(deopt_context)); 626 return static_cast<int64_t>(source_.Value<T>(deopt_context));
648 } 627 }
649 628
650 private: 629 private:
651 const CpuRegisterSource source_; 630 const CpuRegisterSource source_;
652 631
653 DISALLOW_COPY_AND_ASSIGN(DeoptIntInstr); 632 DISALLOW_COPY_AND_ASSIGN(DeoptIntInstr);
654 }; 633 };
655 634
656
657 typedef DeoptIntInstr<DeoptInstr::kUint32, uint32_t> DeoptUint32Instr; 635 typedef DeoptIntInstr<DeoptInstr::kUint32, uint32_t> DeoptUint32Instr;
658 typedef DeoptIntInstr<DeoptInstr::kInt32, int32_t> DeoptInt32Instr; 636 typedef DeoptIntInstr<DeoptInstr::kInt32, int32_t> DeoptInt32Instr;
659 typedef DeoptIntInstr<DeoptInstr::kMint, int64_t> DeoptMintInstr; 637 typedef DeoptIntInstr<DeoptInstr::kMint, int64_t> DeoptMintInstr;
660 638
661
662 template <DeoptInstr::Kind K, typename Type, typename RawObjectType> 639 template <DeoptInstr::Kind K, typename Type, typename RawObjectType>
663 class DeoptFpuInstr : public DeoptInstr { 640 class DeoptFpuInstr : public DeoptInstr {
664 public: 641 public:
665 explicit DeoptFpuInstr(intptr_t source_index) : source_(source_index) {} 642 explicit DeoptFpuInstr(intptr_t source_index) : source_(source_index) {}
666 643
667 explicit DeoptFpuInstr(const FpuRegisterSource& source) : source_(source) {} 644 explicit DeoptFpuInstr(const FpuRegisterSource& source) : source_(source) {}
668 645
669 virtual intptr_t source_index() const { return source_.source_index(); } 646 virtual intptr_t source_index() const { return source_.source_index(); }
670 virtual DeoptInstr::Kind kind() const { return K; } 647 virtual DeoptInstr::Kind kind() const { return K; }
671 648
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 StubCode::FrameAwaitingMaterialization_entry()->code(); 710 StubCode::FrameAwaitingMaterialization_entry()->code();
734 deopt_context->DeferPcMarkerMaterialization(object_table_index_, dest_addr); 711 deopt_context->DeferPcMarkerMaterialization(object_table_index_, dest_addr);
735 } 712 }
736 713
737 private: 714 private:
738 intptr_t object_table_index_; 715 intptr_t object_table_index_;
739 716
740 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr); 717 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
741 }; 718 };
742 719
743
744 // Deoptimization instruction creating a pool pointer for the code of 720 // Deoptimization instruction creating a pool pointer for the code of
745 // function at 'object_table_index'. 721 // function at 'object_table_index'.
746 class DeoptPpInstr : public DeoptInstr { 722 class DeoptPpInstr : public DeoptInstr {
747 public: 723 public:
748 explicit DeoptPpInstr(intptr_t object_table_index) 724 explicit DeoptPpInstr(intptr_t object_table_index)
749 : object_table_index_(object_table_index) { 725 : object_table_index_(object_table_index) {
750 ASSERT(object_table_index >= 0); 726 ASSERT(object_table_index >= 0);
751 } 727 }
752 728
753 virtual intptr_t source_index() const { return object_table_index_; } 729 virtual intptr_t source_index() const { return object_table_index_; }
754 virtual DeoptInstr::Kind kind() const { return kPp; } 730 virtual DeoptInstr::Kind kind() const { return kPp; }
755 731
756 virtual const char* ArgumentsToCString() const { 732 virtual const char* ArgumentsToCString() const {
757 return Thread::Current()->zone()->PrintToString("%" Pd "", 733 return Thread::Current()->zone()->PrintToString("%" Pd "",
758 object_table_index_); 734 object_table_index_);
759 } 735 }
760 736
761 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 737 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
762 *dest_addr = Smi::RawValue(0); 738 *dest_addr = Smi::RawValue(0);
763 deopt_context->DeferPpMaterialization( 739 deopt_context->DeferPpMaterialization(
764 object_table_index_, reinterpret_cast<RawObject**>(dest_addr)); 740 object_table_index_, reinterpret_cast<RawObject**>(dest_addr));
765 } 741 }
766 742
767 private: 743 private:
768 intptr_t object_table_index_; 744 intptr_t object_table_index_;
769 745
770 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); 746 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
771 }; 747 };
772 748
773
774 // Deoptimization instruction copying the caller saved FP from optimized frame. 749 // Deoptimization instruction copying the caller saved FP from optimized frame.
775 class DeoptCallerFpInstr : public DeoptInstr { 750 class DeoptCallerFpInstr : public DeoptInstr {
776 public: 751 public:
777 DeoptCallerFpInstr() {} 752 DeoptCallerFpInstr() {}
778 753
779 virtual intptr_t source_index() const { return 0; } 754 virtual intptr_t source_index() const { return 0; }
780 virtual DeoptInstr::Kind kind() const { return kCallerFp; } 755 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
781 756
782 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 757 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
783 *dest_addr = deopt_context->GetCallerFp(); 758 *dest_addr = deopt_context->GetCallerFp();
784 deopt_context->SetCallerFp( 759 deopt_context->SetCallerFp(
785 reinterpret_cast<intptr_t>(dest_addr - kSavedCallerFpSlotFromFp)); 760 reinterpret_cast<intptr_t>(dest_addr - kSavedCallerFpSlotFromFp));
786 } 761 }
787 762
788 private: 763 private:
789 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 764 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
790 }; 765 };
791 766
792
793 // Deoptimization instruction copying the caller saved PP from optimized frame. 767 // Deoptimization instruction copying the caller saved PP from optimized frame.
794 class DeoptCallerPpInstr : public DeoptInstr { 768 class DeoptCallerPpInstr : public DeoptInstr {
795 public: 769 public:
796 DeoptCallerPpInstr() {} 770 DeoptCallerPpInstr() {}
797 771
798 virtual intptr_t source_index() const { return 0; } 772 virtual intptr_t source_index() const { return 0; }
799 virtual DeoptInstr::Kind kind() const { return kCallerPp; } 773 virtual DeoptInstr::Kind kind() const { return kCallerPp; }
800 774
801 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 775 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
802 *dest_addr = deopt_context->GetSourcePp(); 776 *dest_addr = deopt_context->GetSourcePp();
803 } 777 }
804 778
805 private: 779 private:
806 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); 780 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr);
807 }; 781 };
808 782
809
810 // Deoptimization instruction copying the caller return address from optimized 783 // Deoptimization instruction copying the caller return address from optimized
811 // frame. 784 // frame.
812 class DeoptCallerPcInstr : public DeoptInstr { 785 class DeoptCallerPcInstr : public DeoptInstr {
813 public: 786 public:
814 DeoptCallerPcInstr() {} 787 DeoptCallerPcInstr() {}
815 788
816 virtual intptr_t source_index() const { return 0; } 789 virtual intptr_t source_index() const { return 0; }
817 virtual DeoptInstr::Kind kind() const { return kCallerPc; } 790 virtual DeoptInstr::Kind kind() const { return kCallerPc; }
818 791
819 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 792 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
820 *dest_addr = deopt_context->GetSourcePc(); 793 *dest_addr = deopt_context->GetSourcePc();
821 } 794 }
822 795
823 private: 796 private:
824 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 797 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
825 }; 798 };
826 799
827
828 // Write reference to a materialized object with the given index into the 800 // Write reference to a materialized object with the given index into the
829 // stack slot. 801 // stack slot.
830 class DeoptMaterializedObjectRefInstr : public DeoptInstr { 802 class DeoptMaterializedObjectRefInstr : public DeoptInstr {
831 public: 803 public:
832 explicit DeoptMaterializedObjectRefInstr(intptr_t index) : index_(index) { 804 explicit DeoptMaterializedObjectRefInstr(intptr_t index) : index_(index) {
833 ASSERT(index >= 0); 805 ASSERT(index >= 0);
834 } 806 }
835 807
836 virtual intptr_t source_index() const { return index_; } 808 virtual intptr_t source_index() const { return index_; }
837 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } 809 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
838 810
839 virtual const char* ArgumentsToCString() const { 811 virtual const char* ArgumentsToCString() const {
840 return Thread::Current()->zone()->PrintToString("#%" Pd "", index_); 812 return Thread::Current()->zone()->PrintToString("#%" Pd "", index_);
841 } 813 }
842 814
843 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 815 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
844 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); 816 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
845 deopt_context->DeferMaterializedObjectRef(index_, dest_addr); 817 deopt_context->DeferMaterializedObjectRef(index_, dest_addr);
846 } 818 }
847 819
848 private: 820 private:
849 intptr_t index_; 821 intptr_t index_;
850 822
851 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); 823 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr);
852 }; 824 };
853 825
854
855 // Materialize object with the given number of fields. 826 // Materialize object with the given number of fields.
856 // Arguments for materialization (class and field-value pairs) are pushed 827 // Arguments for materialization (class and field-value pairs) are pushed
857 // to the expression stack of the bottom-most frame. 828 // to the expression stack of the bottom-most frame.
858 class DeoptMaterializeObjectInstr : public DeoptInstr { 829 class DeoptMaterializeObjectInstr : public DeoptInstr {
859 public: 830 public:
860 explicit DeoptMaterializeObjectInstr(intptr_t field_count) 831 explicit DeoptMaterializeObjectInstr(intptr_t field_count)
861 : field_count_(field_count) { 832 : field_count_(field_count) {
862 ASSERT(field_count >= 0); 833 ASSERT(field_count >= 0);
863 } 834 }
864 835
865 virtual intptr_t source_index() const { return field_count_; } 836 virtual intptr_t source_index() const { return field_count_; }
866 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } 837 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
867 838
868 virtual const char* ArgumentsToCString() const { 839 virtual const char* ArgumentsToCString() const {
869 return Thread::Current()->zone()->PrintToString("%" Pd "", field_count_); 840 return Thread::Current()->zone()->PrintToString("%" Pd "", field_count_);
870 } 841 }
871 842
872 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 843 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
873 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. 844 // This instructions are executed manually by the DeoptimizeWithDeoptInfo.
874 UNREACHABLE(); 845 UNREACHABLE();
875 } 846 }
876 847
877 private: 848 private:
878 intptr_t field_count_; 849 intptr_t field_count_;
879 850
880 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr); 851 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializeObjectInstr);
881 }; 852 };
882 853
883
884 uword DeoptInstr::GetRetAddress(DeoptInstr* instr, 854 uword DeoptInstr::GetRetAddress(DeoptInstr* instr,
885 const ObjectPool& object_table, 855 const ObjectPool& object_table,
886 Code* code) { 856 Code* code) {
887 ASSERT(instr->kind() == kRetAddress); 857 ASSERT(instr->kind() == kRetAddress);
888 DeoptRetAddressInstr* ret_address_instr = 858 DeoptRetAddressInstr* ret_address_instr =
889 static_cast<DeoptRetAddressInstr*>(instr); 859 static_cast<DeoptRetAddressInstr*>(instr);
890 // The following assert may trigger when displaying a backtrace 860 // The following assert may trigger when displaying a backtrace
891 // from the simulator. 861 // from the simulator.
892 ASSERT(Thread::IsDeoptAfter(ret_address_instr->deopt_id())); 862 ASSERT(Thread::IsDeoptAfter(ret_address_instr->deopt_id()));
893 ASSERT(!object_table.IsNull()); 863 ASSERT(!object_table.IsNull());
894 Thread* thread = Thread::Current(); 864 Thread* thread = Thread::Current();
895 Zone* zone = thread->zone(); 865 Zone* zone = thread->zone();
896 Function& function = Function::Handle(zone); 866 Function& function = Function::Handle(zone);
897 function ^= object_table.ObjectAt(ret_address_instr->object_table_index()); 867 function ^= object_table.ObjectAt(ret_address_instr->object_table_index());
898 ASSERT(code != NULL); 868 ASSERT(code != NULL);
899 const Error& error = 869 const Error& error =
900 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function)); 870 Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function));
901 if (!error.IsNull()) { 871 if (!error.IsNull()) {
902 Exceptions::PropagateError(error); 872 Exceptions::PropagateError(error);
903 } 873 }
904 *code ^= function.unoptimized_code(); 874 *code ^= function.unoptimized_code();
905 ASSERT(!code->IsNull()); 875 ASSERT(!code->IsNull());
906 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(), 876 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
907 RawPcDescriptors::kDeopt); 877 RawPcDescriptors::kDeopt);
908 ASSERT(res != 0); 878 ASSERT(res != 0);
909 return res; 879 return res;
910 } 880 }
911 881
912
913 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { 882 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
914 Kind kind = static_cast<Kind>(kind_as_int); 883 Kind kind = static_cast<Kind>(kind_as_int);
915 switch (kind) { 884 switch (kind) {
916 case kWord: 885 case kWord:
917 return new DeoptWordInstr(source_index); 886 return new DeoptWordInstr(source_index);
918 case kDouble: 887 case kDouble:
919 return new DeoptDoubleInstr(source_index); 888 return new DeoptDoubleInstr(source_index);
920 case kMint: 889 case kMint:
921 return new DeoptMintInstr(source_index); 890 return new DeoptMintInstr(source_index);
922 case kMintPair: 891 case kMintPair:
(...skipping 24 matching lines...) Expand all
947 return new DeoptCallerPcInstr(); 916 return new DeoptCallerPcInstr();
948 case kMaterializedObjectRef: 917 case kMaterializedObjectRef:
949 return new DeoptMaterializedObjectRefInstr(source_index); 918 return new DeoptMaterializedObjectRefInstr(source_index);
950 case kMaterializeObject: 919 case kMaterializeObject:
951 return new DeoptMaterializeObjectInstr(source_index); 920 return new DeoptMaterializeObjectInstr(source_index);
952 } 921 }
953 UNREACHABLE(); 922 UNREACHABLE();
954 return NULL; 923 return NULL;
955 } 924 }
956 925
957
958 const char* DeoptInstr::KindToCString(Kind kind) { 926 const char* DeoptInstr::KindToCString(Kind kind) {
959 switch (kind) { 927 switch (kind) {
960 case kWord: 928 case kWord:
961 return "word"; 929 return "word";
962 case kDouble: 930 case kDouble:
963 return "double"; 931 return "double";
964 case kMint: 932 case kMint:
965 case kMintPair: 933 case kMintPair:
966 return "mint"; 934 return "mint";
967 case kInt32: 935 case kInt32:
(...skipping 22 matching lines...) Expand all
990 return "callerpc"; 958 return "callerpc";
991 case kMaterializedObjectRef: 959 case kMaterializedObjectRef:
992 return "ref"; 960 return "ref";
993 case kMaterializeObject: 961 case kMaterializeObject:
994 return "mat"; 962 return "mat";
995 } 963 }
996 UNREACHABLE(); 964 UNREACHABLE();
997 return NULL; 965 return NULL;
998 } 966 }
999 967
1000
1001 class DeoptInfoBuilder::TrieNode : public ZoneAllocated { 968 class DeoptInfoBuilder::TrieNode : public ZoneAllocated {
1002 public: 969 public:
1003 // Construct the root node representing the implicit "shared" terminator 970 // Construct the root node representing the implicit "shared" terminator
1004 // at the end of each deopt info. 971 // at the end of each deopt info.
1005 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) {} 972 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) {}
1006 973
1007 // Construct a node representing a written instruction. 974 // Construct a node representing a written instruction.
1008 TrieNode(DeoptInstr* instruction, intptr_t info_number) 975 TrieNode(DeoptInstr* instruction, intptr_t info_number)
1009 : instruction_(instruction), info_number_(info_number), children_(4) {} 976 : instruction_(instruction), info_number_(info_number), children_(4) {}
1010 977
(...skipping 11 matching lines...) Expand all
1022 return NULL; 989 return NULL;
1023 } 990 }
1024 991
1025 private: 992 private:
1026 const DeoptInstr* instruction_; // Instruction that was written. 993 const DeoptInstr* instruction_; // Instruction that was written.
1027 const intptr_t info_number_; // Index of the deopt info it was written to. 994 const intptr_t info_number_; // Index of the deopt info it was written to.
1028 995
1029 GrowableArray<TrieNode*> children_; 996 GrowableArray<TrieNode*> children_;
1030 }; 997 };
1031 998
1032
1033 DeoptInfoBuilder::DeoptInfoBuilder(Zone* zone, 999 DeoptInfoBuilder::DeoptInfoBuilder(Zone* zone,
1034 const intptr_t num_args, 1000 const intptr_t num_args,
1035 Assembler* assembler) 1001 Assembler* assembler)
1036 : zone_(zone), 1002 : zone_(zone),
1037 instructions_(), 1003 instructions_(),
1038 num_args_(num_args), 1004 num_args_(num_args),
1039 assembler_(assembler), 1005 assembler_(assembler),
1040 trie_root_(new (zone) TrieNode()), 1006 trie_root_(new (zone) TrieNode()),
1041 current_info_number_(0), 1007 current_info_number_(0),
1042 frame_start_(-1), 1008 frame_start_(-1),
1043 materializations_() {} 1009 materializations_() {}
1044 1010
1045
1046 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const { 1011 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
1047 return assembler_->object_pool_wrapper().FindObject(obj); 1012 return assembler_->object_pool_wrapper().FindObject(obj);
1048 } 1013 }
1049 1014
1050
1051 intptr_t DeoptInfoBuilder::CalculateStackIndex( 1015 intptr_t DeoptInfoBuilder::CalculateStackIndex(
1052 const Location& source_loc) const { 1016 const Location& source_loc) const {
1053 return source_loc.stack_index() < 0 1017 return source_loc.stack_index() < 0
1054 ? source_loc.stack_index() + num_args_ 1018 ? source_loc.stack_index() + num_args_
1055 : source_loc.stack_index() + num_args_ + kDartFrameFixedSize; 1019 : source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
1056 } 1020 }
1057 1021
1058
1059 CpuRegisterSource DeoptInfoBuilder::ToCpuRegisterSource(const Location& loc) { 1022 CpuRegisterSource DeoptInfoBuilder::ToCpuRegisterSource(const Location& loc) {
1060 if (loc.IsRegister()) { 1023 if (loc.IsRegister()) {
1061 return CpuRegisterSource(CpuRegisterSource::kRegister, loc.reg()); 1024 return CpuRegisterSource(CpuRegisterSource::kRegister, loc.reg());
1062 } else { 1025 } else {
1063 ASSERT(loc.IsStackSlot()); 1026 ASSERT(loc.IsStackSlot());
1064 return CpuRegisterSource(CpuRegisterSource::kStackSlot, 1027 return CpuRegisterSource(CpuRegisterSource::kStackSlot,
1065 CalculateStackIndex(loc)); 1028 CalculateStackIndex(loc));
1066 } 1029 }
1067 } 1030 }
1068 1031
1069
1070 FpuRegisterSource DeoptInfoBuilder::ToFpuRegisterSource( 1032 FpuRegisterSource DeoptInfoBuilder::ToFpuRegisterSource(
1071 const Location& loc, 1033 const Location& loc,
1072 Location::Kind stack_slot_kind) { 1034 Location::Kind stack_slot_kind) {
1073 if (loc.IsFpuRegister()) { 1035 if (loc.IsFpuRegister()) {
1074 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg()); 1036 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg());
1075 #if defined(TARGET_ARCH_DBC) 1037 #if defined(TARGET_ARCH_DBC)
1076 } else if (loc.IsRegister()) { 1038 } else if (loc.IsRegister()) {
1077 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.reg()); 1039 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.reg());
1078 #endif 1040 #endif
1079 } else { 1041 } else {
1080 ASSERT((stack_slot_kind == Location::kQuadStackSlot) || 1042 ASSERT((stack_slot_kind == Location::kQuadStackSlot) ||
1081 (stack_slot_kind == Location::kDoubleStackSlot)); 1043 (stack_slot_kind == Location::kDoubleStackSlot));
1082 ASSERT(loc.kind() == stack_slot_kind); 1044 ASSERT(loc.kind() == stack_slot_kind);
1083 return FpuRegisterSource(FpuRegisterSource::kStackSlot, 1045 return FpuRegisterSource(FpuRegisterSource::kStackSlot,
1084 CalculateStackIndex(loc)); 1046 CalculateStackIndex(loc));
1085 } 1047 }
1086 } 1048 }
1087 1049
1088 void DeoptInfoBuilder::AddReturnAddress(const Function& function, 1050 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
1089 intptr_t deopt_id, 1051 intptr_t deopt_id,
1090 intptr_t dest_index) { 1052 intptr_t dest_index) {
1091 const intptr_t object_table_index = FindOrAddObjectInTable(function); 1053 const intptr_t object_table_index = FindOrAddObjectInTable(function);
1092 ASSERT(dest_index == FrameSize()); 1054 ASSERT(dest_index == FrameSize());
1093 instructions_.Add(new (zone()) 1055 instructions_.Add(new (zone())
1094 DeoptRetAddressInstr(object_table_index, deopt_id)); 1056 DeoptRetAddressInstr(object_table_index, deopt_id));
1095 } 1057 }
1096 1058
1097
1098 void DeoptInfoBuilder::AddPcMarker(const Function& function, 1059 void DeoptInfoBuilder::AddPcMarker(const Function& function,
1099 intptr_t dest_index) { 1060 intptr_t dest_index) {
1100 intptr_t object_table_index = FindOrAddObjectInTable(function); 1061 intptr_t object_table_index = FindOrAddObjectInTable(function);
1101 ASSERT(dest_index == FrameSize()); 1062 ASSERT(dest_index == FrameSize());
1102 instructions_.Add(new (zone()) DeoptPcMarkerInstr(object_table_index)); 1063 instructions_.Add(new (zone()) DeoptPcMarkerInstr(object_table_index));
1103 } 1064 }
1104 1065
1105
1106 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) { 1066 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
1107 intptr_t object_table_index = FindOrAddObjectInTable(function); 1067 intptr_t object_table_index = FindOrAddObjectInTable(function);
1108 ASSERT(dest_index == FrameSize()); 1068 ASSERT(dest_index == FrameSize());
1109 instructions_.Add(new (zone()) DeoptPpInstr(object_table_index)); 1069 instructions_.Add(new (zone()) DeoptPpInstr(object_table_index));
1110 } 1070 }
1111 1071
1112
1113 void DeoptInfoBuilder::AddCopy(Value* value, 1072 void DeoptInfoBuilder::AddCopy(Value* value,
1114 const Location& source_loc, 1073 const Location& source_loc,
1115 const intptr_t dest_index) { 1074 const intptr_t dest_index) {
1116 DeoptInstr* deopt_instr = NULL; 1075 DeoptInstr* deopt_instr = NULL;
1117 if (source_loc.IsConstant()) { 1076 if (source_loc.IsConstant()) {
1118 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); 1077 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
1119 deopt_instr = new (zone()) DeoptConstantInstr(object_table_index); 1078 deopt_instr = new (zone()) DeoptConstantInstr(object_table_index);
1120 } else if (source_loc.IsInvalid() && 1079 } else if (source_loc.IsInvalid() &&
1121 value->definition()->IsMaterializeObject()) { 1080 value->definition()->IsMaterializeObject()) {
1122 const intptr_t index = 1081 const intptr_t index =
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 default: 1135 default:
1177 UNREACHABLE(); 1136 UNREACHABLE();
1178 break; 1137 break;
1179 } 1138 }
1180 } 1139 }
1181 ASSERT(dest_index == FrameSize()); 1140 ASSERT(dest_index == FrameSize());
1182 ASSERT(deopt_instr != NULL); 1141 ASSERT(deopt_instr != NULL);
1183 instructions_.Add(deopt_instr); 1142 instructions_.Add(deopt_instr);
1184 } 1143 }
1185 1144
1186
1187 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) { 1145 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
1188 ASSERT(dest_index == FrameSize()); 1146 ASSERT(dest_index == FrameSize());
1189 instructions_.Add(new (zone()) DeoptCallerFpInstr()); 1147 instructions_.Add(new (zone()) DeoptCallerFpInstr());
1190 } 1148 }
1191 1149
1192
1193 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) { 1150 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
1194 ASSERT(dest_index == FrameSize()); 1151 ASSERT(dest_index == FrameSize());
1195 instructions_.Add(new (zone()) DeoptCallerPpInstr()); 1152 instructions_.Add(new (zone()) DeoptCallerPpInstr());
1196 } 1153 }
1197 1154
1198
1199 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) { 1155 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
1200 ASSERT(dest_index == FrameSize()); 1156 ASSERT(dest_index == FrameSize());
1201 instructions_.Add(new (zone()) DeoptCallerPcInstr()); 1157 instructions_.Add(new (zone()) DeoptCallerPcInstr());
1202 } 1158 }
1203 1159
1204
1205 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) { 1160 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
1206 ASSERT(dest_index == FrameSize()); 1161 ASSERT(dest_index == FrameSize());
1207 intptr_t object_table_index = FindOrAddObjectInTable(obj); 1162 intptr_t object_table_index = FindOrAddObjectInTable(obj);
1208 instructions_.Add(new (zone()) DeoptConstantInstr(object_table_index)); 1163 instructions_.Add(new (zone()) DeoptConstantInstr(object_table_index));
1209 } 1164 }
1210 1165
1211
1212 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) { 1166 void DeoptInfoBuilder::AddMaterialization(MaterializeObjectInstr* mat) {
1213 const intptr_t index = FindMaterialization(mat); 1167 const intptr_t index = FindMaterialization(mat);
1214 if (index >= 0) { 1168 if (index >= 0) {
1215 return; // Already added. 1169 return; // Already added.
1216 } 1170 }
1217 materializations_.Add(mat); 1171 materializations_.Add(mat);
1218 1172
1219 // Count initialized fields and emit kMaterializeObject instruction. 1173 // Count initialized fields and emit kMaterializeObject instruction.
1220 // There is no need to write nulls into fields because object is null 1174 // There is no need to write nulls into fields because object is null
1221 // initialized by default. 1175 // initialized by default.
1222 intptr_t non_null_fields = 0; 1176 intptr_t non_null_fields = 0;
1223 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1177 for (intptr_t i = 0; i < mat->InputCount(); i++) {
1224 if (!mat->InputAt(i)->BindsToConstantNull()) { 1178 if (!mat->InputAt(i)->BindsToConstantNull()) {
1225 non_null_fields++; 1179 non_null_fields++;
1226 } 1180 }
1227 } 1181 }
1228 1182
1229 instructions_.Add(new (zone()) DeoptMaterializeObjectInstr(non_null_fields)); 1183 instructions_.Add(new (zone()) DeoptMaterializeObjectInstr(non_null_fields));
1230 1184
1231 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1185 for (intptr_t i = 0; i < mat->InputCount(); i++) {
1232 MaterializeObjectInstr* nested_mat = 1186 MaterializeObjectInstr* nested_mat =
1233 mat->InputAt(i)->definition()->AsMaterializeObject(); 1187 mat->InputAt(i)->definition()->AsMaterializeObject();
1234 if (nested_mat != NULL) { 1188 if (nested_mat != NULL) {
1235 AddMaterialization(nested_mat); 1189 AddMaterialization(nested_mat);
1236 } 1190 }
1237 } 1191 }
1238 } 1192 }
1239 1193
1240
1241 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) { 1194 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) {
1242 ASSERT(dest_index == kDartFrameFixedSize); 1195 ASSERT(dest_index == kDartFrameFixedSize);
1243 for (intptr_t i = 0; i < materializations_.length(); i++) { 1196 for (intptr_t i = 0; i < materializations_.length(); i++) {
1244 MaterializeObjectInstr* mat = materializations_[i]; 1197 MaterializeObjectInstr* mat = materializations_[i];
1245 // Class of the instance to allocate. 1198 // Class of the instance to allocate.
1246 AddConstant(mat->cls(), dest_index++); 1199 AddConstant(mat->cls(), dest_index++);
1247 AddConstant(Smi::ZoneHandle(Smi::New(mat->num_variables())), dest_index++); 1200 AddConstant(Smi::ZoneHandle(Smi::New(mat->num_variables())), dest_index++);
1248 for (intptr_t i = 0; i < mat->InputCount(); i++) { 1201 for (intptr_t i = 0; i < mat->InputCount(); i++) {
1249 if (!mat->InputAt(i)->BindsToConstantNull()) { 1202 if (!mat->InputAt(i)->BindsToConstantNull()) {
1250 // Emit offset-value pair. 1203 // Emit offset-value pair.
1251 AddConstant(Smi::ZoneHandle(Smi::New(mat->FieldOffsetAt(i))), 1204 AddConstant(Smi::ZoneHandle(Smi::New(mat->FieldOffsetAt(i))),
1252 dest_index++); 1205 dest_index++);
1253 AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++); 1206 AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++);
1254 } 1207 }
1255 } 1208 }
1256 } 1209 }
1257 return dest_index; 1210 return dest_index;
1258 } 1211 }
1259 1212
1260
1261 intptr_t DeoptInfoBuilder::FindMaterialization( 1213 intptr_t DeoptInfoBuilder::FindMaterialization(
1262 MaterializeObjectInstr* mat) const { 1214 MaterializeObjectInstr* mat) const {
1263 for (intptr_t i = 0; i < materializations_.length(); i++) { 1215 for (intptr_t i = 0; i < materializations_.length(); i++) {
1264 if (materializations_[i] == mat) { 1216 if (materializations_[i] == mat) {
1265 return i; 1217 return i;
1266 } 1218 }
1267 } 1219 }
1268 return -1; 1220 return -1;
1269 } 1221 }
1270 1222
1271
1272 static uint8_t* ZoneReAlloc(uint8_t* ptr, 1223 static uint8_t* ZoneReAlloc(uint8_t* ptr,
1273 intptr_t old_size, 1224 intptr_t old_size,
1274 intptr_t new_size) { 1225 intptr_t new_size) {
1275 return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size); 1226 return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size);
1276 } 1227 }
1277 1228
1278
1279 RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) { 1229 RawTypedData* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
1280 intptr_t length = instructions_.length(); 1230 intptr_t length = instructions_.length();
1281 1231
1282 // Count the number of instructions that are a shared suffix of some deopt 1232 // Count the number of instructions that are a shared suffix of some deopt
1283 // info already written. 1233 // info already written.
1284 TrieNode* suffix = trie_root_; 1234 TrieNode* suffix = trie_root_;
1285 intptr_t suffix_length = 0; 1235 intptr_t suffix_length = 0;
1286 if (FLAG_compress_deopt_info) { 1236 if (FLAG_compress_deopt_info) {
1287 for (intptr_t i = length - 1; i >= 0; --i) { 1237 for (intptr_t i = length - 1; i >= 0; --i) {
1288 TrieNode* node = suffix->FindChild(*instructions_[i]); 1238 TrieNode* node = suffix->FindChild(*instructions_[i]);
1289 if (node == NULL) break; 1239 if (node == NULL) break;
1290 suffix = node; 1240 suffix = node;
1291 ++suffix_length; 1241 ++suffix_length;
1292 } 1242 }
1293 } 1243 }
1294 1244
1295
1296 // Allocate space for the translation. If the shared suffix is longer 1245 // Allocate space for the translation. If the shared suffix is longer
1297 // than one instruction, we replace it with a single suffix instruction. 1246 // than one instruction, we replace it with a single suffix instruction.
1298 const bool use_suffix = suffix_length > 1; 1247 const bool use_suffix = suffix_length > 1;
1299 if (use_suffix) { 1248 if (use_suffix) {
1300 length -= (suffix_length - 1); 1249 length -= (suffix_length - 1);
1301 } 1250 }
1302 1251
1303 uint8_t* buffer; 1252 uint8_t* buffer;
1304 typedef WriteStream::Raw<sizeof(intptr_t), intptr_t> Writer; 1253 typedef WriteStream::Raw<sizeof(intptr_t), intptr_t> Writer;
1305 WriteStream stream(&buffer, ZoneReAlloc, 2 * length * kWordSize); 1254 WriteStream stream(&buffer, ZoneReAlloc, 2 * length * kWordSize);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 ASSERT( 1286 ASSERT(
1338 DeoptInfo::VerifyDecompression(instructions_, deopt_table, deopt_info)); 1287 DeoptInfo::VerifyDecompression(instructions_, deopt_table, deopt_info));
1339 instructions_.Clear(); 1288 instructions_.Clear();
1340 materializations_.Clear(); 1289 materializations_.Clear();
1341 frame_start_ = -1; 1290 frame_start_ = -1;
1342 1291
1343 ++current_info_number_; 1292 ++current_info_number_;
1344 return deopt_info.raw(); 1293 return deopt_info.raw();
1345 } 1294 }
1346 1295
1347
1348 intptr_t DeoptTable::SizeFor(intptr_t length) { 1296 intptr_t DeoptTable::SizeFor(intptr_t length) {
1349 return length * kEntrySize; 1297 return length * kEntrySize;
1350 } 1298 }
1351 1299
1352 void DeoptTable::SetEntry(const Array& table, 1300 void DeoptTable::SetEntry(const Array& table,
1353 intptr_t index, 1301 intptr_t index,
1354 const Smi& offset, 1302 const Smi& offset,
1355 const TypedData& info, 1303 const TypedData& info,
1356 const Smi& reason) { 1304 const Smi& reason) {
1357 ASSERT((table.Length() % kEntrySize) == 0); 1305 ASSERT((table.Length() % kEntrySize) == 0);
1358 intptr_t i = index * kEntrySize; 1306 intptr_t i = index * kEntrySize;
1359 table.SetAt(i, offset); 1307 table.SetAt(i, offset);
1360 table.SetAt(i + 1, info); 1308 table.SetAt(i + 1, info);
1361 table.SetAt(i + 2, reason); 1309 table.SetAt(i + 2, reason);
1362 } 1310 }
1363 1311
1364
1365 intptr_t DeoptTable::GetLength(const Array& table) { 1312 intptr_t DeoptTable::GetLength(const Array& table) {
1366 ASSERT((table.Length() % kEntrySize) == 0); 1313 ASSERT((table.Length() % kEntrySize) == 0);
1367 return table.Length() / kEntrySize; 1314 return table.Length() / kEntrySize;
1368 } 1315 }
1369 1316
1370
1371 void DeoptTable::GetEntry(const Array& table, 1317 void DeoptTable::GetEntry(const Array& table,
1372 intptr_t index, 1318 intptr_t index,
1373 Smi* offset, 1319 Smi* offset,
1374 TypedData* info, 1320 TypedData* info,
1375 Smi* reason) { 1321 Smi* reason) {
1376 intptr_t i = index * kEntrySize; 1322 intptr_t i = index * kEntrySize;
1377 *offset ^= table.At(i); 1323 *offset ^= table.At(i);
1378 *info ^= table.At(i + 1); 1324 *info ^= table.At(i + 1);
1379 *reason ^= table.At(i + 2); 1325 *reason ^= table.At(i + 2);
1380 } 1326 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 GrowableArray<DeoptInstr*> unpacked; 1424 GrowableArray<DeoptInstr*> unpacked;
1479 Unpack(deopt_table, packed, &unpacked); 1425 Unpack(deopt_table, packed, &unpacked);
1480 ASSERT(unpacked.length() == original.length()); 1426 ASSERT(unpacked.length() == original.length());
1481 for (intptr_t i = 0; i < unpacked.length(); ++i) { 1427 for (intptr_t i = 0; i < unpacked.length(); ++i) {
1482 ASSERT(unpacked[i]->Equals(*original[i])); 1428 ASSERT(unpacked[i]->Equals(*original[i]));
1483 } 1429 }
1484 return true; 1430 return true;
1485 } 1431 }
1486 1432
1487 } // namespace dart 1433 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/deopt_instructions.h ('k') | runtime/vm/disassembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698