Index: src/compiler.cc |
diff --git a/src/compiler.cc b/src/compiler.cc |
index f6d0611de5b53bd9cc4f7b1dd23dbd99ced3e1ae..efae4db085959c631fd4709a63b58fec1c82c1ca 100644 |
--- a/src/compiler.cc |
+++ b/src/compiler.cc |
@@ -383,12 +383,14 @@ bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info, |
!shared_info->is_asm_wasm_broken() && !is_debug; |
} |
-bool UseCompilerDispatcher(CompilerDispatcher* dispatcher, |
+bool UseCompilerDispatcher(Compiler::ConcurrencyMode inner_function_mode, |
+ CompilerDispatcher* dispatcher, |
DeclarationScope* scope, |
Handle<SharedFunctionInfo> shared_info, |
bool is_debug, bool will_serialize) { |
- return FLAG_compiler_dispatcher_eager_inner && dispatcher->IsEnabled() && |
- !is_debug && !will_serialize && |
+ return FLAG_compiler_dispatcher_eager_inner && |
+ inner_function_mode == Compiler::CONCURRENT && |
+ dispatcher->IsEnabled() && !is_debug && !will_serialize && |
!UseAsmWasm(scope, shared_info, is_debug); |
} |
@@ -509,6 +511,7 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) { |
bool CompileUnoptimizedInnerFunctions( |
Compiler::EagerInnerFunctionLiterals* literals, |
+ Compiler::ConcurrencyMode inner_function_mode, |
CompilationInfo* outer_info) { |
Isolate* isolate = outer_info->isolate(); |
Handle<Script> script = outer_info->script(); |
@@ -529,8 +532,8 @@ bool CompileUnoptimizedInnerFunctions( |
// Try to enqueue the eager function on the compiler dispatcher. |
CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); |
- if (UseCompilerDispatcher(dispatcher, literal->scope(), shared, is_debug, |
- will_serialize) && |
+ if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), |
+ shared, is_debug, will_serialize) && |
dispatcher->EnqueueAndStep(shared, literal)) { |
// If we have successfully queued up the function for compilation on the |
// compiler dispatcher then we are done. |
@@ -538,7 +541,8 @@ bool CompileUnoptimizedInnerFunctions( |
} else { |
// Otherwise generate unoptimized code now. |
ParseInfo parse_info(script); |
- CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
+ CompilationInfo info(parse_info.zone(), &parse_info, |
+ Handle<JSFunction>::null()); |
parse_info.set_literal(literal); |
parse_info.set_shared_info(shared); |
@@ -560,13 +564,43 @@ bool CompileUnoptimizedInnerFunctions( |
return true; |
} |
-bool CompileUnoptimizedCode(CompilationInfo* info) { |
+bool InnerFunctionIsAsmModule( |
+ ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>* literals) { |
+ for (auto it : *literals) { |
+ FunctionLiteral* literal = it->value(); |
+ if (literal->scope()->IsAsmModule()) return true; |
+ } |
+ return false; |
+} |
+ |
+bool CompileUnoptimizedCode(CompilationInfo* info, |
+ Compiler::ConcurrencyMode inner_function_mode) { |
Isolate* isolate = info->isolate(); |
DCHECK(AllowCompilation::IsAllowed(isolate)); |
Compiler::EagerInnerFunctionLiterals inner_literals; |
- if (!Compiler::Analyze(info->parse_info(), &inner_literals) || |
- !CompileUnoptimizedInnerFunctions(&inner_literals, info) || |
+ if (!Compiler::Analyze(info->parse_info(), &inner_literals)) { |
+ if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
+ return false; |
+ } |
+ |
+ // Disable concurrent inner compilation for asm-wasm code. |
+ // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm |
+ // builder doesn't do parsing when visiting function declarations. |
+ if (info->scope()->IsAsmModule() || |
+ InnerFunctionIsAsmModule(&inner_literals)) { |
+ inner_function_mode = Compiler::NOT_CONCURRENT; |
+ } |
+ |
+ if (inner_function_mode == Compiler::CONCURRENT) { |
+ // Seal the parse zone so that it can be shared by parallel inner function |
+ // compilation jobs. |
+ DCHECK_NE(info->parse_info()->zone(), info->zone()); |
+ info->parse_info()->zone()->Seal(); |
+ } |
+ |
+ if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, |
+ info) || |
!GenerateUnoptimizedCode(info)) { |
if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
return false; |
@@ -600,7 +634,8 @@ void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* info) { |
info->script()->set_shared_function_infos(*infos); |
} |
-MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
+MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode( |
+ CompilationInfo* info, Compiler::ConcurrencyMode inner_function_mode) { |
RuntimeCallTimerScope runtimeTimer( |
info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); |
VMState<COMPILER> state(info->isolate()); |
@@ -615,7 +650,9 @@ MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
info->literal()->language_mode()); |
// Compile either unoptimized code or bytecode for the interpreter. |
- if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
+ if (!CompileUnoptimizedCode(info, inner_function_mode)) { |
+ return MaybeHandle<Code>(); |
+ } |
// Record the function compilation event. |
RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
@@ -925,7 +962,7 @@ MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) { |
VMState<COMPILER> state(isolate); |
PostponeInterruptsScope postpone(isolate); |
ParseInfo parse_info(handle(function->shared())); |
- CompilationInfo info(&parse_info, function); |
+ CompilationInfo info(parse_info.zone(), &parse_info, function); |
DCHECK(function->shared()->is_compiled()); |
@@ -1058,9 +1095,11 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
} |
ParseInfo parse_info(handle(function->shared())); |
- CompilationInfo info(&parse_info, function); |
+ Zone compile_zone(isolate->allocator(), ZONE_NAME); |
+ CompilationInfo info(&compile_zone, &parse_info, function); |
Handle<Code> result; |
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCode(&info), Code); |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, result, GetUnoptimizedCode(&info, Compiler::CONCURRENT), Code); |
if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { |
Handle<Code> opt_code; |
@@ -1121,7 +1160,7 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
parse_info->set_function_literal_id(result->function_literal_id()); |
// Compile the code. |
- if (!CompileUnoptimizedCode(info)) { |
+ if (!CompileUnoptimizedCode(info, Compiler::CONCURRENT)) { |
return Handle<SharedFunctionInfo>::null(); |
} |
@@ -1230,20 +1269,11 @@ bool Compiler::CompileOptimized(Handle<JSFunction> function, |
// Start a compilation. |
Handle<Code> code; |
if (!GetOptimizedCode(function, mode).ToHandle(&code)) { |
- // Optimization failed, get unoptimized code. |
+ // Optimization failed, get unoptimized code. Unoptimized code must exist |
+ // already if we are optimizing. |
DCHECK(!isolate->has_pending_exception()); |
- if (function->shared()->is_compiled()) { |
- code = handle(function->shared()->code(), isolate); |
- } else if (function->shared()->HasBytecodeArray()) { |
- code = isolate->builtins()->InterpreterEntryTrampoline(); |
- function->shared()->ReplaceCode(*code); |
- } else { |
- ParseInfo parse_info(handle(function->shared())); |
- CompilationInfo info(&parse_info, function); |
- if (!GetUnoptimizedCode(&info).ToHandle(&code)) { |
- return false; |
- } |
- } |
+ DCHECK(function->shared()->is_compiled()); |
+ code = handle(function->shared()->code(), isolate); |
} |
// Install code on closure. |
@@ -1263,9 +1293,10 @@ bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { |
// Start a compilation. |
ParseInfo parse_info(shared); |
- CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
+ CompilationInfo info(parse_info.zone(), &parse_info, |
+ Handle<JSFunction>::null()); |
info.MarkAsDebug(); |
- if (GetUnoptimizedCode(&info).is_null()) { |
+ if (GetUnoptimizedCode(&info, Compiler::NOT_CONCURRENT).is_null()) { |
isolate->clear_pending_exception(); |
return false; |
} |
@@ -1290,7 +1321,8 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { |
// Start a compilation. |
ParseInfo parse_info(script); |
- CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
+ Zone compile_zone(isolate->allocator(), ZONE_NAME); |
+ CompilationInfo info(&compile_zone, &parse_info, Handle<JSFunction>::null()); |
info.MarkAsDebug(); |
// TODO(635): support extensions. |
@@ -1313,7 +1345,9 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { |
bool Compiler::EnsureBytecode(CompilationInfo* info) { |
if (!info->shared_info()->is_compiled()) { |
- if (GetUnoptimizedCode(info).is_null()) return false; |
+ if (GetUnoptimizedCode(info, Compiler::NOT_CONCURRENT).is_null()) { |
+ return false; |
+ } |
} |
DCHECK(info->shared_info()->is_compiled()); |
@@ -1330,8 +1364,9 @@ bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
DCHECK_NOT_NULL(info->scope()); |
Handle<SharedFunctionInfo> shared = info->shared_info(); |
if (!shared->has_deoptimization_support()) { |
- Zone zone(info->isolate()->allocator(), ZONE_NAME); |
- CompilationInfo unoptimized(info->parse_info(), info->closure()); |
+ Zone compile_zone(info->isolate()->allocator(), ZONE_NAME); |
+ CompilationInfo unoptimized(&compile_zone, info->parse_info(), |
+ info->closure()); |
unoptimized.EnableDeoptimizationSupport(); |
// Don't generate full-codegen code for functions it can't support. |
@@ -1431,7 +1466,9 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( |
Script::SetEvalOrigin(script, outer_info, eval_position); |
ParseInfo parse_info(script); |
- CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
+ Zone compile_zone(isolate->allocator(), ZONE_NAME); |
+ CompilationInfo info(&compile_zone, &parse_info, |
+ Handle<JSFunction>::null()); |
parse_info.set_eval(); |
parse_info.set_language_mode(language_mode); |
parse_info.set_parse_restriction(restriction); |
@@ -1639,7 +1676,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript( |
// Compile the function and add it to the cache. |
ParseInfo parse_info(script); |
- CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
+ Zone compile_zone(isolate->allocator(), ZONE_NAME); |
+ CompilationInfo info(&compile_zone, &parse_info, |
+ Handle<JSFunction>::null()); |
if (resource_options.IsModule()) parse_info.set_module(); |
if (compile_options != ScriptCompiler::kNoCompileOptions) { |
parse_info.set_cached_data(cached_data); |
@@ -1706,7 +1745,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript( |
parse_info->set_language_mode( |
static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
- CompilationInfo compile_info(parse_info, Handle<JSFunction>::null()); |
+ Zone compile_zone(isolate->allocator(), ZONE_NAME); |
+ CompilationInfo compile_info(&compile_zone, parse_info, |
+ Handle<JSFunction>::null()); |
// The source was parsed lazily, so compiling for debugging is not possible. |
DCHECK(!compile_info.is_debug()); |