[Interpreter] Localize the CanonicalHandleScope to parsing and renumbering.
Ignition requires that objects which will be inserted into the constant pool are canonicalized (to enable off-thread bytecode generation). We created a CanonicalizeHandleScope across parse/compile however this impacts performance (~5-8% on CodeLoad). Now we localize the CanonicalHandleScope to only the parse / internalization and renumbering phases where objects are created which could end up in the constant array pool. This seems to address the performance regression. BUG=v8:5203,chromium:634953 Review-Url: https://codereview.chromium.org/2318653002 Cr-Commit-Position: refs/heads/master@{#39443}
This commit is contained in:
parent
eeb4f28aed
commit
b37daacd6b
19
src/api.cc
19
src/api.cc
@ -2223,15 +2223,18 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
|
||||
source->info->set_script(script);
|
||||
source->info->set_context(isolate->native_context());
|
||||
|
||||
// Create a canonical handle scope before internalizing parsed values if
|
||||
// compiling bytecode. This is required for off-thread bytecode generation.
|
||||
std::unique_ptr<i::CanonicalHandleScope> canonical;
|
||||
if (i::FLAG_ignition) canonical.reset(new i::CanonicalHandleScope(isolate));
|
||||
{
|
||||
// Create a canonical handle scope if compiling ignition bytecode. This is
|
||||
// required by the constant array builder to de-duplicate objects without
|
||||
// dereferencing handles.
|
||||
std::unique_ptr<i::CanonicalHandleScope> canonical;
|
||||
if (i::FLAG_ignition) canonical.reset(new i::CanonicalHandleScope(isolate));
|
||||
|
||||
// Do the parsing tasks which need to be done on the main thread. This will
|
||||
// also handle parse errors.
|
||||
source->parser->Internalize(isolate, script,
|
||||
source->info->literal() == nullptr);
|
||||
// Do the parsing tasks which need to be done on the main thread. This will
|
||||
// also handle parse errors.
|
||||
source->parser->Internalize(isolate, script,
|
||||
source->info->literal() == nullptr);
|
||||
}
|
||||
source->parser->HandleSourceURLComments(isolate, script);
|
||||
|
||||
i::Handle<i::SharedFunctionInfo> result;
|
||||
|
@ -138,11 +138,6 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
|
||||
|
||||
DeferredHandleScope scope(isolate_);
|
||||
{
|
||||
// Create a canonical handle scope before internalizing parsed values if
|
||||
// compiling bytecode. This is required for off-thread bytecode generation.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(isolate_));
|
||||
|
||||
Handle<SharedFunctionInfo> shared(function_->shared(), isolate_);
|
||||
Handle<Script> script(Script::cast(shared->script()), isolate_);
|
||||
|
||||
@ -150,9 +145,17 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
|
||||
parse_info_->set_context(handle(function_->context(), isolate_));
|
||||
parse_info_->set_shared_info(handle(function_->shared(), isolate_));
|
||||
|
||||
// Do the parsing tasks which need to be done on the main thread. This will
|
||||
// also handle parse errors.
|
||||
parser_->Internalize(isolate_, script, parse_info_->literal() == nullptr);
|
||||
{
|
||||
// Create a canonical handle scope if compiling ignition bytecode. This is
|
||||
// required by the constant array builder to de-duplicate objects without
|
||||
// dereferencing handles.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(isolate_));
|
||||
|
||||
// Do the parsing tasks which need to be done on the main thread. This
|
||||
// will also handle parse errors.
|
||||
parser_->Internalize(isolate_, script, parse_info_->literal() == nullptr);
|
||||
}
|
||||
parser_->HandleSourceURLComments(isolate_, script);
|
||||
|
||||
parse_info_->set_character_stream(nullptr);
|
||||
@ -173,16 +176,9 @@ bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
|
||||
compile_info_.reset(new CompilationInfo(parse_info_.get(), function_));
|
||||
|
||||
DeferredHandleScope scope(isolate_);
|
||||
{
|
||||
// Create a canonical handle scope before ast numbering if compiling
|
||||
// bytecode. This is required for off-thread bytecode generation.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(isolate_));
|
||||
|
||||
if (Compiler::Analyze(parse_info_.get())) {
|
||||
compile_job_.reset(
|
||||
Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
|
||||
}
|
||||
if (Compiler::Analyze(parse_info_.get())) {
|
||||
compile_job_.reset(
|
||||
Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
|
||||
}
|
||||
compile_info_->set_deferred_handles(scope.Detach());
|
||||
|
||||
|
@ -257,6 +257,16 @@ bool IsEvalToplevel(Handle<SharedFunctionInfo> shared) {
|
||||
Script::COMPILATION_TYPE_EVAL;
|
||||
}
|
||||
|
||||
bool Parse(ParseInfo* info) {
|
||||
// Create a canonical handle scope if compiling ignition bytecode. This is
|
||||
// required by the constant array builder to de-duplicate objects without
|
||||
// dereferencing handles.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate()));
|
||||
|
||||
return Parser::ParseStatic(info);
|
||||
}
|
||||
|
||||
void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
|
||||
CompilationInfo* info) {
|
||||
// Log the code generation. If source information is available include
|
||||
@ -421,13 +431,8 @@ MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) {
|
||||
VMState<COMPILER> state(info->isolate());
|
||||
PostponeInterruptsScope postpone(info->isolate());
|
||||
|
||||
// Create a canonical handle scope before internalizing parsed values if
|
||||
// compiling bytecode. This is required for off-thread bytecode generation.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info->isolate()));
|
||||
|
||||
// Parse and update CompilationInfo with the results.
|
||||
if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
|
||||
if (!Parse(info->parse_info())) return MaybeHandle<Code>();
|
||||
DCHECK_EQ(info->shared_info()->language_mode(),
|
||||
info->literal()->language_mode());
|
||||
|
||||
@ -501,6 +506,14 @@ void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
|
||||
}
|
||||
|
||||
bool Renumber(ParseInfo* parse_info) {
|
||||
// Create a canonical handle scope if compiling ignition bytecode. This is
|
||||
// required by the constant array builder to de-duplicate objects without
|
||||
// dereferencing handles.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) {
|
||||
canonical.reset(new CanonicalHandleScope(parse_info->isolate()));
|
||||
}
|
||||
|
||||
if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(),
|
||||
parse_info->literal())) {
|
||||
return false;
|
||||
@ -924,7 +937,7 @@ MaybeHandle<Code> GetBaselineCode(Handle<JSFunction> function) {
|
||||
}
|
||||
|
||||
// Parse and update CompilationInfo with the results.
|
||||
if (!Parser::ParseStatic(info.parse_info())) return MaybeHandle<Code>();
|
||||
if (!Parse(info.parse_info())) return MaybeHandle<Code>();
|
||||
Handle<SharedFunctionInfo> shared = info.shared_info();
|
||||
DCHECK_EQ(shared->language_mode(), info.literal()->language_mode());
|
||||
|
||||
@ -1027,11 +1040,6 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
ParseInfo* parse_info = info->parse_info();
|
||||
Handle<Script> script = parse_info->script();
|
||||
|
||||
// Create a canonical handle scope before internalizing parsed values if
|
||||
// compiling bytecode. This is required for off-thread bytecode generation.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(isolate));
|
||||
|
||||
// TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
|
||||
FixedArray* array = isolate->native_context()->embedder_data();
|
||||
script->set_context_data(array->get(v8::Context::kDebugIdIndex));
|
||||
@ -1075,7 +1083,7 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
parse_info->set_compile_options(ScriptCompiler::kNoCompileOptions);
|
||||
}
|
||||
|
||||
if (!Parser::ParseStatic(parse_info)) {
|
||||
if (!Parse(parse_info)) {
|
||||
return Handle<SharedFunctionInfo>::null();
|
||||
}
|
||||
}
|
||||
@ -1152,7 +1160,7 @@ bool Compiler::Analyze(ParseInfo* info) {
|
||||
}
|
||||
|
||||
bool Compiler::ParseAndAnalyze(ParseInfo* info) {
|
||||
if (!Parser::ParseStatic(info)) return false;
|
||||
if (!Parse(info)) return false;
|
||||
if (!Compiler::Analyze(info)) return false;
|
||||
DCHECK_NOT_NULL(info->literal());
|
||||
DCHECK_NOT_NULL(info->scope());
|
||||
@ -1774,12 +1782,6 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
|
||||
|
||||
// Create a canonical handle scope if compiling ignition bytecode. This is
|
||||
// required by the constant array builder to de-duplicate common objects
|
||||
// without dereferencing handles.
|
||||
std::unique_ptr<CanonicalHandleScope> canonical;
|
||||
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(info.isolate()));
|
||||
|
||||
if (lazy) {
|
||||
info.SetCode(isolate->builtins()->CompileLazy());
|
||||
} else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) {
|
||||
|
Loading…
Reference in New Issue
Block a user