Commit 42c8812d authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[compiler] Allocate SharedFunctionInfo before compile.

This changes the compilation pipeline so that SharedFunctionInfo objects
are always allocated before the various compilers are invoked. It is a
preparation towards having that object available during compile time and
hence reducing the dependency on FunctionLiteral and the need to copy a
lot of the information into the CompilationInfo.

Optimizing compilers already assume the SharedFunctionInfo is present
and the baseline compilers have other heap accesses sprinkled throughout
the compilation process. Duplicating statically available information
from the SharedFunctionInfo within the CompilationInfo has no benefit.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1813803002

Cr-Commit-Position: refs/heads/master@{#34885}
parent e4735768
...@@ -856,6 +856,20 @@ static bool CompileBaselineCode(CompilationInfo* info) { ...@@ -856,6 +856,20 @@ static bool CompileBaselineCode(CompilationInfo* info) {
return true; return true;
} }
static void InstallBaselineCompilationResult(CompilationInfo* info,
Handle<SharedFunctionInfo> shared,
Handle<ScopeInfo> scope_info) {
// Assert that we are not overwriting (possibly patched) debug code.
DCHECK(!shared->HasDebugCode());
DCHECK(!info->code().is_null());
shared->ReplaceCode(*info->code());
shared->set_scope_info(*scope_info);
shared->set_feedback_vector(*info->feedback_vector());
if (info->has_bytecode_array()) {
DCHECK(!shared->HasBytecodeArray()); // Only compiled once.
shared->set_bytecode_array(*info->bytecode_array());
}
}
MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
CompilationInfo* info) { CompilationInfo* info) {
...@@ -878,15 +892,9 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( ...@@ -878,15 +892,9 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
// ScopeInfo object may cause a GC. // ScopeInfo object may cause a GC.
Handle<ScopeInfo> scope_info = Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info->isolate(), info->zone(), info->scope()); ScopeInfo::Create(info->isolate(), info->zone(), info->scope());
shared->set_scope_info(*scope_info);
// Update the code and feedback vector for the shared function info. // Install compilation result on the shared function info
shared->ReplaceCode(*info->code()); InstallBaselineCompilationResult(info, shared, scope_info);
shared->set_feedback_vector(*info->feedback_vector());
if (info->has_bytecode_array()) {
DCHECK(!shared->HasBytecodeArray()); // Only compiled once.
shared->set_bytecode_array(*info->bytecode_array());
}
return info->code(); return info->code();
} }
...@@ -1378,6 +1386,17 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) { ...@@ -1378,6 +1386,17 @@ void Compiler::CompileForLiveEdit(Handle<Script> script) {
tracker.RecordRootFunctionInfo(info.code()); tracker.RecordRootFunctionInfo(info.code());
} }
static Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral(
Isolate* isolate, FunctionLiteral* literal, Handle<Script> script) {
Handle<Code> code = isolate->builtins()->CompileLazy();
Handle<ScopeInfo> scope_info = handle(ScopeInfo::Empty(isolate));
Handle<SharedFunctionInfo> result = isolate->factory()->NewSharedFunctionInfo(
literal->name(), literal->materialized_literal_count(), literal->kind(),
code, scope_info);
SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
SharedFunctionInfo::SetScript(result, script);
return result;
}
static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
Isolate* isolate = info->isolate(); Isolate* isolate = info->isolate();
...@@ -1447,32 +1466,25 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -1447,32 +1466,25 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
HistogramTimerScope timer(rate); HistogramTimerScope timer(rate);
TRACE_EVENT0("v8", info->is_eval() ? "V8.CompileEval" : "V8.Compile"); TRACE_EVENT0("v8", info->is_eval() ? "V8.CompileEval" : "V8.Compile");
// Compile the code. // Allocate a shared function info object.
if (!CompileBaselineCode(info)) {
return Handle<SharedFunctionInfo>::null();
}
// Allocate function.
DCHECK(!info->code().is_null());
result = isolate->factory()->NewSharedFunctionInfo(
lit->name(), lit->materialized_literal_count(), lit->kind(),
info->code(),
ScopeInfo::Create(info->isolate(), info->zone(), info->scope()),
info->feedback_vector());
if (info->has_bytecode_array()) {
DCHECK(!result->HasBytecodeArray()); // Only compiled once.
result->set_bytecode_array(*info->bytecode_array());
}
DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position());
SharedFunctionInfo::InitFromFunctionLiteral(result, lit); result = NewSharedFunctionInfoForLiteral(isolate, lit, script);
SharedFunctionInfo::SetScript(result, script);
result->set_is_toplevel(true); result->set_is_toplevel(true);
if (info->is_eval()) { if (info->is_eval()) {
// Eval scripts cannot be (re-)compiled without context. // Eval scripts cannot be (re-)compiled without context.
result->set_allows_lazy_compilation_without_context(false); result->set_allows_lazy_compilation_without_context(false);
} }
// Compile the code.
if (!CompileBaselineCode(info)) {
return Handle<SharedFunctionInfo>::null();
}
// Install compilation result on the shared function info
Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info->isolate(), info->zone(), info->scope());
InstallBaselineCompilationResult(info, result, scope_info);
Handle<String> script_name = Handle<String> script_name =
script->name()->IsString() script->name()->IsString()
? Handle<String>(String::cast(script->name())) ? Handle<String>(String::cast(script->name()))
...@@ -1746,6 +1758,13 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( ...@@ -1746,6 +1758,13 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
} }
} }
// Allocate a shared function info object.
Handle<SharedFunctionInfo> result;
if (!maybe_existing.ToHandle(&result)) {
result = NewSharedFunctionInfoForLiteral(isolate, literal, script);
result->set_is_toplevel(false);
}
Zone zone; Zone zone;
ParseInfo parse_info(&zone, script); ParseInfo parse_info(&zone, script);
CompilationInfo info(&parse_info); CompilationInfo info(&parse_info);
...@@ -1781,46 +1800,25 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( ...@@ -1781,46 +1800,25 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
// Generate code // Generate code
TimerEventScope<TimerEventCompileCode> timer(isolate); TimerEventScope<TimerEventCompileCode> timer(isolate);
TRACE_EVENT0("v8", "V8.CompileCode"); TRACE_EVENT0("v8", "V8.CompileCode");
Handle<ScopeInfo> scope_info;
if (lazy) { if (lazy) {
Handle<Code> code = isolate->builtins()->CompileLazy(); info.SetCode(isolate->builtins()->CompileLazy());
info.SetCode(code);
// There's no need in theory for a lazy-compiled function to have a type
// feedback vector, but some parts of the system expect all
// SharedFunctionInfo instances to have one. The size of the vector depends
// on how many feedback-needing nodes are in the tree, and when lazily
// parsing we might not know that, if this function was never parsed before.
// In that case the vector will be replaced the next time MakeCode is
// called.
info.EnsureFeedbackVector();
scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
} else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) { } else if (Renumber(info.parse_info()) && GenerateBaselineCode(&info)) {
// Code generation will ensure that the feedback vector is present and // Code generation will ensure that the feedback vector is present and
// appropriately sized. // appropriately sized.
DCHECK(!info.code().is_null()); DCHECK(!info.code().is_null());
scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); Handle<ScopeInfo> scope_info =
ScopeInfo::Create(info.isolate(), info.zone(), info.scope());
if (literal->should_eager_compile() && if (literal->should_eager_compile() &&
literal->should_be_used_once_hint()) { literal->should_be_used_once_hint()) {
info.code()->MarkToBeExecutedOnce(isolate); info.code()->MarkToBeExecutedOnce(isolate);
} }
// Install compilation result on the shared function info.
InstallBaselineCompilationResult(&info, result, scope_info);
} else { } else {
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
if (maybe_existing.is_null()) { if (maybe_existing.is_null()) {
// Create a shared function info object.
Handle<SharedFunctionInfo> result =
isolate->factory()->NewSharedFunctionInfo(
literal->name(), literal->materialized_literal_count(),
literal->kind(), info.code(), scope_info, info.feedback_vector());
if (info.has_bytecode_array()) {
DCHECK(!result->HasBytecodeArray()); // Only compiled once.
result->set_bytecode_array(*info.bytecode_array());
}
SharedFunctionInfo::InitFromFunctionLiteral(result, literal);
SharedFunctionInfo::SetScript(result, script);
result->set_is_toplevel(false);
// If the outer function has been compiled before, we cannot be sure that // If the outer function has been compiled before, we cannot be sure that
// shared function info for this function literal has been created for the // shared function info for this function literal has been created for the
// first time. It may have already been compiled previously. // first time. It may have already been compiled previously.
...@@ -1835,15 +1833,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( ...@@ -1835,15 +1833,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
SetExpectedNofPropertiesFromEstimate(result, SetExpectedNofPropertiesFromEstimate(result,
literal->expected_property_count()); literal->expected_property_count());
live_edit_tracker.RecordFunctionInfo(result, literal, info.zone()); live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
return result;
} else if (!lazy) {
// Assert that we are not overwriting (possibly patched) debug code.
DCHECK(!existing->HasDebugCode());
existing->ReplaceCode(*info.code());
existing->set_scope_info(*scope_info);
existing->set_feedback_vector(*info.feedback_vector());
} }
return existing;
return result;
} }
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative(
...@@ -1866,9 +1858,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative( ...@@ -1866,9 +1858,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForNative(
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
name, literals, FunctionKind::kNormalFunction, code, name, literals, FunctionKind::kNormalFunction, code,
Handle<ScopeInfo>(fun->shared()->scope_info()), Handle<ScopeInfo>(fun->shared()->scope_info()));
Handle<TypeFeedbackVector>(fun->shared()->feedback_vector()));
shared->set_construct_stub(*construct_stub); shared->set_construct_stub(*construct_stub);
shared->set_feedback_vector(fun->shared()->feedback_vector());
// Copy the function data to the shared function info. // Copy the function data to the shared function info.
shared->set_function_data(fun->shared()->function_data()); shared->set_function_data(fun->shared()->function_data());
......
...@@ -444,7 +444,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, ...@@ -444,7 +444,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
bytecode_array_(handle(info->shared_info()->bytecode_array())), bytecode_array_(handle(info->shared_info()->bytecode_array())),
exception_handler_table_( exception_handler_table_(
handle(HandlerTable::cast(bytecode_array()->handler_table()))), handle(HandlerTable::cast(bytecode_array()->handler_table()))),
feedback_vector_(info->feedback_vector()), feedback_vector_(handle(info->shared_info()->feedback_vector())),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo( frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kInterpretedFunction, FrameStateType::kInterpretedFunction,
bytecode_array()->parameter_count(), bytecode_array()->parameter_count(),
......
...@@ -2042,16 +2042,13 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, ...@@ -2042,16 +2042,13 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
object->set_hash(*hash); object->set_hash(*hash);
} }
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind, Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info, Handle<Code> code, Handle<ScopeInfo> scope_info) {
Handle<TypeFeedbackVector> feedback_vector) {
DCHECK(IsValidFunctionKind(kind)); DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo( Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
name, code, IsConstructable(kind, scope_info->language_mode())); name, code, IsConstructable(kind, scope_info->language_mode()));
shared->set_scope_info(*scope_info); shared->set_scope_info(*scope_info);
shared->set_feedback_vector(*feedback_vector);
shared->set_kind(kind); shared->set_kind(kind);
shared->set_num_literals(number_of_literals); shared->set_num_literals(number_of_literals);
if (IsGeneratorFunction(kind)) { if (IsGeneratorFunction(kind)) {
......
...@@ -627,8 +627,7 @@ class Factory final { ...@@ -627,8 +627,7 @@ class Factory final {
// Allocates a new SharedFunctionInfo object. // Allocates a new SharedFunctionInfo object.
Handle<SharedFunctionInfo> NewSharedFunctionInfo( Handle<SharedFunctionInfo> NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind, Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info, Handle<Code> code, Handle<ScopeInfo> scope_info);
Handle<TypeFeedbackVector> feedback_vector);
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name, Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name,
MaybeHandle<Code> code, MaybeHandle<Code> code,
bool is_constructor); bool is_constructor);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment