OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler.h" | 5 #include "src/compiler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 AddWeakObjectToCodeDependency(isolate, object, code); | 244 AddWeakObjectToCodeDependency(isolate, object, code); |
245 } | 245 } |
246 code->set_can_have_weak_objects(true); | 246 code->set_can_have_weak_objects(true); |
247 } | 247 } |
248 | 248 |
249 // ---------------------------------------------------------------------------- | 249 // ---------------------------------------------------------------------------- |
250 // Local helper methods that make up the compilation pipeline. | 250 // Local helper methods that make up the compilation pipeline. |
251 | 251 |
252 namespace { | 252 namespace { |
253 | 253 |
254 bool Parse(ParseInfo* info) { | |
255 // Create a canonical handle scope if compiling ignition bytecode. This is | |
256 // required by the constant array builder to de-duplicate objects without | |
257 // dereferencing handles. | |
258 std::unique_ptr<CanonicalHandleScope> canonical; | |
259 if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate())); | |
260 | |
261 return Parser::ParseStatic(info); | |
262 } | |
263 | |
264 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, | 254 void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, |
265 CompilationInfo* info) { | 255 CompilationInfo* info) { |
266 // Log the code generation. If source information is available include | 256 // Log the code generation. If source information is available include |
267 // script name and line number. Check explicitly whether logging is | 257 // script name and line number. Check explicitly whether logging is |
268 // enabled as finding the line number is not free. | 258 // enabled as finding the line number is not free. |
269 if (info->isolate()->logger()->is_logging_code_events() || | 259 if (info->isolate()->logger()->is_logging_code_events() || |
270 info->isolate()->is_profiling()) { | 260 info->isolate()->is_profiling()) { |
271 Handle<SharedFunctionInfo> shared = info->shared_info(); | 261 Handle<SharedFunctionInfo> shared = info->shared_info(); |
272 Handle<Script> script = info->parse_info()->script(); | 262 Handle<Script> script = info->parse_info()->script(); |
273 Handle<AbstractCode> abstract_code = | 263 Handle<AbstractCode> abstract_code = |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 return false; | 422 return false; |
433 } | 423 } |
434 return true; | 424 return true; |
435 } | 425 } |
436 | 426 |
437 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 427 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
438 VMState<COMPILER> state(info->isolate()); | 428 VMState<COMPILER> state(info->isolate()); |
439 PostponeInterruptsScope postpone(info->isolate()); | 429 PostponeInterruptsScope postpone(info->isolate()); |
440 | 430 |
441 // Parse and update CompilationInfo with the results. | 431 // Parse and update CompilationInfo with the results. |
442 if (!Parse(info->parse_info())) return MaybeHandle<Code>(); | 432 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
443 DCHECK_EQ(info->shared_info()->language_mode(), | 433 DCHECK_EQ(info->shared_info()->language_mode(), |
444 info->literal()->language_mode()); | 434 info->literal()->language_mode()); |
445 | 435 |
446 // Compile either unoptimized code or bytecode for the interpreter. | 436 // Compile either unoptimized code or bytecode for the interpreter. |
447 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 437 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
448 | 438 |
449 // Record the function compilation event. | 439 // Record the function compilation event. |
450 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 440 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
451 | 441 |
452 return info->code(); | 442 return info->code(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 // Cache optimized context-specific code. | 475 // Cache optimized context-specific code. |
486 Handle<JSFunction> function = info->closure(); | 476 Handle<JSFunction> function = info->closure(); |
487 Handle<SharedFunctionInfo> shared(function->shared()); | 477 Handle<SharedFunctionInfo> shared(function->shared()); |
488 Handle<LiteralsArray> literals(function->literals()); | 478 Handle<LiteralsArray> literals(function->literals()); |
489 Handle<Context> native_context(function->context()->native_context()); | 479 Handle<Context> native_context(function->context()->native_context()); |
490 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 480 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
491 literals, info->osr_ast_id()); | 481 literals, info->osr_ast_id()); |
492 } | 482 } |
493 | 483 |
494 bool Renumber(ParseInfo* parse_info) { | 484 bool Renumber(ParseInfo* parse_info) { |
495 // Create a canonical handle scope if compiling ignition bytecode. This is | |
496 // required by the constant array builder to de-duplicate objects without | |
497 // dereferencing handles. | |
498 std::unique_ptr<CanonicalHandleScope> canonical; | |
499 if (FLAG_ignition) { | |
500 canonical.reset(new CanonicalHandleScope(parse_info->isolate())); | |
501 } | |
502 | |
503 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | 485 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
504 parse_info->literal())) { | 486 parse_info->literal())) { |
505 return false; | 487 return false; |
506 } | 488 } |
507 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | 489 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
508 if (!shared_info.is_null()) { | 490 if (!shared_info.is_null()) { |
509 FunctionLiteral* lit = parse_info->literal(); | 491 FunctionLiteral* lit = parse_info->literal(); |
510 shared_info->set_ast_node_count(lit->ast_node_count()); | 492 shared_info->set_ast_node_count(lit->ast_node_count()); |
511 if (lit->dont_optimize_reason() != kNoReason) { | 493 if (lit->dont_optimize_reason() != kNoReason) { |
512 shared_info->DisableOptimization(lit->dont_optimize_reason()); | 494 shared_info->DisableOptimization(lit->dont_optimize_reason()); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 } | 901 } |
920 } | 902 } |
921 | 903 |
922 if (FLAG_trace_opt) { | 904 if (FLAG_trace_opt) { |
923 OFStream os(stdout); | 905 OFStream os(stdout); |
924 os << "[switching method " << Brief(*function) << " to baseline code]" | 906 os << "[switching method " << Brief(*function) << " to baseline code]" |
925 << std::endl; | 907 << std::endl; |
926 } | 908 } |
927 | 909 |
928 // Parse and update CompilationInfo with the results. | 910 // Parse and update CompilationInfo with the results. |
929 if (!Parse(info.parse_info())) return MaybeHandle<Code>(); | 911 if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>(); |
930 Handle<SharedFunctionInfo> shared = info.shared_info(); | 912 Handle<SharedFunctionInfo> shared = info.shared_info(); |
931 DCHECK_EQ(shared->language_mode(), info.literal()->language_mode()); | 913 DCHECK_EQ(shared->language_mode(), info.literal()->language_mode()); |
932 | 914 |
933 // Compile baseline code using the full code generator. | 915 // Compile baseline code using the full code generator. |
934 if (!Compiler::Analyze(info.parse_info()) || | 916 if (!Compiler::Analyze(info.parse_info()) || |
935 !FullCodeGenerator::MakeCode(&info)) { | 917 !FullCodeGenerator::MakeCode(&info)) { |
936 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 918 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
937 return MaybeHandle<Code>(); | 919 return MaybeHandle<Code>(); |
938 } | 920 } |
939 | 921 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 | 1029 |
1048 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1030 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
1049 FixedArray* array = isolate->native_context()->embedder_data(); | 1031 FixedArray* array = isolate->native_context()->embedder_data(); |
1050 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); | 1032 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); |
1051 | 1033 |
1052 isolate->debug()->OnBeforeCompile(script); | 1034 isolate->debug()->OnBeforeCompile(script); |
1053 | 1035 |
1054 Handle<SharedFunctionInfo> result; | 1036 Handle<SharedFunctionInfo> result; |
1055 | 1037 |
1056 { VMState<COMPILER> state(info->isolate()); | 1038 { VMState<COMPILER> state(info->isolate()); |
1057 if (parse_info->literal() == nullptr && !Parse(parse_info)) { | 1039 if (parse_info->literal() == nullptr && !Parser::ParseStatic(parse_info)) { |
1058 return Handle<SharedFunctionInfo>::null(); | 1040 return Handle<SharedFunctionInfo>::null(); |
1059 } | 1041 } |
1060 | 1042 |
1061 FunctionLiteral* lit = parse_info->literal(); | 1043 FunctionLiteral* lit = parse_info->literal(); |
1062 | 1044 |
1063 // Measure how long it takes to do the compilation; only take the | 1045 // Measure how long it takes to do the compilation; only take the |
1064 // rest of the function into account to avoid overlap with the | 1046 // rest of the function into account to avoid overlap with the |
1065 // parsing statistics. | 1047 // parsing statistics. |
1066 RuntimeCallTimerScope runtimeTimer( | 1048 RuntimeCallTimerScope runtimeTimer( |
1067 isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval | 1049 isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 bool Compiler::Analyze(ParseInfo* info) { | 1093 bool Compiler::Analyze(ParseInfo* info) { |
1112 DCHECK_NOT_NULL(info->literal()); | 1094 DCHECK_NOT_NULL(info->literal()); |
1113 if (!Rewriter::Rewrite(info)) return false; | 1095 if (!Rewriter::Rewrite(info)) return false; |
1114 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); | 1096 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); |
1115 if (!Renumber(info)) return false; | 1097 if (!Renumber(info)) return false; |
1116 DCHECK_NOT_NULL(info->scope()); | 1098 DCHECK_NOT_NULL(info->scope()); |
1117 return true; | 1099 return true; |
1118 } | 1100 } |
1119 | 1101 |
1120 bool Compiler::ParseAndAnalyze(ParseInfo* info) { | 1102 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
1121 if (!Parse(info)) return false; | 1103 if (!Parser::ParseStatic(info)) return false; |
1122 if (!Compiler::Analyze(info)) return false; | 1104 if (!Compiler::Analyze(info)) return false; |
1123 DCHECK_NOT_NULL(info->literal()); | 1105 DCHECK_NOT_NULL(info->literal()); |
1124 DCHECK_NOT_NULL(info->scope()); | 1106 DCHECK_NOT_NULL(info->scope()); |
1125 return true; | 1107 return true; |
1126 } | 1108 } |
1127 | 1109 |
1128 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { | 1110 bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { |
1129 if (function->is_compiled()) return true; | 1111 if (function->is_compiled()) return true; |
1130 Isolate* isolate = function->GetIsolate(); | 1112 Isolate* isolate = function->GetIsolate(); |
1131 DCHECK(AllowCompilation::IsAllowed(isolate)); | 1113 DCHECK(AllowCompilation::IsAllowed(isolate)); |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 // first time. It may have already been compiled previously. | 1683 // first time. It may have already been compiled previously. |
1702 result->set_never_compiled(outer_info->shared_info()->never_compiled()); | 1684 result->set_never_compiled(outer_info->shared_info()->never_compiled()); |
1703 } | 1685 } |
1704 | 1686 |
1705 Zone zone(isolate->allocator(), ZONE_NAME); | 1687 Zone zone(isolate->allocator(), ZONE_NAME); |
1706 ParseInfo parse_info(&zone, script); | 1688 ParseInfo parse_info(&zone, script); |
1707 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1689 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
1708 parse_info.set_literal(literal); | 1690 parse_info.set_literal(literal); |
1709 parse_info.set_shared_info(result); | 1691 parse_info.set_shared_info(result); |
1710 parse_info.set_language_mode(literal->scope()->language_mode()); | 1692 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 1693 parse_info.set_ast_value_factory( |
| 1694 outer_info->parse_info()->ast_value_factory()); |
| 1695 parse_info.set_ast_value_factory_owned(false); |
| 1696 |
1711 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1697 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1712 if (outer_info->is_debug()) info.MarkAsDebug(); | 1698 if (outer_info->is_debug()) info.MarkAsDebug(); |
1713 | 1699 |
1714 // Generate code | 1700 // Generate code |
1715 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1701 TimerEventScope<TimerEventCompileCode> timer(isolate); |
1716 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); | 1702 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); |
1717 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); | 1703 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); |
1718 | 1704 |
1719 if (!literal->ShouldEagerCompile()) { | 1705 if (!literal->ShouldEagerCompile()) { |
1720 info.SetCode(isolate->builtins()->CompileLazy()); | 1706 info.SetCode(isolate->builtins()->CompileLazy()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1830 DCHECK(shared->is_compiled()); | 1816 DCHECK(shared->is_compiled()); |
1831 function->set_literals(cached.literals); | 1817 function->set_literals(cached.literals); |
1832 } else if (shared->is_compiled()) { | 1818 } else if (shared->is_compiled()) { |
1833 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1819 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1834 JSFunction::EnsureLiterals(function); | 1820 JSFunction::EnsureLiterals(function); |
1835 } | 1821 } |
1836 } | 1822 } |
1837 | 1823 |
1838 } // namespace internal | 1824 } // namespace internal |
1839 } // namespace v8 | 1825 } // namespace v8 |
OLD | NEW |