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

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

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

Powered by Google App Engine
This is Rietveld 408576698