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

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

Issue 10389023: Fixed compilation time measurement, restructure some code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // Use previously compiled code. 124 // Use previously compiled code.
125 function.SetCode(Code::Handle(function.unoptimized_code())); 125 function.SetCode(Code::Handle(function.unoptimized_code()));
126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); 126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
127 if (FLAG_trace_compiler) { 127 if (FLAG_trace_compiler) {
128 OS::Print("--> restoring entry at 0x%x\n", 128 OS::Print("--> restoring entry at 0x%x\n",
129 Code::Handle(function.unoptimized_code()).EntryPoint()); 129 Code::Handle(function.unoptimized_code()).EntryPoint());
130 } 130 }
131 } 131 }
132 132
133 133
134 static void CompileParsedFunctionHelper( 134 // Return false if bailed out.
135 static bool CompileWithNewCompiler(
135 const ParsedFunction& parsed_function, bool optimized) { 136 const ParsedFunction& parsed_function, bool optimized) {
137 bool is_compiled = false;
136 Isolate* isolate = Isolate::Current(); 138 Isolate* isolate = Isolate::Current();
137 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 139 LongJump* old_base = isolate->long_jump_base();
138 const Function& function = parsed_function.function(); 140 LongJump bailout_jump;
139 const char* function_fullname = function.ToFullyQualifiedCString(); 141 isolate->set_long_jump_base(&bailout_jump);
140 bool is_compiled = false; 142 if (setjmp(*bailout_jump.Set()) == 0) {
141 // TODO(srdjan): Remove once the old compiler has been ripped out. 143 GrowableArray<BlockEntryInstr*> block_order;
142 #if defined(TARGET_ARCH_X64) 144 // TimerScope needs an isolate to be properly terminated in case of a
143 const bool use_new_compiler = true; 145 // LongJump.
144 #else 146 {
145 const bool use_new_compiler = FLAG_use_new_compiler; 147 TimerScope timer(FLAG_compiler_stats,
146 #endif 148 &CompilerStats::graphbuilder_timer,
147 if (use_new_compiler) { 149 isolate);
148 LongJump* old_base = isolate->long_jump_base(); 150 CompilerStats::graphbuilder_timer.Start();
149 LongJump bailout_jump;
150 isolate->set_long_jump_base(&bailout_jump);
151 if (setjmp(*bailout_jump.Set()) == 0) {
152 FlowGraphBuilder graph_builder(parsed_function); 151 FlowGraphBuilder graph_builder(parsed_function);
153 graph_builder.BuildGraph(optimized); 152 graph_builder.BuildGraph(optimized);
154 153
155 // The non-optimizing compiler compiles blocks in reverse postorder, 154 // The non-optimizing compiler compiles blocks in reverse postorder,
156 // because it is a 'natural' order for the human reader of the 155 // because it is a 'natural' order for the human reader of the
157 // generated code. 156 // generated code.
158 intptr_t length = graph_builder.postorder_block_entries().length(); 157 intptr_t length = graph_builder.postorder_block_entries().length();
159 GrowableArray<BlockEntryInstr*> block_order(length);
160 for (intptr_t i = length - 1; i >= 0; --i) { 158 for (intptr_t i = length - 1; i >= 0; --i) {
161 block_order.Add(graph_builder.postorder_block_entries()[i]); 159 block_order.Add(graph_builder.postorder_block_entries()[i]);
162 } 160 }
163 161
164 if (optimized) { 162 if (optimized) {
165 // Transition to optimized code only from unoptimized code ... 163 // Transition to optimized code only from unoptimized code ...
166 // for now. 164 // for now.
167 ASSERT(function.HasCode()); 165 ASSERT(parsed_function.function().HasCode());
168 ASSERT(!function.HasOptimizedCode()); 166 ASSERT(!parsed_function.function().HasOptimizedCode());
169 // Do not use type feedback to optimize a function that was 167 // Do not use type feedback to optimize a function that was
170 // deoptimized too often. 168 // deoptimized too often.
171 if (parsed_function.function().deoptimization_counter() < 169 if (parsed_function.function().deoptimization_counter() <
172 FLAG_deoptimization_counter_threshold) { 170 FLAG_deoptimization_counter_threshold) {
173 // Extract type feedback etc. 171 // Extract type feedback etc.
174 } 172 }
175 } 173 }
176 Assembler assembler; 174 }
177 FlowGraphCompiler graph_compiler(&assembler, parsed_function, 175
178 block_order, optimized); 176 Assembler assembler;
177 FlowGraphCompiler graph_compiler(&assembler, parsed_function,
178 block_order, optimized);
179 {
180 TimerScope timer(FLAG_compiler_stats,
181 &CompilerStats::graphcompiler_timer,
182 isolate);
179 graph_compiler.CompileGraph(); 183 graph_compiler.CompileGraph();
180 184 }
185 {
181 TimerScope timer(FLAG_compiler_stats, 186 TimerScope timer(FLAG_compiler_stats,
182 &CompilerStats::codefinalizer_timer); 187 &CompilerStats::codefinalizer_timer,
183 const Code& code = 188 isolate);
184 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); 189 const Function& function = parsed_function.function();
190 const Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
185 code.set_is_optimized(optimized); 191 code.set_is_optimized(optimized);
186 graph_compiler.FinalizePcDescriptors(code); 192 graph_compiler.FinalizePcDescriptors(code);
187 graph_compiler.FinalizeStackmaps(code); 193 graph_compiler.FinalizeStackmaps(code);
188 graph_compiler.FinalizeVarDescriptors(code); 194 graph_compiler.FinalizeVarDescriptors(code);
189 graph_compiler.FinalizeExceptionHandlers(code); 195 graph_compiler.FinalizeExceptionHandlers(code);
190 if (optimized) { 196 if (optimized) {
191 function.SetCode(code); 197 function.SetCode(code);
192 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); 198 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
193 if (FLAG_trace_compiler) { 199 if (FLAG_trace_compiler) {
194 OS::Print("--> patching entry 0x%x\n", 200 OS::Print("--> patching entry 0x%x\n",
195 Code::Handle(function.unoptimized_code()).EntryPoint()); 201 Code::Handle(function.unoptimized_code()).EntryPoint());
196 } 202 }
197 } else { 203 } else {
198 function.set_unoptimized_code(code); 204 function.set_unoptimized_code(code);
199 function.SetCode(code); 205 function.SetCode(code);
200 ASSERT(CodePatcher::CodeIsPatchable(code)); 206 ASSERT(CodePatcher::CodeIsPatchable(code));
201 } 207 }
202 is_compiled = true;
203 } else {
204 // We bailed out.
205 Error& bailout_error = Error::Handle(
206 isolate->object_store()->sticky_error());
207 isolate->object_store()->clear_sticky_error();
208 if (FLAG_trace_bailout) {
209 OS::Print("%s\n", bailout_error.ToErrorCString());
210 }
211 } 208 }
212 isolate->set_long_jump_base(old_base); 209 is_compiled = true;
210 } else {
211 // We bailed out.
212 Error& bailout_error = Error::Handle(
213 isolate->object_store()->sticky_error());
214 isolate->object_store()->clear_sticky_error();
215 if (FLAG_trace_bailout) {
216 OS::Print("%s\n", bailout_error.ToErrorCString());
217 }
218 is_compiled = false;
213 } 219 }
220 isolate->set_long_jump_base(old_base);
221 return is_compiled;
222 }
214 223
215 if (!is_compiled) { 224
216 Assembler assembler; 225 static void CompileWithOldCompiler(
217 if (optimized) { 226 const ParsedFunction& parsed_function, bool optimized) {
218 // Transition to optimized code only from unoptimized code ... 227 const Function& function = parsed_function.function();
219 // for now. 228 Assembler assembler;
220 ASSERT(function.HasCode()); 229 if (optimized) {
221 ASSERT(!function.HasOptimizedCode()); 230 // Transition to optimized code only from unoptimized code ...
222 // Do not use type feedback to optimize a function that was 231 // for now.
223 // deoptimized too often. 232 ASSERT(function.HasCode());
224 if (parsed_function.function().deoptimization_counter() < 233 ASSERT(!function.HasOptimizedCode());
225 FLAG_deoptimization_counter_threshold) { 234 // Do not use type feedback to optimize a function that was
226 ExtractTypeFeedback( 235 // deoptimized too often.
227 Code::Handle(parsed_function.function().unoptimized_code()), 236 if (parsed_function.function().deoptimization_counter() <
228 parsed_function.node_sequence()); 237 FLAG_deoptimization_counter_threshold) {
229 } 238 TimerScope timer(FLAG_compiler_stats,
230 OptimizingCodeGenerator code_gen(&assembler, parsed_function); 239 &CompilerStats::graphbuilder_timer);
240 ExtractTypeFeedback(
241 Code::Handle(parsed_function.function().unoptimized_code()),
242 parsed_function.node_sequence());
243 }
244 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
245 {
246 TimerScope timer(FLAG_compiler_stats,
247 &CompilerStats::graphcompiler_timer);
231 code_gen.GenerateCode(); 248 code_gen.GenerateCode();
249 }
250 {
232 TimerScope timer(FLAG_compiler_stats, 251 TimerScope timer(FLAG_compiler_stats,
233 &CompilerStats::codefinalizer_timer); 252 &CompilerStats::codefinalizer_timer);
234 Code& code = Code::Handle( 253 Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
235 Code::FinalizeCode(function_fullname, &assembler));
236 code.set_is_optimized(true); 254 code.set_is_optimized(true);
237 code_gen.FinalizePcDescriptors(code); 255 code_gen.FinalizePcDescriptors(code);
238 code_gen.FinalizeStackmaps(code); 256 code_gen.FinalizeStackmaps(code);
239 code_gen.FinalizeExceptionHandlers(code); 257 code_gen.FinalizeExceptionHandlers(code);
240 function.SetCode(code); 258 function.SetCode(code);
241 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); 259 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
242 if (FLAG_trace_compiler) { 260 }
243 OS::Print("--> patching entry 0x%x\n", 261 if (FLAG_trace_compiler) {
244 Code::Handle(function.unoptimized_code()).EntryPoint()); 262 OS::Print("--> patching entry 0x%x\n",
245 } 263 Code::Handle(function.unoptimized_code()).EntryPoint());
246 } else { 264 }
247 // Compile unoptimized code. 265 } else {
248 ASSERT(!function.HasCode()); 266 // Compile unoptimized code.
249 // Compiling first time. 267 ASSERT(!function.HasCode());
250 CodeGenerator code_gen(&assembler, parsed_function); 268 // Compiling first time.
269 CodeGenerator code_gen(&assembler, parsed_function);
270 {
271 TimerScope timer(FLAG_compiler_stats,
272 &CompilerStats::graphcompiler_timer);
251 code_gen.GenerateCode(); 273 code_gen.GenerateCode();
274 }
275 {
252 TimerScope timer(FLAG_compiler_stats, 276 TimerScope timer(FLAG_compiler_stats,
253 &CompilerStats::codefinalizer_timer); 277 &CompilerStats::codefinalizer_timer);
254 const Code& code = 278 const Code& code = Code::Handle(Code::FinalizeCode(function, &assembler));
255 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
256 code.set_is_optimized(false); 279 code.set_is_optimized(false);
257 code_gen.FinalizePcDescriptors(code); 280 code_gen.FinalizePcDescriptors(code);
258 code_gen.FinalizeStackmaps(code); 281 code_gen.FinalizeStackmaps(code);
259 code_gen.FinalizeVarDescriptors(code); 282 code_gen.FinalizeVarDescriptors(code);
260 code_gen.FinalizeExceptionHandlers(code); 283 code_gen.FinalizeExceptionHandlers(code);
261 function.set_unoptimized_code(code); 284 function.set_unoptimized_code(code);
262 function.SetCode(code); 285 function.SetCode(code);
263 ASSERT(CodePatcher::CodeIsPatchable(code)); 286 ASSERT(CodePatcher::CodeIsPatchable(code));
264 } 287 }
265 } 288 }
266 } 289 }
267 290
291 static void CompileParsedFunctionHelper(
292 const ParsedFunction& parsed_function, bool optimized) {
293 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
294 bool is_compiled = false;
295 // TODO(srdjan): Remove once the old compiler has been ripped out.
296 #if defined(TARGET_ARCH_X64)
297 const bool use_new_compiler = true;
298 #else
299 const bool use_new_compiler = FLAG_use_new_compiler;
300 #endif
301 if (use_new_compiler) {
302 is_compiled = CompileWithNewCompiler(parsed_function, optimized);
303 }
304
305 if (!is_compiled) {
306 CompileWithOldCompiler(parsed_function, optimized);
307 }
308 }
309
268 310
269 static RawError* CompileFunctionHelper(const Function& function, 311 static RawError* CompileFunctionHelper(const Function& function,
270 bool optimized) { 312 bool optimized) {
271 Isolate* isolate = Isolate::Current(); 313 Isolate* isolate = Isolate::Current();
272 LongJump* base = isolate->long_jump_base(); 314 LongJump* base = isolate->long_jump_base();
273 LongJump jump; 315 LongJump jump;
274 isolate->set_long_jump_base(&jump); 316 isolate->set_long_jump_base(&jump);
275 // Skips parsing if we need to only install unoptimized code. 317 // Skips parsing if we need to only install unoptimized code.
276 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { 318 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) {
277 InstallUnoptimizedCode(function); 319 InstallUnoptimizedCode(function);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 isolate->object_store()->clear_sticky_error(); 508 isolate->object_store()->clear_sticky_error();
467 isolate->set_long_jump_base(base); 509 isolate->set_long_jump_base(base);
468 return result.raw(); 510 return result.raw();
469 } 511 }
470 UNREACHABLE(); 512 UNREACHABLE();
471 return Object::null(); 513 return Object::null();
472 } 514 }
473 515
474 516
475 } // namespace dart 517 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698