| 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 |