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

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

Issue 462403004: Refactor deopt_instructions.cc to minimize boilerplate and duplication. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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"
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 178
179 179
180 void DeoptContext::SetCallerFp(intptr_t caller_fp) { 180 void DeoptContext::SetCallerFp(intptr_t caller_fp) {
181 caller_fp_ = caller_fp; 181 caller_fp_ = caller_fp;
182 } 182 }
183 183
184 184
185 static bool IsObjectInstruction(DeoptInstr::Kind kind) { 185 static bool IsObjectInstruction(DeoptInstr::Kind kind) {
186 switch (kind) { 186 switch (kind) {
187 case DeoptInstr::kConstant: 187 case DeoptInstr::kConstant:
188 case DeoptInstr::kStackSlot:
189 case DeoptInstr::kDoubleStackSlot:
190 case DeoptInstr::kMintStackSlotPair:
191 case DeoptInstr::kFloat32x4StackSlot:
192 case DeoptInstr::kInt32x4StackSlot:
193 case DeoptInstr::kFloat64x2StackSlot:
194 case DeoptInstr::kPp: 188 case DeoptInstr::kPp:
195 case DeoptInstr::kCallerPp: 189 case DeoptInstr::kCallerPp:
196 case DeoptInstr::kMaterializedObjectRef: 190 case DeoptInstr::kMaterializedObjectRef:
191 case DeoptInstr::kFloat32x4:
192 case DeoptInstr::kInt32x4:
193 case DeoptInstr::kFloat64x2:
194 case DeoptInstr::kWord:
195 case DeoptInstr::kDouble:
196 case DeoptInstr::kMintPair:
197 return true; 197 return true;
198 198
199 case DeoptInstr::kRegister:
200 case DeoptInstr::kFpuRegister:
201 case DeoptInstr::kMintRegisterPair:
202 case DeoptInstr::kMintStackSlotRegister:
203 case DeoptInstr::kFloat32x4FpuRegister:
204 case DeoptInstr::kInt32x4FpuRegister:
205 case DeoptInstr::kFloat64x2FpuRegister:
206 // TODO(turnidge): Sometimes we encounter a deopt instruction
207 // with a register source while deoptimizing frames during
208 // debugging but we haven't saved our register set. This
209 // happens specifically when using the VMService to inspect the
210 // stack. In that case, the register values will have been
211 // saved before the StackOverflow runtime call but we do not
212 // actually keep track of which registers were saved and
213 // restored.
214 //
215 // It is possible to save this information at the point of the
216 // StackOverflow runtime call but would require a bit of magic
217 // to either make sure that the registers are pushed on the
218 // stack in a predictable fashion or that we save enough
219 // information to recover them after the fact.
220 //
221 // For now, we punt on these instructions.
222 return false;
223
224 case DeoptInstr::kRetAddress: 199 case DeoptInstr::kRetAddress:
225 case DeoptInstr::kPcMarker: 200 case DeoptInstr::kPcMarker:
226 case DeoptInstr::kCallerFp: 201 case DeoptInstr::kCallerFp:
227 case DeoptInstr::kCallerPc: 202 case DeoptInstr::kCallerPc:
228 return false; 203 return false;
229 204
230 case DeoptInstr::kSuffix: 205 case DeoptInstr::kSuffix:
231 case DeoptInstr::kMaterializeObject: 206 case DeoptInstr::kMaterializeObject:
232 default: 207 default:
233 // We should not encounter these instructions when filling stack slots. 208 // We should not encounter these instructions when filling stack slots.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 Array::Handle(Array::New(dest_frame_size_)); 338 Array::Handle(Array::New(dest_frame_size_));
364 Object& obj = Object::Handle(); 339 Object& obj = Object::Handle();
365 for (intptr_t i = 0; i < dest_frame_size_; i++) { 340 for (intptr_t i = 0; i < dest_frame_size_; i++) {
366 obj = reinterpret_cast<RawObject*>(dest_frame_[i]); 341 obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
367 dest_array.SetAt(i, obj); 342 dest_array.SetAt(i, obj);
368 } 343 }
369 return dest_array.raw(); 344 return dest_array.raw();
370 } 345 }
371 346
372 347
373 // Deoptimization instruction moving value from optimized frame at
374 // 'source_index' to specified slots in the unoptimized frame.
375 // 'source_index' represents the slot index of the frame (0 being
376 // first argument) and accounts for saved return address, frame
377 // pointer, pool pointer and pc marker.
378 class DeoptStackSlotInstr : public DeoptInstr {
379 public:
380 explicit DeoptStackSlotInstr(intptr_t source_index)
381 : stack_slot_index_(source_index) {
382 ASSERT(stack_slot_index_ >= 0);
383 }
384
385 virtual intptr_t source_index() const { return stack_slot_index_; }
386 virtual DeoptInstr::Kind kind() const { return kStackSlot; }
387
388 virtual const char* ToCString() const {
389 return Isolate::Current()->current_zone()->PrintToString(
390 "s%" Pd "", stack_slot_index_);
391 }
392
393 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
394 intptr_t source_index =
395 deopt_context->source_frame_size() - stack_slot_index_ - 1;
396 intptr_t* source_addr =
397 deopt_context->GetSourceFrameAddressAt(source_index);
398 *dest_addr = *source_addr;
399 }
400
401 private:
402 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
403
404 DISALLOW_COPY_AND_ASSIGN(DeoptStackSlotInstr);
405 };
406
407
408 class DeoptDoubleStackSlotInstr : public DeoptInstr {
409 public:
410 explicit DeoptDoubleStackSlotInstr(intptr_t source_index)
411 : stack_slot_index_(source_index) {
412 ASSERT(stack_slot_index_ >= 0);
413 }
414
415 virtual intptr_t source_index() const { return stack_slot_index_; }
416 virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; }
417
418 virtual const char* ToCString() const {
419 return Isolate::Current()->current_zone()->PrintToString(
420 "ds%" Pd "", stack_slot_index_);
421 }
422
423 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
424 intptr_t source_index =
425 deopt_context->source_frame_size() - stack_slot_index_ - 1;
426 double* source_addr = reinterpret_cast<double*>(
427 deopt_context->GetSourceFrameAddressAt(source_index));
428 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
429 deopt_context->DeferDoubleMaterialization(
430 *source_addr, reinterpret_cast<RawDouble**>(dest_addr));
431 }
432
433 private:
434 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
435
436 DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr);
437 };
438
439
440 class DeoptFloat32x4StackSlotInstr : public DeoptInstr {
441 public:
442 explicit DeoptFloat32x4StackSlotInstr(intptr_t source_index)
443 : stack_slot_index_(source_index) {
444 ASSERT(stack_slot_index_ >= 0);
445 }
446
447 virtual intptr_t source_index() const { return stack_slot_index_; }
448 virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; }
449
450 virtual const char* ToCString() const {
451 return Isolate::Current()->current_zone()->PrintToString(
452 "f32x4s%" Pd "", stack_slot_index_);
453 }
454
455 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
456 intptr_t source_index =
457 deopt_context->source_frame_size() - stack_slot_index_ - 1;
458 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
459 deopt_context->GetSourceFrameAddressAt(source_index));
460 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
461 deopt_context->DeferFloat32x4Materialization(
462 *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr));
463 }
464
465 private:
466 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
467
468 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4StackSlotInstr);
469 };
470
471
472 class DeoptFloat64x2StackSlotInstr : public DeoptInstr {
473 public:
474 explicit DeoptFloat64x2StackSlotInstr(intptr_t source_index)
475 : stack_slot_index_(source_index) {
476 ASSERT(stack_slot_index_ >= 0);
477 }
478
479 virtual intptr_t source_index() const { return stack_slot_index_; }
480 virtual DeoptInstr::Kind kind() const { return kFloat64x2StackSlot; }
481
482 virtual const char* ToCString() const {
483 return Isolate::Current()->current_zone()->PrintToString(
484 "f64x2s%" Pd "", stack_slot_index_);
485 }
486
487 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
488 intptr_t source_index =
489 deopt_context->source_frame_size() - stack_slot_index_ - 1;
490 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
491 deopt_context->GetSourceFrameAddressAt(source_index));
492 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
493 deopt_context->DeferFloat64x2Materialization(
494 *source_addr, reinterpret_cast<RawFloat64x2**>(dest_addr));
495 }
496
497 private:
498 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
499
500 DISALLOW_COPY_AND_ASSIGN(DeoptFloat64x2StackSlotInstr);
501 };
502
503
504 class DeoptInt32x4StackSlotInstr : public DeoptInstr {
505 public:
506 explicit DeoptInt32x4StackSlotInstr(intptr_t source_index)
507 : stack_slot_index_(source_index) {
508 ASSERT(stack_slot_index_ >= 0);
509 }
510
511 virtual intptr_t source_index() const { return stack_slot_index_; }
512 virtual DeoptInstr::Kind kind() const { return kInt32x4StackSlot; }
513
514 virtual const char* ToCString() const {
515 return Isolate::Current()->current_zone()->PrintToString(
516 "ui32x4s%" Pd "", stack_slot_index_);
517 }
518
519 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
520 intptr_t source_index =
521 deopt_context->source_frame_size() - stack_slot_index_ - 1;
522 simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
523 deopt_context->GetSourceFrameAddressAt(source_index));
524 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
525 deopt_context->DeferInt32x4Materialization(
526 *source_addr, reinterpret_cast<RawInt32x4**>(dest_addr));
527 }
528
529 private:
530 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
531
532 DISALLOW_COPY_AND_ASSIGN(DeoptInt32x4StackSlotInstr);
533 };
534
535
536 // Deoptimization instruction creating return address using function and 348 // Deoptimization instruction creating return address using function and
537 // deopt-id stored at 'object_table_index'. 349 // deopt-id stored at 'object_table_index'.
538 class DeoptRetAddressInstr : public DeoptInstr { 350 class DeoptRetAddressInstr : public DeoptInstr {
539 public: 351 public:
540 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id) 352 DeoptRetAddressInstr(intptr_t object_table_index, intptr_t deopt_id)
541 : object_table_index_(object_table_index), deopt_id_(deopt_id) { 353 : object_table_index_(object_table_index), deopt_id_(deopt_id) {
542 ASSERT(object_table_index >= 0); 354 ASSERT(object_table_index >= 0);
543 ASSERT(deopt_id >= 0); 355 ASSERT(deopt_id >= 0);
544 } 356 }
545 357
546 explicit DeoptRetAddressInstr(intptr_t source_index) 358 explicit DeoptRetAddressInstr(intptr_t source_index)
547 : object_table_index_(ObjectTableIndex::decode(source_index)), 359 : object_table_index_(ObjectTableIndex::decode(source_index)),
548 deopt_id_(DeoptId::decode(source_index)) { 360 deopt_id_(DeoptId::decode(source_index)) {
549 } 361 }
550 362
551 virtual intptr_t source_index() const { 363 virtual intptr_t source_index() const {
552 return ObjectTableIndex::encode(object_table_index_) | 364 return ObjectTableIndex::encode(object_table_index_) |
553 DeoptId::encode(deopt_id_); 365 DeoptId::encode(deopt_id_);
554 } 366 }
555 367
556 virtual DeoptInstr::Kind kind() const { return kRetAddress; } 368 virtual DeoptInstr::Kind kind() const { return kRetAddress; }
557 369
558 virtual const char* ToCString() const { 370 virtual const char* ArgumentsToCString() const {
559 return Isolate::Current()->current_zone()->PrintToString( 371 return Isolate::Current()->current_zone()->PrintToString(
560 "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_); 372 "%" Pd ", %" Pd "", object_table_index_, deopt_id_);
561 } 373 }
562 374
563 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 375 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
564 Code& code = Code::Handle(deopt_context->isolate()); 376 Code& code = Code::Handle(deopt_context->isolate());
565 code ^= deopt_context->ObjectAt(object_table_index_); 377 code ^= deopt_context->ObjectAt(object_table_index_);
566 ASSERT(!code.IsNull()); 378 ASSERT(!code.IsNull());
567 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_, 379 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
568 RawPcDescriptors::kDeopt); 380 RawPcDescriptors::kDeopt);
569 ASSERT(continue_at_pc != 0); 381 ASSERT(continue_at_pc != 0);
570 *dest_addr = continue_at_pc; 382 *dest_addr = continue_at_pc;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 class DeoptConstantInstr : public DeoptInstr { 416 class DeoptConstantInstr : public DeoptInstr {
605 public: 417 public:
606 explicit DeoptConstantInstr(intptr_t object_table_index) 418 explicit DeoptConstantInstr(intptr_t object_table_index)
607 : object_table_index_(object_table_index) { 419 : object_table_index_(object_table_index) {
608 ASSERT(object_table_index >= 0); 420 ASSERT(object_table_index >= 0);
609 } 421 }
610 422
611 virtual intptr_t source_index() const { return object_table_index_; } 423 virtual intptr_t source_index() const { return object_table_index_; }
612 virtual DeoptInstr::Kind kind() const { return kConstant; } 424 virtual DeoptInstr::Kind kind() const { return kConstant; }
613 425
614 virtual const char* ToCString() const { 426 virtual const char* ArgumentsToCString() const {
615 return Isolate::Current()->current_zone()->PrintToString( 427 return Isolate::Current()->current_zone()->PrintToString(
616 "const oti:%" Pd "", object_table_index_); 428 "%" Pd "", object_table_index_);
617 } 429 }
618 430
619 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 431 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
620 const Object& obj = Object::Handle( 432 const Object& obj = Object::Handle(
621 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_)); 433 deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_));
622 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw(); 434 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
623 } 435 }
624 436
625 private: 437 private:
626 const intptr_t object_table_index_; 438 const intptr_t object_table_index_;
627 439
628 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); 440 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr);
629 }; 441 };
630 442
631 443
444 // Deoptimization instruction moving value from optimized frame at
445 // 'source_index' to specified slots in the unoptimized frame.
446 // 'source_index' represents the slot index of the frame (0 being
447 // first argument) and accounts for saved return address, frame
448 // pointer, pool pointer and pc marker.
632 // Deoptimization instruction moving a CPU register. 449 // Deoptimization instruction moving a CPU register.
633 class DeoptRegisterInstr: public DeoptInstr { 450 class DeoptWordInstr: public DeoptInstr {
634 public: 451 public:
635 explicit DeoptRegisterInstr(intptr_t reg_as_int) 452 explicit DeoptWordInstr(intptr_t source_index)
636 : reg_(static_cast<Register>(reg_as_int)) {} 453 : source_(source_index) {}
637 454
638 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } 455 explicit DeoptWordInstr(const MachineWordSource& source)
639 virtual DeoptInstr::Kind kind() const { return kRegister; } 456 : source_(source) {}
640 457
641 virtual const char* ToCString() const { 458 virtual intptr_t source_index() const { return source_.source_index(); }
642 return Assembler::RegisterName(reg_); 459 virtual DeoptInstr::Kind kind() const { return kWord; }
460
461 virtual const char* ArgumentsToCString() const {
462 return source_.ToCString();
643 } 463 }
644 464
645 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 465 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
646 *dest_addr = deopt_context->RegisterValue(reg_); 466 *dest_addr = source_.Value<intptr_t>(deopt_context);
647 } 467 }
648 468
649 private: 469 private:
650 const Register reg_; 470 const MachineWordSource source_;
651 471
652 DISALLOW_COPY_AND_ASSIGN(DeoptRegisterInstr); 472 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr);
653 }; 473 };
654 474
655 475
656 // Deoptimization instruction moving an XMM register. 476 class DeoptIntegerInstrBase: public DeoptInstr {
657 class DeoptFpuRegisterInstr: public DeoptInstr {
658 public: 477 public:
659 explicit DeoptFpuRegisterInstr(intptr_t reg_as_int) 478 DeoptIntegerInstrBase() { }
660 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
661
662 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
663 virtual DeoptInstr::Kind kind() const { return kFpuRegister; }
664
665 virtual const char* ToCString() const {
666 return Assembler::FpuRegisterName(reg_);
667 }
668 479
669 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 480 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
670 double value = deopt_context->FpuRegisterValue(reg_); 481 const int64_t value = GetValue(deopt_context);
671 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
672 deopt_context->DeferDoubleMaterialization(
673 value, reinterpret_cast<RawDouble**>(dest_addr));
674 }
675
676 private:
677 const FpuRegister reg_;
678
679 DISALLOW_COPY_AND_ASSIGN(DeoptFpuRegisterInstr);
680 };
681
682
683 class DeoptMintRegisterPairInstr: public DeoptInstr {
684 public:
685 DeoptMintRegisterPairInstr(intptr_t lo_reg_as_int, intptr_t hi_reg_as_int)
686 : lo_reg_(static_cast<Register>(lo_reg_as_int)),
687 hi_reg_(static_cast<Register>(hi_reg_as_int)) {}
688
689 virtual intptr_t source_index() const {
690 return EncodeRegisters(static_cast<intptr_t>(lo_reg_),
691 static_cast<intptr_t>(hi_reg_));
692 }
693 virtual DeoptInstr::Kind kind() const { return kMintRegisterPair; }
694
695 virtual const char* ToCString() const {
696 return Isolate::Current()->current_zone()->PrintToString(
697 "int64 register pair: %s,%s", Assembler::RegisterName(hi_reg_),
698 Assembler::RegisterName(lo_reg_));
699 }
700
701 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
702 uint32_t lo_value = deopt_context->RegisterValue(lo_reg_);
703 int32_t hi_value = deopt_context->RegisterValue(hi_reg_);
704 int64_t value = Utils::LowHighTo64Bits(lo_value, hi_value);
705 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
706 if (Smi::IsValid(value)) { 482 if (Smi::IsValid(value)) {
707 *dest_addr = reinterpret_cast<intptr_t>( 483 *dest_addr = Smi::RawValue(static_cast<intptr_t>(value));
708 Smi::New(static_cast<intptr_t>(value)));
709 } else { 484 } else {
485 *dest_addr = Smi::RawValue(0);
710 deopt_context->DeferMintMaterialization( 486 deopt_context->DeferMintMaterialization(
711 value, reinterpret_cast<RawMint**>(dest_addr)); 487 value, reinterpret_cast<RawMint**>(dest_addr));
712 } 488 }
713 } 489 }
714 490
491 virtual int64_t GetValue(DeoptContext* deopt_context) = 0;
492
493 private:
494 DISALLOW_COPY_AND_ASSIGN(DeoptIntegerInstrBase);
495 };
496
497
498 class DeoptMintPairInstr: public DeoptIntegerInstrBase {
499 public:
500 explicit DeoptMintPairInstr(intptr_t source_index)
501 : DeoptIntegerInstrBase(),
502 lo_(LoRegister::decode(source_index)),
503 hi_(HiRegister::decode(source_index)) {
504 }
505
506 DeoptMintPairInstr(const MachineWordSource& lo, const MachineWordSource& hi)
507 : DeoptIntegerInstrBase(), lo_(lo), hi_(hi) {}
508
509 virtual intptr_t source_index() const {
510 return LoRegister::encode(lo_.source_index()) |
511 HiRegister::encode(hi_.source_index());
512 }
513 virtual DeoptInstr::Kind kind() const { return kMintPair; }
514
515 virtual const char* ArgumentsToCString() const {
516 return Isolate::Current()->current_zone()->PrintToString(
517 "%s,%s",
518 lo_.ToCString(),
519 hi_.ToCString());
520 }
521
522 virtual int64_t GetValue(DeoptContext* deopt_context) {
523 return Utils::LowHighTo64Bits(
524 lo_.Value<uint32_t>(deopt_context), hi_.Value<int32_t>(deopt_context));
525 }
526
527 private:
715 static const intptr_t kFieldWidth = kBitsPerWord / 2; 528 static const intptr_t kFieldWidth = kBitsPerWord / 2;
716 class LoRegister : public BitField<intptr_t, 0, kFieldWidth> { }; 529 class LoRegister : public BitField<intptr_t, 0, kFieldWidth> { };
717 class HiRegister : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; 530 class HiRegister : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
718 static intptr_t EncodeRegisters(intptr_t lo_reg_as_int, 531
719 intptr_t hi_reg_as_int) { 532 const MachineWordSource lo_;
720 return LoRegister::encode(lo_reg_as_int) | 533 const MachineWordSource hi_;
721 HiRegister::encode(hi_reg_as_int); 534
535 DISALLOW_COPY_AND_ASSIGN(DeoptMintPairInstr);
536 };
537
538
539 class DeoptUint32Instr : public DeoptIntegerInstrBase {
540 public:
541 explicit DeoptUint32Instr(intptr_t source_index)
542 : DeoptIntegerInstrBase(), source_(source_index) {
722 } 543 }
723 544
724 static intptr_t DecodeLoRegister(intptr_t v) { 545 explicit DeoptUint32Instr(const MachineWordSource& source)
725 return LoRegister::decode(v); 546 : DeoptIntegerInstrBase(), source_(source) {
726 } 547 }
727 548
728 static intptr_t DecodeHiRegister(intptr_t v) { 549 virtual intptr_t source_index() const { return source_.source_index(); }
729 return HiRegister::decode(v); 550 virtual DeoptInstr::Kind kind() const { return kUint32; }
551
552 virtual const char* ArgumentsToCString() const {
553 return source_.ToCString();
554 }
555
556 virtual int64_t GetValue(DeoptContext* deopt_context) {
557 return static_cast<int64_t>(source_.Value<uint32_t>(deopt_context));
730 } 558 }
731 559
732 private: 560 private:
733 const Register lo_reg_; 561 const MachineWordSource source_;
734 const Register hi_reg_;
735 562
736 DISALLOW_COPY_AND_ASSIGN(DeoptMintRegisterPairInstr); 563 DISALLOW_COPY_AND_ASSIGN(DeoptUint32Instr);
737 }; 564 };
738 565
739 566
740 class DeoptMintStackSlotPairInstr: public DeoptInstr { 567 template<DeoptInstr::Kind K,
568 typename Type,
569 typename RawObjectType>
570 class DeoptFpuInstr: public DeoptInstr {
741 public: 571 public:
742 DeoptMintStackSlotPairInstr(intptr_t lo_slot, intptr_t hi_slot) 572 explicit DeoptFpuInstr(intptr_t source_index)
743 : lo_slot_(static_cast<Register>(lo_slot)), 573 : source_(source_index) {}
744 hi_slot_(static_cast<Register>(hi_slot)) {}
745 574
746 virtual intptr_t source_index() const { 575 explicit DeoptFpuInstr(const MachineFpuSource& source)
747 return EncodeSlots(static_cast<intptr_t>(lo_slot_), 576 : source_(source) {}
748 static_cast<intptr_t>(hi_slot_));
749 }
750 virtual DeoptInstr::Kind kind() const { return kMintStackSlotPair; }
751 577
752 virtual const char* ToCString() const { 578 virtual intptr_t source_index() const { return source_.source_index(); }
753 return Isolate::Current()->current_zone()->PrintToString( 579 virtual DeoptInstr::Kind kind() const { return K; }
754 "int64 stack slots: %" Pd", %" Pd "", lo_slot_, hi_slot_); 580
581 virtual const char* ArgumentsToCString() const {
582 return source_.ToCString();
755 } 583 }
756 584
757 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 585 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
758 intptr_t lo_source_index = 586 *dest_addr = Smi::RawValue(0);
759 deopt_context->source_frame_size() - lo_slot_ - 1; 587 deopt_context->DeferMaterialization(
760 int32_t* lo_source_addr = reinterpret_cast<int32_t*>( 588 source_.Value<Type>(deopt_context),
761 deopt_context->GetSourceFrameAddressAt(lo_source_index)); 589 reinterpret_cast<RawObjectType**>(dest_addr));
762 intptr_t hi_source_index =
763 deopt_context->source_frame_size() - hi_slot_ - 1;
764 int32_t* hi_source_addr = reinterpret_cast<int32_t*>(
765 deopt_context->GetSourceFrameAddressAt(hi_source_index));
766 int64_t value = Utils::LowHighTo64Bits(*lo_source_addr, *hi_source_addr);
767 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
768 if (Smi::IsValid(value)) {
769 *dest_addr = reinterpret_cast<intptr_t>(
770 Smi::New(static_cast<intptr_t>(value)));
771 } else {
772 deopt_context->DeferMintMaterialization(
773 value, reinterpret_cast<RawMint**>(dest_addr));
774 }
775 }
776
777 static const intptr_t kFieldWidth = kBitsPerWord / 2;
778 class LoSlot : public BitField<intptr_t, 0, kFieldWidth> { };
779 class HiSlot : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
780 static intptr_t EncodeSlots(intptr_t lo_slot,
781 intptr_t hi_slot) {
782 return LoSlot::encode(lo_slot) |
783 HiSlot::encode(hi_slot);
784 }
785
786 static intptr_t DecodeLoSlot(intptr_t v) {
787 return LoSlot::decode(v);
788 }
789
790 static intptr_t DecodeHiSlot(intptr_t v) {
791 return HiSlot::decode(v);
792 } 590 }
793 591
794 private: 592 private:
795 const intptr_t lo_slot_; 593 const MachineFpuSource source_;
796 const intptr_t hi_slot_;
797 594
798 DISALLOW_COPY_AND_ASSIGN(DeoptMintStackSlotPairInstr); 595 DISALLOW_COPY_AND_ASSIGN(DeoptFpuInstr);
799 }; 596 };
800 597
598 typedef DeoptFpuInstr<DeoptInstr::kDouble, double, RawDouble> DeoptDoubleInstr;
801 599
802 class DeoptMintStackSlotRegisterInstr : public DeoptInstr { 600 // Simd128 types.
803 public: 601 typedef DeoptFpuInstr<DeoptInstr::kFloat32x4, simd128_value_t, RawFloat32x4>
804 DeoptMintStackSlotRegisterInstr(intptr_t source_index, 602 DeoptFloat32x4Instr;
805 intptr_t reg_as_int, 603 typedef DeoptFpuInstr<DeoptInstr::kFloat32x4, simd128_value_t, RawFloat32x4>
806 bool flip) 604 DeoptFloat32x4Instr;
807 : slot_(source_index), 605 typedef DeoptFpuInstr<DeoptInstr::kFloat64x2, simd128_value_t, RawFloat64x2>
808 reg_(static_cast<Register>(reg_as_int)), 606 DeoptFloat64x2Instr;
809 flip_(flip) { 607 typedef DeoptFpuInstr<DeoptInstr::kInt32x4, simd128_value_t, RawInt32x4>
810 // when flip_ is false, stack slot is low bits and reg is high bits. 608 DeoptInt32x4Instr;
811 // when flip_ is true, stack slot is high bits and reg is low bits.
812 }
813
814 virtual intptr_t source_index() const {
815 return Encode(static_cast<intptr_t>(slot_),
816 static_cast<intptr_t>(reg_),
817 flip_ ? 1 : 0);
818 }
819 virtual DeoptInstr::Kind kind() const { return kMintStackSlotRegister; }
820
821 virtual const char* ToCString() const {
822 if (flip_) {
823 return Isolate::Current()->current_zone()->PrintToString(
824 "int64 reg: %s, stack slot: %" Pd "", Assembler::RegisterName(reg_),
825 slot_);
826 } else {
827 return Isolate::Current()->current_zone()->PrintToString(
828 "int64 stack slot: %" Pd", reg: %s", slot_,
829 Assembler::RegisterName(reg_));
830 }
831 }
832
833 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
834 intptr_t slot_source_index =
835 deopt_context->source_frame_size() - slot_ - 1;
836 int32_t* slot_source_addr = reinterpret_cast<int32_t*>(
837 deopt_context->GetSourceFrameAddressAt(slot_source_index));
838 int32_t slot_value = *slot_source_addr;
839 int32_t reg_value = deopt_context->RegisterValue(reg_);
840 int64_t value;
841 if (flip_) {
842 value = Utils::LowHighTo64Bits(reg_value, slot_value);
843 } else {
844 value = Utils::LowHighTo64Bits(slot_value, reg_value);
845 }
846 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
847 if (Smi::IsValid(value)) {
848 *dest_addr = reinterpret_cast<intptr_t>(
849 Smi::New(static_cast<intptr_t>(value)));
850 } else {
851 deopt_context->DeferMintMaterialization(
852 value, reinterpret_cast<RawMint**>(dest_addr));
853 }
854 }
855
856 static const intptr_t kFieldWidth = kBitsPerWord / 2;
857 class Slot : public BitField<intptr_t, 0, kFieldWidth> { };
858 class Reg : public BitField<intptr_t, kFieldWidth, kFieldWidth - 1> { };
859 // 1 bit for the flip.
860 class Flip : public BitField<intptr_t, kFieldWidth * 2 - 1, 1> { };
861
862 static intptr_t Encode(intptr_t slot,
863 intptr_t reg_as_int,
864 bool flip) {
865 return Slot::encode(slot) |
866 Reg::encode(reg_as_int) |
867 Flip::encode(flip ? 1 : 0);
868 }
869
870 static intptr_t DecodeSlot(intptr_t v) {
871 return Slot::decode(v);
872 }
873
874 static intptr_t DecodeReg(intptr_t v) {
875 return Reg::decode(v);
876 }
877
878 static bool DecodeFlip(intptr_t v) {
879 return Flip::decode(v);
880 }
881
882 private:
883 const intptr_t slot_;
884 const Register reg_;
885 const bool flip_;
886 DISALLOW_COPY_AND_ASSIGN(DeoptMintStackSlotRegisterInstr);
887 };
888
889
890 class DeoptUint32RegisterInstr: public DeoptInstr {
891 public:
892 explicit DeoptUint32RegisterInstr(intptr_t reg_as_int)
893 : reg_(static_cast<Register>(reg_as_int)) {}
894
895 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
896 virtual DeoptInstr::Kind kind() const { return kUint32Register; }
897
898 virtual const char* ToCString() const {
899 return Isolate::Current()->current_zone()->PrintToString(
900 "uint32 %s", Assembler::RegisterName(reg_));
901 }
902
903 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
904 uint32_t low = static_cast<uint32_t>(deopt_context->RegisterValue(reg_));
905 int64_t value = Utils::LowHighTo64Bits(low, 0);
906 if (Smi::IsValid(value)) {
907 *dest_addr = reinterpret_cast<intptr_t>(
908 Smi::New(static_cast<intptr_t>(value)));
909 } else {
910 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
911 deopt_context->DeferMintMaterialization(
912 value, reinterpret_cast<RawMint**>(dest_addr));
913 }
914 }
915
916 private:
917 const Register reg_;
918
919 DISALLOW_COPY_AND_ASSIGN(DeoptUint32RegisterInstr);
920 };
921
922
923 class DeoptUint32StackSlotInstr : public DeoptInstr {
924 public:
925 explicit DeoptUint32StackSlotInstr(intptr_t source_index)
926 : stack_slot_index_(source_index) {
927 ASSERT(stack_slot_index_ >= 0);
928 }
929
930 virtual intptr_t source_index() const { return stack_slot_index_; }
931 virtual DeoptInstr::Kind kind() const { return kUint32StackSlot; }
932
933 virtual const char* ToCString() const {
934 return Isolate::Current()->current_zone()->PrintToString(
935 "uint32 s%" Pd "", stack_slot_index_);
936 }
937
938 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
939 intptr_t source_index =
940 deopt_context->source_frame_size() - stack_slot_index_ - 1;
941 uint32_t* source_addr = reinterpret_cast<uint32_t*>(
942 deopt_context->GetSourceFrameAddressAt(source_index));
943 int64_t value = Utils::LowHighTo64Bits(*source_addr, 0);
944 if (Smi::IsValid(value)) {
945 *dest_addr = reinterpret_cast<intptr_t>(
946 Smi::New(static_cast<intptr_t>(value)));
947 } else {
948 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
949 deopt_context->DeferMintMaterialization(
950 value, reinterpret_cast<RawMint**>(dest_addr));
951 }
952 }
953
954 private:
955 const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
956
957 DISALLOW_COPY_AND_ASSIGN(DeoptUint32StackSlotInstr);
958 };
959
960
961 // Deoptimization instruction moving an XMM register.
962 class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr {
963 public:
964 explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int)
965 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
966
967 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
968 virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; }
969
970 virtual const char* ToCString() const {
971 return Isolate::Current()->current_zone()->PrintToString(
972 "%s(f32x4)", Assembler::FpuRegisterName(reg_));
973 }
974
975 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
976 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
977 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
978 deopt_context->DeferFloat32x4Materialization(
979 value, reinterpret_cast<RawFloat32x4**>(dest_addr));
980 }
981
982 private:
983 const FpuRegister reg_;
984
985 DISALLOW_COPY_AND_ASSIGN(DeoptFloat32x4FpuRegisterInstr);
986 };
987
988
989 class DeoptFloat64x2FpuRegisterInstr: public DeoptInstr {
990 public:
991 explicit DeoptFloat64x2FpuRegisterInstr(intptr_t reg_as_int)
992 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
993
994 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
995 virtual DeoptInstr::Kind kind() const { return kFloat64x2FpuRegister; }
996
997 virtual const char* ToCString() const {
998 return Isolate::Current()->current_zone()->PrintToString(
999 "%s(f64x2)", Assembler::FpuRegisterName(reg_));
1000 }
1001
1002 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1003 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
1004 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
1005 deopt_context->DeferFloat64x2Materialization(
1006 value, reinterpret_cast<RawFloat64x2**>(dest_addr));
1007 }
1008
1009 private:
1010 const FpuRegister reg_;
1011
1012 DISALLOW_COPY_AND_ASSIGN(DeoptFloat64x2FpuRegisterInstr);
1013 };
1014
1015
1016 // Deoptimization instruction moving an XMM register.
1017 class DeoptInt32x4FpuRegisterInstr: public DeoptInstr {
1018 public:
1019 explicit DeoptInt32x4FpuRegisterInstr(intptr_t reg_as_int)
1020 : reg_(static_cast<FpuRegister>(reg_as_int)) {}
1021
1022 virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
1023 virtual DeoptInstr::Kind kind() const { return kInt32x4FpuRegister; }
1024
1025 virtual const char* ToCString() const {
1026 return Isolate::Current()->current_zone()->PrintToString(
1027 "%s(f32x4)", Assembler::FpuRegisterName(reg_));
1028 }
1029
1030 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1031 simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
1032 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
1033 deopt_context->DeferInt32x4Materialization(
1034 value, reinterpret_cast<RawInt32x4**>(dest_addr));
1035 }
1036
1037 private:
1038 const FpuRegister reg_;
1039
1040 DISALLOW_COPY_AND_ASSIGN(DeoptInt32x4FpuRegisterInstr);
1041 };
1042
1043 609
1044 // Deoptimization instruction creating a PC marker for the code of 610 // Deoptimization instruction creating a PC marker for the code of
1045 // function at 'object_table_index'. 611 // function at 'object_table_index'.
1046 class DeoptPcMarkerInstr : public DeoptInstr { 612 class DeoptPcMarkerInstr : public DeoptInstr {
1047 public: 613 public:
1048 explicit DeoptPcMarkerInstr(intptr_t object_table_index) 614 explicit DeoptPcMarkerInstr(intptr_t object_table_index)
1049 : object_table_index_(object_table_index) { 615 : object_table_index_(object_table_index) {
1050 ASSERT(object_table_index >= 0); 616 ASSERT(object_table_index >= 0);
1051 } 617 }
1052 618
1053 virtual intptr_t source_index() const { return object_table_index_; } 619 virtual intptr_t source_index() const { return object_table_index_; }
1054 virtual DeoptInstr::Kind kind() const { return kPcMarker; } 620 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
1055 621
1056 virtual const char* ToCString() const { 622 virtual const char* ArgumentsToCString() const {
1057 return Isolate::Current()->current_zone()->PrintToString( 623 return Isolate::Current()->current_zone()->PrintToString(
1058 "pcmark oti:%" Pd "", object_table_index_); 624 "%" Pd "", object_table_index_);
1059 } 625 }
1060 626
1061 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 627 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1062 Code& code = Code::Handle(deopt_context->isolate()); 628 Code& code = Code::Handle(deopt_context->isolate());
1063 code ^= deopt_context->ObjectAt(object_table_index_); 629 code ^= deopt_context->ObjectAt(object_table_index_);
1064 if (code.IsNull()) { 630 if (code.IsNull()) {
1065 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0. 631 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
1066 *dest_addr = 0; 632 *dest_addr = 0;
1067 return; 633 return;
1068 } 634 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 class DeoptPpInstr : public DeoptInstr { 666 class DeoptPpInstr : public DeoptInstr {
1101 public: 667 public:
1102 explicit DeoptPpInstr(intptr_t object_table_index) 668 explicit DeoptPpInstr(intptr_t object_table_index)
1103 : object_table_index_(object_table_index) { 669 : object_table_index_(object_table_index) {
1104 ASSERT(object_table_index >= 0); 670 ASSERT(object_table_index >= 0);
1105 } 671 }
1106 672
1107 virtual intptr_t source_index() const { return object_table_index_; } 673 virtual intptr_t source_index() const { return object_table_index_; }
1108 virtual DeoptInstr::Kind kind() const { return kPp; } 674 virtual DeoptInstr::Kind kind() const { return kPp; }
1109 675
1110 virtual const char* ToCString() const { 676 virtual const char* ArgumentsToCString() const {
1111 return Isolate::Current()->current_zone()->PrintToString( 677 return Isolate::Current()->current_zone()->PrintToString(
1112 "pp oti:%" Pd "", object_table_index_); 678 "%" Pd "", object_table_index_);
1113 } 679 }
1114 680
1115 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 681 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1116 Code& code = Code::Handle(deopt_context->isolate()); 682 Code& code = Code::Handle(deopt_context->isolate());
1117 code ^= deopt_context->ObjectAt(object_table_index_); 683 code ^= deopt_context->ObjectAt(object_table_index_);
1118 ASSERT(!code.IsNull()); 684 ASSERT(!code.IsNull());
1119 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool()); 685 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
1120 *dest_addr = pp; 686 *dest_addr = pp;
1121 } 687 }
1122 688
1123 private: 689 private:
1124 intptr_t object_table_index_; 690 intptr_t object_table_index_;
1125 691
1126 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); 692 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
1127 }; 693 };
1128 694
1129 695
1130 // Deoptimization instruction copying the caller saved FP from optimized frame. 696 // Deoptimization instruction copying the caller saved FP from optimized frame.
1131 class DeoptCallerFpInstr : public DeoptInstr { 697 class DeoptCallerFpInstr : public DeoptInstr {
1132 public: 698 public:
1133 DeoptCallerFpInstr() {} 699 DeoptCallerFpInstr() {}
1134 700
1135 virtual intptr_t source_index() const { return 0; } 701 virtual intptr_t source_index() const { return 0; }
1136 virtual DeoptInstr::Kind kind() const { return kCallerFp; } 702 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
1137 703
1138 virtual const char* ToCString() const {
1139 return "callerfp";
1140 }
1141
1142 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 704 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1143 *dest_addr = deopt_context->GetCallerFp(); 705 *dest_addr = deopt_context->GetCallerFp();
1144 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>( 706 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
1145 dest_addr - (kSavedCallerFpSlotFromFp * kWordSize))); 707 dest_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
1146 } 708 }
1147 709
1148 private: 710 private:
1149 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 711 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
1150 }; 712 };
1151 713
1152 714
1153 // Deoptimization instruction copying the caller saved PP from optimized frame. 715 // Deoptimization instruction copying the caller saved PP from optimized frame.
1154 class DeoptCallerPpInstr : public DeoptInstr { 716 class DeoptCallerPpInstr : public DeoptInstr {
1155 public: 717 public:
1156 DeoptCallerPpInstr() {} 718 DeoptCallerPpInstr() {}
1157 719
1158 virtual intptr_t source_index() const { return 0; } 720 virtual intptr_t source_index() const { return 0; }
1159 virtual DeoptInstr::Kind kind() const { return kCallerPp; } 721 virtual DeoptInstr::Kind kind() const { return kCallerPp; }
1160 722
1161 virtual const char* ToCString() const {
1162 return "callerpp";
1163 }
1164
1165 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 723 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1166 *dest_addr = deopt_context->GetSourcePp(); 724 *dest_addr = deopt_context->GetSourcePp();
1167 } 725 }
1168 726
1169 private: 727 private:
1170 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr); 728 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr);
1171 }; 729 };
1172 730
1173 731
1174 // Deoptimization instruction copying the caller return address from optimized 732 // Deoptimization instruction copying the caller return address from optimized
1175 // frame. 733 // frame.
1176 class DeoptCallerPcInstr : public DeoptInstr { 734 class DeoptCallerPcInstr : public DeoptInstr {
1177 public: 735 public:
1178 DeoptCallerPcInstr() {} 736 DeoptCallerPcInstr() {}
1179 737
1180 virtual intptr_t source_index() const { return 0; } 738 virtual intptr_t source_index() const { return 0; }
1181 virtual DeoptInstr::Kind kind() const { return kCallerPc; } 739 virtual DeoptInstr::Kind kind() const { return kCallerPc; }
1182 740
1183 virtual const char* ToCString() const {
1184 return "callerpc";
1185 }
1186
1187 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 741 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1188 *dest_addr = deopt_context->GetSourcePc(); 742 *dest_addr = deopt_context->GetSourcePc();
1189 } 743 }
1190 744
1191 private: 745 private:
1192 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr); 746 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPcInstr);
1193 }; 747 };
1194 748
1195 749
1196 // Deoptimization instruction that indicates the rest of this DeoptInfo is a 750 // Deoptimization instruction that indicates the rest of this DeoptInfo is a
(...skipping 12 matching lines...) Expand all
1209 : info_number_(InfoNumber::decode(source_index)), 763 : info_number_(InfoNumber::decode(source_index)),
1210 suffix_length_(SuffixLength::decode(source_index)) { 764 suffix_length_(SuffixLength::decode(source_index)) {
1211 } 765 }
1212 766
1213 virtual intptr_t source_index() const { 767 virtual intptr_t source_index() const {
1214 return InfoNumber::encode(info_number_) | 768 return InfoNumber::encode(info_number_) |
1215 SuffixLength::encode(suffix_length_); 769 SuffixLength::encode(suffix_length_);
1216 } 770 }
1217 virtual DeoptInstr::Kind kind() const { return kSuffix; } 771 virtual DeoptInstr::Kind kind() const { return kSuffix; }
1218 772
1219 virtual const char* ToCString() const { 773 virtual const char* ArgumentsToCString() const {
1220 return Isolate::Current()->current_zone()->PrintToString( 774 return Isolate::Current()->current_zone()->PrintToString(
1221 "suffix %" Pd ":%" Pd, info_number_, suffix_length_); 775 "%" Pd ":%" Pd, info_number_, suffix_length_);
1222 } 776 }
1223 777
1224 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 778 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1225 // The deoptimization info is uncompressed by translating away suffixes 779 // The deoptimization info is uncompressed by translating away suffixes
1226 // before executing the instructions. 780 // before executing the instructions.
1227 UNREACHABLE(); 781 UNREACHABLE();
1228 } 782 }
1229 783
1230 private: 784 private:
1231 // Static decoder functions in DeoptInstr have access to the bitfield 785 // Static decoder functions in DeoptInstr have access to the bitfield
(...skipping 16 matching lines...) Expand all
1248 class DeoptMaterializedObjectRefInstr : public DeoptInstr { 802 class DeoptMaterializedObjectRefInstr : public DeoptInstr {
1249 public: 803 public:
1250 explicit DeoptMaterializedObjectRefInstr(intptr_t index) 804 explicit DeoptMaterializedObjectRefInstr(intptr_t index)
1251 : index_(index) { 805 : index_(index) {
1252 ASSERT(index >= 0); 806 ASSERT(index >= 0);
1253 } 807 }
1254 808
1255 virtual intptr_t source_index() const { return index_; } 809 virtual intptr_t source_index() const { return index_; }
1256 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; } 810 virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
1257 811
1258 virtual const char* ToCString() const { 812 virtual const char* ArgumentsToCString() const {
1259 return Isolate::Current()->current_zone()->PrintToString( 813 return Isolate::Current()->current_zone()->PrintToString(
1260 "mat ref #%" Pd "", index_); 814 "#%" Pd "", index_);
1261 } 815 }
1262 816
1263 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 817 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1264 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); 818 *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
1265 deopt_context->DeferMaterializedObjectRef( 819 deopt_context->DeferMaterializedObjectRef(
1266 index_, dest_addr); 820 index_, dest_addr);
1267 } 821 }
1268 822
1269 private: 823 private:
1270 intptr_t index_; 824 intptr_t index_;
1271 825
1272 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr); 826 DISALLOW_COPY_AND_ASSIGN(DeoptMaterializedObjectRefInstr);
1273 }; 827 };
1274 828
1275 829
1276 // Materialize object with the given number of fields. 830 // Materialize object with the given number of fields.
1277 // Arguments for materialization (class and field-value pairs) are pushed 831 // Arguments for materialization (class and field-value pairs) are pushed
1278 // to the expression stack of the bottom-most frame. 832 // to the expression stack of the bottom-most frame.
1279 class DeoptMaterializeObjectInstr : public DeoptInstr { 833 class DeoptMaterializeObjectInstr : public DeoptInstr {
1280 public: 834 public:
1281 explicit DeoptMaterializeObjectInstr(intptr_t field_count) 835 explicit DeoptMaterializeObjectInstr(intptr_t field_count)
1282 : field_count_(field_count) { 836 : field_count_(field_count) {
1283 ASSERT(field_count >= 0); 837 ASSERT(field_count >= 0);
1284 } 838 }
1285 839
1286 virtual intptr_t source_index() const { return field_count_; } 840 virtual intptr_t source_index() const { return field_count_; }
1287 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; } 841 virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
1288 842
1289 virtual const char* ToCString() const { 843 virtual const char* ArgumentsToCString() const {
1290 return Isolate::Current()->current_zone()->PrintToString( 844 return Isolate::Current()->current_zone()->PrintToString(
1291 "mat obj len:%" Pd "", field_count_); 845 "%" Pd "", field_count_);
1292 } 846 }
1293 847
1294 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 848 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
1295 // This instructions are executed manually by the DeoptimizeWithDeoptInfo. 849 // This instructions are executed manually by the DeoptimizeWithDeoptInfo.
1296 UNREACHABLE(); 850 UNREACHABLE();
1297 } 851 }
1298 852
1299 private: 853 private:
1300 intptr_t field_count_; 854 intptr_t field_count_;
1301 855
(...skipping 24 matching lines...) Expand all
1326 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(), 880 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
1327 RawPcDescriptors::kDeopt); 881 RawPcDescriptors::kDeopt);
1328 ASSERT(res != 0); 882 ASSERT(res != 0);
1329 return res; 883 return res;
1330 } 884 }
1331 885
1332 886
1333 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { 887 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
1334 Kind kind = static_cast<Kind>(kind_as_int); 888 Kind kind = static_cast<Kind>(kind_as_int);
1335 switch (kind) { 889 switch (kind) {
1336 case kStackSlot: return new DeoptStackSlotInstr(source_index); 890 case kWord:
1337 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index); 891 return new DeoptWordInstr(source_index);
1338 case kFloat32x4StackSlot: 892 case kDouble:
1339 return new DeoptFloat32x4StackSlotInstr(source_index); 893 return new DeoptDoubleInstr(source_index);
1340 case kFloat64x2StackSlot: 894 case kMintPair:
1341 return new DeoptFloat64x2StackSlotInstr(source_index); 895 return new DeoptMintPairInstr(source_index);
1342 case kInt32x4StackSlot: 896 case kUint32:
1343 return new DeoptInt32x4StackSlotInstr(source_index); 897 return new DeoptUint32Instr(source_index);
1344 case kRetAddress: return new DeoptRetAddressInstr(source_index); 898 case kFloat32x4:
1345 case kConstant: return new DeoptConstantInstr(source_index); 899 return new DeoptFloat32x4Instr(source_index);
1346 case kRegister: return new DeoptRegisterInstr(source_index); 900 case kFloat64x2:
1347 case kFpuRegister: return new DeoptFpuRegisterInstr(source_index); 901 return new DeoptFloat64x2Instr(source_index);
1348 case kMintRegisterPair: { 902 case kInt32x4:
1349 intptr_t lo_reg_as_int = 903 return new DeoptInt32x4Instr(source_index);
1350 DeoptMintRegisterPairInstr::LoRegister::decode(source_index); 904 case kRetAddress:
1351 intptr_t hi_reg_as_int = 905 return new DeoptRetAddressInstr(source_index);
1352 DeoptMintRegisterPairInstr::HiRegister::decode(source_index); 906 case kConstant:
1353 return new DeoptMintRegisterPairInstr(lo_reg_as_int, hi_reg_as_int); 907 return new DeoptConstantInstr(source_index);
1354 } 908 case kPcMarker:
1355 case kMintStackSlotPair: { 909 return new DeoptPcMarkerInstr(source_index);
1356 intptr_t lo_slot = 910 case kPp:
1357 DeoptMintStackSlotPairInstr::LoSlot::decode(source_index); 911 return new DeoptPpInstr(source_index);
1358 intptr_t hi_slot = 912 case kCallerFp:
1359 DeoptMintStackSlotPairInstr::HiSlot::decode(source_index); 913 return new DeoptCallerFpInstr();
1360 return new DeoptMintStackSlotPairInstr(lo_slot, hi_slot); 914 case kCallerPp:
1361 } 915 return new DeoptCallerPpInstr();
1362 case kMintStackSlotRegister: { 916 case kCallerPc:
1363 intptr_t slot = 917 return new DeoptCallerPcInstr();
1364 DeoptMintStackSlotRegisterInstr::Slot::decode(source_index); 918 case kSuffix:
1365 intptr_t reg_as_int = 919 return new DeoptSuffixInstr(source_index);
1366 DeoptMintStackSlotRegisterInstr::Reg::decode(source_index);
1367 bool flip = DeoptMintStackSlotRegisterInstr::Flip::decode(source_index);
1368 return new DeoptMintStackSlotRegisterInstr(slot, reg_as_int, flip);
1369 }
1370 case kUint32Register:
1371 return new DeoptUint32RegisterInstr(source_index);
1372 case kUint32StackSlot:
1373 return new DeoptUint32StackSlotInstr(source_index);
1374 case kFloat32x4FpuRegister:
1375 return new DeoptFloat32x4FpuRegisterInstr(source_index);
1376 case kFloat64x2FpuRegister:
1377 return new DeoptFloat64x2FpuRegisterInstr(source_index);
1378 case kInt32x4FpuRegister:
1379 return new DeoptInt32x4FpuRegisterInstr(source_index);
1380 case kPcMarker: return new DeoptPcMarkerInstr(source_index);
1381 case kPp: return new DeoptPpInstr(source_index);
1382 case kCallerFp: return new DeoptCallerFpInstr();
1383 case kCallerPp: return new DeoptCallerPpInstr();
1384 case kCallerPc: return new DeoptCallerPcInstr();
1385 case kSuffix: return new DeoptSuffixInstr(source_index);
1386 case kMaterializedObjectRef: 920 case kMaterializedObjectRef:
1387 return new DeoptMaterializedObjectRefInstr(source_index); 921 return new DeoptMaterializedObjectRefInstr(source_index);
1388 case kMaterializeObject: 922 case kMaterializeObject:
1389 return new DeoptMaterializeObjectInstr(source_index); 923 return new DeoptMaterializeObjectInstr(source_index);
1390 } 924 }
1391 UNREACHABLE(); 925 UNREACHABLE();
1392 return NULL; 926 return NULL;
1393 } 927 }
1394 928
1395 929
930 const char* DeoptInstr::KindToCString(Kind kind) {
931 switch (kind) {
932 case kWord:
933 return "word";
934 case kDouble:
935 return "double";
936 case kMintPair:
937 return "mint";
938 case kUint32:
939 return "uint32";
940 case kFloat32x4:
941 return "float32x4";
942 case kFloat64x2:
943 return "float64x2";
944 case kInt32x4:
945 return "int32x4";
946 case kRetAddress:
947 return "retaddr";
948 case kConstant:
949 return "const";
950 case kPcMarker:
951 return "pc";
952 case kPp:
953 return "pp";
954 case kCallerFp:
955 return "callerfp";
956 case kCallerPp:
957 return "callerpp";
958 case kCallerPc:
959 return "callerpc";
960 case kSuffix:
961 return "suffix";
962 case kMaterializedObjectRef:
963 return "ref";
964 case kMaterializeObject:
965 return "mat";
966 }
967 UNREACHABLE();
968 return NULL;
969 }
970
971
1396 class DeoptInfoBuilder::TrieNode : public ZoneAllocated { 972 class DeoptInfoBuilder::TrieNode : public ZoneAllocated {
1397 public: 973 public:
1398 // Construct the root node representing the implicit "shared" terminator 974 // Construct the root node representing the implicit "shared" terminator
1399 // at the end of each deopt info. 975 // at the end of each deopt info.
1400 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) { } 976 TrieNode() : instruction_(NULL), info_number_(-1), children_(16) { }
1401 977
1402 // Construct a node representing a written instruction. 978 // Construct a node representing a written instruction.
1403 TrieNode(DeoptInstr* instruction, intptr_t info_number) 979 TrieNode(DeoptInstr* instruction, intptr_t info_number)
1404 : instruction_(instruction), info_number_(info_number), children_(4) { } 980 : instruction_(instruction), info_number_(info_number), children_(4) { }
1405 981
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 1028
1453 1029
1454 intptr_t DeoptInfoBuilder::CalculateStackIndex( 1030 intptr_t DeoptInfoBuilder::CalculateStackIndex(
1455 const Location& source_loc) const { 1031 const Location& source_loc) const {
1456 return source_loc.stack_index() < 0 ? 1032 return source_loc.stack_index() < 0 ?
1457 source_loc.stack_index() + num_args_ : 1033 source_loc.stack_index() + num_args_ :
1458 source_loc.stack_index() + num_args_ + kDartFrameFixedSize; 1034 source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
1459 } 1035 }
1460 1036
1461 1037
1038 MachineWordSource DeoptInfoBuilder::ToMachineWordSource(const Location& loc) {
1039 if (loc.IsRegister()) {
1040 return MachineWordSource(MachineWordSource::kRegister, loc.reg());
1041 } else {
1042 ASSERT(loc.IsStackSlot());
1043 return MachineWordSource(
1044 MachineWordSource::kStackSlot, CalculateStackIndex(loc));
1045 }
1046 }
1047
1048
1049 MachineFpuSource DeoptInfoBuilder::ToMachineFpuSource(
1050 const Location& loc,
1051 Location::Kind stack_slot_kind) {
1052 if (loc.IsFpuRegister()) {
1053 return MachineFpuSource(MachineFpuSource::kRegister, loc.fpu_reg());
1054 } else {
1055 ASSERT((stack_slot_kind == Location::kQuadStackSlot) ||
1056 (stack_slot_kind == Location::kDoubleStackSlot));
1057 ASSERT(loc.kind() == stack_slot_kind);
1058 return MachineFpuSource(
1059 MachineFpuSource::kStackSlot, CalculateStackIndex(loc));
1060 }
1061 }
1062
1462 void DeoptInfoBuilder::AddReturnAddress(const Code& code, 1063 void DeoptInfoBuilder::AddReturnAddress(const Code& code,
1463 intptr_t deopt_id, 1064 intptr_t deopt_id,
1464 intptr_t dest_index) { 1065 intptr_t dest_index) {
1465 // Check that deopt_id exists. 1066 // Check that deopt_id exists.
1466 // TODO(vegorov): verify after deoptimization targets as well. 1067 // TODO(vegorov): verify after deoptimization targets as well.
1467 #ifdef DEBUG 1068 #ifdef DEBUG
1468 ASSERT(Isolate::IsDeoptAfter(deopt_id) || 1069 ASSERT(Isolate::IsDeoptAfter(deopt_id) ||
1469 (code.GetPcForDeoptId(deopt_id, RawPcDescriptors::kDeopt) != 0)); 1070 (code.GetPcForDeoptId(deopt_id, RawPcDescriptors::kDeopt) != 0));
1470 #endif 1071 #endif
1471 const intptr_t object_table_index = FindOrAddObjectInTable(code); 1072 const intptr_t object_table_index = FindOrAddObjectInTable(code);
(...skipping 19 matching lines...) Expand all
1491 } 1092 }
1492 1093
1493 1094
1494 void DeoptInfoBuilder::AddCopy(Value* value, 1095 void DeoptInfoBuilder::AddCopy(Value* value,
1495 const Location& source_loc, 1096 const Location& source_loc,
1496 const intptr_t dest_index) { 1097 const intptr_t dest_index) {
1497 DeoptInstr* deopt_instr = NULL; 1098 DeoptInstr* deopt_instr = NULL;
1498 if (source_loc.IsConstant()) { 1099 if (source_loc.IsConstant()) {
1499 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); 1100 intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
1500 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); 1101 deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index);
1501 } else if (source_loc.IsRegister()) {
1502 if (value->definition()->representation() == kUnboxedUint32) {
1503 deopt_instr = new(isolate()) DeoptUint32RegisterInstr(source_loc.reg());
1504 } else {
1505 ASSERT(value->definition()->representation() == kTagged);
1506 deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg());
1507 }
1508 } else if (source_loc.IsFpuRegister()) {
1509 if (value->definition()->representation() == kUnboxedDouble) {
1510 deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg());
1511 } else if (value->definition()->representation() == kUnboxedFloat32x4) {
1512 deopt_instr =
1513 new(isolate()) DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg());
1514 } else if (value->definition()->representation() == kUnboxedInt32x4) {
1515 deopt_instr =
1516 new(isolate()) DeoptInt32x4FpuRegisterInstr(source_loc.fpu_reg());
1517 } else {
1518 ASSERT(value->definition()->representation() == kUnboxedFloat64x2);
1519 deopt_instr =
1520 new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg());
1521 }
1522 } else if (source_loc.IsStackSlot()) {
1523 if (value->definition()->representation() == kUnboxedUint32) {
1524 intptr_t source_index = CalculateStackIndex(source_loc);
1525 deopt_instr = new(isolate()) DeoptUint32StackSlotInstr(source_index);
1526 } else {
1527 ASSERT(value->definition()->representation() == kTagged);
1528 intptr_t source_index = CalculateStackIndex(source_loc);
1529 deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index);
1530 }
1531 } else if (source_loc.IsDoubleStackSlot()) {
1532 ASSERT(value->definition()->representation() == kUnboxedDouble);
1533 intptr_t source_index = CalculateStackIndex(source_loc);
1534 deopt_instr = new(isolate()) DeoptDoubleStackSlotInstr(source_index);
1535 } else if (source_loc.IsQuadStackSlot()) {
1536 intptr_t source_index = CalculateStackIndex(source_loc);
1537 if (value->definition()->representation() == kUnboxedFloat32x4) {
1538 deopt_instr = new(isolate()) DeoptFloat32x4StackSlotInstr(source_index);
1539 } else if (value->definition()->representation() == kUnboxedInt32x4) {
1540 deopt_instr = new(isolate()) DeoptInt32x4StackSlotInstr(source_index);
1541 } else {
1542 ASSERT(value->definition()->representation() == kUnboxedFloat64x2);
1543 deopt_instr = new(isolate()) DeoptFloat64x2StackSlotInstr(source_index);
1544 }
1545 } else if (source_loc.IsPairLocation()) {
1546 ASSERT(value->definition()->representation() == kUnboxedMint);
1547 // There are four cases to consider here:
1548 // (R = Register, S = Stack slot).
1549 // 1) R, R.
1550 // 2) S, S.
1551 // 3) R, S.
1552 // 4) S, R.
1553 PairLocation* pair = source_loc.AsPairLocation();
1554 if (pair->At(0).IsRegister() && pair->At(1).IsRegister()) {
1555 deopt_instr =
1556 new(isolate()) DeoptMintRegisterPairInstr(pair->At(0).reg(),
1557 pair->At(1).reg());
1558 } else if (pair->At(0).IsStackSlot() && pair->At(1).IsStackSlot()) {
1559 deopt_instr = new(isolate()) DeoptMintStackSlotPairInstr(
1560 CalculateStackIndex(pair->At(0)),
1561 CalculateStackIndex(pair->At(1)));
1562 } else if (pair->At(0).IsRegister() && pair->At(1).IsStackSlot()) {
1563 deopt_instr = new(isolate()) DeoptMintStackSlotRegisterInstr(
1564 CalculateStackIndex(pair->At(1)),
1565 pair->At(0).reg(),
1566 true);
1567 } else {
1568 ASSERT(pair->At(0).IsStackSlot() && pair->At(1).IsRegister());
1569 deopt_instr = new(isolate()) DeoptMintStackSlotRegisterInstr(
1570 CalculateStackIndex(pair->At(0)),
1571 pair->At(1).reg(),
1572 false);
1573 }
1574 } else if (source_loc.IsInvalid() && 1102 } else if (source_loc.IsInvalid() &&
1575 value->definition()->IsMaterializeObject()) { 1103 value->definition()->IsMaterializeObject()) {
1576 const intptr_t index = FindMaterialization( 1104 const intptr_t index = FindMaterialization(
1577 value->definition()->AsMaterializeObject()); 1105 value->definition()->AsMaterializeObject());
1578 ASSERT(index >= 0); 1106 ASSERT(index >= 0);
1579 deopt_instr = new(isolate()) DeoptMaterializedObjectRefInstr(index); 1107 deopt_instr = new(isolate()) DeoptMaterializedObjectRefInstr(index);
1580 } else { 1108 } else {
1581 UNREACHABLE(); 1109 ASSERT(!source_loc.IsInvalid());
1110 switch (value->definition()->representation()) {
1111 case kTagged:
1112 deopt_instr = new(isolate()) DeoptWordInstr(
1113 ToMachineWordSource(source_loc));
1114 break;
1115 case kUnboxedMint: {
1116 ASSERT(source_loc.IsPairLocation());
1117 PairLocation* pair = source_loc.AsPairLocation();
1118 deopt_instr = new(isolate()) DeoptMintPairInstr(
1119 ToMachineWordSource(pair->At(0)),
1120 ToMachineWordSource(pair->At(1)));
1121 break;
1122 }
1123 case kUnboxedUint32:
1124 deopt_instr = new(isolate()) DeoptUint32Instr(
1125 ToMachineWordSource(source_loc));
1126 break;
1127 case kUnboxedDouble:
1128 deopt_instr = new(isolate()) DeoptDoubleInstr(
1129 ToMachineFpuSource(source_loc, Location::kDoubleStackSlot));
1130 break;
1131 case kUnboxedFloat32x4:
1132 deopt_instr = new(isolate()) DeoptFloat32x4Instr(
1133 ToMachineFpuSource(source_loc, Location::kQuadStackSlot));
1134 break;
1135 case kUnboxedFloat64x2:
1136 deopt_instr = new(isolate()) DeoptFloat64x2Instr(
1137 ToMachineFpuSource(source_loc, Location::kQuadStackSlot));
1138 break;
1139 case kUnboxedInt32x4:
1140 deopt_instr = new(isolate()) DeoptInt32x4Instr(
1141 ToMachineFpuSource(source_loc, Location::kQuadStackSlot));
1142 break;
1143 default:
1144 UNREACHABLE();
1145 break;
1146 }
1582 } 1147 }
1583 ASSERT(dest_index == FrameSize()); 1148 ASSERT(dest_index == FrameSize());
1584 ASSERT(deopt_instr != NULL); 1149 ASSERT(deopt_instr != NULL);
1585 instructions_.Add(deopt_instr); 1150 instructions_.Add(deopt_instr);
1586 } 1151 }
1587 1152
1588 1153
1589 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) { 1154 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
1590 ASSERT(dest_index == FrameSize()); 1155 ASSERT(dest_index == FrameSize());
1591 instructions_.Add(new(isolate()) DeoptCallerFpInstr()); 1156 instructions_.Add(new(isolate()) DeoptCallerFpInstr());
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 Smi* offset, 1321 Smi* offset,
1757 DeoptInfo* info, 1322 DeoptInfo* info,
1758 Smi* reason) { 1323 Smi* reason) {
1759 intptr_t i = index * kEntrySize; 1324 intptr_t i = index * kEntrySize;
1760 *offset ^= table.At(i); 1325 *offset ^= table.At(i);
1761 *info ^= table.At(i + 1); 1326 *info ^= table.At(i + 1);
1762 *reason ^= table.At(i + 2); 1327 *reason ^= table.At(i + 2);
1763 } 1328 }
1764 1329
1765 } // namespace dart 1330 } // namespace dart
OLDNEW
« runtime/vm/deopt_instructions.h ('K') | « runtime/vm/deopt_instructions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698