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

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

Issue 16693006: Initial implementation of on-stack replacement (OSR). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Clean up for review. Created 7 years, 6 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/globals.h" // Needed here to get TARGET_ARCH_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 94
95 bool FlowGraphCompiler::HasFinally() const { 95 bool FlowGraphCompiler::HasFinally() const {
96 return parsed_function().function().has_finally(); 96 return parsed_function().function().has_finally();
97 } 97 }
98 98
99 99
100 void FlowGraphCompiler::InitCompiler() { 100 void FlowGraphCompiler::InitCompiler() {
101 pc_descriptors_list_ = new DescriptorList(64); 101 pc_descriptors_list_ = new DescriptorList(64);
102 exception_handlers_list_ = new ExceptionHandlerList(); 102 exception_handlers_list_ = new ExceptionHandlerList();
103 block_info_.Clear(); 103 block_info_.Clear();
104 bool is_leaf = !parsed_function().function().IsClosureFunction() && 104 // Conservative detection of leaf routines used to remove the stack check
105 is_optimizing(); 105 // on function entry.
106 bool is_leaf = !parsed_function().function().IsClosureFunction()
107 && is_optimizing()
108 && !flow_graph().IsCompiledForOsr();
109 // Initialize block info and search optimized (non-OSR) code for calls
110 // indicating a non-leaf routine and calls without IC data indicating
111 // possible reoptimization.
106 for (int i = 0; i < block_order_.length(); ++i) { 112 for (int i = 0; i < block_order_.length(); ++i) {
107 block_info_.Add(new BlockInfo()); 113 block_info_.Add(new BlockInfo());
108 if (is_optimizing()) { 114 if (is_optimizing() && !flow_graph().IsCompiledForOsr()) {
109 BlockEntryInstr* entry = block_order_[i]; 115 BlockEntryInstr* entry = block_order_[i];
110 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 116 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
111 Instruction* current = it.Current(); 117 Instruction* current = it.Current();
112 const ICData* ic_data = NULL;
113 if (current->IsBranch()) { 118 if (current->IsBranch()) {
114 current = current->AsBranch()->comparison(); 119 current = current->AsBranch()->comparison();
115 } 120 }
116 // In optimized code, ICData is always set in the instructions. 121 // In optimized code, ICData is always set in the instructions.
122 const ICData* ic_data = NULL;
117 if (current->IsInstanceCall()) { 123 if (current->IsInstanceCall()) {
118 ic_data = current->AsInstanceCall()->ic_data(); 124 ic_data = current->AsInstanceCall()->ic_data();
119 ASSERT(ic_data != NULL); 125 ASSERT(ic_data != NULL);
120 } else if (current->IsRelationalOp()) { 126 } else if (current->IsRelationalOp()) {
121 ic_data = current->AsRelationalOp()->ic_data(); 127 ic_data = current->AsRelationalOp()->ic_data();
122 ASSERT(ic_data != NULL); 128 ASSERT(ic_data != NULL);
123 } else if (current->IsEqualityCompare()) { 129 } else if (current->IsEqualityCompare()) {
124 ic_data = current->AsEqualityCompare()->ic_data(); 130 ic_data = current->AsEqualityCompare()->ic_data();
125 ASSERT(ic_data != NULL); 131 ASSERT(ic_data != NULL);
126 } 132 }
127 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) { 133 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) {
128 may_reoptimize_ = true; 134 may_reoptimize_ = true;
129 break;
130 } 135 }
131 if (is_leaf && !current->IsCheckStackOverflow()) { 136 if (is_leaf && !current->IsCheckStackOverflow()) {
132 // Note that we do no care if the code contains instructions that 137 // Note that we do not care if the code contains instructions that
133 // can deoptimize. 138 // can deoptimize.
134 LocationSummary* locs = current->locs(); 139 LocationSummary* locs = current->locs();
135 if ((locs != NULL) && locs->can_call()) { 140 if ((locs != NULL) && locs->can_call()) {
136 is_leaf = false; 141 is_leaf = false;
137 } 142 }
138 } 143 }
139 } 144 }
140 } 145 }
141 } 146 }
142 if (is_leaf) { 147 if (is_leaf) {
143 // Remove check stack overflow at entry. 148 // Remove the stack overflow check at function entry.
144 CheckStackOverflowInstr* check = flow_graph_.graph_entry()->normal_entry() 149 Instruction* first = flow_graph_.graph_entry()->normal_entry()->next();
145 ->next()->AsCheckStackOverflow(); 150 ASSERT(first->IsCheckStackOverflow());
146 ASSERT(check != NULL); 151 if (first->IsCheckStackOverflow()) first->RemoveFromGraph();
147 check->RemoveFromGraph();
148 } 152 }
149 } 153 }
150 154
151 155
152 bool FlowGraphCompiler::CanOptimize() { 156 bool FlowGraphCompiler::CanOptimize() {
153 return !FLAG_report_usage_count && 157 return !FLAG_report_usage_count &&
154 (FLAG_optimization_counter_threshold >= 0); 158 (FLAG_optimization_counter_threshold >= 0);
155 } 159 }
156 160
157 161
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 label_address = StubCode::ClosureCallInlineCacheEntryPoint(); 551 label_address = StubCode::ClosureCallInlineCacheEntryPoint();
548 ExternalLabel target_label("InlineCache", label_address); 552 ExternalLabel target_label("InlineCache", label_address);
549 EmitInstanceCall(&target_label, 553 EmitInstanceCall(&target_label,
550 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()), 554 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()),
551 arguments_descriptor, argument_count, 555 arguments_descriptor, argument_count,
552 deopt_id, token_pos, locs); 556 deopt_id, token_pos, locs);
553 return; 557 return;
554 } 558 }
555 // Emit IC call that will count and thus may need reoptimization at 559 // Emit IC call that will count and thus may need reoptimization at
556 // function entry. 560 // function entry.
557 ASSERT(!is_optimizing() || may_reoptimize()); 561 ASSERT(!is_optimizing()
562 || may_reoptimize()
563 || flow_graph().IsCompiledForOsr());
558 switch (ic_data.num_args_tested()) { 564 switch (ic_data.num_args_tested()) {
559 case 1: 565 case 1:
560 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint(); 566 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint();
561 break; 567 break;
562 case 2: 568 case 2:
563 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint(); 569 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint();
564 break; 570 break;
565 case 3: 571 case 3:
566 label_address = 572 label_address =
567 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint(); 573 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint();
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 1087
1082 for (int i = 0; i < len; i++) { 1088 for (int i = 0; i < len; i++) {
1083 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), 1089 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
1084 &Function::ZoneHandle(ic_data.GetTargetAt(i)), 1090 &Function::ZoneHandle(ic_data.GetTargetAt(i)),
1085 ic_data.GetCountAt(i))); 1091 ic_data.GetCountAt(i)));
1086 } 1092 }
1087 sorted->Sort(HighestCountFirst); 1093 sorted->Sort(HighestCountFirst);
1088 } 1094 }
1089 1095
1090 } // namespace dart 1096 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698