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

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

Issue 15979010: Fix two bugs in the Dart VM's super-noSuchMethod invocation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.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 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 233 }
234 function.SwitchToUnoptimizedCode(); 234 function.SwitchToUnoptimizedCode();
235 if (FLAG_trace_compiler) { 235 if (FLAG_trace_compiler) {
236 OS::Print("--> restoring entry at %#"Px"\n", 236 OS::Print("--> restoring entry at %#"Px"\n",
237 Code::Handle(function.unoptimized_code()).EntryPoint()); 237 Code::Handle(function.unoptimized_code()).EntryPoint());
238 } 238 }
239 } 239 }
240 240
241 241
242 // Return false if bailed out. 242 // Return false if bailed out.
243 static bool CompileParsedFunctionHelper(const ParsedFunction& parsed_function, 243 static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function,
244 bool optimized) { 244 bool optimized) {
245 if (optimized && !parsed_function.function().is_optimizable()) { 245 const Function& function = parsed_function->function();
246 if (optimized && !function.is_optimizable()) {
246 return false; 247 return false;
247 } 248 }
248 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 249 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
249 bool is_compiled = false; 250 bool is_compiled = false;
250 Isolate* isolate = Isolate::Current(); 251 Isolate* isolate = Isolate::Current();
251 HANDLESCOPE(isolate); 252 HANDLESCOPE(isolate);
252 const intptr_t prev_deopt_id = isolate->deopt_id(); 253 const intptr_t prev_deopt_id = isolate->deopt_id();
253 isolate->set_deopt_id(0); 254 isolate->set_deopt_id(0);
254 LongJump* old_base = isolate->long_jump_base(); 255 LongJump* old_base = isolate->long_jump_base();
255 LongJump bailout_jump; 256 LongJump bailout_jump;
256 isolate->set_long_jump_base(&bailout_jump); 257 isolate->set_long_jump_base(&bailout_jump);
257 if (setjmp(*bailout_jump.Set()) == 0) { 258 if (setjmp(*bailout_jump.Set()) == 0) {
258 FlowGraph* flow_graph = NULL; 259 FlowGraph* flow_graph = NULL;
259 // TimerScope needs an isolate to be properly terminated in case of a 260 // TimerScope needs an isolate to be properly terminated in case of a
260 // LongJump. 261 // LongJump.
261 { 262 {
262 TimerScope timer(FLAG_compiler_stats, 263 TimerScope timer(FLAG_compiler_stats,
263 &CompilerStats::graphbuilder_timer, 264 &CompilerStats::graphbuilder_timer,
264 isolate); 265 isolate);
265 Array& ic_data_array = Array::Handle(); 266 Array& ic_data_array = Array::Handle();
266 if (optimized) { 267 if (optimized) {
267 ASSERT(parsed_function.function().HasCode()); 268 ASSERT(function.HasCode());
268 // Extract type feedback before the graph is built, as the graph 269 // Extract type feedback before the graph is built, as the graph
269 // builder uses it to attach it to nodes. 270 // builder uses it to attach it to nodes.
270 // Do not use type feedback to optimize a function that was 271 // Do not use type feedback to optimize a function that was
271 // deoptimized too often. 272 // deoptimized too often.
272 if (parsed_function.function().deoptimization_counter() < 273 if (function.deoptimization_counter() <
273 FLAG_deoptimization_counter_threshold) { 274 FLAG_deoptimization_counter_threshold) {
274 const Code& unoptimized_code = 275 const Code& unoptimized_code =
275 Code::Handle(parsed_function.function().unoptimized_code()); 276 Code::Handle(function.unoptimized_code());
srdjan 2013/06/03 16:56:15 Can this fit in one line now?
Florian Schneider 2013/06/03 17:01:36 No, still not.
276 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); 277 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
277 } 278 }
278 } 279 }
279 280
280 // Build the flow graph. 281 // Build the flow graph.
281 FlowGraphBuilder builder(parsed_function, 282 FlowGraphBuilder builder(parsed_function,
282 ic_data_array, 283 ic_data_array,
283 NULL); // NULL = not inlining. 284 NULL); // NULL = not inlining.
284 flow_graph = builder.BuildGraph(); 285 flow_graph = builder.BuildGraph();
285 } 286 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 if (DominatorBasedCSE::Optimize(flow_graph)) { 390 if (DominatorBasedCSE::Optimize(flow_graph)) {
390 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 391 DEBUG_ASSERT(flow_graph->VerifyUseLists());
391 // Do another round of CSE to take secondary effects into account: 392 // Do another round of CSE to take secondary effects into account:
392 // e.g. when eliminating dependent loads (a.x[0] + a.x[0]) 393 // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
393 // TODO(fschneider): Change to a one-pass optimization pass. 394 // TODO(fschneider): Change to a one-pass optimization pass.
394 DominatorBasedCSE::Optimize(flow_graph); 395 DominatorBasedCSE::Optimize(flow_graph);
395 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 396 DEBUG_ASSERT(flow_graph->VerifyUseLists());
396 } 397 }
397 } 398 }
398 if (FLAG_loop_invariant_code_motion && 399 if (FLAG_loop_invariant_code_motion &&
399 (parsed_function.function().deoptimization_counter() < 400 (parsed_function->function().deoptimization_counter() <
srdjan 2013/06/03 16:56:15 s/parsed_function->function()/function/
Florian Schneider 2013/06/03 17:01:36 Done.
400 (FLAG_deoptimization_counter_threshold - 1))) { 401 (FLAG_deoptimization_counter_threshold - 1))) {
401 LICM licm(flow_graph); 402 LICM licm(flow_graph);
402 licm.Optimize(); 403 licm.Optimize();
403 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 404 DEBUG_ASSERT(flow_graph->VerifyUseLists());
404 } 405 }
405 flow_graph->RemoveRedefinitions(); 406 flow_graph->RemoveRedefinitions();
406 407
407 if (FLAG_range_analysis) { 408 if (FLAG_range_analysis) {
408 // We have to perform range analysis after LICM because it 409 // We have to perform range analysis after LICM because it
409 // optimistically moves CheckSmi through phis into loop preheaders 410 // optimistically moves CheckSmi through phis into loop preheaders
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 { 479 {
479 TimerScope timer(FLAG_compiler_stats, 480 TimerScope timer(FLAG_compiler_stats,
480 &CompilerStats::graphcompiler_timer, 481 &CompilerStats::graphcompiler_timer,
481 isolate); 482 isolate);
482 graph_compiler.CompileGraph(); 483 graph_compiler.CompileGraph();
483 } 484 }
484 { 485 {
485 TimerScope timer(FLAG_compiler_stats, 486 TimerScope timer(FLAG_compiler_stats,
486 &CompilerStats::codefinalizer_timer, 487 &CompilerStats::codefinalizer_timer,
487 isolate); 488 isolate);
488 const Function& function = parsed_function.function(); 489 const Function& function = parsed_function->function();
srdjan 2013/06/03 16:56:15 Remove
Florian Schneider 2013/06/03 17:01:36 Done.
489 const Code& code = Code::Handle( 490 const Code& code = Code::Handle(
490 Code::FinalizeCode(function, &assembler, optimized)); 491 Code::FinalizeCode(function, &assembler, optimized));
491 code.set_is_optimized(optimized); 492 code.set_is_optimized(optimized);
492 graph_compiler.FinalizePcDescriptors(code); 493 graph_compiler.FinalizePcDescriptors(code);
493 graph_compiler.FinalizeDeoptInfo(code); 494 graph_compiler.FinalizeDeoptInfo(code);
494 graph_compiler.FinalizeStackmaps(code); 495 graph_compiler.FinalizeStackmaps(code);
495 graph_compiler.FinalizeVarDescriptors(code); 496 graph_compiler.FinalizeVarDescriptors(code);
496 graph_compiler.FinalizeExceptionHandlers(code); 497 graph_compiler.FinalizeExceptionHandlers(code);
497 graph_compiler.FinalizeComments(code); 498 graph_compiler.FinalizeComments(code);
498 graph_compiler.FinalizeStaticCallTargetsTable(code); 499 graph_compiler.FinalizeStaticCallTargetsTable(code);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 function.token_pos(), 694 function.token_pos(),
694 (function.end_token_pos() - function.token_pos())); 695 (function.end_token_pos() - function.token_pos()));
695 } 696 }
696 { 697 {
697 HANDLESCOPE(isolate); 698 HANDLESCOPE(isolate);
698 Parser::ParseFunction(parsed_function); 699 Parser::ParseFunction(parsed_function);
699 parsed_function->AllocateVariables(); 700 parsed_function->AllocateVariables();
700 } 701 }
701 702
702 const bool success = 703 const bool success =
703 CompileParsedFunctionHelper(*parsed_function, optimized); 704 CompileParsedFunctionHelper(parsed_function, optimized);
704 if (optimized && !success) { 705 if (optimized && !success) {
705 // Optimizer bailed out. Disable optimizations and to never try again. 706 // Optimizer bailed out. Disable optimizations and to never try again.
706 if (FLAG_trace_compiler) { 707 if (FLAG_trace_compiler) {
707 OS::Print("--> disabling optimizations for '%s'\n", 708 OS::Print("--> disabling optimizations for '%s'\n",
708 function.ToFullyQualifiedCString()); 709 function.ToFullyQualifiedCString());
709 } else if (FLAG_trace_failed_optimization_attempts) { 710 } else if (FLAG_trace_failed_optimization_attempts) {
710 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); 711 OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString());
711 } 712 }
712 function.set_is_optimizable(false); 713 function.set_is_optimizable(false);
713 isolate->set_long_jump_base(base); 714 isolate->set_long_jump_base(base);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 return CompileFunctionHelper(function, false); // Non-optimized. 756 return CompileFunctionHelper(function, false); // Non-optimized.
756 } 757 }
757 758
758 759
759 RawError* Compiler::CompileOptimizedFunction(const Function& function) { 760 RawError* Compiler::CompileOptimizedFunction(const Function& function) {
760 return CompileFunctionHelper(function, true); // Optimized. 761 return CompileFunctionHelper(function, true); // Optimized.
761 } 762 }
762 763
763 764
764 RawError* Compiler::CompileParsedFunction( 765 RawError* Compiler::CompileParsedFunction(
765 const ParsedFunction& parsed_function) { 766 ParsedFunction* parsed_function) {
srdjan 2013/06/03 16:56:15 One line?
766 Isolate* isolate = Isolate::Current(); 767 Isolate* isolate = Isolate::Current();
767 LongJump* base = isolate->long_jump_base(); 768 LongJump* base = isolate->long_jump_base();
768 LongJump jump; 769 LongJump jump;
769 isolate->set_long_jump_base(&jump); 770 isolate->set_long_jump_base(&jump);
770 if (setjmp(*jump.Set()) == 0) { 771 if (setjmp(*jump.Set()) == 0) {
771 // Non-optimized code generator. 772 // Non-optimized code generator.
772 CompileParsedFunctionHelper(parsed_function, false); 773 CompileParsedFunctionHelper(parsed_function, false);
773 if (FLAG_disassemble) { 774 if (FLAG_disassemble) {
774 DisassembleCode(parsed_function.function(), false); 775 DisassembleCode(parsed_function->function(), false);
775 } 776 }
776 isolate->set_long_jump_base(base); 777 isolate->set_long_jump_base(base);
777 return Error::null(); 778 return Error::null();
778 } else { 779 } else {
779 Error& error = Error::Handle(); 780 Error& error = Error::Handle();
780 // We got an error during compilation. 781 // We got an error during compilation.
781 error = isolate->object_store()->sticky_error(); 782 error = isolate->object_store()->sticky_error();
782 isolate->object_store()->clear_sticky_error(); 783 isolate->object_store()->clear_sticky_error();
783 isolate->set_long_jump_base(base); 784 isolate->set_long_jump_base(base);
784 return error.raw(); 785 return error.raw();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 func.SetNumOptionalParameters(0, true); 845 func.SetNumOptionalParameters(0, true);
845 // Manually generated AST, do not recompile. 846 // Manually generated AST, do not recompile.
846 func.set_is_optimizable(false); 847 func.set_is_optimizable(false);
847 848
848 // We compile the function here, even though InvokeStatic() below 849 // We compile the function here, even though InvokeStatic() below
849 // would compile func automatically. We are checking fewer invariants 850 // would compile func automatically. We are checking fewer invariants
850 // here. 851 // here.
851 ParsedFunction* parsed_function = new ParsedFunction(func); 852 ParsedFunction* parsed_function = new ParsedFunction(func);
852 parsed_function->SetNodeSequence(fragment); 853 parsed_function->SetNodeSequence(fragment);
853 parsed_function->set_default_parameter_values(Array::ZoneHandle()); 854 parsed_function->set_default_parameter_values(Array::ZoneHandle());
854 parsed_function->set_expression_temp_var( 855 parsed_function->EnsureExpressionTemp();
855 ParsedFunction::CreateExpressionTempVar(0));
856 fragment->scope()->AddVariable(parsed_function->expression_temp_var()); 856 fragment->scope()->AddVariable(parsed_function->expression_temp_var());
857 parsed_function->AllocateVariables(); 857 parsed_function->AllocateVariables();
858 858
859 // Non-optimized code generator. 859 // Non-optimized code generator.
860 CompileParsedFunctionHelper(*parsed_function, false); 860 CompileParsedFunctionHelper(parsed_function, false);
861 861
862 const Object& result = Object::Handle( 862 const Object& result = Object::Handle(
863 DartEntry::InvokeFunction(func, Object::empty_array())); 863 DartEntry::InvokeFunction(func, Object::empty_array()));
864 isolate->set_long_jump_base(base); 864 isolate->set_long_jump_base(base);
865 return result.raw(); 865 return result.raw();
866 } else { 866 } else {
867 const Object& result = 867 const Object& result =
868 Object::Handle(isolate->object_store()->sticky_error()); 868 Object::Handle(isolate->object_store()->sticky_error());
869 isolate->object_store()->clear_sticky_error(); 869 isolate->object_store()->clear_sticky_error();
870 isolate->set_long_jump_base(base); 870 isolate->set_long_jump_base(base);
871 return result.raw(); 871 return result.raw();
872 } 872 }
873 UNREACHABLE(); 873 UNREACHABLE();
874 return Object::null(); 874 return Object::null();
875 } 875 }
876 876
877 } // namespace dart 877 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698