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

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