Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| 11 #include "vm/cha.h" | |
| 11 #include "vm/code_generator.h" | 12 #include "vm/code_generator.h" |
| 12 #include "vm/code_patcher.h" | 13 #include "vm/code_patcher.h" |
| 13 #include "vm/dart_entry.h" | 14 #include "vm/dart_entry.h" |
| 14 #include "vm/debugger.h" | 15 #include "vm/debugger.h" |
| 15 #include "vm/deopt_instructions.h" | 16 #include "vm/deopt_instructions.h" |
| 16 #include "vm/exceptions.h" | 17 #include "vm/exceptions.h" |
| 17 #include "vm/flags.h" | 18 #include "vm/flags.h" |
| 18 #include "vm/flow_graph.h" | 19 #include "vm/flow_graph.h" |
| 19 #include "vm/flow_graph_allocator.h" | 20 #include "vm/flow_graph_allocator.h" |
| 20 #include "vm/flow_graph_builder.h" | 21 #include "vm/flow_graph_builder.h" |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 bool optimized, | 246 bool optimized, |
| 246 intptr_t osr_id) { | 247 intptr_t osr_id) { |
| 247 const Function& function = parsed_function->function(); | 248 const Function& function = parsed_function->function(); |
| 248 if (optimized && !function.IsOptimizable()) { | 249 if (optimized && !function.IsOptimizable()) { |
| 249 return false; | 250 return false; |
| 250 } | 251 } |
| 251 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); | 252 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); |
| 252 bool is_compiled = false; | 253 bool is_compiled = false; |
| 253 Isolate* isolate = Isolate::Current(); | 254 Isolate* isolate = Isolate::Current(); |
| 254 HANDLESCOPE(isolate); | 255 HANDLESCOPE(isolate); |
| 255 isolate->set_cha_used(false); | |
| 256 | 256 |
| 257 // We may reattempt compilation if the function needs to be assembled using | 257 // We may reattempt compilation if the function needs to be assembled using |
| 258 // far branches on ARM and MIPS. In the else branch of the setjmp call, | 258 // far branches on ARM and MIPS. In the else branch of the setjmp call, |
| 259 // done is set to false, and use_far_branches is set to true if there is a | 259 // done is set to false, and use_far_branches is set to true if there is a |
| 260 // longjmp from the ARM or MIPS assemblers. In all other paths through this | 260 // longjmp from the ARM or MIPS assemblers. In all other paths through this |
| 261 // while loop, done is set to true. use_far_branches is always false on ia32 | 261 // while loop, done is set to true. use_far_branches is always false on ia32 |
| 262 // and x64. | 262 // and x64. |
| 263 bool done = false; | 263 bool done = false; |
| 264 // volatile because the variable may be clobbered by a longjmp. | 264 // volatile because the variable may be clobbered by a longjmp. |
| 265 volatile bool use_far_branches = false; | 265 volatile bool use_far_branches = false; |
| 266 while (!done) { | 266 while (!done) { |
| 267 const intptr_t prev_deopt_id = isolate->deopt_id(); | 267 const intptr_t prev_deopt_id = isolate->deopt_id(); |
| 268 isolate->set_deopt_id(0); | 268 isolate->set_deopt_id(0); |
| 269 LongJumpScope jump; | 269 LongJumpScope jump; |
| 270 if (setjmp(*jump.Set()) == 0) { | 270 if (setjmp(*jump.Set()) == 0) { |
| 271 FlowGraph* flow_graph = NULL; | 271 FlowGraph* flow_graph = NULL; |
| 272 | |
| 273 // Class hierarchy analysis is registered with the isolate in the | |
| 274 // constructor and unregisters itself upon destruction. | |
| 275 CHA cha(isolate); | |
| 276 | |
| 272 // TimerScope needs an isolate to be properly terminated in case of a | 277 // TimerScope needs an isolate to be properly terminated in case of a |
| 273 // LongJump. | 278 // LongJump. |
| 274 { | 279 { |
| 275 TimerScope timer(FLAG_compiler_stats, | 280 TimerScope timer(FLAG_compiler_stats, |
| 276 &CompilerStats::graphbuilder_timer, | 281 &CompilerStats::graphbuilder_timer, |
| 277 isolate); | 282 isolate); |
| 278 ZoneGrowableArray<const ICData*>* ic_data_array = | 283 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 279 new(isolate) ZoneGrowableArray<const ICData*>(); | 284 new(isolate) ZoneGrowableArray<const ICData*>(); |
| 280 if (optimized) { | 285 if (optimized) { |
| 281 ASSERT(function.HasCode()); | 286 ASSERT(function.HasCode()); |
| 282 // Extract type feedback before the graph is built, as the graph | 287 // Extract type feedback before the graph is built, as the graph |
| 283 // builder uses it to attach it to nodes. | 288 // builder uses it to attach it to nodes. |
| 284 ASSERT(function.deoptimization_counter() < | 289 ASSERT(function.deoptimization_counter() < |
| 285 FLAG_deoptimization_counter_threshold); | 290 FLAG_deoptimization_counter_threshold); |
| 286 function.RestoreICDataMap(ic_data_array); | 291 function.RestoreICDataMap(ic_data_array); |
| 287 } | 292 } |
| 288 | 293 |
| 294 | |
| 289 // Build the flow graph. | 295 // Build the flow graph. |
| 290 FlowGraphBuilder builder(parsed_function, | 296 FlowGraphBuilder builder(parsed_function, |
| 291 *ic_data_array, | 297 *ic_data_array, |
| 292 NULL, // NULL = not inlining. | 298 NULL, // NULL = not inlining. |
| 293 osr_id, | 299 osr_id, |
| 294 optimized); | 300 optimized); |
| 295 flow_graph = builder.BuildGraph(); | 301 flow_graph = builder.BuildGraph(); |
| 296 } | 302 } |
| 297 | 303 |
| 298 if (FLAG_print_flow_graph || | 304 if (FLAG_print_flow_graph || |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 isolate); | 544 isolate); |
| 539 graph_compiler.CompileGraph(); | 545 graph_compiler.CompileGraph(); |
| 540 } | 546 } |
| 541 { | 547 { |
| 542 TimerScope timer(FLAG_compiler_stats, | 548 TimerScope timer(FLAG_compiler_stats, |
| 543 &CompilerStats::codefinalizer_timer, | 549 &CompilerStats::codefinalizer_timer, |
| 544 isolate); | 550 isolate); |
| 545 const Code& code = Code::Handle( | 551 const Code& code = Code::Handle( |
| 546 Code::FinalizeCode(function, &assembler, optimized)); | 552 Code::FinalizeCode(function, &assembler, optimized)); |
| 547 code.set_is_optimized(optimized); | 553 code.set_is_optimized(optimized); |
| 548 // CHA should not be used for unoptimized code. | |
| 549 ASSERT(optimized || !isolate->cha_used()); | |
| 550 if (isolate->cha_used()) { | |
| 551 Class::Handle(function.Owner()).RegisterCHACode(code); | |
| 552 isolate->set_cha_used(false); | |
| 553 } | |
| 554 graph_compiler.FinalizePcDescriptors(code); | 554 graph_compiler.FinalizePcDescriptors(code); |
| 555 graph_compiler.FinalizeDeoptInfo(code); | 555 graph_compiler.FinalizeDeoptInfo(code); |
| 556 graph_compiler.FinalizeStackmaps(code); | 556 graph_compiler.FinalizeStackmaps(code); |
| 557 graph_compiler.FinalizeVarDescriptors(code); | 557 graph_compiler.FinalizeVarDescriptors(code); |
| 558 graph_compiler.FinalizeExceptionHandlers(code); | 558 graph_compiler.FinalizeExceptionHandlers(code); |
| 559 graph_compiler.FinalizeStaticCallTargetsTable(code); | 559 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 560 | 560 |
| 561 if (optimized) { | 561 if (optimized) { |
| 562 if (osr_id == Isolate::kNoDeoptId) { | 562 if (osr_id == Isolate::kNoDeoptId) { |
| 563 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 563 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 564 if (FLAG_trace_compiler || FLAG_trace_patching) { | 564 if (FLAG_trace_compiler || FLAG_trace_patching) { |
| 565 if (FLAG_trace_compiler) { | 565 if (FLAG_trace_compiler) { |
| 566 OS::Print(" "); | 566 OS::Print(" "); |
| 567 } | 567 } |
| 568 OS::Print("Patch unoptimized '%s' entry point %#" Px "\n", | 568 OS::Print("Patch unoptimized '%s' entry point %#" Px "\n", |
| 569 function.ToFullyQualifiedCString(), | 569 function.ToFullyQualifiedCString(), |
| 570 Code::Handle(function.unoptimized_code()).EntryPoint()); | 570 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 571 } | 571 } |
| 572 } | 572 } |
| 573 function.AttachCode(code); | 573 function.AttachCode(code); |
| 574 | 574 |
| 575 // Register code with the classes it depends on because of CHA. | |
| 576 for (intptr_t i = 0; | |
| 577 i < isolate->cha()->cha_classes().length(); | |
| 578 ++i) { | |
| 579 isolate->cha()->cha_classes()[i]->RegisterCHACode(code); | |
|
Florian Schneider
2014/08/12 11:37:10
This fixes bug #2: The optimized code is now regis
| |
| 580 } | |
| 581 | |
| 575 for (intptr_t i = 0; | 582 for (intptr_t i = 0; |
| 576 i < flow_graph->guarded_fields()->length(); | 583 i < flow_graph->guarded_fields()->length(); |
| 577 i++) { | 584 i++) { |
| 578 const Field* field = (*flow_graph->guarded_fields())[i]; | 585 const Field* field = (*flow_graph->guarded_fields())[i]; |
| 579 field->RegisterDependentCode(code); | 586 field->RegisterDependentCode(code); |
| 580 } | 587 } |
| 581 } else { // not optimized. | 588 } else { // not optimized. |
| 582 if (function.ic_data_array() == Array::null()) { | 589 if (function.ic_data_array() == Array::null()) { |
| 583 function.SaveICDataMap(graph_compiler.deopt_id_to_ic_data()); | 590 function.SaveICDataMap(graph_compiler.deopt_id_to_ic_data()); |
| 584 } | 591 } |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 973 const Object& result = | 980 const Object& result = |
| 974 Object::Handle(isolate->object_store()->sticky_error()); | 981 Object::Handle(isolate->object_store()->sticky_error()); |
| 975 isolate->object_store()->clear_sticky_error(); | 982 isolate->object_store()->clear_sticky_error(); |
| 976 return result.raw(); | 983 return result.raw(); |
| 977 } | 984 } |
| 978 UNREACHABLE(); | 985 UNREACHABLE(); |
| 979 return Object::null(); | 986 return Object::null(); |
| 980 } | 987 } |
| 981 | 988 |
| 982 } // namespace dart | 989 } // namespace dart |
| OLD | NEW |