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

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

Issue 9316071: Dart_PropagateError, take 2. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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/bootstrap_nocorelib.cc ('k') | runtime/vm/code_generator_ia32.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 424
425 Function& function = Function::Handle(); 425 Function& function = Function::Handle();
426 function = Resolver::ResolveDynamic(receiver, 426 function = Resolver::ResolveDynamic(receiver,
427 function_name, 427 function_name,
428 num_arguments, 428 num_arguments,
429 num_named_arguments); 429 num_named_arguments);
430 if (function.IsNull()) { 430 if (function.IsNull()) {
431 return Code::null(); 431 return Code::null();
432 } else { 432 } else {
433 if (!function.HasCode()) { 433 if (!function.HasCode()) {
434 Compiler::CompileFunction(function); 434 const Error& error = Error::Handle(Compiler::CompileFunction(function));
435 if (!error.IsNull()) {
436 Exceptions::PropagateError(error);
437 }
435 } 438 }
436 functions_cache.AddCompiledFunction(function, 439 functions_cache.AddCompiledFunction(function,
437 num_arguments, 440 num_arguments,
438 num_named_arguments); 441 num_named_arguments);
439 return function.code(); 442 return function.code();
440 } 443 }
441 } 444 }
442 445
443 446
444 // Result of an invoke may be an unhandled exception, in which case we 447 // Result of an invoke may be an unhandled exception, in which case we
445 // rethrow it. 448 // rethrow it.
446 static void CheckResultException(const Instance& result) { 449 static void CheckResultError(const Object& result) {
447 if (result.IsUnhandledException()) { 450 if (result.IsError()) {
448 const UnhandledException& unhandled = UnhandledException::Handle( 451 Exceptions::PropagateError(result);
449 reinterpret_cast<RawUnhandledException*>(result.raw()));
450 const Instance& excp = Instance::Handle(unhandled.exception());
451 const Instance& stack = Instance::Handle(unhandled.stacktrace());
452 Exceptions::ReThrow(excp, stack);
453 } 452 }
454 } 453 }
455 454
456 455
457 // Resolves an instance function and compiles it if necessary. 456 // Resolves an instance function and compiles it if necessary.
458 // Arg0: receiver object. 457 // Arg0: receiver object.
459 // Returns: RawCode object or NULL (method not found or not compileable). 458 // Returns: RawCode object or NULL (method not found or not compileable).
460 // This is called by the megamorphic stub when instance call does not need to be 459 // This is called by the megamorphic stub when instance call does not need to be
461 // patched. 460 // patched.
462 // Used by megamorphic lookup/no-such-method-handling. 461 // Used by megamorphic lookup/no-such-method-handling.
(...skipping 12 matching lines...) Expand all
475 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 1) { 474 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 1) {
476 ASSERT(arguments.Count() == 475 ASSERT(arguments.Count() ==
477 kBreakpointStaticHandlerRuntimeEntry.argument_count()); 476 kBreakpointStaticHandlerRuntimeEntry.argument_count());
478 ASSERT(isolate->debugger() != NULL); 477 ASSERT(isolate->debugger() != NULL);
479 isolate->debugger()->BreakpointCallback(); 478 isolate->debugger()->BreakpointCallback();
480 // Make sure the static function that is about to be called is 479 // Make sure the static function that is about to be called is
481 // compiled. The stub will jump to the entry point without any 480 // compiled. The stub will jump to the entry point without any
482 // further tests. 481 // further tests.
483 const Function& function = Function::CheckedHandle(arguments.At(0)); 482 const Function& function = Function::CheckedHandle(arguments.At(0));
484 if (!function.HasCode()) { 483 if (!function.HasCode()) {
485 Compiler::CompileFunction(function); 484 const Error& error = Error::Handle(Compiler::CompileFunction(function));
485 if (!error.IsNull()) {
486 Exceptions::PropagateError(error);
487 }
486 } 488 }
487 } 489 }
488 490
489 491
490 // Gets called from debug stub when code reaches a breakpoint. 492 // Gets called from debug stub when code reaches a breakpoint.
491 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) { 493 DEFINE_RUNTIME_ENTRY(BreakpointDynamicHandler, 0) {
492 ASSERT(arguments.Count() == 494 ASSERT(arguments.Count() ==
493 kBreakpointDynamicHandlerRuntimeEntry.argument_count()); 495 kBreakpointDynamicHandlerRuntimeEntry.argument_count());
494 ASSERT(isolate->debugger() != NULL); 496 ASSERT(isolate->debugger() != NULL);
495 isolate->debugger()->BreakpointCallback(); 497 isolate->debugger()->BreakpointCallback();
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 getter_function_name, 702 getter_function_name,
701 kNumArguments, 703 kNumArguments,
702 kNumNamedArguments)); 704 kNumNamedArguments));
703 Code& code = Code::Handle(); 705 Code& code = Code::Handle();
704 if (function.IsNull()) { 706 if (function.IsNull()) {
705 arguments.SetReturn(code); 707 arguments.SetReturn(code);
706 return; // No getter function found so can't be an implicit closure. 708 return; // No getter function found so can't be an implicit closure.
707 } 709 }
708 GrowableArray<const Object*> invoke_arguments(0); 710 GrowableArray<const Object*> invoke_arguments(0);
709 const Array& kNoArgumentNames = Array::Handle(); 711 const Array& kNoArgumentNames = Array::Handle();
710 const Instance& result = 712 const Object& result =
711 Instance::Handle( 713 Object::Handle(DartEntry::InvokeDynamic(receiver,
712 DartEntry::InvokeDynamic(receiver, 714 function,
713 function, 715 invoke_arguments,
714 invoke_arguments, 716 kNoArgumentNames));
715 kNoArgumentNames)); 717 if (result.IsError()) {
716 if (result.IsUnhandledException()) { 718 if (result.IsUnhandledException()) {
717 arguments.SetReturn(code); 719 // If the getter throws an exception, treat as no such method.
718 return; // Error accessing getter, treat as no such method. 720 arguments.SetReturn(code);
721 return;
722 } else {
723 Exceptions::PropagateError(result);
724 }
719 } 725 }
720 if (!result.IsSmi()) { 726 if (!result.IsSmi()) {
721 const Class& cls = Class::Handle(result.clazz()); 727 const Class& cls = Class::Handle(result.clazz());
722 ASSERT(!cls.IsNull()); 728 ASSERT(!cls.IsNull());
723 function = cls.signature_function(); 729 function = cls.signature_function();
724 if (!function.IsNull()) { 730 if (!function.IsNull()) {
725 arguments.SetReturn(result); 731 arguments.SetReturn(result);
726 return; // Return closure object. 732 return; // Return closure object.
727 } 733 }
728 } 734 }
729 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, invoke_arguments); 735 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, invoke_arguments);
730 } 736 }
731 737
732 738
733 // Invoke Implicit Closure function. 739 // Invoke Implicit Closure function.
734 // Arg0: closure object. 740 // Arg0: closure object.
735 // Arg1: arguments descriptor (originally passed as dart instance invocation). 741 // Arg1: arguments descriptor (originally passed as dart instance invocation).
736 // Arg2: arguments array (originally passed to dart instance invocation). 742 // Arg2: arguments array (originally passed to dart instance invocation).
737 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { 743 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) {
738 ASSERT(arguments.Count() == 744 ASSERT(arguments.Count() ==
739 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); 745 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count());
740 const Closure& closure = Closure::CheckedHandle(arguments.At(0)); 746 const Closure& closure = Closure::CheckedHandle(arguments.At(0));
741 const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1)); 747 const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1));
742 const Array& func_arguments = Array::CheckedHandle(arguments.At(2)); 748 const Array& func_arguments = Array::CheckedHandle(arguments.At(2));
743 const Function& function = Function::Handle(closure.function()); 749 const Function& function = Function::Handle(closure.function());
744 ASSERT(!function.IsNull()); 750 ASSERT(!function.IsNull());
745 if (!function.HasCode()) { 751 if (!function.HasCode()) {
746 Compiler::CompileFunction(function); 752 const Error& error = Error::Handle(Compiler::CompileFunction(function));
753 if (!error.IsNull()) {
754 Exceptions::PropagateError(error);
755 }
747 } 756 }
748 const Context& context = Context::Handle(closure.context()); 757 const Context& context = Context::Handle(closure.context());
749 const Code& code = Code::Handle(function.code()); 758 const Code& code = Code::Handle(function.code());
750 ASSERT(!code.IsNull()); 759 ASSERT(!code.IsNull());
751 const Instructions& instrs = Instructions::Handle(code.instructions()); 760 const Instructions& instrs = Instructions::Handle(code.instructions());
752 ASSERT(!instrs.IsNull()); 761 ASSERT(!instrs.IsNull());
753 762
754 // Adjust arguments descriptor array to account for removal of the receiver 763 // Adjust arguments descriptor array to account for removal of the receiver
755 // parameter. Since the arguments descriptor array is canonicalized, create a 764 // parameter. Since the arguments descriptor array is canonicalized, create a
756 // new one instead of patching the original one. 765 // new one instead of patching the original one.
(...skipping 28 matching lines...) Expand all
785 GrowableArray<const Object*> invoke_arguments(0); 794 GrowableArray<const Object*> invoke_arguments(0);
786 for (intptr_t i = 0; i < func_arguments.Length(); i++) { 795 for (intptr_t i = 0; i < func_arguments.Length(); i++) {
787 const Object& value = Object::Handle(func_arguments.At(i)); 796 const Object& value = Object::Handle(func_arguments.At(i));
788 invoke_arguments.Add(&value); 797 invoke_arguments.Add(&value);
789 } 798 }
790 799
791 // Now Call the invoke stub which will invoke the closure. 800 // Now Call the invoke stub which will invoke the closure.
792 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( 801 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
793 StubCode::InvokeDartCodeEntryPoint()); 802 StubCode::InvokeDartCodeEntryPoint());
794 ASSERT(context.isolate() == Isolate::Current()); 803 ASSERT(context.isolate() == Isolate::Current());
795 const Instance& result = Instance::Handle( 804 const Object& result = Object::Handle(
796 entrypoint(instrs.EntryPoint(), 805 entrypoint(instrs.EntryPoint(),
797 adjusted_arg_descriptor, 806 adjusted_arg_descriptor,
798 invoke_arguments.data(), 807 invoke_arguments.data(),
799 context)); 808 context));
800 CheckResultException(result); 809 CheckResultError(result);
801 arguments.SetReturn(result); 810 arguments.SetReturn(result);
802 } 811 }
803 812
804 813
805 // Invoke appropriate noSuchMethod function. 814 // Invoke appropriate noSuchMethod function.
806 // Arg0: receiver. 815 // Arg0: receiver.
807 // Arg1: ic-data array. 816 // Arg1: ic-data array.
808 // Arg2: original arguments descriptor array. 817 // Arg2: original arguments descriptor array.
809 // Arg3: original arguments array. 818 // Arg3: original arguments array.
810 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { 819 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
(...skipping 15 matching lines...) Expand all
826 String::Handle(String::NewSymbol("noSuchMethod")); 835 String::Handle(String::NewSymbol("noSuchMethod"));
827 const Function& function = Function::ZoneHandle( 836 const Function& function = Function::ZoneHandle(
828 Resolver::ResolveDynamic(receiver, 837 Resolver::ResolveDynamic(receiver,
829 function_name, 838 function_name,
830 kNumArguments, 839 kNumArguments,
831 kNumNamedArguments)); 840 kNumNamedArguments));
832 ASSERT(!function.IsNull()); 841 ASSERT(!function.IsNull());
833 GrowableArray<const Object*> invoke_arguments(2); 842 GrowableArray<const Object*> invoke_arguments(2);
834 invoke_arguments.Add(&original_function_name); 843 invoke_arguments.Add(&original_function_name);
835 invoke_arguments.Add(&orig_arguments); 844 invoke_arguments.Add(&orig_arguments);
836 const Instance& result = Instance::Handle( 845 const Object& result = Object::Handle(
837 DartEntry::InvokeDynamic(receiver, 846 DartEntry::InvokeDynamic(receiver,
838 function, 847 function,
839 invoke_arguments, 848 invoke_arguments,
840 kNoArgumentNames)); 849 kNoArgumentNames));
841 CheckResultException(result); 850 CheckResultError(result);
842 arguments.SetReturn(result); 851 arguments.SetReturn(result);
843 } 852 }
844 853
845 854
846 // Report that an object is not a closure. 855 // Report that an object is not a closure.
847 // Arg0: non-closure object. 856 // Arg0: non-closure object.
848 // Arg1: arguments array. 857 // Arg1: arguments array.
849 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { 858 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) {
850 ASSERT(arguments.Count() == 859 ASSERT(arguments.Count() ==
851 kReportObjectNotClosureRuntimeEntry.argument_count()); 860 kReportObjectNotClosureRuntimeEntry.argument_count());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 if (function.deoptimization_counter() >= 920 if (function.deoptimization_counter() >=
912 FLAG_deoptimization_counter_threshold) { 921 FLAG_deoptimization_counter_threshold) {
913 // TODO(srdjan): Investigate excessive deoptimization. 922 // TODO(srdjan): Investigate excessive deoptimization.
914 function.set_invocation_counter(0); 923 function.set_invocation_counter(0);
915 return; 924 return;
916 } 925 }
917 if (function.is_optimizable()) { 926 if (function.is_optimizable()) {
918 ASSERT(!Code::Handle(function.code()).is_optimized()); 927 ASSERT(!Code::Handle(function.code()).is_optimized());
919 const Code& unoptimized_code = Code::Handle(function.code()); 928 const Code& unoptimized_code = Code::Handle(function.code());
920 // Compilation patches the entry of unoptimized code. 929 // Compilation patches the entry of unoptimized code.
921 Compiler::CompileOptimizedFunction(function); 930 const Error& error =
931 Error::Handle(Compiler::CompileOptimizedFunction(function));
932 if (!error.IsNull()) {
933 Exceptions::PropagateError(error);
934 }
922 const Code& optimized_code = Code::Handle(function.code()); 935 const Code& optimized_code = Code::Handle(function.code());
923 ASSERT(!optimized_code.IsNull()); 936 ASSERT(!optimized_code.IsNull());
924 ASSERT(!unoptimized_code.IsNull()); 937 ASSERT(!unoptimized_code.IsNull());
925 } else { 938 } else {
926 // TODO(5442338): Abort as this should not happen. 939 // TODO(5442338): Abort as this should not happen.
927 function.set_invocation_counter(0); 940 function.set_invocation_counter(0);
928 } 941 }
929 } 942 }
930 943
931 944
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 // types/classes have been collected. 1031 // types/classes have been collected.
1019 function.set_invocation_counter(0); 1032 function.set_invocation_counter(0);
1020 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 1033 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
1021 1034
1022 // We have to skip the following otherwise the compiler will complain 1035 // We have to skip the following otherwise the compiler will complain
1023 // when it attempts to install unoptimized code into a function that 1036 // when it attempts to install unoptimized code into a function that
1024 // was already deoptimized. 1037 // was already deoptimized.
1025 if (Code::Handle(function.code()).is_optimized()) { 1038 if (Code::Handle(function.code()).is_optimized()) {
1026 // Get unoptimized code. Compilation restores (reenables) the entry of 1039 // Get unoptimized code. Compilation restores (reenables) the entry of
1027 // unoptimized code. 1040 // unoptimized code.
1028 Compiler::CompileFunction(function); 1041 const Error& error = Error::Handle(Compiler::CompileFunction(function));
1042 if (!error.IsNull()) {
1043 Exceptions::PropagateError(error);
1044 }
1029 } 1045 }
1030 // TODO(srdjan): Handle better complex cases, e.g. when an older optimized 1046 // TODO(srdjan): Handle better complex cases, e.g. when an older optimized
1031 // code is alive on frame and gets deoptimized after the function was 1047 // code is alive on frame and gets deoptimized after the function was
1032 // optimized a second time. 1048 // optimized a second time.
1033 if (FLAG_trace_deopt) { 1049 if (FLAG_trace_deopt) {
1034 OS::Print("After patching ->0x%x:\n", continue_at_pc); 1050 OS::Print("After patching ->0x%x:\n", continue_at_pc);
1035 } 1051 }
1036 } 1052 }
1037 1053
1038 1054
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 } 1125 }
1110 } 1126 }
1111 } 1127 }
1112 // The cache is null terminated, therefore the loop above should never 1128 // The cache is null terminated, therefore the loop above should never
1113 // terminate by itself. 1129 // terminate by itself.
1114 UNREACHABLE(); 1130 UNREACHABLE();
1115 return Code::null(); 1131 return Code::null();
1116 } 1132 }
1117 1133
1118 } // namespace dart 1134 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/bootstrap_nocorelib.cc ('k') | runtime/vm/code_generator_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698