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

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: Removed some unneeded includes Created 8 years, 11 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));
siva 2012/01/31 00:52:34 Would it make sense to have a version of CompileFu
turnidge 2012/01/31 21:56:31 I sort of find the current version less magical.
siva 2012/02/01 19:09:38 Sure.
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 }
siva 2012/01/31 00:52:34 ASSERT(result.IsNull());
turnidge 2012/01/31 21:56:31 Why should the result be null?
siva 2012/02/01 19:09:38 You are right the result does not have to be NULL,
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.
463 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) { 464 DEFINE_RUNTIME_ENTRY(ResolveCompileInstanceFunction, 1) {
(...skipping 11 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 //
723 // TODO(turnidge): Is this the desired behavior?
siva 2012/01/31 00:52:34 Yes this is the desired behaviour.
turnidge 2012/01/31 21:56:31 Thanks. Updated comment.
724 arguments.SetReturn(code);
725 return;
726 } else {
727 Error& error = Error::Handle();
728 error ^= result.raw();
729 Exceptions::PropagateError(error);
730 }
719 } 731 }
720 if (!result.IsSmi()) { 732 if (!result.IsSmi()) {
721 const Class& cls = Class::Handle(result.clazz()); 733 const Class& cls = Class::Handle(result.clazz());
722 ASSERT(!cls.IsNull()); 734 ASSERT(!cls.IsNull());
723 function = cls.signature_function(); 735 function = cls.signature_function();
724 if (!function.IsNull()) { 736 if (!function.IsNull()) {
725 arguments.SetReturn(result); 737 arguments.SetReturn(result);
726 return; // Return closure object. 738 return; // Return closure object.
727 } 739 }
728 } 740 }
729 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, invoke_arguments); 741 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, invoke_arguments);
730 } 742 }
731 743
732 744
733 // Invoke Implicit Closure function. 745 // Invoke Implicit Closure function.
734 // Arg0: closure object. 746 // Arg0: closure object.
735 // Arg1: arguments descriptor (originally passed as dart instance invocation). 747 // Arg1: arguments descriptor (originally passed as dart instance invocation).
736 // Arg2: arguments array (originally passed to dart instance invocation). 748 // Arg2: arguments array (originally passed to dart instance invocation).
737 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { 749 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) {
738 ASSERT(arguments.Count() == 750 ASSERT(arguments.Count() ==
739 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); 751 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count());
740 const Closure& closure = Closure::CheckedHandle(arguments.At(0)); 752 const Closure& closure = Closure::CheckedHandle(arguments.At(0));
741 const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1)); 753 const Array& arg_descriptor = Array::CheckedHandle(arguments.At(1));
742 const Array& func_arguments = Array::CheckedHandle(arguments.At(2)); 754 const Array& func_arguments = Array::CheckedHandle(arguments.At(2));
743 const Function& function = Function::Handle(closure.function()); 755 const Function& function = Function::Handle(closure.function());
744 ASSERT(!function.IsNull()); 756 ASSERT(!function.IsNull());
745 if (!function.HasCode()) { 757 if (!function.HasCode()) {
746 Compiler::CompileFunction(function); 758 const Error& error = Error::Handle(Compiler::CompileFunction(function));
759 if (!error.IsNull()) {
760 Exceptions::PropagateError(error);
761 }
747 } 762 }
748 const Context& context = Context::Handle(closure.context()); 763 const Context& context = Context::Handle(closure.context());
749 const Code& code = Code::Handle(function.code()); 764 const Code& code = Code::Handle(function.code());
750 ASSERT(!code.IsNull()); 765 ASSERT(!code.IsNull());
751 const Instructions& instrs = Instructions::Handle(code.instructions()); 766 const Instructions& instrs = Instructions::Handle(code.instructions());
752 ASSERT(!instrs.IsNull()); 767 ASSERT(!instrs.IsNull());
753 768
754 // Adjust arguments descriptor array to account for removal of the receiver 769 // Adjust arguments descriptor array to account for removal of the receiver
755 // parameter. Since the arguments descriptor array is canonicalized, create a 770 // parameter. Since the arguments descriptor array is canonicalized, create a
756 // new one instead of patching the original one. 771 // new one instead of patching the original one.
(...skipping 28 matching lines...) Expand all
785 GrowableArray<const Object*> invoke_arguments(0); 800 GrowableArray<const Object*> invoke_arguments(0);
786 for (intptr_t i = 0; i < func_arguments.Length(); i++) { 801 for (intptr_t i = 0; i < func_arguments.Length(); i++) {
787 const Object& value = Object::Handle(func_arguments.At(i)); 802 const Object& value = Object::Handle(func_arguments.At(i));
788 invoke_arguments.Add(&value); 803 invoke_arguments.Add(&value);
789 } 804 }
790 805
791 // Now Call the invoke stub which will invoke the closure. 806 // Now Call the invoke stub which will invoke the closure.
792 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( 807 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
793 StubCode::InvokeDartCodeEntryPoint()); 808 StubCode::InvokeDartCodeEntryPoint());
794 ASSERT(context.isolate() == Isolate::Current()); 809 ASSERT(context.isolate() == Isolate::Current());
795 const Instance& result = Instance::Handle( 810 const Object& result = Object::Handle(
796 entrypoint(instrs.EntryPoint(), 811 entrypoint(instrs.EntryPoint(),
797 adjusted_arg_descriptor, 812 adjusted_arg_descriptor,
798 invoke_arguments.data(), 813 invoke_arguments.data(),
799 context)); 814 context));
800 CheckResultException(result); 815 CheckResultError(result);
801 arguments.SetReturn(result); 816 arguments.SetReturn(result);
802 } 817 }
803 818
804 819
805 // Invoke appropriate noSuchMethod function. 820 // Invoke appropriate noSuchMethod function.
806 // Arg0: receiver. 821 // Arg0: receiver.
807 // Arg1: ic-data array. 822 // Arg1: ic-data array.
808 // Arg2: original arguments descriptor array. 823 // Arg2: original arguments descriptor array.
809 // Arg3: original arguments array. 824 // Arg3: original arguments array.
810 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { 825 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
(...skipping 15 matching lines...) Expand all
826 String::Handle(String::NewSymbol("noSuchMethod")); 841 String::Handle(String::NewSymbol("noSuchMethod"));
827 const Function& function = Function::ZoneHandle( 842 const Function& function = Function::ZoneHandle(
828 Resolver::ResolveDynamic(receiver, 843 Resolver::ResolveDynamic(receiver,
829 function_name, 844 function_name,
830 kNumArguments, 845 kNumArguments,
831 kNumNamedArguments)); 846 kNumNamedArguments));
832 ASSERT(!function.IsNull()); 847 ASSERT(!function.IsNull());
833 GrowableArray<const Object*> invoke_arguments(2); 848 GrowableArray<const Object*> invoke_arguments(2);
834 invoke_arguments.Add(&original_function_name); 849 invoke_arguments.Add(&original_function_name);
835 invoke_arguments.Add(&orig_arguments); 850 invoke_arguments.Add(&orig_arguments);
836 const Instance& result = Instance::Handle( 851 const Object& result = Object::Handle(
837 DartEntry::InvokeDynamic(receiver, 852 DartEntry::InvokeDynamic(receiver,
838 function, 853 function,
839 invoke_arguments, 854 invoke_arguments,
840 kNoArgumentNames)); 855 kNoArgumentNames));
841 CheckResultException(result); 856 CheckResultError(result);
842 arguments.SetReturn(result); 857 arguments.SetReturn(result);
843 } 858 }
844 859
845 860
846 // Report that an object is not a closure. 861 // Report that an object is not a closure.
847 // Arg0: non-closure object. 862 // Arg0: non-closure object.
848 // Arg1: arguments array. 863 // Arg1: arguments array.
849 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { 864 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) {
850 ASSERT(arguments.Count() == 865 ASSERT(arguments.Count() ==
851 kReportObjectNotClosureRuntimeEntry.argument_count()); 866 kReportObjectNotClosureRuntimeEntry.argument_count());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 if (function.deoptimization_counter() >= 923 if (function.deoptimization_counter() >=
909 FLAG_deoptimization_counter_threshold) { 924 FLAG_deoptimization_counter_threshold) {
910 // TODO(srdjan): Investigate excessive deoptimization. 925 // TODO(srdjan): Investigate excessive deoptimization.
911 function.set_invocation_counter(0); 926 function.set_invocation_counter(0);
912 return; 927 return;
913 } 928 }
914 if (function.is_optimizable()) { 929 if (function.is_optimizable()) {
915 ASSERT(!Code::Handle(function.code()).is_optimized()); 930 ASSERT(!Code::Handle(function.code()).is_optimized());
916 const Code& unoptimized_code = Code::Handle(function.code()); 931 const Code& unoptimized_code = Code::Handle(function.code());
917 // Compilation patches the entry of unoptimized code. 932 // Compilation patches the entry of unoptimized code.
918 Compiler::CompileOptimizedFunction(function); 933 const Error& error =
934 Error::Handle(Compiler::CompileOptimizedFunction(function));
935 if (!error.IsNull()) {
936 Exceptions::PropagateError(error);
937 }
919 const Code& optimized_code = Code::Handle(function.code()); 938 const Code& optimized_code = Code::Handle(function.code());
920 ASSERT(!optimized_code.IsNull()); 939 ASSERT(!optimized_code.IsNull());
921 ASSERT(!unoptimized_code.IsNull()); 940 ASSERT(!unoptimized_code.IsNull());
922 } else { 941 } else {
923 // TODO(5442338): Abort as this should not happen. 942 // TODO(5442338): Abort as this should not happen.
924 function.set_invocation_counter(0); 943 function.set_invocation_counter(0);
925 } 944 }
926 } 945 }
927 946
928 947
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 // types/classes have been collected. 1034 // types/classes have been collected.
1016 function.set_invocation_counter(0); 1035 function.set_invocation_counter(0);
1017 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 1036 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
1018 1037
1019 // We have to skip the following otherwise the compiler will complain 1038 // We have to skip the following otherwise the compiler will complain
1020 // when it attempts to install unoptimized code into a function that 1039 // when it attempts to install unoptimized code into a function that
1021 // was already deoptimized. 1040 // was already deoptimized.
1022 if (Code::Handle(function.code()).is_optimized()) { 1041 if (Code::Handle(function.code()).is_optimized()) {
1023 // Get unoptimized code. Compilation restores (reenables) the entry of 1042 // Get unoptimized code. Compilation restores (reenables) the entry of
1024 // unoptimized code. 1043 // unoptimized code.
1025 Compiler::CompileFunction(function); 1044 const Error& error = Error::Handle(Compiler::CompileFunction(function));
1045 if (!error.IsNull()) {
1046 Exceptions::PropagateError(error);
1047 }
1026 } 1048 }
1027 // TODO(srdjan): Handle better complex cases, e.g. when an older optimized 1049 // 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 1050 // code is alive on frame and gets deoptimized after the function was
1029 // optimized a second time. 1051 // optimized a second time.
1030 if (FLAG_trace_deopt) { 1052 if (FLAG_trace_deopt) {
1031 OS::Print("After patching ->0x%x:\n", continue_at_pc); 1053 OS::Print("After patching ->0x%x:\n", continue_at_pc);
1032 } 1054 }
1033 } 1055 }
1034 1056
1035 1057
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 } 1128 }
1107 } 1129 }
1108 } 1130 }
1109 // The cache is null terminated, therefore the loop above should never 1131 // The cache is null terminated, therefore the loop above should never
1110 // terminate by itself. 1132 // terminate by itself.
1111 UNREACHABLE(); 1133 UNREACHABLE();
1112 return Code::null(); 1134 return Code::null();
1113 } 1135 }
1114 1136
1115 } // namespace dart 1137 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698