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

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

Powered by Google App Engine
This is Rietveld 408576698