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

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

Issue 15110003: Make deoptimization architecture dependent (it depends on the frame layout). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 18 matching lines...) Expand all
29 from_frame_size_(0), 29 from_frame_size_(0),
30 registers_copy_(NULL), 30 registers_copy_(NULL),
31 fpu_registers_copy_(NULL), 31 fpu_registers_copy_(NULL),
32 num_args_(num_args), 32 num_args_(num_args),
33 deopt_reason_(deopt_reason), 33 deopt_reason_(deopt_reason),
34 isolate_(Isolate::Current()) { 34 isolate_(Isolate::Current()) {
35 from_frame_ = isolate_->deopt_frame_copy(); 35 from_frame_ = isolate_->deopt_frame_copy();
36 from_frame_size_ = isolate_->deopt_frame_copy_size(); 36 from_frame_size_ = isolate_->deopt_frame_copy_size();
37 registers_copy_ = isolate_->deopt_cpu_registers_copy(); 37 registers_copy_ = isolate_->deopt_cpu_registers_copy();
38 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy(); 38 fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy();
39 // The deoptimized frame is filled starting just below the sp of its caller
40 // down to kDartFrameFixedSize words below its own sp.
41 // The chain of frame pointers is recreated from the fp of the caller.
39 caller_fp_ = GetFromFp(); 42 caller_fp_ = GetFromFp();
40 } 43 }
41 44
42 45
43 intptr_t DeoptimizationContext::GetFromFp() const { 46 intptr_t DeoptimizationContext::GetFromFp() const {
44 return from_frame_[from_frame_size_ - num_args_ - 1 - kParamEndSlotFromFp]; 47 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp];
48 }
49
50
51 intptr_t DeoptimizationContext::GetFromPp() const {
52 // Should not be called if the pool pointer is not used.
53 ASSERT(kSavedCallerPpSlotFromFp != kSavedCallerFpSlotFromFp);
54 return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp +
55 kSavedCallerPpSlotFromFp];
45 } 56 }
46 57
47 58
48 intptr_t DeoptimizationContext::GetFromPc() const { 59 intptr_t DeoptimizationContext::GetFromPc() const {
49 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp]; 60 return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp];
50 } 61 }
51 62
63
52 intptr_t DeoptimizationContext::GetCallerFp() const { 64 intptr_t DeoptimizationContext::GetCallerFp() const {
53 return caller_fp_; 65 return caller_fp_;
54 } 66 }
55 67
68
56 void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) { 69 void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) {
57 caller_fp_ = caller_fp; 70 caller_fp_ = caller_fp;
58 } 71 }
59 72
73
60 // Deoptimization instruction moving value from optimized frame at 74 // Deoptimization instruction moving value from optimized frame at
61 // 'from_index' to specified slots in the unoptimized frame. 75 // 'from_index' to specified slots in the unoptimized frame.
62 // 'from_index' represents the slot index of the frame (0 being first argument) 76 // 'from_index' represents the slot index of the frame (0 being first argument)
63 // and accounts for saved return address, frame pointer and pc marker. 77 // and accounts for saved return address, frame pointer and pc marker.
64 class DeoptStackSlotInstr : public DeoptInstr { 78 class DeoptStackSlotInstr : public DeoptInstr {
65 public: 79 public:
66 explicit DeoptStackSlotInstr(intptr_t from_index) 80 explicit DeoptStackSlotInstr(intptr_t from_index)
67 : stack_slot_index_(from_index) { 81 : stack_slot_index_(from_index) {
68 ASSERT(stack_slot_index_ >= 0); 82 ASSERT(stack_slot_index_ >= 0);
69 } 83 }
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 virtual DeoptInstr::Kind kind() const { return kPcMarker; } 483 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
470 484
471 virtual const char* ToCString() const { 485 virtual const char* ToCString() const {
472 return Isolate::Current()->current_zone()->PrintToString( 486 return Isolate::Current()->current_zone()->PrintToString(
473 "pcmark oti:%"Pd"", object_table_index_); 487 "pcmark oti:%"Pd"", object_table_index_);
474 } 488 }
475 489
476 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 490 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
477 Function& function = Function::Handle(deopt_context->isolate()); 491 Function& function = Function::Handle(deopt_context->isolate());
478 function ^= deopt_context->ObjectAt(object_table_index_); 492 function ^= deopt_context->ObjectAt(object_table_index_);
493 if (function.IsNull()) {
494 // Callee's PC marker is not used anymore. Set to 0.
srdjan 2013/05/14 22:16:39 When can this occur?
regis 2013/05/14 23:23:42 The Deoptimize stub sets up a Dart frame that is c
495 *to_addr = 0;
496 return;
497 }
479 const Code& code = 498 const Code& code =
480 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); 499 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
481 ASSERT(!code.IsNull()); 500 ASSERT(!code.IsNull());
482 const intptr_t pc_marker = 501 const intptr_t pc_marker =
483 code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset; 502 code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset;
484 *to_addr = pc_marker; 503 *to_addr = pc_marker;
485 // Increment the deoptimization counter. This effectively increments each 504 // Increment the deoptimization counter. This effectively increments each
486 // function occurring in the optimized frame. 505 // function occurring in the optimized frame.
487 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 506 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
488 if (FLAG_trace_deoptimization) { 507 if (FLAG_trace_deoptimization) {
489 OS::PrintErr("Deoptimizing %s (count %d)\n", 508 OS::PrintErr("Deoptimizing %s (count %d)\n",
490 function.ToFullyQualifiedCString(), 509 function.ToFullyQualifiedCString(),
491 function.deoptimization_counter()); 510 function.deoptimization_counter());
492 } 511 }
493 // Clear invocation counter so that hopefully the function gets reoptimized 512 // Clear invocation counter so that hopefully the function gets reoptimized
494 // only after more feedback has been collected. 513 // only after more feedback has been collected.
495 function.set_usage_counter(0); 514 function.set_usage_counter(0);
496 if (function.HasOptimizedCode()) function.SwitchToUnoptimizedCode(); 515 if (function.HasOptimizedCode()) function.SwitchToUnoptimizedCode();
497 } 516 }
498 517
499 private: 518 private:
500 intptr_t object_table_index_; 519 intptr_t object_table_index_;
501 520
502 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr); 521 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
503 }; 522 };
504 523
505 524
525 // Deoptimization instruction creating a pool pointer for the code of
526 // function at 'object_table_index'.
527 class DeoptPpInstr : public DeoptInstr {
528 public:
529 explicit DeoptPpInstr(intptr_t object_table_index)
530 : object_table_index_(object_table_index) {
531 ASSERT(object_table_index >= 0);
532 }
533
534 virtual intptr_t from_index() const { return object_table_index_; }
535 virtual DeoptInstr::Kind kind() const { return kPp; }
536
537 virtual const char* ToCString() const {
538 return Isolate::Current()->current_zone()->PrintToString(
539 "pp oti:%"Pd"", object_table_index_);
540 }
541
542 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
543 Function& function = Function::Handle(deopt_context->isolate());
544 function ^= deopt_context->ObjectAt(object_table_index_);
545 const Code& code =
546 Code::Handle(deopt_context->isolate(), function.unoptimized_code());
547 ASSERT(!code.IsNull());
548 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
549 *to_addr = pp;
550 }
551
552 private:
553 intptr_t object_table_index_;
554
555 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
556 };
557
558
506 // Deoptimization instruction copying the caller saved FP from optimized frame. 559 // Deoptimization instruction copying the caller saved FP from optimized frame.
507 class DeoptCallerFpInstr : public DeoptInstr { 560 class DeoptCallerFpInstr : public DeoptInstr {
508 public: 561 public:
509 DeoptCallerFpInstr() {} 562 DeoptCallerFpInstr() {}
510 563
511 virtual intptr_t from_index() const { return 0; } 564 virtual intptr_t from_index() const { return 0; }
512 virtual DeoptInstr::Kind kind() const { return kCallerFp; } 565 virtual DeoptInstr::Kind kind() const { return kCallerFp; }
513 566
514 virtual const char* ToCString() const { 567 virtual const char* ToCString() const {
515 return "callerfp"; 568 return "callerfp";
516 } 569 }
517 570
518 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) { 571 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
519 *to_addr = deopt_context->GetCallerFp(); 572 *to_addr = deopt_context->GetCallerFp();
520 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(to_addr)); 573 deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
574 to_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
521 } 575 }
522 576
523 private: 577 private:
524 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr); 578 DISALLOW_COPY_AND_ASSIGN(DeoptCallerFpInstr);
525 }; 579 };
526 580
527 581
582 // Deoptimization instruction copying the caller saved PP from optimized frame.
583 class DeoptCallerPpInstr : public DeoptInstr {
584 public:
585 DeoptCallerPpInstr() {}
586
587 virtual intptr_t from_index() const { return 0; }
588 virtual DeoptInstr::Kind kind() const { return kCallerPp; }
589
590 virtual const char* ToCString() const {
591 return "callerpp";
592 }
593
594 void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
595 *to_addr = deopt_context->GetFromPp();
596 }
597
598 private:
599 DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr);
600 };
601
602
528 // Deoptimization instruction copying the caller return address from optimized 603 // Deoptimization instruction copying the caller return address from optimized
529 // frame. 604 // frame.
530 class DeoptCallerPcInstr : public DeoptInstr { 605 class DeoptCallerPcInstr : public DeoptInstr {
531 public: 606 public:
532 DeoptCallerPcInstr() {} 607 DeoptCallerPcInstr() {}
533 608
534 virtual intptr_t from_index() const { return 0; } 609 virtual intptr_t from_index() const { return 0; }
535 virtual DeoptInstr::Kind kind() const { return kCallerPc; } 610 virtual DeoptInstr::Kind kind() const { return kCallerPc; }
536 611
537 virtual const char* ToCString() const { 612 virtual const char* ToCString() const {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 case kRetAddress: return new DeoptRetAddressInstr(from_index); 770 case kRetAddress: return new DeoptRetAddressInstr(from_index);
696 case kConstant: return new DeoptConstantInstr(from_index); 771 case kConstant: return new DeoptConstantInstr(from_index);
697 case kRegister: return new DeoptRegisterInstr(from_index); 772 case kRegister: return new DeoptRegisterInstr(from_index);
698 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index); 773 case kFpuRegister: return new DeoptFpuRegisterInstr(from_index);
699 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index); 774 case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index);
700 case kFloat32x4FpuRegister: 775 case kFloat32x4FpuRegister:
701 return new DeoptFloat32x4FpuRegisterInstr(from_index); 776 return new DeoptFloat32x4FpuRegisterInstr(from_index);
702 case kUint32x4FpuRegister: 777 case kUint32x4FpuRegister:
703 return new DeoptUint32x4FpuRegisterInstr(from_index); 778 return new DeoptUint32x4FpuRegisterInstr(from_index);
704 case kPcMarker: return new DeoptPcMarkerInstr(from_index); 779 case kPcMarker: return new DeoptPcMarkerInstr(from_index);
780 case kPp: return new DeoptPpInstr(from_index);
705 case kCallerFp: return new DeoptCallerFpInstr(); 781 case kCallerFp: return new DeoptCallerFpInstr();
782 case kCallerPp: return new DeoptCallerPpInstr();
706 case kCallerPc: return new DeoptCallerPcInstr(); 783 case kCallerPc: return new DeoptCallerPcInstr();
707 case kSuffix: return new DeoptSuffixInstr(from_index); 784 case kSuffix: return new DeoptSuffixInstr(from_index);
708 case kMaterializedObjectRef: 785 case kMaterializedObjectRef:
709 return new DeoptMaterializedObjectRefInstr(from_index); 786 return new DeoptMaterializedObjectRefInstr(from_index);
710 case kMaterializeObject: return new DeoptMaterializeObjectInstr(from_index); 787 case kMaterializeObject: return new DeoptMaterializeObjectInstr(from_index);
711 } 788 }
712 UNREACHABLE(); 789 UNREACHABLE();
713 return NULL; 790 return NULL;
714 } 791 }
715 792
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0)); 865 (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
789 #endif 866 #endif
790 const intptr_t object_table_index = FindOrAddObjectInTable(function); 867 const intptr_t object_table_index = FindOrAddObjectInTable(function);
791 ASSERT(to_index == FrameSize()); 868 ASSERT(to_index == FrameSize());
792 instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id)); 869 instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id));
793 } 870 }
794 871
795 872
796 void DeoptInfoBuilder::AddPcMarker(const Function& function, 873 void DeoptInfoBuilder::AddPcMarker(const Function& function,
797 intptr_t to_index) { 874 intptr_t to_index) {
798 // Function object was already added by AddReturnAddress, find it. 875 intptr_t object_table_index = FindOrAddObjectInTable(function);
799 intptr_t from_index = FindOrAddObjectInTable(function);
800 ASSERT(to_index == FrameSize()); 876 ASSERT(to_index == FrameSize());
801 instructions_.Add(new DeoptPcMarkerInstr(from_index)); 877 instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
878 }
879
880
881 void DeoptInfoBuilder::AddPp(const Function& function, intptr_t to_index) {
882 intptr_t object_table_index = FindOrAddObjectInTable(function);
883 ASSERT(to_index == FrameSize());
884 instructions_.Add(new DeoptPpInstr(object_table_index));
802 } 885 }
803 886
804 887
805 void DeoptInfoBuilder::AddCopy(Value* value, 888 void DeoptInfoBuilder::AddCopy(Value* value,
806 const Location& from_loc, 889 const Location& from_loc,
807 const intptr_t to_index) { 890 const intptr_t to_index) {
808 DeoptInstr* deopt_instr = NULL; 891 DeoptInstr* deopt_instr = NULL;
809 if (from_loc.IsConstant()) { 892 if (from_loc.IsConstant()) {
810 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant()); 893 intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant());
811 deopt_instr = new DeoptConstantInstr(object_table_index); 894 deopt_instr = new DeoptConstantInstr(object_table_index);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 instructions_.Add(deopt_instr); 940 instructions_.Add(deopt_instr);
858 } 941 }
859 942
860 943
861 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) { 944 void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) {
862 ASSERT(to_index == FrameSize()); 945 ASSERT(to_index == FrameSize());
863 instructions_.Add(new DeoptCallerFpInstr()); 946 instructions_.Add(new DeoptCallerFpInstr());
864 } 947 }
865 948
866 949
950 void DeoptInfoBuilder::AddCallerPp(intptr_t to_index) {
951 ASSERT(to_index == FrameSize());
952 instructions_.Add(new DeoptCallerPpInstr());
953 }
954
955
867 void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) { 956 void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) {
868 ASSERT(to_index == FrameSize()); 957 ASSERT(to_index == FrameSize());
869 instructions_.Add(new DeoptCallerPcInstr()); 958 instructions_.Add(new DeoptCallerPcInstr());
870 } 959 }
871 960
872 961
873 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t to_index) { 962 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t to_index) {
874 ASSERT(to_index == FrameSize()); 963 ASSERT(to_index == FrameSize());
875 intptr_t object_table_index = FindOrAddObjectInTable(obj); 964 intptr_t object_table_index = FindOrAddObjectInTable(obj);
876 instructions_.Add(new DeoptConstantInstr(object_table_index)); 965 instructions_.Add(new DeoptConstantInstr(object_table_index));
(...skipping 14 matching lines...) Expand all
891 for (intptr_t i = 0; i < mat->InputCount(); i++) { 980 for (intptr_t i = 0; i < mat->InputCount(); i++) {
892 if (!mat->InputAt(i)->BindsToConstantNull()) { 981 if (!mat->InputAt(i)->BindsToConstantNull()) {
893 non_null_fields++; 982 non_null_fields++;
894 } 983 }
895 } 984 }
896 985
897 instructions_.Add(new DeoptMaterializeObjectInstr(non_null_fields)); 986 instructions_.Add(new DeoptMaterializeObjectInstr(non_null_fields));
898 } 987 }
899 988
900 989
901 intptr_t DeoptInfoBuilder::EmitMaterializationArguments() { 990 intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t to_index) {
902 intptr_t slot_idx = 1; // Return address is emitted at 0. 991 ASSERT(to_index == kDartFrameFixedSize);
903 for (intptr_t i = 0; i < materializations_.length(); i++) { 992 for (intptr_t i = 0; i < materializations_.length(); i++) {
904 MaterializeObjectInstr* mat = materializations_[i]; 993 MaterializeObjectInstr* mat = materializations_[i];
905 AddConstant(mat->cls(), slot_idx++); // Class of the instance to allocate. 994 AddConstant(mat->cls(), to_index++); // Class of the instance to allocate.
906 for (intptr_t i = 0; i < mat->InputCount(); i++) { 995 for (intptr_t i = 0; i < mat->InputCount(); i++) {
907 if (!mat->InputAt(i)->BindsToConstantNull()) { 996 if (!mat->InputAt(i)->BindsToConstantNull()) {
908 // Emit field-value pair. 997 // Emit field-value pair.
909 AddConstant(mat->FieldAt(i), slot_idx++); 998 AddConstant(mat->FieldAt(i), to_index++);
910 AddCopy(mat->InputAt(i), mat->LocationAt(i), slot_idx++); 999 AddCopy(mat->InputAt(i), mat->LocationAt(i), to_index++);
911 } 1000 }
912 } 1001 }
913 } 1002 }
914 return slot_idx; 1003 return to_index;
915 } 1004 }
916 1005
917 1006
918 intptr_t DeoptInfoBuilder::FindMaterialization( 1007 intptr_t DeoptInfoBuilder::FindMaterialization(
919 MaterializeObjectInstr* mat) const { 1008 MaterializeObjectInstr* mat) const {
920 for (intptr_t i = 0; i < materializations_.length(); i++) { 1009 for (intptr_t i = 0; i < materializations_.length(); i++) {
921 if (materializations_[i] == mat) { 1010 if (materializations_[i] == mat) {
922 return i; 1011 return i;
923 } 1012 }
924 } 1013 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 Smi* offset, 1096 Smi* offset,
1008 DeoptInfo* info, 1097 DeoptInfo* info,
1009 Smi* reason) { 1098 Smi* reason) {
1010 intptr_t i = index * kEntrySize; 1099 intptr_t i = index * kEntrySize;
1011 *offset ^= table.At(i); 1100 *offset ^= table.At(i);
1012 *info ^= table.At(i + 1); 1101 *info ^= table.At(i + 1);
1013 *reason ^= table.At(i + 2); 1102 *reason ^= table.At(i + 2);
1014 } 1103 }
1015 1104
1016 } // namespace dart 1105 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698