OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 630 |
631 if (!FullCodeGenerator::MakeCode(info)) { | 631 if (!FullCodeGenerator::MakeCode(info)) { |
632 Isolate* isolate = info->isolate(); | 632 Isolate* isolate = info->isolate(); |
633 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 633 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
634 return false; | 634 return false; |
635 } | 635 } |
636 return true; | 636 return true; |
637 } | 637 } |
638 | 638 |
639 | 639 |
640 static Handle<Code> GetUnoptimizedCodeCommon(CompilationInfo* info) { | 640 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| 641 CompilationInfo* info) { |
641 VMState<COMPILER> state(info->isolate()); | 642 VMState<COMPILER> state(info->isolate()); |
642 PostponeInterruptsScope postpone(info->isolate()); | 643 PostponeInterruptsScope postpone(info->isolate()); |
643 if (!Parser::Parse(info)) return Handle<Code>::null(); | 644 if (!Parser::Parse(info)) return MaybeHandle<Code>(); |
644 info->SetStrictMode(info->function()->strict_mode()); | 645 info->SetStrictMode(info->function()->strict_mode()); |
645 | 646 |
646 if (!CompileUnoptimizedCode(info)) return Handle<Code>::null(); | 647 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
647 Compiler::RecordFunctionCompilation( | 648 Compiler::RecordFunctionCompilation( |
648 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); | 649 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); |
649 UpdateSharedFunctionInfo(info); | 650 UpdateSharedFunctionInfo(info); |
650 ASSERT_EQ(Code::FUNCTION, info->code()->kind()); | 651 ASSERT_EQ(Code::FUNCTION, info->code()->kind()); |
651 return info->code(); | 652 return info->code(); |
652 } | 653 } |
653 | 654 |
654 | 655 |
655 Handle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { | 656 MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { |
656 ASSERT(!function->GetIsolate()->has_pending_exception()); | 657 ASSERT(!function->GetIsolate()->has_pending_exception()); |
657 ASSERT(!function->is_compiled()); | 658 ASSERT(!function->is_compiled()); |
658 if (function->shared()->is_compiled()) { | 659 if (function->shared()->is_compiled()) { |
659 return Handle<Code>(function->shared()->code()); | 660 return Handle<Code>(function->shared()->code()); |
660 } | 661 } |
661 | 662 |
662 CompilationInfoWithZone info(function); | 663 CompilationInfoWithZone info(function); |
663 Handle<Code> result = GetUnoptimizedCodeCommon(&info); | 664 Handle<Code> result; |
664 ASSERT_EQ(result.is_null(), info.isolate()->has_pending_exception()); | 665 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, |
| 666 GetUnoptimizedCodeCommon(&info), |
| 667 Code); |
665 | 668 |
666 if (FLAG_always_opt && | 669 if (FLAG_always_opt && |
667 !result.is_null() && | |
668 info.isolate()->use_crankshaft() && | 670 info.isolate()->use_crankshaft() && |
669 !info.shared_info()->optimization_disabled() && | 671 !info.shared_info()->optimization_disabled() && |
670 !info.isolate()->DebuggerHasBreakPoints()) { | 672 !info.isolate()->DebuggerHasBreakPoints()) { |
671 Handle<Code> opt_code = Compiler::GetOptimizedCode( | 673 Handle<Code> opt_code; |
672 function, result, Compiler::NOT_CONCURRENT); | 674 if (Compiler::GetOptimizedCode( |
673 if (!opt_code.is_null()) result = opt_code; | 675 function, result, |
| 676 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { |
| 677 result = opt_code; |
| 678 } |
674 } | 679 } |
675 | 680 |
676 return result; | 681 return result; |
677 } | 682 } |
678 | 683 |
679 | 684 |
680 Handle<Code> Compiler::GetUnoptimizedCode(Handle<SharedFunctionInfo> shared) { | 685 MaybeHandle<Code> Compiler::GetUnoptimizedCode( |
| 686 Handle<SharedFunctionInfo> shared) { |
681 ASSERT(!shared->GetIsolate()->has_pending_exception()); | 687 ASSERT(!shared->GetIsolate()->has_pending_exception()); |
682 ASSERT(!shared->is_compiled()); | 688 ASSERT(!shared->is_compiled()); |
683 | 689 |
684 CompilationInfoWithZone info(shared); | 690 CompilationInfoWithZone info(shared); |
685 Handle<Code> result = GetUnoptimizedCodeCommon(&info); | 691 return GetUnoptimizedCodeCommon(&info); |
686 ASSERT_EQ(result.is_null(), info.isolate()->has_pending_exception()); | |
687 return result; | |
688 } | 692 } |
689 | 693 |
690 | 694 |
691 bool Compiler::EnsureCompiled(Handle<JSFunction> function, | 695 bool Compiler::EnsureCompiled(Handle<JSFunction> function, |
692 ClearExceptionFlag flag) { | 696 ClearExceptionFlag flag) { |
693 if (function->is_compiled()) return true; | 697 if (function->is_compiled()) return true; |
694 Handle<Code> code = Compiler::GetUnoptimizedCode(function); | 698 MaybeHandle<Code> maybe_code = Compiler::GetUnoptimizedCode(function); |
695 if (code.is_null()) { | 699 Handle<Code> code; |
| 700 if (!maybe_code.ToHandle(&code)) { |
696 if (flag == CLEAR_EXCEPTION) { | 701 if (flag == CLEAR_EXCEPTION) { |
697 function->GetIsolate()->clear_pending_exception(); | 702 function->GetIsolate()->clear_pending_exception(); |
698 } | 703 } |
699 return false; | 704 return false; |
700 } | 705 } |
701 function->ReplaceCode(*code); | 706 function->ReplaceCode(*code); |
702 ASSERT(function->is_compiled()); | 707 ASSERT(function->is_compiled()); |
703 return true; | 708 return true; |
704 } | 709 } |
705 | 710 |
706 | 711 |
707 // Compile full code for debugging. This code will have debug break slots | 712 // Compile full code for debugging. This code will have debug break slots |
708 // and deoptimization information. Deoptimization information is required | 713 // and deoptimization information. Deoptimization information is required |
709 // in case that an optimized version of this function is still activated on | 714 // in case that an optimized version of this function is still activated on |
710 // the stack. It will also make sure that the full code is compiled with | 715 // the stack. It will also make sure that the full code is compiled with |
711 // the same flags as the previous version, that is flags which can change | 716 // the same flags as the previous version, that is flags which can change |
712 // the code generated. The current method of mapping from already compiled | 717 // the code generated. The current method of mapping from already compiled |
713 // full code without debug break slots to full code with debug break slots | 718 // full code without debug break slots to full code with debug break slots |
714 // depends on the generated code is otherwise exactly the same. | 719 // depends on the generated code is otherwise exactly the same. |
715 // If compilation fails, just keep the existing code. | 720 // If compilation fails, just keep the existing code. |
716 Handle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) { | 721 MaybeHandle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) { |
717 CompilationInfoWithZone info(function); | 722 CompilationInfoWithZone info(function); |
718 Isolate* isolate = info.isolate(); | 723 Isolate* isolate = info.isolate(); |
719 VMState<COMPILER> state(isolate); | 724 VMState<COMPILER> state(isolate); |
720 | 725 |
721 ASSERT(!isolate->has_pending_exception()); | 726 ASSERT(!isolate->has_pending_exception()); |
722 Handle<Code> old_code(function->shared()->code()); | 727 Handle<Code> old_code(function->shared()->code()); |
723 ASSERT(old_code->kind() == Code::FUNCTION); | 728 ASSERT(old_code->kind() == Code::FUNCTION); |
724 ASSERT(!old_code->has_debug_break_slots()); | 729 ASSERT(!old_code->has_debug_break_slots()); |
725 | 730 |
726 info.MarkCompilingForDebugging(); | 731 info.MarkCompilingForDebugging(); |
727 if (old_code->is_compiled_optimizable()) { | 732 if (old_code->is_compiled_optimizable()) { |
728 info.EnableDeoptimizationSupport(); | 733 info.EnableDeoptimizationSupport(); |
729 } else { | 734 } else { |
730 info.MarkNonOptimizable(); | 735 info.MarkNonOptimizable(); |
731 } | 736 } |
732 Handle<Code> new_code = GetUnoptimizedCodeCommon(&info); | 737 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info); |
733 if (new_code.is_null()) { | 738 Handle<Code> new_code; |
| 739 if (!maybe_new_code.ToHandle(&new_code)) { |
734 isolate->clear_pending_exception(); | 740 isolate->clear_pending_exception(); |
735 } else { | 741 } else { |
736 ASSERT_EQ(old_code->is_compiled_optimizable(), | 742 ASSERT_EQ(old_code->is_compiled_optimizable(), |
737 new_code->is_compiled_optimizable()); | 743 new_code->is_compiled_optimizable()); |
738 } | 744 } |
739 return new_code; | 745 return maybe_new_code; |
740 } | 746 } |
741 | 747 |
742 | 748 |
743 #ifdef ENABLE_DEBUGGER_SUPPORT | 749 #ifdef ENABLE_DEBUGGER_SUPPORT |
744 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 750 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
745 // TODO(635): support extensions. | 751 // TODO(635): support extensions. |
746 CompilationInfoWithZone info(script); | 752 CompilationInfoWithZone info(script); |
747 PostponeInterruptsScope postpone(info.isolate()); | 753 PostponeInterruptsScope postpone(info.isolate()); |
748 VMState<COMPILER> state(info.isolate()); | 754 VMState<COMPILER> state(info.isolate()); |
749 | 755 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 | 1047 |
1042 // Set the expected number of properties for instances and return | 1048 // Set the expected number of properties for instances and return |
1043 // the resulting function. | 1049 // the resulting function. |
1044 SetExpectedNofPropertiesFromEstimate(result, | 1050 SetExpectedNofPropertiesFromEstimate(result, |
1045 literal->expected_property_count()); | 1051 literal->expected_property_count()); |
1046 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); | 1052 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); |
1047 return result; | 1053 return result; |
1048 } | 1054 } |
1049 | 1055 |
1050 | 1056 |
1051 static Handle<Code> GetCodeFromOptimizedCodeMap(Handle<JSFunction> function, | 1057 MUST_USE_RESULT static MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
1052 BailoutId osr_ast_id) { | 1058 Handle<JSFunction> function, |
| 1059 BailoutId osr_ast_id) { |
1053 if (FLAG_cache_optimized_code) { | 1060 if (FLAG_cache_optimized_code) { |
1054 Handle<SharedFunctionInfo> shared(function->shared()); | 1061 Handle<SharedFunctionInfo> shared(function->shared()); |
1055 DisallowHeapAllocation no_gc; | 1062 DisallowHeapAllocation no_gc; |
1056 int index = shared->SearchOptimizedCodeMap( | 1063 int index = shared->SearchOptimizedCodeMap( |
1057 function->context()->native_context(), osr_ast_id); | 1064 function->context()->native_context(), osr_ast_id); |
1058 if (index > 0) { | 1065 if (index > 0) { |
1059 if (FLAG_trace_opt) { | 1066 if (FLAG_trace_opt) { |
1060 PrintF("[found optimized code for "); | 1067 PrintF("[found optimized code for "); |
1061 function->ShortPrint(); | 1068 function->ShortPrint(); |
1062 if (!osr_ast_id.IsNone()) { | 1069 if (!osr_ast_id.IsNone()) { |
1063 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); | 1070 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); |
1064 } | 1071 } |
1065 PrintF("]\n"); | 1072 PrintF("]\n"); |
1066 } | 1073 } |
1067 FixedArray* literals = shared->GetLiteralsFromOptimizedCodeMap(index); | 1074 FixedArray* literals = shared->GetLiteralsFromOptimizedCodeMap(index); |
1068 if (literals != NULL) function->set_literals(literals); | 1075 if (literals != NULL) function->set_literals(literals); |
1069 return Handle<Code>(shared->GetCodeFromOptimizedCodeMap(index)); | 1076 return Handle<Code>(shared->GetCodeFromOptimizedCodeMap(index)); |
1070 } | 1077 } |
1071 } | 1078 } |
1072 return Handle<Code>::null(); | 1079 return MaybeHandle<Code>(); |
1073 } | 1080 } |
1074 | 1081 |
1075 | 1082 |
1076 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { | 1083 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) { |
1077 Handle<Code> code = info->code(); | 1084 Handle<Code> code = info->code(); |
1078 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. | 1085 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. |
1079 | 1086 |
1080 // Cache optimized code. | 1087 // Cache optimized code. |
1081 if (FLAG_cache_optimized_code) { | 1088 if (FLAG_cache_optimized_code) { |
1082 Handle<JSFunction> function = info->closure(); | 1089 Handle<JSFunction> function = info->closure(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 if (info->is_osr()) { | 1156 if (info->is_osr()) { |
1150 PrintF(" for concurrent OSR at %d.\n", info->osr_ast_id().ToInt()); | 1157 PrintF(" for concurrent OSR at %d.\n", info->osr_ast_id().ToInt()); |
1151 } else { | 1158 } else { |
1152 PrintF(" for concurrent optimization.\n"); | 1159 PrintF(" for concurrent optimization.\n"); |
1153 } | 1160 } |
1154 } | 1161 } |
1155 return true; | 1162 return true; |
1156 } | 1163 } |
1157 | 1164 |
1158 | 1165 |
1159 Handle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, | 1166 MaybeHandle<Code> Compiler::GetOptimizedCode(Handle<JSFunction> function, |
1160 Handle<Code> current_code, | 1167 Handle<Code> current_code, |
1161 ConcurrencyMode mode, | 1168 ConcurrencyMode mode, |
1162 BailoutId osr_ast_id) { | 1169 BailoutId osr_ast_id) { |
1163 Handle<Code> cached_code = GetCodeFromOptimizedCodeMap(function, osr_ast_id); | 1170 Handle<Code> cached_code; |
1164 if (!cached_code.is_null()) return cached_code; | 1171 if (GetCodeFromOptimizedCodeMap( |
| 1172 function, osr_ast_id).ToHandle(&cached_code)) { |
| 1173 return cached_code; |
| 1174 } |
1165 | 1175 |
1166 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); | 1176 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); |
1167 Isolate* isolate = info->isolate(); | 1177 Isolate* isolate = info->isolate(); |
1168 VMState<COMPILER> state(isolate); | 1178 VMState<COMPILER> state(isolate); |
1169 ASSERT(!isolate->has_pending_exception()); | 1179 ASSERT(!isolate->has_pending_exception()); |
1170 PostponeInterruptsScope postpone(isolate); | 1180 PostponeInterruptsScope postpone(isolate); |
1171 | 1181 |
1172 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1182 Handle<SharedFunctionInfo> shared = info->shared_info(); |
1173 ASSERT_NE(ScopeInfo::Empty(isolate), shared->scope_info()); | 1183 ASSERT_NE(ScopeInfo::Empty(isolate), shared->scope_info()); |
1174 int compiled_size = shared->end_position() - shared->start_position(); | 1184 int compiled_size = shared->end_position() - shared->start_position(); |
(...skipping 12 matching lines...) Expand all Loading... |
1187 } | 1197 } |
1188 | 1198 |
1189 // Failed. | 1199 // Failed. |
1190 if (FLAG_trace_opt) { | 1200 if (FLAG_trace_opt) { |
1191 PrintF("[failed to optimize "); | 1201 PrintF("[failed to optimize "); |
1192 function->PrintName(); | 1202 function->PrintName(); |
1193 PrintF(": %s]\n", GetBailoutReason(info->bailout_reason())); | 1203 PrintF(": %s]\n", GetBailoutReason(info->bailout_reason())); |
1194 } | 1204 } |
1195 | 1205 |
1196 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | 1206 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
1197 return Handle<Code>::null(); | 1207 return MaybeHandle<Code>(); |
1198 } | 1208 } |
1199 | 1209 |
1200 | 1210 |
1201 Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { | 1211 Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { |
1202 // Take ownership of compilation info. Deleting compilation info | 1212 // Take ownership of compilation info. Deleting compilation info |
1203 // also tears down the zone and the recompile job. | 1213 // also tears down the zone and the recompile job. |
1204 SmartPointer<CompilationInfo> info(job->info()); | 1214 SmartPointer<CompilationInfo> info(job->info()); |
1205 Isolate* isolate = info->isolate(); | 1215 Isolate* isolate = info->isolate(); |
1206 | 1216 |
1207 VMState<COMPILER> state(isolate); | 1217 VMState<COMPILER> state(isolate); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 AllowHandleDereference allow_deref; | 1314 AllowHandleDereference allow_deref; |
1305 bool tracing_on = info()->IsStub() | 1315 bool tracing_on = info()->IsStub() |
1306 ? FLAG_trace_hydrogen_stubs | 1316 ? FLAG_trace_hydrogen_stubs |
1307 : (FLAG_trace_hydrogen && | 1317 : (FLAG_trace_hydrogen && |
1308 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1318 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1309 return (tracing_on && | 1319 return (tracing_on && |
1310 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1320 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1311 } | 1321 } |
1312 | 1322 |
1313 } } // namespace v8::internal | 1323 } } // namespace v8::internal |
OLD | NEW |