Commit b4e55e94 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Compiler] Decouple CompilationInfo and ParseInfo.

Don't hold a pointer to parse_info in compilation_info, and instead explicitly
add the fields needed in compiation_info. The intention is to make ParseInfo
only actually needed for parsing, and eventually make it possible to compile
with only a CompileInfo.

BUG=v8:5203

Change-Id: Iecd39245e44c218874401c3991eeaf3ceef2816f
Reviewed-on: https://chromium-review.googlesource.com/595738Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47119}
parent e44c2af0
...@@ -184,8 +184,8 @@ void ReportInstantiationFailure(Handle<Script> script, int position, ...@@ -184,8 +184,8 @@ void ReportInstantiationFailure(Handle<Script> script, int position,
// code. // code.
class AsmJsCompilationJob final : public CompilationJob { class AsmJsCompilationJob final : public CompilationJob {
public: public:
explicit AsmJsCompilationJob(CompilationInfo* info) explicit AsmJsCompilationJob(ParseInfo* parse_info, CompilationInfo* info)
: CompilationJob(info->isolate(), info, "AsmJs"), : CompilationJob(info->isolate(), parse_info, info, "AsmJs"),
module_(nullptr), module_(nullptr),
asm_offsets_(nullptr), asm_offsets_(nullptr),
translate_time_(0), translate_time_(0),
...@@ -210,23 +210,25 @@ class AsmJsCompilationJob final : public CompilationJob { ...@@ -210,23 +210,25 @@ class AsmJsCompilationJob final : public CompilationJob {
CompilationJob::Status AsmJsCompilationJob::PrepareJobImpl() { CompilationJob::Status AsmJsCompilationJob::PrepareJobImpl() {
// Step 1: Translate asm.js module to WebAssembly module. // Step 1: Translate asm.js module to WebAssembly module.
HistogramTimerScope translate_time_scope( HistogramTimerScope translate_time_scope(
info()->isolate()->counters()->asm_wasm_translation_time()); compilation_info()->isolate()->counters()->asm_wasm_translation_time());
size_t compile_zone_start = info()->zone()->allocation_size(); size_t compile_zone_start = compilation_info()->zone()->allocation_size();
base::ElapsedTimer translate_timer; base::ElapsedTimer translate_timer;
translate_timer.Start(); translate_timer.Start();
Zone* compile_zone = info()->zone(); Zone* compile_zone = compilation_info()->zone();
Zone translate_zone(info()->isolate()->allocator(), ZONE_NAME); Zone translate_zone(compilation_info()->isolate()->allocator(), ZONE_NAME);
// TODO(mstarzinger): In order to move translation to the non-main thread // TODO(mstarzinger): In order to move translation to the non-main thread
// ExecuteJob phase, the scanner stream needs to be off-heap. // ExecuteJob phase, the scanner stream needs to be off-heap.
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For( std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
handle(String::cast(info()->script()->source())), handle(String::cast(compilation_info()->script()->source())),
info()->literal()->start_position(), info()->literal()->end_position())); compilation_info()->literal()->start_position(),
compilation_info()->literal()->end_position()));
wasm::AsmJsParser parser(&translate_zone, stack_limit(), std::move(stream)); wasm::AsmJsParser parser(&translate_zone, stack_limit(), std::move(stream));
if (!parser.Run()) { if (!parser.Run()) {
DCHECK(!info()->isolate()->has_pending_exception()); DCHECK(!compilation_info()->isolate()->has_pending_exception());
ReportCompilationFailure(info()->script(), parser.failure_location(), ReportCompilationFailure(compilation_info()->script(),
parser.failure_location(),
parser.failure_message()); parser.failure_message());
return FAILED; return FAILED;
} }
...@@ -237,9 +239,9 @@ CompilationJob::Status AsmJsCompilationJob::PrepareJobImpl() { ...@@ -237,9 +239,9 @@ CompilationJob::Status AsmJsCompilationJob::PrepareJobImpl() {
stdlib_uses_ = *parser.stdlib_uses(); stdlib_uses_ = *parser.stdlib_uses();
size_t compile_zone_size = size_t compile_zone_size =
info()->zone()->allocation_size() - compile_zone_start; compilation_info()->zone()->allocation_size() - compile_zone_start;
size_t translate_zone_size = translate_zone.allocation_size(); size_t translate_zone_size = translate_zone.allocation_size();
info() compilation_info()
->isolate() ->isolate()
->counters() ->counters()
->asm_wasm_translation_peak_memory_bytes() ->asm_wasm_translation_peak_memory_bytes()
...@@ -266,15 +268,15 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl() { ...@@ -266,15 +268,15 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl() {
compile_timer.Start(); compile_timer.Start();
Handle<HeapNumber> uses_bitset = Handle<HeapNumber> uses_bitset =
info()->isolate()->factory()->NewHeapNumberFromBits( compilation_info()->isolate()->factory()->NewHeapNumberFromBits(
stdlib_uses_.ToIntegral()); stdlib_uses_.ToIntegral());
wasm::ErrorThrower thrower(info()->isolate(), "AsmJs::Compile"); wasm::ErrorThrower thrower(compilation_info()->isolate(), "AsmJs::Compile");
Handle<WasmModuleObject> compiled = Handle<WasmModuleObject> compiled =
SyncCompileTranslatedAsmJs( SyncCompileTranslatedAsmJs(
info()->isolate(), &thrower, compilation_info()->isolate(), &thrower,
wasm::ModuleWireBytes(module_->begin(), module_->end()), wasm::ModuleWireBytes(module_->begin(), module_->end()),
info()->script(), compilation_info()->script(),
Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size())) Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size()))
.ToHandleChecked(); .ToHandleChecked();
DCHECK(!thrower.error()); DCHECK(!thrower.error());
...@@ -282,19 +284,23 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl() { ...@@ -282,19 +284,23 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl() {
// The result is a compiled module and serialized standard library uses. // The result is a compiled module and serialized standard library uses.
Handle<FixedArray> result = Handle<FixedArray> result =
info()->isolate()->factory()->NewFixedArray(kWasmDataEntryCount); compilation_info()->isolate()->factory()->NewFixedArray(
kWasmDataEntryCount);
result->set(kWasmDataCompiledModule, *compiled); result->set(kWasmDataCompiledModule, *compiled);
result->set(kWasmDataUsesBitSet, *uses_bitset); result->set(kWasmDataUsesBitSet, *uses_bitset);
info()->SetAsmWasmData(result); compilation_info()->SetAsmWasmData(result);
info()->SetCode(BUILTIN_CODE(info()->isolate(), InstantiateAsmJs)); compilation_info()->SetCode(
BUILTIN_CODE(compilation_info()->isolate(), InstantiateAsmJs));
ReportCompilationSuccess(info()->script(), info()->literal()->position(), ReportCompilationSuccess(compilation_info()->script(),
compilation_info()->literal()->position(),
translate_time_, compile_time_, module_->size()); translate_time_, compile_time_, module_->size());
return SUCCEEDED; return SUCCEEDED;
} }
CompilationJob* AsmJs::NewCompilationJob(CompilationInfo* info) { CompilationJob* AsmJs::NewCompilationJob(ParseInfo* parse_info,
return new AsmJsCompilationJob(info); CompilationInfo* compilation_info) {
return new AsmJsCompilationJob(parse_info, compilation_info);
} }
MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate, MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
......
...@@ -15,12 +15,14 @@ namespace internal { ...@@ -15,12 +15,14 @@ namespace internal {
class CompilationInfo; class CompilationInfo;
class CompilationJob; class CompilationJob;
class JSArrayBuffer; class JSArrayBuffer;
class ParseInfo;
class SharedFunctionInfo; class SharedFunctionInfo;
// Interface to compile and instantiate for asm.js modules. // Interface to compile and instantiate for asm.js modules.
class AsmJs { class AsmJs {
public: public:
static CompilationJob* NewCompilationJob(CompilationInfo* info); static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
static MaybeHandle<Object> InstantiateAsmWasm(Isolate* isolate, static MaybeHandle<Object> InstantiateAsmWasm(Isolate* isolate,
Handle<SharedFunctionInfo>, Handle<SharedFunctionInfo>,
Handle<FixedArray> wasm_data, Handle<FixedArray> wasm_data,
......
...@@ -84,8 +84,8 @@ Comment::~Comment() { ...@@ -84,8 +84,8 @@ Comment::~Comment() {
#endif // DEBUG #endif // DEBUG
void CodeGenerator::MakeCodePrologue(ParseInfo* parse_info,
void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) { CompilationInfo* info, const char* kind) {
bool print_ast = false; bool print_ast = false;
const char* ftype; const char* ftype;
...@@ -103,7 +103,7 @@ void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) { ...@@ -103,7 +103,7 @@ void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) {
DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id()));
AllowDeferredHandleDereference allow_deref; AllowDeferredHandleDereference allow_deref;
AllowHeapAllocation allow_gc; AllowHeapAllocation allow_gc;
info->parse_info()->ast_value_factory()->Internalize(info->isolate()); parse_info->ast_value_factory()->Internalize(info->isolate());
if (FLAG_trace_codegen || print_ast) { if (FLAG_trace_codegen || print_ast) {
std::unique_ptr<char[]> name = info->GetDebugName(); std::unique_ptr<char[]> name = info->GetDebugName();
...@@ -112,7 +112,7 @@ void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) { ...@@ -112,7 +112,7 @@ void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) {
} }
#ifdef DEBUG #ifdef DEBUG
if (info->parse_info() && print_ast) { if (!info->IsStub() && print_ast) {
PrintF("--- AST ---\n%s\n", PrintF("--- AST ---\n%s\n",
AstPrinter(info->isolate()).PrintProgram(info->literal())); AstPrinter(info->isolate()).PrintProgram(info->literal()));
} }
...@@ -252,8 +252,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { ...@@ -252,8 +252,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
OFStream os(tracing_scope.file()); OFStream os(tracing_scope.file());
// Print the source code if available. // Print the source code if available.
bool print_source = bool print_source = code->kind() == Code::OPTIMIZED_FUNCTION;
info->parse_info() && (code->kind() == Code::OPTIMIZED_FUNCTION);
if (print_source) { if (print_source) {
Handle<SharedFunctionInfo> shared = info->shared_info(); Handle<SharedFunctionInfo> shared = info->shared_info();
Handle<Script> script = info->script(); Handle<Script> script = info->script();
...@@ -274,7 +273,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { ...@@ -274,7 +273,7 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
} }
} }
if (info->IsOptimizing()) { if (info->IsOptimizing()) {
if (FLAG_print_unopt_code && info->parse_info()) { if (FLAG_print_unopt_code) {
os << "--- Unoptimized code ---\n"; os << "--- Unoptimized code ---\n";
info->closure()->shared()->code()->Disassemble(debug_name.get(), os); info->closure()->shared()->code()->Disassemble(debug_name.get(), os);
} }
......
...@@ -69,11 +69,13 @@ namespace internal { ...@@ -69,11 +69,13 @@ namespace internal {
class CompilationInfo; class CompilationInfo;
class EhFrameWriter; class EhFrameWriter;
class ParseInfo;
class CodeGenerator { class CodeGenerator {
public: public:
// Printing of AST, etc. as requested by flags. // Printing of AST, etc. as requested by flags.
static void MakeCodePrologue(CompilationInfo* info, const char* kind); static void MakeCodePrologue(ParseInfo* parse_info, CompilationInfo* info,
const char* kind);
// Allocate and install the code. // Allocate and install the code.
static Handle<Code> MakeCodeEpilogue(TurboAssembler* tasm, static Handle<Code> MakeCodeEpilogue(TurboAssembler* tasm,
......
...@@ -10,49 +10,16 @@ ...@@ -10,49 +10,16 @@
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "src/source-position.h" #include "src/source-position.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
#define PARSE_INFO_GETTER(type, name) \ CompilationInfo::CompilationInfo(Zone* zone, Isolate* isolate,
type CompilationInfo::name() const { \ Handle<Script> script,
CHECK(parse_info()); \
return parse_info()->name(); \
}
#define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \
type CompilationInfo::name() const { \
return parse_info() ? parse_info()->name() : def; \
}
PARSE_INFO_GETTER(Handle<Script>, script)
PARSE_INFO_GETTER(FunctionLiteral*, literal)
PARSE_INFO_GETTER_WITH_DEFAULT(DeclarationScope*, scope, nullptr)
#undef PARSE_INFO_GETTER
#undef PARSE_INFO_GETTER_WITH_DEFAULT
bool CompilationInfo::is_debug() const {
return parse_info() ? parse_info()->is_debug() : false;
}
void CompilationInfo::set_is_debug() {
CHECK(parse_info());
parse_info()->set_is_debug();
}
void CompilationInfo::PrepareForSerializing() {
if (parse_info()) parse_info()->set_will_serialize();
SetFlag(kSerializing);
}
CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info,
Isolate* isolate,
Handle<SharedFunctionInfo> shared, Handle<SharedFunctionInfo> shared,
Handle<JSFunction> closure) Handle<JSFunction> closure)
: CompilationInfo(parse_info, {}, Code::ComputeFlags(Code::FUNCTION), BASE, : CompilationInfo(script, {}, Code::ComputeFlags(Code::FUNCTION), BASE,
isolate, zone) { isolate, zone) {
shared_info_ = shared; shared_info_ = shared;
closure_ = closure; closure_ = closure;
...@@ -68,22 +35,31 @@ CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info, ...@@ -68,22 +35,31 @@ CompilationInfo::CompilationInfo(Zone* zone, ParseInfo* parse_info,
} }
if (FLAG_block_coverage && isolate->is_block_code_coverage() && if (FLAG_block_coverage && isolate->is_block_code_coverage() &&
parse_info->script()->IsUserJavaScript()) { script_->IsUserJavaScript()) {
MarkAsBlockCoverageEnabled(); MarkAsBlockCoverageEnabled();
} }
if (script_->type() == Script::TYPE_NATIVE) {
MarkAsNative();
}
if (script_->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
MarkAsEval();
}
} }
CompilationInfo::CompilationInfo(Vector<const char> debug_name, CompilationInfo::CompilationInfo(Vector<const char> debug_name,
Isolate* isolate, Zone* zone, Isolate* isolate, Zone* zone,
Code::Flags code_flags) Code::Flags code_flags)
: CompilationInfo(nullptr, debug_name, code_flags, STUB, isolate, zone) {} : CompilationInfo(Handle<Script>::null(), debug_name, code_flags, STUB,
isolate, zone) {}
CompilationInfo::CompilationInfo(ParseInfo* parse_info, CompilationInfo::CompilationInfo(Handle<Script> script,
Vector<const char> debug_name, Vector<const char> debug_name,
Code::Flags code_flags, Mode mode, Code::Flags code_flags, Mode mode,
Isolate* isolate, Zone* zone) Isolate* isolate, Zone* zone)
: parse_info_(parse_info), : isolate_(isolate),
isolate_(isolate), script_(script),
literal_(nullptr),
flags_(0), flags_(0),
code_flags_(code_flags), code_flags_(code_flags),
mode_(mode), mode_(mode),
...@@ -105,6 +81,11 @@ CompilationInfo::~CompilationInfo() { ...@@ -105,6 +81,11 @@ CompilationInfo::~CompilationInfo() {
dependencies()->Rollback(); dependencies()->Rollback();
} }
DeclarationScope* CompilationInfo::scope() const {
DCHECK_NOT_NULL(literal_);
return literal_->scope();
}
int CompilationInfo::num_parameters() const { int CompilationInfo::num_parameters() const {
return !IsStub() ? scope()->num_parameters() : parameter_count_; return !IsStub() ? scope()->num_parameters() : parameter_count_;
} }
...@@ -137,6 +118,9 @@ void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) { ...@@ -137,6 +118,9 @@ void CompilationInfo::set_deferred_handles(DeferredHandles* deferred_handles) {
} }
void CompilationInfo::ReopenHandlesInNewHandleScope() { void CompilationInfo::ReopenHandlesInNewHandleScope() {
if (!script_.is_null()) {
script_ = Handle<Script>(*script_);
}
if (!shared_info_.is_null()) { if (!shared_info_.is_null()) {
shared_info_ = Handle<SharedFunctionInfo>(*shared_info_); shared_info_ = Handle<SharedFunctionInfo>(*shared_info_);
} }
...@@ -150,9 +134,9 @@ bool CompilationInfo::has_simple_parameters() { ...@@ -150,9 +134,9 @@ bool CompilationInfo::has_simple_parameters() {
} }
std::unique_ptr<char[]> CompilationInfo::GetDebugName() const { std::unique_ptr<char[]> CompilationInfo::GetDebugName() const {
if (parse_info() && parse_info()->literal()) { if (literal()) {
AllowHandleDereference allow_deref; AllowHandleDereference allow_deref;
return parse_info()->literal()->debug_name()->ToCString(); return literal()->debug_name()->ToCString();
} }
if (!shared_info().is_null()) { if (!shared_info().is_null()) {
return shared_info()->DebugName()->ToCString(); return shared_info()->DebugName()->ToCString();
...@@ -190,14 +174,13 @@ StackFrame::Type CompilationInfo::GetOutputStackFrameType() const { ...@@ -190,14 +174,13 @@ StackFrame::Type CompilationInfo::GetOutputStackFrameType() const {
} }
int CompilationInfo::GetDeclareGlobalsFlags() const { int CompilationInfo::GetDeclareGlobalsFlags() const {
return DeclareGlobalsEvalFlag::encode(parse_info()->is_eval()) | return DeclareGlobalsEvalFlag::encode(is_eval()) |
DeclareGlobalsNativeFlag::encode(parse_info()->is_native()); DeclareGlobalsNativeFlag::encode(is_native());
} }
SourcePositionTableBuilder::RecordingMode SourcePositionTableBuilder::RecordingMode
CompilationInfo::SourcePositionRecordingMode() const { CompilationInfo::SourcePositionRecordingMode() const {
return parse_info() && parse_info()->is_native() return is_native() ? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
? SourcePositionTableBuilder::OMIT_SOURCE_POSITIONS
: SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS; : SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
} }
......
...@@ -23,9 +23,9 @@ class CoverageInfo; ...@@ -23,9 +23,9 @@ class CoverageInfo;
class DeclarationScope; class DeclarationScope;
class DeferredHandles; class DeferredHandles;
class FunctionLiteral; class FunctionLiteral;
class JavaScriptFrame;
class ParseInfo;
class Isolate; class Isolate;
class JavaScriptFrame;
class SourceRangeMap;
class Zone; class Zone;
// CompilationInfo encapsulates some information known at compile time. It // CompilationInfo encapsulates some information known at compile time. It
...@@ -52,24 +52,32 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -52,24 +52,32 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
kOptimizeFromBytecode = 1 << 14, kOptimizeFromBytecode = 1 << 14,
kLoopPeelingEnabled = 1 << 15, kLoopPeelingEnabled = 1 << 15,
kBlockCoverageEnabled = 1 << 16, kBlockCoverageEnabled = 1 << 16,
kIsDebug = 1 << 17,
kIsEval = 1 << 18,
kIsNative = 1 << 19,
}; };
CompilationInfo(Zone* zone, ParseInfo* parse_info, Isolate* isolate, CompilationInfo(Zone* zone, Isolate* isolate, Handle<Script> script,
Handle<SharedFunctionInfo> shared, Handle<SharedFunctionInfo> shared,
Handle<JSFunction> closure); Handle<JSFunction> closure);
CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone, CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
Code::Flags code_flags); Code::Flags code_flags);
~CompilationInfo(); ~CompilationInfo();
ParseInfo* parse_info() const { return parse_info_; } Handle<Script> script() const { return script_; }
FunctionLiteral* literal() const { return literal_; }
void set_literal(FunctionLiteral* literal) {
DCHECK_NOT_NULL(literal);
literal_ = literal;
}
SourceRangeMap* source_range_map() const { return source_range_map_; }
void set_source_range_map(SourceRangeMap* source_range_map) {
source_range_map_ = source_range_map;
}
// -----------------------------------------------------------
// TODO(titzer): inline and delete accessors of ParseInfo
// -----------------------------------------------------------
Handle<Script> script() const;
FunctionLiteral* literal() const;
DeclarationScope* scope() const; DeclarationScope* scope() const;
// -----------------------------------------------------------
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
Zone* zone() { return zone_; } Zone* zone() { return zone_; }
...@@ -121,13 +129,11 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -121,13 +129,11 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// Compiles marked as debug produce unoptimized code with debug break slots. // Compiles marked as debug produce unoptimized code with debug break slots.
// Inner functions that cannot be compiled w/o context are compiled eagerly. // Inner functions that cannot be compiled w/o context are compiled eagerly.
void MarkAsDebug() { void MarkAsDebug() { SetFlag(kIsDebug); }
set_is_debug();
}
bool is_debug() const; bool is_debug() const { return GetFlag(kIsDebug); }
void PrepareForSerializing(); void MarkAsSerializing() { SetFlag(kSerializing); }
bool will_serialize() const { return GetFlag(kSerializing); } bool will_serialize() const { return GetFlag(kSerializing); }
...@@ -191,6 +197,14 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -191,6 +197,14 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
return GetFlag(kBlockCoverageEnabled); return GetFlag(kBlockCoverageEnabled);
} }
void MarkAsEval() { SetFlag(kIsEval); }
bool is_eval() const { return GetFlag(kIsEval); }
void MarkAsNative() { SetFlag(kIsNative); }
bool is_native() const { return GetFlag(kIsNative); }
bool GeneratePreagedPrologue() const { bool GeneratePreagedPrologue() const {
// Generate a pre-aged prologue if we are optimizing for size, which // Generate a pre-aged prologue if we are optimizing for size, which
// will make code old more aggressive. Only apply to Code::FUNCTION, // will make code old more aggressive. Only apply to Code::FUNCTION,
...@@ -335,13 +349,10 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -335,13 +349,10 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
// OPTIMIZE is optimized code generated by the Hydrogen-based backend. // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
enum Mode { BASE, OPTIMIZE, STUB }; enum Mode { BASE, OPTIMIZE, STUB };
CompilationInfo(ParseInfo* parse_info, Vector<const char> debug_name, CompilationInfo(Handle<Script> script, Vector<const char> debug_name,
Code::Flags code_flags, Mode mode, Isolate* isolate, Code::Flags code_flags, Mode mode, Isolate* isolate,
Zone* zone); Zone* zone);
ParseInfo* parse_info_;
Isolate* isolate_;
void SetMode(Mode mode) { mode_ = mode; } void SetMode(Mode mode) { mode_ = mode; }
void SetFlag(Flag flag) { flags_ |= flag; } void SetFlag(Flag flag) { flags_ |= flag; }
...@@ -352,7 +363,10 @@ class V8_EXPORT_PRIVATE CompilationInfo final { ...@@ -352,7 +363,10 @@ class V8_EXPORT_PRIVATE CompilationInfo final {
bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
void set_is_debug(); Isolate* isolate_;
Handle<Script> script_;
FunctionLiteral* literal_;
SourceRangeMap* source_range_map_; // Used when block coverage is enabled.
unsigned flags_; unsigned flags_;
......
...@@ -20,7 +20,7 @@ namespace { ...@@ -20,7 +20,7 @@ namespace {
void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) { void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) {
if (restore_function_code) { if (restore_function_code) {
Handle<JSFunction> function = job->info()->closure(); Handle<JSFunction> function = job->compilation_info()->closure();
function->ReplaceCode(function->shared()->code()); function->ReplaceCode(function->shared()->code());
if (function->IsInOptimizationQueue()) { if (function->IsInOptimizationQueue()) {
function->ClearOptimizationMarker(); function->ClearOptimizationMarker();
...@@ -197,7 +197,7 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() { ...@@ -197,7 +197,7 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() {
job = output_queue_.front(); job = output_queue_.front();
output_queue_.pop(); output_queue_.pop();
} }
CompilationInfo* info = job->info(); CompilationInfo* info = job->compilation_info();
Handle<JSFunction> function(*info->closure()); Handle<JSFunction> function(*info->closure());
if (function->HasOptimizedCode()) { if (function->HasOptimizedCode()) {
if (FLAG_trace_concurrent_recompilation) { if (FLAG_trace_concurrent_recompilation) {
......
...@@ -400,20 +400,21 @@ void UnoptimizedCompileJob::AnalyzeOnMainThread(Isolate* isolate) { ...@@ -400,20 +400,21 @@ void UnoptimizedCompileJob::AnalyzeOnMainThread(Isolate* isolate) {
} }
compile_zone_.reset(new Zone(isolate->allocator(), ZONE_NAME)); compile_zone_.reset(new Zone(isolate->allocator(), ZONE_NAME));
compile_info_.reset(new CompilationInfo( compilation_info_.reset(new CompilationInfo(
compile_zone_.get(), parse_info_.get(), isolate, compile_zone_.get(), isolate, parse_info_->script(),
Handle<SharedFunctionInfo>::null(), Handle<JSFunction>::null())); Handle<SharedFunctionInfo>::null(), Handle<JSFunction>::null()));
compilation_info_->set_literal(parse_info_->literal());
DeferredHandleScope scope(isolate); DeferredHandleScope scope(isolate);
{ {
if (Compiler::Analyze(compile_info_.get())) { if (Compiler::Analyze(parse_info_.get(), isolate)) {
status_ = Status::kAnalyzed; status_ = Status::kAnalyzed;
} else { } else {
status_ = Status::kFailed; status_ = Status::kFailed;
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
} }
} }
compile_info_->set_deferred_handles(scope.Detach()); compilation_info_->set_deferred_handles(scope.Detach());
} }
void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) { void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) {
...@@ -422,15 +423,15 @@ void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) { ...@@ -422,15 +423,15 @@ void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) {
DCHECK(status() == Status::kAnalyzed); DCHECK(status() == Status::kAnalyzed);
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile); COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
compile_job_.reset( compilation_job_.reset(Compiler::PrepareUnoptimizedCompilationJob(
Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get())); parse_info_.get(), compilation_info_.get()));
if (!compile_job_.get()) { if (!compilation_job_.get()) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
status_ = Status::kFailed; status_ = Status::kFailed;
return; return;
} }
CHECK(compile_job_->can_execute_on_background_thread()); CHECK(compilation_job_->can_execute_on_background_thread());
status_ = Status::kReadyToCompile; status_ = Status::kReadyToCompile;
} }
...@@ -445,9 +446,9 @@ void UnoptimizedCompileJob::Compile() { ...@@ -445,9 +446,9 @@ void UnoptimizedCompileJob::Compile() {
// CompilationJob::ExecuteJob. // CompilationJob::ExecuteJob.
uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
compile_job_->set_stack_limit(stack_limit); compilation_job_->set_stack_limit(stack_limit);
CompilationJob::Status status = compile_job_->ExecuteJob(); CompilationJob::Status status = compilation_job_->ExecuteJob();
USE(status); USE(status);
// Always transition to kCompiled - errors will be reported by // Always transition to kCompiled - errors will be reported by
...@@ -467,17 +468,17 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) { ...@@ -467,17 +468,17 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) {
{ {
HandleScope scope(isolate); HandleScope scope(isolate);
compile_info_->set_shared_info(shared_); compilation_info_->set_shared_info(shared_);
if (compile_job_->state() == CompilationJob::State::kFailed || if (compilation_job_->state() == CompilationJob::State::kFailed ||
!Compiler::FinalizeCompilationJob(compile_job_.release())) { !Compiler::FinalizeCompilationJob(compilation_job_.release())) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
status_ = Status::kFailed; status_ = Status::kFailed;
return; return;
} }
} }
compile_job_.reset(); compilation_job_.reset();
compile_info_.reset(); compilation_info_.reset();
compile_zone_.reset(); compile_zone_.reset();
parse_info_.reset(); parse_info_.reset();
...@@ -489,8 +490,8 @@ void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) { ...@@ -489,8 +490,8 @@ void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) {
PrintF("UnoptimizedCompileJob[%p]: Resetting\n", static_cast<void*>(this)); PrintF("UnoptimizedCompileJob[%p]: Resetting\n", static_cast<void*>(this));
} }
compile_job_.reset(); compilation_job_.reset();
compile_info_.reset(); compilation_info_.reset();
compile_zone_.reset(); compile_zone_.reset();
parser_.reset(); parser_.reset();
unicode_cache_.reset(); unicode_cache_.reset();
......
...@@ -132,8 +132,8 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob { ...@@ -132,8 +132,8 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
// Members required for compiling. // Members required for compiling.
std::shared_ptr<Zone> compile_zone_; std::shared_ptr<Zone> compile_zone_;
std::unique_ptr<CompilationInfo> compile_info_; std::unique_ptr<CompilationInfo> compilation_info_;
std::unique_ptr<CompilationJob> compile_job_; std::unique_ptr<CompilationJob> compilation_job_;
bool trace_compiler_dispatcher_jobs_; bool trace_compiler_dispatcher_jobs_;
......
...@@ -72,9 +72,11 @@ struct ScopedTimer { ...@@ -72,9 +72,11 @@ struct ScopedTimer {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of CompilationJob // Implementation of CompilationJob
CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info, CompilationJob::CompilationJob(Isolate* isolate, ParseInfo* parse_info,
CompilationInfo* compilation_info,
const char* compiler_name, State initial_state) const char* compiler_name, State initial_state)
: info_(info), : parse_info_(parse_info),
compilation_info_(compilation_info),
isolate_thread_id_(isolate->thread_id()), isolate_thread_id_(isolate->thread_id()),
compiler_name_(compiler_name), compiler_name_(compiler_name),
state_(initial_state), state_(initial_state),
...@@ -82,14 +84,15 @@ CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info, ...@@ -82,14 +84,15 @@ CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info,
executed_on_background_thread_(false) {} executed_on_background_thread_(false) {}
CompilationJob::Status CompilationJob::PrepareJob() { CompilationJob::Status CompilationJob::PrepareJob() {
DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); DCHECK(
ThreadId::Current().Equals(compilation_info()->isolate()->thread_id()));
DisallowJavascriptExecution no_js(isolate()); DisallowJavascriptExecution no_js(isolate());
if (FLAG_trace_opt && info()->IsOptimizing()) { if (FLAG_trace_opt && compilation_info()->IsOptimizing()) {
OFStream os(stdout); OFStream os(stdout);
os << "[compiling method " << Brief(*info()->closure()) << " using " os << "[compiling method " << Brief(*compilation_info()->closure())
<< compiler_name_; << " using " << compiler_name_;
if (info()->is_osr()) os << " OSR"; if (compilation_info()->is_osr()) os << " OSR";
os << "]" << std::endl; os << "]" << std::endl;
} }
...@@ -122,10 +125,11 @@ CompilationJob::Status CompilationJob::ExecuteJob() { ...@@ -122,10 +125,11 @@ CompilationJob::Status CompilationJob::ExecuteJob() {
} }
CompilationJob::Status CompilationJob::FinalizeJob() { CompilationJob::Status CompilationJob::FinalizeJob() {
DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); DCHECK(
ThreadId::Current().Equals(compilation_info()->isolate()->thread_id()));
DisallowCodeDependencyChange no_dependency_change; DisallowCodeDependencyChange no_dependency_change;
DisallowJavascriptExecution no_js(isolate()); DisallowJavascriptExecution no_js(isolate());
DCHECK(!info()->dependencies()->HasAborted()); DCHECK(!compilation_info()->dependencies()->HasAborted());
// Delegate to the underlying implementation. // Delegate to the underlying implementation.
DCHECK(state() == State::kReadyToFinalize); DCHECK(state() == State::kReadyToFinalize);
...@@ -134,25 +138,25 @@ CompilationJob::Status CompilationJob::FinalizeJob() { ...@@ -134,25 +138,25 @@ CompilationJob::Status CompilationJob::FinalizeJob() {
} }
CompilationJob::Status CompilationJob::RetryOptimization(BailoutReason reason) { CompilationJob::Status CompilationJob::RetryOptimization(BailoutReason reason) {
DCHECK(info_->IsOptimizing()); DCHECK(compilation_info_->IsOptimizing());
info_->RetryOptimization(reason); compilation_info_->RetryOptimization(reason);
state_ = State::kFailed; state_ = State::kFailed;
return FAILED; return FAILED;
} }
CompilationJob::Status CompilationJob::AbortOptimization(BailoutReason reason) { CompilationJob::Status CompilationJob::AbortOptimization(BailoutReason reason) {
DCHECK(info_->IsOptimizing()); DCHECK(compilation_info_->IsOptimizing());
info_->AbortOptimization(reason); compilation_info_->AbortOptimization(reason);
state_ = State::kFailed; state_ = State::kFailed;
return FAILED; return FAILED;
} }
void CompilationJob::RecordUnoptimizedCompilationStats() const { void CompilationJob::RecordUnoptimizedCompilationStats() const {
int code_size; int code_size;
if (info()->has_bytecode_array()) { if (compilation_info()->has_bytecode_array()) {
code_size = info()->bytecode_array()->SizeIncludingMetadata(); code_size = compilation_info()->bytecode_array()->SizeIncludingMetadata();
} else { } else {
code_size = info()->code()->SizeIncludingMetadata(); code_size = compilation_info()->code()->SizeIncludingMetadata();
} }
Counters* counters = isolate()->counters(); Counters* counters = isolate()->counters();
...@@ -164,8 +168,8 @@ void CompilationJob::RecordUnoptimizedCompilationStats() const { ...@@ -164,8 +168,8 @@ void CompilationJob::RecordUnoptimizedCompilationStats() const {
} }
void CompilationJob::RecordOptimizedCompilationStats() const { void CompilationJob::RecordOptimizedCompilationStats() const {
DCHECK(info()->IsOptimizing()); DCHECK(compilation_info()->IsOptimizing());
Handle<JSFunction> function = info()->closure(); Handle<JSFunction> function = compilation_info()->closure();
double ms_creategraph = time_taken_to_prepare_.InMillisecondsF(); double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
double ms_optimize = time_taken_to_execute_.InMillisecondsF(); double ms_optimize = time_taken_to_execute_.InMillisecondsF();
double ms_codegen = time_taken_to_finalize_.InMillisecondsF(); double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
...@@ -188,7 +192,9 @@ void CompilationJob::RecordOptimizedCompilationStats() const { ...@@ -188,7 +192,9 @@ void CompilationJob::RecordOptimizedCompilationStats() const {
} }
} }
Isolate* CompilationJob::isolate() const { return info()->isolate(); } Isolate* CompilationJob::isolate() const {
return compilation_info()->isolate();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Local helper methods that make up the compilation pipeline. // Local helper methods that make up the compilation pipeline.
...@@ -196,38 +202,39 @@ Isolate* CompilationJob::isolate() const { return info()->isolate(); } ...@@ -196,38 +202,39 @@ Isolate* CompilationJob::isolate() const { return info()->isolate(); }
namespace { namespace {
void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
CompilationInfo* info) { CompilationInfo* compilation_info) {
// Log the code generation. If source information is available include // Log the code generation. If source information is available include
// script name and line number. Check explicitly whether logging is // script name and line number. Check explicitly whether logging is
// enabled as finding the line number is not free. // enabled as finding the line number is not free.
if (info->isolate()->logger()->is_logging_code_events() || if (compilation_info->isolate()->logger()->is_logging_code_events() ||
info->isolate()->is_profiling()) { compilation_info->isolate()->is_profiling()) {
Handle<SharedFunctionInfo> shared = info->shared_info(); Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
Handle<Script> script = info->parse_info()->script(); Handle<Script> script = compilation_info->script();
Handle<AbstractCode> abstract_code = Handle<AbstractCode> abstract_code =
info->has_bytecode_array() compilation_info->has_bytecode_array()
? Handle<AbstractCode>::cast(info->bytecode_array()) ? Handle<AbstractCode>::cast(compilation_info->bytecode_array())
: Handle<AbstractCode>::cast(info->code()); : Handle<AbstractCode>::cast(compilation_info->code());
if (abstract_code.is_identical_to( if (abstract_code.is_identical_to(
BUILTIN_CODE(info->isolate(), CompileLazy))) { BUILTIN_CODE(compilation_info->isolate(), CompileLazy))) {
return; return;
} }
int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; int line_num = Script::GetLineNumber(script, shared->start_position()) + 1;
int column_num = int column_num =
Script::GetColumnNumber(script, shared->start_position()) + 1; Script::GetColumnNumber(script, shared->start_position()) + 1;
String* script_name = script->name()->IsString() String* script_name =
script->name()->IsString()
? String::cast(script->name()) ? String::cast(script->name())
: info->isolate()->heap()->empty_string(); : compilation_info->isolate()->heap()->empty_string();
CodeEventListener::LogEventsAndTags log_tag = CodeEventListener::LogEventsAndTags log_tag =
Logger::ToNativeByScript(tag, *script); Logger::ToNativeByScript(tag, *script);
PROFILE(info->isolate(), PROFILE(compilation_info->isolate(),
CodeCreateEvent(log_tag, *abstract_code, *shared, script_name, CodeCreateEvent(log_tag, *abstract_code, *shared, script_name,
line_num, column_num)); line_num, column_num));
} }
} }
void EnsureFeedbackMetadata(CompilationInfo* info) { void EnsureFeedbackMetadata(CompilationInfo* compilation_info) {
DCHECK(info->has_shared_info()); DCHECK(compilation_info->has_shared_info());
// If no type feedback metadata exists, create it. At this point the // If no type feedback metadata exists, create it. At this point the
// AstNumbering pass has already run. Note the snapshot can contain outdated // AstNumbering pass has already run. Note the snapshot can contain outdated
...@@ -235,17 +242,18 @@ void EnsureFeedbackMetadata(CompilationInfo* info) { ...@@ -235,17 +242,18 @@ void EnsureFeedbackMetadata(CompilationInfo* info) {
// when the function is not compiled (i.e. no code was serialized). // when the function is not compiled (i.e. no code was serialized).
// TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata(). // TODO(mvstanton): reintroduce is_empty() predicate to feedback_metadata().
if (info->shared_info()->feedback_metadata()->length() == 0 || if (compilation_info->shared_info()->feedback_metadata()->length() == 0 ||
!info->shared_info()->is_compiled()) { !compilation_info->shared_info()->is_compiled()) {
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New( Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
info->isolate(), info->literal()->feedback_vector_spec()); compilation_info->isolate(),
info->shared_info()->set_feedback_metadata(*feedback_metadata); compilation_info->literal()->feedback_vector_spec());
compilation_info->shared_info()->set_feedback_metadata(*feedback_metadata);
} }
// It's very important that recompiles do not alter the structure of the type // It's very important that recompiles do not alter the structure of the type
// feedback vector. Verify that the structure fits the function literal. // feedback vector. Verify that the structure fits the function literal.
CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( CHECK(!compilation_info->shared_info()->feedback_metadata()->SpecDiffersFrom(
info->literal()->feedback_vector_spec())); compilation_info->literal()->feedback_vector_spec()));
} }
bool ShouldUseFullCodegen(FunctionLiteral* literal) { bool ShouldUseFullCodegen(FunctionLiteral* literal) {
...@@ -283,38 +291,40 @@ bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info, ...@@ -283,38 +291,40 @@ bool UseAsmWasm(DeclarationScope* scope, Handle<SharedFunctionInfo> shared_info,
return scope->asm_module(); return scope->asm_module();
} }
CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { CompilationJob* GetUnoptimizedCompilationJob(
ParseInfo* parse_info, CompilationInfo* compilation_info) {
// Function should have been parsed and analyzed before creating a compilation // Function should have been parsed and analyzed before creating a compilation
// job. // job.
DCHECK_NOT_NULL(info->literal()); DCHECK_NOT_NULL(compilation_info->literal());
DCHECK_NOT_NULL(info->scope()); DCHECK_NOT_NULL(compilation_info->scope());
if (ShouldUseFullCodegen(info->literal())) { if (ShouldUseFullCodegen(compilation_info->literal())) {
return FullCodeGenerator::NewCompilationJob(info); return FullCodeGenerator::NewCompilationJob(parse_info, compilation_info);
} else { } else {
return interpreter::Interpreter::NewCompilationJob(info); return interpreter::Interpreter::NewCompilationJob(parse_info,
compilation_info);
} }
} }
void InstallUnoptimizedCode(CompilationInfo* info) { void InstallUnoptimizedCode(CompilationInfo* compilation_info) {
Handle<SharedFunctionInfo> shared = info->shared_info(); Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
DCHECK_EQ(info->shared_info()->language_mode(), DCHECK_EQ(compilation_info->shared_info()->language_mode(),
info->literal()->language_mode()); compilation_info->literal()->language_mode());
// Ensure feedback metadata is installed. // Ensure feedback metadata is installed.
EnsureFeedbackMetadata(info); EnsureFeedbackMetadata(compilation_info);
// Mark code to be executed once before being aged if necessary. // Mark code to be executed once before being aged if necessary.
// TODO(6409): Remove when full-codegen dies. // TODO(6409): Remove when full-codegen dies.
DCHECK(!info->code().is_null()); DCHECK(!compilation_info->code().is_null());
if (info->parse_info()->literal()->should_be_used_once_hint()) { if (compilation_info->literal()->should_be_used_once_hint()) {
info->code()->MarkToBeExecutedOnce(info->isolate()); compilation_info->code()->MarkToBeExecutedOnce(compilation_info->isolate());
} }
// Update the shared function info with the scope info. // Update the shared function info with the scope info.
Handle<ScopeInfo> scope_info = info->scope()->scope_info(); Handle<ScopeInfo> scope_info = compilation_info->scope()->scope_info();
shared->set_scope_info(*scope_info); shared->set_scope_info(*scope_info);
Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); Scope* outer_scope = compilation_info->scope()->GetOuterScopeWithContext();
if (outer_scope) { if (outer_scope) {
shared->set_outer_scope_info(*outer_scope->scope_info()); shared->set_outer_scope_info(*outer_scope->scope_info());
} }
...@@ -323,38 +333,39 @@ void InstallUnoptimizedCode(CompilationInfo* info) { ...@@ -323,38 +333,39 @@ void InstallUnoptimizedCode(CompilationInfo* info) {
// TODO(mstarzinger): Compiling for debug code might be used to reveal inner // TODO(mstarzinger): Compiling for debug code might be used to reveal inner
// functions via {FindSharedFunctionInfoInScript}, in which case we end up // functions via {FindSharedFunctionInfoInScript}, in which case we end up
// regenerating existing bytecode. Fix this! // regenerating existing bytecode. Fix this!
if (info->is_debug() && info->has_bytecode_array()) { if (compilation_info->is_debug() && compilation_info->has_bytecode_array()) {
shared->ClearBytecodeArray(); shared->ClearBytecodeArray();
} }
DCHECK(!info->code().is_null()); DCHECK(!compilation_info->code().is_null());
shared->ReplaceCode(*info->code()); shared->ReplaceCode(*compilation_info->code());
if (info->has_bytecode_array()) { if (compilation_info->has_bytecode_array()) {
DCHECK(!shared->HasBytecodeArray()); // Only compiled once. DCHECK(!shared->HasBytecodeArray()); // Only compiled once.
DCHECK(!info->has_asm_wasm_data()); DCHECK(!compilation_info->has_asm_wasm_data());
shared->set_bytecode_array(*info->bytecode_array()); shared->set_bytecode_array(*compilation_info->bytecode_array());
} else if (info->has_asm_wasm_data()) { } else if (compilation_info->has_asm_wasm_data()) {
shared->set_asm_wasm_data(*info->asm_wasm_data()); shared->set_asm_wasm_data(*compilation_info->asm_wasm_data());
} }
// Install coverage info on the shared function info. // Install coverage info on the shared function info.
if (info->has_coverage_info()) { if (compilation_info->has_coverage_info()) {
DCHECK(info->is_block_coverage_enabled()); DCHECK(compilation_info->is_block_coverage_enabled());
info->isolate()->debug()->InstallCoverageInfo(info->shared_info(), compilation_info->isolate()->debug()->InstallCoverageInfo(
info->coverage_info()); compilation_info->shared_info(), compilation_info->coverage_info());
} }
} }
void EnsureSharedFunctionInfosArrayOnScript(CompilationInfo* info) { void EnsureSharedFunctionInfosArrayOnScript(ParseInfo* parse_info,
DCHECK(info->parse_info()->is_toplevel()); Isolate* isolate) {
DCHECK(!info->script().is_null()); DCHECK(parse_info->is_toplevel());
if (info->script()->shared_function_infos()->length() > 0) { DCHECK(!parse_info->script().is_null());
DCHECK_EQ(info->script()->shared_function_infos()->length(), if (parse_info->script()->shared_function_infos()->length() > 0) {
info->parse_info()->max_function_literal_id() + 1); DCHECK_EQ(parse_info->script()->shared_function_infos()->length(),
parse_info->max_function_literal_id() + 1);
return; return;
} }
Handle<FixedArray> infos(info->isolate()->factory()->NewFixedArray( Handle<FixedArray> infos(isolate->factory()->NewFixedArray(
info->parse_info()->max_function_literal_id() + 1)); parse_info->max_function_literal_id() + 1));
info->script()->set_shared_function_infos(*infos); parse_info->script()->set_shared_function_infos(*infos);
} }
void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal, void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal,
...@@ -372,9 +383,9 @@ void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal, ...@@ -372,9 +383,9 @@ void SetSharedFunctionFlagsFromLiteral(FunctionLiteral* literal,
} }
CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
CompilationInfo* info = job->info(); CompilationInfo* compilation_info = job->compilation_info();
ParseInfo* parse_info = info->parse_info(); ParseInfo* parse_info = job->parse_info();
Isolate* isolate = info->isolate(); Isolate* isolate = compilation_info->isolate();
// Internalize ast values onto the heap. // Internalize ast values onto the heap.
parse_info->ast_value_factory()->Internalize(isolate); parse_info->ast_value_factory()->Internalize(isolate);
...@@ -386,39 +397,41 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { ...@@ -386,39 +397,41 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) {
if (parse_info->is_toplevel()) { if (parse_info->is_toplevel()) {
// Allocate a shared function info and an array for shared function infos // Allocate a shared function info and an array for shared function infos
// for inner functions. // for inner functions.
EnsureSharedFunctionInfosArrayOnScript(info); EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
DCHECK_EQ(kNoSourcePosition, info->literal()->function_token_position()); DCHECK_EQ(kNoSourcePosition,
if (!info->has_shared_info()) { compilation_info->literal()->function_token_position());
if (!compilation_info->has_shared_info()) {
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfoForLiteral(info->literal(), isolate->factory()->NewSharedFunctionInfoForLiteral(
info->script()); compilation_info->literal(), compilation_info->script());
shared->set_is_toplevel(true); shared->set_is_toplevel(true);
info->set_shared_info(shared); compilation_info->set_shared_info(shared);
} }
} }
SetSharedFunctionFlagsFromLiteral(info->literal(), info->shared_info()); SetSharedFunctionFlagsFromLiteral(compilation_info->literal(),
compilation_info->shared_info());
CompilationJob::Status status = job->FinalizeJob(); CompilationJob::Status status = job->FinalizeJob();
if (status == CompilationJob::SUCCEEDED) { if (status == CompilationJob::SUCCEEDED) {
InstallUnoptimizedCode(info); InstallUnoptimizedCode(compilation_info);
CodeEventListener::LogEventsAndTags log_tags = CodeEventListener::LogEventsAndTags log_tags =
parse_info->is_toplevel() ? parse_info->is_eval() parse_info->is_toplevel() ? compilation_info->is_eval()
? CodeEventListener::EVAL_TAG ? CodeEventListener::EVAL_TAG
: CodeEventListener::SCRIPT_TAG : CodeEventListener::SCRIPT_TAG
: CodeEventListener::FUNCTION_TAG; : CodeEventListener::FUNCTION_TAG;
RecordFunctionCompilation(log_tags, info); RecordFunctionCompilation(log_tags, compilation_info);
job->RecordUnoptimizedCompilationStats(); job->RecordUnoptimizedCompilationStats();
} }
return status; return status;
} }
bool Renumber(ParseInfo* info, bool Renumber(ParseInfo* parse_info,
Compiler::EagerInnerFunctionLiterals* eager_literals) { Compiler::EagerInnerFunctionLiterals* eager_literals) {
RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(), RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
&RuntimeCallStats::CompileRenumber); &RuntimeCallStats::CompileRenumber);
return AstNumbering::Renumber(info->stack_limit(), info->zone(), return AstNumbering::Renumber(parse_info->stack_limit(), parse_info->zone(),
info->literal(), eager_literals, parse_info->literal(), eager_literals,
info->collect_type_profile()); parse_info->collect_type_profile());
} }
bool RunUnoptimizedCompilationJob(CompilationJob* job) { bool RunUnoptimizedCompilationJob(CompilationJob* job) {
...@@ -427,50 +440,60 @@ bool RunUnoptimizedCompilationJob(CompilationJob* job) { ...@@ -427,50 +440,60 @@ bool RunUnoptimizedCompilationJob(CompilationJob* job) {
return FinalizeUnoptimizedCompilationJob(job) == CompilationJob::SUCCEEDED; return FinalizeUnoptimizedCompilationJob(job) == CompilationJob::SUCCEEDED;
} }
bool GenerateUnoptimizedCode(CompilationInfo* info) { bool GenerateUnoptimizedCode(ParseInfo* parse_info,
if (UseAsmWasm(info->scope(), info->shared_info(), info->is_debug())) { CompilationInfo* compilation_info) {
std::unique_ptr<CompilationJob> job(AsmJs::NewCompilationJob(info)); if (UseAsmWasm(compilation_info->scope(), compilation_info->shared_info(),
compilation_info->is_debug())) {
std::unique_ptr<CompilationJob> job(
AsmJs::NewCompilationJob(parse_info, compilation_info));
if (RunUnoptimizedCompilationJob(job.get())) return true; if (RunUnoptimizedCompilationJob(job.get())) return true;
// asm.js validation failed, fall through to standard unoptimized compile. // asm.js validation failed, fall through to standard unoptimized compile.
} }
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); std::unique_ptr<CompilationJob> job(
GetUnoptimizedCompilationJob(parse_info, compilation_info));
return RunUnoptimizedCompilationJob(job.get()); return RunUnoptimizedCompilationJob(job.get());
} }
bool CompileUnoptimizedInnerFunctions( bool CompileUnoptimizedInnerFunctions(
Compiler::EagerInnerFunctionLiterals* literals, Compiler::EagerInnerFunctionLiterals* literals, ParseInfo* outer_parse_info,
CompilationInfo* outer_info) { CompilationInfo* outer_compilation_info) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompileUnoptimizedInnerFunctions"); "V8.CompileUnoptimizedInnerFunctions");
Isolate* isolate = outer_info->isolate(); Isolate* isolate = outer_compilation_info->isolate();
Handle<Script> script = outer_info->script(); Handle<Script> script = outer_compilation_info->script();
bool is_debug = outer_info->is_debug(); bool is_debug = outer_compilation_info->is_debug();
bool will_serialize = outer_info->will_serialize(); bool will_serialize = outer_compilation_info->will_serialize();
RuntimeCallTimerScope runtimeTimer(isolate, RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileInnerFunction); &RuntimeCallStats::CompileInnerFunction);
for (auto it : *literals) { for (auto it : *literals) {
FunctionLiteral* literal = it->value(); FunctionLiteral* literal = it->value();
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfo(
Compiler::GetSharedFunctionInfo(literal, script, outer_info); literal, script, outer_compilation_info);
if (shared->is_compiled()) continue; if (shared->is_compiled()) continue;
// Generate unoptimized code now. // Generate unoptimized code now.
ParseInfo parse_info(script); ParseInfo parse_info(script);
CompilationInfo info(parse_info.zone(), &parse_info, isolate, shared, CompilationInfo info(parse_info.zone(), isolate, script, shared,
Handle<JSFunction>::null()); Handle<JSFunction>::null());
parse_info.set_toplevel(false); parse_info.set_toplevel(false);
parse_info.set_literal(literal); parse_info.set_literal(literal);
parse_info.set_function_literal_id(shared->function_literal_id()); parse_info.set_function_literal_id(shared->function_literal_id());
parse_info.set_language_mode(literal->scope()->language_mode()); parse_info.set_language_mode(literal->scope()->language_mode());
parse_info.set_source_range_map( parse_info.ShareAstValueFactory(outer_parse_info);
outer_info->parse_info()->source_range_map());
parse_info.ShareAstValueFactory(outer_info->parse_info());
if (will_serialize) info.PrepareForSerializing(); info.set_source_range_map(outer_compilation_info->source_range_map());
if (is_debug) info.MarkAsDebug(); info.set_literal(literal);
if (will_serialize) {
parse_info.set_will_serialize();
info.MarkAsSerializing();
}
if (is_debug) {
parse_info.set_is_debug();
info.MarkAsDebug();
}
if (!GenerateUnoptimizedCode(&info)) { if (!GenerateUnoptimizedCode(&parse_info, &info)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false; return false;
} }
...@@ -487,35 +510,37 @@ bool InnerFunctionShouldUseFullCodegen( ...@@ -487,35 +510,37 @@ bool InnerFunctionShouldUseFullCodegen(
return false; return false;
} }
bool CompileUnoptimizedCode(CompilationInfo* info) { bool CompileUnoptimizedCode(ParseInfo* parse_info,
Isolate* isolate = info->isolate(); CompilationInfo* compilation_info) {
Isolate* isolate = compilation_info->isolate();
DCHECK(AllowCompilation::IsAllowed(isolate)); DCHECK(AllowCompilation::IsAllowed(isolate));
Compiler::EagerInnerFunctionLiterals inner_literals; Compiler::EagerInnerFunctionLiterals inner_literals;
if (!Compiler::Analyze(info, &inner_literals)) { if (!Compiler::Analyze(parse_info, isolate, &inner_literals)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false; return false;
} }
if (ShouldUseFullCodegen(info->literal()) || if (ShouldUseFullCodegen(compilation_info->literal()) ||
InnerFunctionShouldUseFullCodegen(&inner_literals)) { InnerFunctionShouldUseFullCodegen(&inner_literals)) {
// If we might compile with full-codegen internalize now, otherwise // If we might compile with full-codegen internalize now, otherwise
// we internalize when finalizing compilation. // we internalize when finalizing compilation.
info->parse_info()->ast_value_factory()->Internalize(info->isolate()); parse_info->ast_value_factory()->Internalize(compilation_info->isolate());
// Full-codegen needs to access ScopeInfos when compiling, so allocate now. // Full-codegen needs to access ScopeInfos when compiling, so allocate now.
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate, DeclarationScope::AllocateScopeInfos(parse_info, isolate,
AnalyzeMode::kRegular); AnalyzeMode::kRegular);
if (info->parse_info()->is_toplevel()) { if (parse_info->is_toplevel()) {
// Full-codegen needs to access SFI when compiling, so allocate the array // Full-codegen needs to access SFI when compiling, so allocate the array
// now. // now.
EnsureSharedFunctionInfosArrayOnScript(info); EnsureSharedFunctionInfosArrayOnScript(parse_info, isolate);
} }
} }
if (!GenerateUnoptimizedCode(info) || if (!GenerateUnoptimizedCode(parse_info, compilation_info) ||
!CompileUnoptimizedInnerFunctions(&inner_literals, info)) { !CompileUnoptimizedInnerFunctions(&inner_literals, parse_info,
compilation_info)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow(); if (!isolate->has_pending_exception()) isolate->StackOverflow();
return false; return false;
} }
...@@ -524,27 +549,35 @@ bool CompileUnoptimizedCode(CompilationInfo* info) { ...@@ -524,27 +549,35 @@ bool CompileUnoptimizedCode(CompilationInfo* info) {
} }
MUST_USE_RESULT MaybeHandle<Code> CompileUnoptimizedFunction( MUST_USE_RESULT MaybeHandle<Code> CompileUnoptimizedFunction(
CompilationInfo* info, Handle<SharedFunctionInfo> shared_info) { ParseInfo* parse_info, CompilationInfo* compilation_info,
Handle<SharedFunctionInfo> shared_info) {
RuntimeCallTimerScope runtimeTimer( RuntimeCallTimerScope runtimeTimer(
info->isolate(), &RuntimeCallStats::CompileUnoptimizedFunction); compilation_info->isolate(),
VMState<COMPILER> state(info->isolate()); &RuntimeCallStats::CompileUnoptimizedFunction);
PostponeInterruptsScope postpone(info->isolate()); Isolate* isolate = compilation_info->isolate();
VMState<COMPILER> state(isolate);
PostponeInterruptsScope postpone(isolate);
// Parse and update ParseInfo with the results. // Parse and update ParseInfo with the results.
if (!parsing::ParseFunction(info->parse_info(), shared_info, if (!parsing::ParseFunction(parse_info, shared_info, isolate)) {
info->isolate())) {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
// TODO(rmcilroy): Construct compile info at this point passing literal and
// source_range_map to the constructor.
compilation_info->set_literal(parse_info->literal());
compilation_info->set_source_range_map(parse_info->source_range_map());
// Compile either unoptimized code or bytecode for the interpreter. // Compile either unoptimized code or bytecode for the interpreter.
if (!CompileUnoptimizedCode(info)) { if (!CompileUnoptimizedCode(parse_info, compilation_info)) {
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
// Record the function compilation event. // Record the function compilation event.
RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
compilation_info);
return info->code(); return compilation_info->code();
} }
MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache( MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
...@@ -572,35 +605,35 @@ MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache( ...@@ -572,35 +605,35 @@ MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
void ClearOptimizedCodeCache(CompilationInfo* info) { void ClearOptimizedCodeCache(CompilationInfo* compilation_info) {
Handle<JSFunction> function = info->closure(); Handle<JSFunction> function = compilation_info->closure();
if (info->osr_ast_id().IsNone()) { if (compilation_info->osr_ast_id().IsNone()) {
Handle<FeedbackVector> vector = Handle<FeedbackVector> vector =
handle(function->feedback_vector(), function->GetIsolate()); handle(function->feedback_vector(), function->GetIsolate());
vector->ClearOptimizedCode(); vector->ClearOptimizedCode();
} }
} }
void InsertCodeIntoOptimizedCodeCache(CompilationInfo* info) { void InsertCodeIntoOptimizedCodeCache(CompilationInfo* compilation_info) {
Handle<Code> code = info->code(); Handle<Code> code = compilation_info->code();
if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do. if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
// Function context specialization folds-in the function context, // Function context specialization folds-in the function context,
// so no sharing can occur. // so no sharing can occur.
if (info->is_function_context_specializing()) { if (compilation_info->is_function_context_specializing()) {
// Native context specialized code is not shared, so make sure the optimized // Native context specialized code is not shared, so make sure the optimized
// code cache is clear. // code cache is clear.
ClearOptimizedCodeCache(info); ClearOptimizedCodeCache(compilation_info);
return; return;
} }
// Frame specialization implies function context specialization. // Frame specialization implies function context specialization.
DCHECK(!info->is_frame_specializing()); DCHECK(!compilation_info->is_frame_specializing());
// Cache optimized context-specific code. // Cache optimized context-specific code.
Handle<JSFunction> function = info->closure(); Handle<JSFunction> function = compilation_info->closure();
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
Handle<Context> native_context(function->context()->native_context()); Handle<Context> native_context(function->context()->native_context());
if (info->osr_ast_id().IsNone()) { if (compilation_info->osr_ast_id().IsNone()) {
Handle<FeedbackVector> vector = Handle<FeedbackVector> vector =
handle(function->feedback_vector(), function->GetIsolate()); handle(function->feedback_vector(), function->GetIsolate());
FeedbackVector::SetOptimizedCode(vector, code); FeedbackVector::SetOptimizedCode(vector, code);
...@@ -608,16 +641,21 @@ void InsertCodeIntoOptimizedCodeCache(CompilationInfo* info) { ...@@ -608,16 +641,21 @@ void InsertCodeIntoOptimizedCodeCache(CompilationInfo* info) {
} }
bool GetOptimizedCodeNow(CompilationJob* job) { bool GetOptimizedCodeNow(CompilationJob* job) {
CompilationInfo* info = job->info(); CompilationInfo* compilation_info = job->compilation_info();
Isolate* isolate = info->isolate(); Isolate* isolate = compilation_info->isolate();
// Parsing is not required when optimizing from existing bytecode. // Parsing is not required when optimizing from existing bytecode.
if (!info->is_optimizing_from_bytecode()) { if (!compilation_info->is_optimizing_from_bytecode()) {
if (!Compiler::ParseAndAnalyze(info)) return false; ParseInfo* parse_info = job->parse_info();
info->parse_info()->ast_value_factory()->Internalize(isolate); if (!Compiler::ParseAndAnalyze(parse_info, compilation_info->shared_info(),
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate, isolate)) {
return false;
}
compilation_info->set_literal(parse_info->literal());
parse_info->ast_value_factory()->Internalize(isolate);
DeclarationScope::AllocateScopeInfos(parse_info, isolate,
AnalyzeMode::kRegular); AnalyzeMode::kRegular);
EnsureFeedbackMetadata(info); EnsureFeedbackMetadata(compilation_info);
} }
TimerEventScope<TimerEventRecompileSynchronous> timer(isolate); TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
...@@ -631,8 +669,9 @@ bool GetOptimizedCodeNow(CompilationJob* job) { ...@@ -631,8 +669,9 @@ bool GetOptimizedCodeNow(CompilationJob* job) {
job->FinalizeJob() != CompilationJob::SUCCEEDED) { job->FinalizeJob() != CompilationJob::SUCCEEDED) {
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[aborted optimizing "); PrintF("[aborted optimizing ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); PrintF(" because: %s]\n",
GetBailoutReason(compilation_info->bailout_reason()));
} }
return false; return false;
} }
...@@ -640,19 +679,20 @@ bool GetOptimizedCodeNow(CompilationJob* job) { ...@@ -640,19 +679,20 @@ bool GetOptimizedCodeNow(CompilationJob* job) {
// Success! // Success!
job->RecordOptimizedCompilationStats(); job->RecordOptimizedCompilationStats();
DCHECK(!isolate->has_pending_exception()); DCHECK(!isolate->has_pending_exception());
InsertCodeIntoOptimizedCodeCache(info); InsertCodeIntoOptimizedCodeCache(compilation_info);
RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
compilation_info);
return true; return true;
} }
bool GetOptimizedCodeLater(CompilationJob* job) { bool GetOptimizedCodeLater(CompilationJob* job) {
CompilationInfo* info = job->info(); CompilationInfo* compilation_info = job->compilation_info();
Isolate* isolate = info->isolate(); Isolate* isolate = compilation_info->isolate();
if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) { if (!isolate->optimizing_compile_dispatcher()->IsQueueAvailable()) {
if (FLAG_trace_concurrent_recompilation) { if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** Compilation queue full, will retry optimizing "); PrintF(" ** Compilation queue full, will retry optimizing ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF(" later.\n"); PrintF(" later.\n");
} }
return false; return false;
...@@ -661,23 +701,27 @@ bool GetOptimizedCodeLater(CompilationJob* job) { ...@@ -661,23 +701,27 @@ bool GetOptimizedCodeLater(CompilationJob* job) {
if (isolate->heap()->HighMemoryPressure()) { if (isolate->heap()->HighMemoryPressure()) {
if (FLAG_trace_concurrent_recompilation) { if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** High memory pressure, will retry optimizing "); PrintF(" ** High memory pressure, will retry optimizing ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF(" later.\n"); PrintF(" later.\n");
} }
return false; return false;
} }
// Parsing is not required when optimizing from existing bytecode. // Parsing is not required when optimizing from existing bytecode.
if (!info->is_optimizing_from_bytecode()) { if (!compilation_info->is_optimizing_from_bytecode()) {
if (!Compiler::ParseAndAnalyze(info)) return false; ParseInfo* parse_info = job->parse_info();
info->parse_info()->ast_value_factory()->Internalize(isolate); if (!Compiler::ParseAndAnalyze(parse_info, compilation_info->shared_info(),
DeclarationScope::AllocateScopeInfos(info->parse_info(), isolate, isolate)) {
return false;
}
compilation_info->set_literal(parse_info->literal());
DeclarationScope::AllocateScopeInfos(parse_info, isolate,
AnalyzeMode::kRegular); AnalyzeMode::kRegular);
EnsureFeedbackMetadata(info); EnsureFeedbackMetadata(compilation_info);
} }
TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
RuntimeCallTimerScope runtimeTimer(info->isolate(), RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::RecompileSynchronous); &RuntimeCallStats::RecompileSynchronous);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.RecompileSynchronous"); "V8.RecompileSynchronous");
...@@ -687,7 +731,7 @@ bool GetOptimizedCodeLater(CompilationJob* job) { ...@@ -687,7 +731,7 @@ bool GetOptimizedCodeLater(CompilationJob* job) {
if (FLAG_trace_concurrent_recompilation) { if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** Queued "); PrintF(" ** Queued ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF(" for concurrent optimization.\n"); PrintF(" for concurrent optimization.\n");
} }
return true; return true;
...@@ -738,28 +782,28 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -738,28 +782,28 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
DCHECK_IMPLIES(!has_script, shared->HasBytecodeArray()); DCHECK_IMPLIES(!has_script, shared->HasBytecodeArray());
std::unique_ptr<CompilationJob> job( std::unique_ptr<CompilationJob> job(
compiler::Pipeline::NewCompilationJob(function, has_script)); compiler::Pipeline::NewCompilationJob(function, has_script));
CompilationInfo* info = job->info(); CompilationInfo* compilation_info = job->compilation_info();
ParseInfo* parse_info = info->parse_info(); ParseInfo* parse_info = job->parse_info();
info->SetOptimizingForOsr(osr_ast_id, osr_frame); compilation_info->SetOptimizingForOsr(osr_ast_id, osr_frame);
// Do not use TurboFan if we need to be able to set break points. // Do not use TurboFan if we need to be able to set break points.
if (info->shared_info()->HasBreakInfo()) { if (compilation_info->shared_info()->HasBreakInfo()) {
info->AbortOptimization(kFunctionBeingDebugged); compilation_info->AbortOptimization(kFunctionBeingDebugged);
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
// Do not use TurboFan when %NeverOptimizeFunction was applied. // Do not use TurboFan when %NeverOptimizeFunction was applied.
if (shared->optimization_disabled() && if (shared->optimization_disabled() &&
shared->disable_optimization_reason() == kOptimizationDisabledForTest) { shared->disable_optimization_reason() == kOptimizationDisabledForTest) {
info->AbortOptimization(kOptimizationDisabledForTest); compilation_info->AbortOptimization(kOptimizationDisabledForTest);
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
// Do not use TurboFan if optimization is disabled or function doesn't pass // Do not use TurboFan if optimization is disabled or function doesn't pass
// turbo_filter. // turbo_filter.
if (!FLAG_opt || !shared->PassesFilter(FLAG_turbo_filter)) { if (!FLAG_opt || !shared->PassesFilter(FLAG_turbo_filter)) {
info->AbortOptimization(kOptimizationDisabled); compilation_info->AbortOptimization(kOptimizationDisabled);
return MaybeHandle<Code>(); return MaybeHandle<Code>();
} }
...@@ -769,7 +813,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -769,7 +813,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
// TurboFan can optimize directly from existing bytecode. // TurboFan can optimize directly from existing bytecode.
if (shared->HasBytecodeArray()) { if (shared->HasBytecodeArray()) {
info->MarkAsOptimizeFromBytecode(); compilation_info->MarkAsOptimizeFromBytecode();
} }
// Verify that OSR compilations are delegated to the correct graph builder. // Verify that OSR compilations are delegated to the correct graph builder.
...@@ -777,24 +821,24 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -777,24 +821,24 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
// and the various graph builders hard-code a certain semantic: // and the various graph builders hard-code a certain semantic:
// - Interpreter : The BailoutId represents a bytecode offset. // - Interpreter : The BailoutId represents a bytecode offset.
// - FullCodegen : The BailoutId represents the id of an AST node. // - FullCodegen : The BailoutId represents the id of an AST node.
DCHECK_IMPLIES(info->is_osr() && ignition_osr, DCHECK_IMPLIES(compilation_info->is_osr() && ignition_osr,
info->is_optimizing_from_bytecode()); compilation_info->is_optimizing_from_bytecode());
DCHECK_IMPLIES(info->is_osr() && !ignition_osr, DCHECK_IMPLIES(compilation_info->is_osr() && !ignition_osr,
!info->is_optimizing_from_bytecode()); !compilation_info->is_optimizing_from_bytecode());
// In case of concurrent recompilation, all handles below this point will be // In case of concurrent recompilation, all handles below this point will be
// allocated in a deferred handle scope that is detached and handed off to // allocated in a deferred handle scope that is detached and handed off to
// the background thread when we return. // the background thread when we return.
base::Optional<CompilationHandleScope> compilation; base::Optional<CompilationHandleScope> compilation;
if (mode == ConcurrencyMode::kConcurrent) { if (mode == ConcurrencyMode::kConcurrent) {
compilation.emplace(info); compilation.emplace(compilation_info);
} }
// All handles below will be canonicalized. // All handles below will be canonicalized.
CanonicalHandleScope canonical(info->isolate()); CanonicalHandleScope canonical(isolate);
// Reopen handles in the new CompilationHandleScope. // Reopen handles in the new CompilationHandleScope.
info->ReopenHandlesInNewHandleScope(); compilation_info->ReopenHandlesInNewHandleScope();
parse_info->ReopenHandlesInNewHandleScope(); parse_info->ReopenHandlesInNewHandleScope();
if (mode == ConcurrencyMode::kConcurrent) { if (mode == ConcurrencyMode::kConcurrent) {
...@@ -810,7 +854,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -810,7 +854,7 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
} }
} }
} else { } else {
if (GetOptimizedCodeNow(job.get())) return info->code(); if (GetOptimizedCodeNow(job.get())) return compilation_info->code();
} }
if (isolate->has_pending_exception()) isolate->clear_pending_exception(); if (isolate->has_pending_exception()) isolate->clear_pending_exception();
...@@ -818,19 +862,19 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, ...@@ -818,19 +862,19 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function,
} }
CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) { CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) {
CompilationInfo* info = job->info(); CompilationInfo* compilation_info = job->compilation_info();
Isolate* isolate = info->isolate(); Isolate* isolate = compilation_info->isolate();
TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); TimerEventScope<TimerEventRecompileSynchronous> timer(isolate);
RuntimeCallTimerScope runtimeTimer(isolate, RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::RecompileSynchronous); &RuntimeCallStats::RecompileSynchronous);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.RecompileSynchronous"); "V8.RecompileSynchronous");
Handle<SharedFunctionInfo> shared = info->shared_info(); Handle<SharedFunctionInfo> shared = compilation_info->shared_info();
// Reset profiler ticks, function is no longer considered hot. // Reset profiler ticks, function is no longer considered hot.
info->closure()->feedback_vector()->set_profiler_ticks(0); compilation_info->closure()->feedback_vector()->set_profiler_ticks(0);
DCHECK(!shared->HasBreakInfo()); DCHECK(!shared->HasBreakInfo());
...@@ -842,18 +886,19 @@ CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) { ...@@ -842,18 +886,19 @@ CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) {
if (job->state() == CompilationJob::State::kReadyToFinalize) { if (job->state() == CompilationJob::State::kReadyToFinalize) {
if (shared->optimization_disabled()) { if (shared->optimization_disabled()) {
job->RetryOptimization(kOptimizationDisabled); job->RetryOptimization(kOptimizationDisabled);
} else if (info->dependencies()->HasAborted()) { } else if (compilation_info->dependencies()->HasAborted()) {
job->RetryOptimization(kBailedOutDueToDependencyChange); job->RetryOptimization(kBailedOutDueToDependencyChange);
} else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) { } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) {
job->RecordOptimizedCompilationStats(); job->RecordOptimizedCompilationStats();
RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG,
InsertCodeIntoOptimizedCodeCache(info); compilation_info);
InsertCodeIntoOptimizedCodeCache(compilation_info);
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[completed optimizing "); PrintF("[completed optimizing ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF("]\n"); PrintF("]\n");
} }
info->closure()->ReplaceCode(*info->code()); compilation_info->closure()->ReplaceCode(*compilation_info->code());
return CompilationJob::SUCCEEDED; return CompilationJob::SUCCEEDED;
} }
} }
...@@ -861,13 +906,14 @@ CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) { ...@@ -861,13 +906,14 @@ CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) {
DCHECK(job->state() == CompilationJob::State::kFailed); DCHECK(job->state() == CompilationJob::State::kFailed);
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[aborted optimizing "); PrintF("[aborted optimizing ");
info->closure()->ShortPrint(); compilation_info->closure()->ShortPrint();
PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); PrintF(" because: %s]\n",
GetBailoutReason(compilation_info->bailout_reason()));
} }
info->closure()->ReplaceCode(shared->code()); compilation_info->closure()->ReplaceCode(shared->code());
// Clear the InOptimizationQueue marker, if it exists. // Clear the InOptimizationQueue marker, if it exists.
if (info->closure()->IsInOptimizationQueue()) { if (compilation_info->closure()->IsInOptimizationQueue()) {
info->closure()->ClearOptimizationMarker(); compilation_info->closure()->ClearOptimizationMarker();
} }
return CompilationJob::FAILED; return CompilationJob::FAILED;
} }
...@@ -908,7 +954,8 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { ...@@ -908,7 +954,8 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
Zone compile_zone(isolate->allocator(), ZONE_NAME); Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate, shared, function); CompilationInfo compilation_info(&compile_zone, isolate,
parse_info.script(), shared, function);
if (FLAG_experimental_preparser_scope_analysis) { if (FLAG_experimental_preparser_scope_analysis) {
if (shared->HasPreParsedScopeData()) { if (shared->HasPreParsedScopeData()) {
Handle<PreParsedScopeData> data( Handle<PreParsedScopeData> data(
...@@ -920,10 +967,12 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { ...@@ -920,10 +967,12 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
} }
} }
Handle<Code> result; Handle<Code> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result, ASSIGN_RETURN_ON_EXCEPTION(
CompileUnoptimizedFunction(&info, shared), Code); isolate, result,
CompileUnoptimizedFunction(&parse_info, &compilation_info, shared),
Code);
if (FLAG_always_opt && !info.shared_info()->HasAsmWasmData()) { if (FLAG_always_opt && !compilation_info.shared_info()->HasAsmWasmData()) {
if (FLAG_trace_opt) { if (FLAG_trace_opt) {
PrintF("[optimizing "); PrintF("[optimizing ");
function->ShortPrint(); function->ShortPrint();
...@@ -943,13 +992,13 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { ...@@ -943,13 +992,13 @@ MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
} }
} }
Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { Handle<SharedFunctionInfo> CompileToplevel(ParseInfo* parse_info,
Isolate* isolate = info->isolate(); CompilationInfo* compilation_info) {
Isolate* isolate = compilation_info->isolate();
TimerEventScope<TimerEventCompileCode> timer(isolate); TimerEventScope<TimerEventCompileCode> timer(isolate);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode");
PostponeInterruptsScope postpone(isolate); PostponeInterruptsScope postpone(isolate);
DCHECK(!isolate->native_context().is_null()); DCHECK(!isolate->native_context().is_null());
ParseInfo* parse_info = info->parse_info();
RuntimeCallTimerScope runtimeTimer( RuntimeCallTimerScope runtimeTimer(
isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval isolate, parse_info->is_eval() ? &RuntimeCallStats::CompileEval
: &RuntimeCallStats::CompileScript); : &RuntimeCallStats::CompileScript);
...@@ -958,24 +1007,30 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -958,24 +1007,30 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
Handle<SharedFunctionInfo> result; Handle<SharedFunctionInfo> result;
{ VMState<COMPILER> state(info->isolate()); {
VMState<COMPILER> state(isolate);
if (parse_info->literal() == nullptr && if (parse_info->literal() == nullptr &&
!parsing::ParseProgram(parse_info, info->isolate())) { !parsing::ParseProgram(parse_info, isolate)) {
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
// TODO(rmcilroy): Construct compile info at this point passing literal and
// source_range_map to the constructor.
compilation_info->set_literal(parse_info->literal());
compilation_info->set_source_range_map(parse_info->source_range_map());
// Measure how long it takes to do the compilation; only take the // Measure how long it takes to do the compilation; only take the
// rest of the function into account to avoid overlap with the // rest of the function into account to avoid overlap with the
// parsing statistics. // parsing statistics.
HistogramTimer* rate = parse_info->is_eval() HistogramTimer* rate =
? info->isolate()->counters()->compile_eval() parse_info->is_eval()
: info->isolate()->counters()->compile(); ? compilation_info->isolate()->counters()->compile_eval()
: compilation_info->isolate()->counters()->compile();
HistogramTimerScope timer(rate); HistogramTimerScope timer(rate);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile"); parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
// Compile the code. // Compile the code.
if (!CompileUnoptimizedCode(info)) { if (!CompileUnoptimizedCode(parse_info, compilation_info)) {
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
...@@ -984,7 +1039,7 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -984,7 +1039,7 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
} }
} }
return info->shared_info(); return compilation_info->shared_info();
} }
} // namespace } // namespace
...@@ -992,41 +1047,26 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { ...@@ -992,41 +1047,26 @@ Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of Compiler // Implementation of Compiler
bool Compiler::Analyze(ParseInfo* info, Isolate* isolate, bool Compiler::Analyze(ParseInfo* parse_info, Isolate* isolate,
EagerInnerFunctionLiterals* eager_literals) { EagerInnerFunctionLiterals* eager_literals) {
DCHECK_NOT_NULL(info->literal()); DCHECK_NOT_NULL(parse_info->literal());
RuntimeCallTimerScope runtimeTimer(isolate, RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileAnalyse); &RuntimeCallStats::CompileAnalyse);
if (!Rewriter::Rewrite(info)) return false; if (!Rewriter::Rewrite(parse_info)) return false;
DeclarationScope::Analyze(info, isolate); DeclarationScope::Analyze(parse_info, isolate);
if (!Renumber(info, eager_literals)) { if (!Renumber(parse_info, eager_literals)) return false;
return false;
}
DCHECK_NOT_NULL(info->scope());
return true; return true;
} }
bool Compiler::Analyze(CompilationInfo* info, bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
EagerInnerFunctionLiterals* eager_literals) {
return Compiler::Analyze(info->parse_info(), info->isolate(), eager_literals);
}
bool Compiler::ParseAndAnalyze(ParseInfo* info,
Handle<SharedFunctionInfo> shared_info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate) { Isolate* isolate) {
if (!parsing::ParseAny(info, shared_info, isolate)) { if (!parsing::ParseAny(parse_info, shared_info, isolate)) {
return false; return false;
} }
if (!Compiler::Analyze(info, isolate)) return false; return Compiler::Analyze(parse_info, isolate);
DCHECK_NOT_NULL(info->literal());
DCHECK_NOT_NULL(info->scope());
return true;
} }
bool Compiler::ParseAndAnalyze(CompilationInfo* info) {
return Compiler::ParseAndAnalyze(info->parse_info(), info->shared_info(),
info->isolate());
}
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) { bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
if (function->is_compiled()) return true; if (function->is_compiled()) return true;
Isolate* isolate = function->GetIsolate(); Isolate* isolate = function->GetIsolate();
...@@ -1102,16 +1142,19 @@ bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) { ...@@ -1102,16 +1142,19 @@ bool Compiler::CompileDebugCode(Handle<SharedFunctionInfo> shared) {
// Start a compilation. // Start a compilation.
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, isolate, shared, CompilationInfo compilation_info(parse_info.zone(), isolate,
parse_info.script(), shared,
Handle<JSFunction>::null()); Handle<JSFunction>::null());
info.MarkAsDebug(); parse_info.set_is_debug();
compilation_info.MarkAsDebug();
if (parse_info.is_toplevel()) { if (parse_info.is_toplevel()) {
if (CompileToplevel(&info).is_null()) { if (CompileToplevel(&parse_info, &compilation_info).is_null()) {
isolate->clear_pending_exception(); isolate->clear_pending_exception();
return false; return false;
} }
} else { } else {
if (CompileUnoptimizedFunction(&info, shared).is_null()) { if (CompileUnoptimizedFunction(&parse_info, &compilation_info, shared)
.is_null()) {
isolate->clear_pending_exception(); isolate->clear_pending_exception();
return false; return false;
} }
...@@ -1138,13 +1181,15 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { ...@@ -1138,13 +1181,15 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
// Start a compilation. // Start a compilation.
ParseInfo parse_info(script); ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME); Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate, CompilationInfo compilation_info(&compile_zone, isolate, script,
Handle<SharedFunctionInfo>::null(), Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null()); Handle<JSFunction>::null());
info.MarkAsDebug(); parse_info.set_is_debug();
compilation_info.MarkAsDebug();
// TODO(635): support extensions. // TODO(635): support extensions.
const bool compilation_succeeded = !CompileToplevel(&info).is_null(); const bool compilation_succeeded =
!CompileToplevel(&parse_info, &compilation_info).is_null();
Handle<JSArray> infos; Handle<JSArray> infos;
if (compilation_succeeded) { if (compilation_succeeded) {
// Check postconditions on success. // Check postconditions on success.
...@@ -1161,14 +1206,18 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) { ...@@ -1161,14 +1206,18 @@ MaybeHandle<JSArray> Compiler::CompileForLiveEdit(Handle<Script> script) {
return infos; return infos;
} }
bool Compiler::EnsureBytecode(CompilationInfo* info) { bool Compiler::EnsureBytecode(ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared_info = info->shared_info(); CompilationInfo* compilation_info) {
Handle<SharedFunctionInfo> shared_info = compilation_info->shared_info();
if (!shared_info->is_compiled()) { if (!shared_info->is_compiled()) {
DCHECK(!info->parse_info()->is_toplevel()); DCHECK(!parse_info->is_toplevel());
CompilerDispatcher* dispatcher = info->isolate()->compiler_dispatcher(); CompilerDispatcher* dispatcher =
compilation_info->isolate()->compiler_dispatcher();
if (dispatcher->IsEnqueued(shared_info)) { if (dispatcher->IsEnqueued(shared_info)) {
if (!dispatcher->FinishNow(info->shared_info())) return false; if (!dispatcher->FinishNow(compilation_info->shared_info())) return false;
} else if (CompileUnoptimizedFunction(info, shared_info).is_null()) { } else if (CompileUnoptimizedFunction(parse_info, compilation_info,
shared_info)
.is_null()) {
return false; return false;
} }
} }
...@@ -1235,9 +1284,10 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( ...@@ -1235,9 +1284,10 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
ParseInfo parse_info(script); ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME); Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate, CompilationInfo compilation_info(&compile_zone, isolate, script,
Handle<SharedFunctionInfo>::null(), Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null()); Handle<JSFunction>::null());
compilation_info.MarkAsEval();
parse_info.set_eval(); parse_info.set_eval();
parse_info.set_language_mode(language_mode); parse_info.set_language_mode(language_mode);
parse_info.set_parse_restriction(restriction); parse_info.set_parse_restriction(restriction);
...@@ -1246,7 +1296,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval( ...@@ -1246,7 +1296,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
parse_info.set_outer_scope_info(handle(context->scope_info())); parse_info.set_outer_scope_info(handle(context->scope_info()));
} }
shared_info = CompileToplevel(&info); shared_info = CompileToplevel(&parse_info, &compilation_info);
if (shared_info.is_null()) { if (shared_info.is_null()) {
return MaybeHandle<JSFunction>(); return MaybeHandle<JSFunction>();
} }
...@@ -1449,7 +1499,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript( ...@@ -1449,7 +1499,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
// Compile the function and add it to the cache. // Compile the function and add it to the cache.
ParseInfo parse_info(script); ParseInfo parse_info(script);
Zone compile_zone(isolate->allocator(), ZONE_NAME); Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo info(&compile_zone, &parse_info, isolate, CompilationInfo compilation_info(&compile_zone, isolate, script,
Handle<SharedFunctionInfo>::null(), Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null()); Handle<JSFunction>::null());
if (resource_options.IsModule()) parse_info.set_module(); if (resource_options.IsModule()) parse_info.set_module();
...@@ -1463,12 +1513,13 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript( ...@@ -1463,12 +1513,13 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
} }
if (FLAG_serialize_toplevel && if (FLAG_serialize_toplevel &&
compile_options == ScriptCompiler::kProduceCodeCache) { compile_options == ScriptCompiler::kProduceCodeCache) {
info.PrepareForSerializing(); parse_info.set_will_serialize();
compilation_info.MarkAsSerializing();
} }
parse_info.set_language_mode( parse_info.set_language_mode(
static_cast<LanguageMode>(parse_info.language_mode() | language_mode)); static_cast<LanguageMode>(parse_info.language_mode() | language_mode));
result = CompileToplevel(&info); result = CompileToplevel(&parse_info, &compilation_info);
if (extension == NULL && !result.is_null()) { if (extension == NULL && !result.is_null()) {
// We need a feedback vector. // We need a feedback vector.
DCHECK(result->is_compiled()); DCHECK(result->is_compiled());
...@@ -1517,14 +1568,15 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript( ...@@ -1517,14 +1568,15 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForStreamedScript(
static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); static_cast<LanguageMode>(parse_info->language_mode() | language_mode));
Zone compile_zone(isolate->allocator(), ZONE_NAME); Zone compile_zone(isolate->allocator(), ZONE_NAME);
CompilationInfo compile_info(&compile_zone, parse_info, isolate, CompilationInfo compilation_info(&compile_zone, isolate, script,
Handle<SharedFunctionInfo>::null(), Handle<SharedFunctionInfo>::null(),
Handle<JSFunction>::null()); Handle<JSFunction>::null());
// The source was parsed lazily, so compiling for debugging is not possible. // The source was parsed lazily, so compiling for debugging is not possible.
DCHECK(!compile_info.is_debug()); DCHECK(!compilation_info.is_debug());
Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); Handle<SharedFunctionInfo> result =
CompileToplevel(parse_info, &compilation_info);
if (!result.is_null()) isolate->debug()->OnAfterCompile(script); if (!result.is_null()) isolate->debug()->OnAfterCompile(script);
return result; return result;
} }
...@@ -1599,9 +1651,10 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, ...@@ -1599,9 +1651,10 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function,
} }
CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( CompilationJob* Compiler::PrepareUnoptimizedCompilationJob(
CompilationInfo* info) { ParseInfo* parse_info, CompilationInfo* compilation_info) {
VMState<COMPILER> state(info->isolate()); VMState<COMPILER> state(compilation_info->isolate());
std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); std::unique_ptr<CompilationJob> job(
GetUnoptimizedCompilationJob(parse_info, compilation_info));
if (job->PrepareJob() != CompilationJob::SUCCEEDED) { if (job->PrepareJob() != CompilationJob::SUCCEEDED) {
return nullptr; return nullptr;
} }
...@@ -1612,8 +1665,8 @@ bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { ...@@ -1612,8 +1665,8 @@ bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
// Take ownership of compilation job. Deleting job also tears down the zone. // Take ownership of compilation job. Deleting job also tears down the zone.
std::unique_ptr<CompilationJob> job(raw_job); std::unique_ptr<CompilationJob> job(raw_job);
VMState<COMPILER> state(job->info()->isolate()); VMState<COMPILER> state(job->compilation_info()->isolate());
if (job->info()->IsOptimizing()) { if (job->compilation_info()->IsOptimizing()) {
return FinalizeOptimizedCompilationJob(job.get()) == return FinalizeOptimizedCompilationJob(job.get()) ==
CompilationJob::SUCCEEDED; CompilationJob::SUCCEEDED;
} else { } else {
......
...@@ -54,7 +54,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic { ...@@ -54,7 +54,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
// Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse. // Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse.
static CompilationJob* PrepareUnoptimizedCompilationJob( static CompilationJob* PrepareUnoptimizedCompilationJob(
CompilationInfo* info); ParseInfo* parse_info, CompilationInfo* compilation_info);
// Generate and install code from previously queued compilation job. // Generate and install code from previously queued compilation job.
static bool FinalizeCompilationJob(CompilationJob* job); static bool FinalizeCompilationJob(CompilationJob* job);
...@@ -68,20 +68,16 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic { ...@@ -68,20 +68,16 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
EagerInnerFunctionLiterals; EagerInnerFunctionLiterals;
// Parser::Parse, then Compiler::Analyze. // Parser::Parse, then Compiler::Analyze.
static bool ParseAndAnalyze(ParseInfo* info, static bool ParseAndAnalyze(ParseInfo* parse_info,
Handle<SharedFunctionInfo> shared_info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate); Isolate* isolate);
// Convenience function.
static bool ParseAndAnalyze(CompilationInfo* info);
// Rewrite, analyze scopes, and renumber. If |eager_literals| is non-null, it // Rewrite, analyze scopes, and renumber. If |eager_literals| is non-null, it
// is appended with inner function literals which should be eagerly compiled. // is appended with inner function literals which should be eagerly compiled.
static bool Analyze(ParseInfo* info, Isolate* isolate, static bool Analyze(ParseInfo* parse_info, Isolate* isolate,
EagerInnerFunctionLiterals* eager_literals = nullptr);
// Convenience function
static bool Analyze(CompilationInfo* info,
EagerInnerFunctionLiterals* eager_literals = nullptr); EagerInnerFunctionLiterals* eager_literals = nullptr);
// Ensures that bytecode is generated, calls ParseAndAnalyze internally. // Ensures that bytecode is generated, calls ParseAndAnalyze internally.
static bool EnsureBytecode(CompilationInfo* info); static bool EnsureBytecode(ParseInfo* parse_info,
CompilationInfo* compilation_info);
// =========================================================================== // ===========================================================================
// The following family of methods instantiates new functions for scripts or // The following family of methods instantiates new functions for scripts or
...@@ -169,7 +165,7 @@ class V8_EXPORT_PRIVATE CompilationJob { ...@@ -169,7 +165,7 @@ class V8_EXPORT_PRIVATE CompilationJob {
kFailed, kFailed,
}; };
CompilationJob(Isolate* isolate, CompilationInfo* info, CompilationJob(Isolate* isolate, ParseInfo* parse_info, CompilationInfo* info,
const char* compiler_name, const char* compiler_name,
State initial_state = State::kReadyToPrepare); State initial_state = State::kReadyToPrepare);
virtual ~CompilationJob() {} virtual ~CompilationJob() {}
...@@ -206,7 +202,8 @@ class V8_EXPORT_PRIVATE CompilationJob { ...@@ -206,7 +202,8 @@ class V8_EXPORT_PRIVATE CompilationJob {
return executed_on_background_thread_; return executed_on_background_thread_;
} }
State state() const { return state_; } State state() const { return state_; }
CompilationInfo* info() const { return info_; } ParseInfo* parse_info() const { return parse_info_; }
CompilationInfo* compilation_info() const { return compilation_info_; }
Isolate* isolate() const; Isolate* isolate() const;
virtual size_t AllocatedMemory() const { return 0; } virtual size_t AllocatedMemory() const { return 0; }
...@@ -217,7 +214,9 @@ class V8_EXPORT_PRIVATE CompilationJob { ...@@ -217,7 +214,9 @@ class V8_EXPORT_PRIVATE CompilationJob {
virtual Status FinalizeJobImpl() = 0; virtual Status FinalizeJobImpl() = 0;
private: private:
CompilationInfo* info_; // TODO(6409): Remove parse_info once Fullcode and AstGraphBuilder are gone.
ParseInfo* parse_info_;
CompilationInfo* compilation_info_;
ThreadId isolate_thread_id_; ThreadId isolate_thread_id_;
base::TimeDelta time_taken_to_prepare_; base::TimeDelta time_taken_to_prepare_;
base::TimeDelta time_taken_to_execute_; base::TimeDelta time_taken_to_execute_;
......
...@@ -527,7 +527,7 @@ void CodeGenerator::AssembleSourcePosition(SourcePosition source_position) { ...@@ -527,7 +527,7 @@ void CodeGenerator::AssembleSourcePosition(SourcePosition source_position) {
source_position, false); source_position, false);
if (FLAG_code_comments) { if (FLAG_code_comments) {
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
if (!info->parse_info()) return; if (info->IsStub()) return;
std::ostringstream buffer; std::ostringstream buffer;
buffer << "-- "; buffer << "-- ";
if (FLAG_trace_turbo || if (FLAG_trace_turbo ||
......
...@@ -46,7 +46,7 @@ std::unique_ptr<char[]> GetVisualizerLogFileName(CompilationInfo* info, ...@@ -46,7 +46,7 @@ std::unique_ptr<char[]> GetVisualizerLogFileName(CompilationInfo* info,
} }
EmbeddedVector<char, 256> source_file(0); EmbeddedVector<char, 256> source_file(0);
bool source_available = false; bool source_available = false;
if (FLAG_trace_file_names && info->parse_info()) { if (FLAG_trace_file_names && !info->script().is_null()) {
Object* source_name = info->script()->name(); Object* source_name = info->script()->name();
if (source_name->IsString()) { if (source_name->IsString()) {
String* str = String::cast(source_name); String* str = String::cast(source_name);
......
...@@ -507,13 +507,13 @@ Reduction JSInliner::ReduceJSCall(Node* node) { ...@@ -507,13 +507,13 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
} }
ParseInfo parse_info(shared_info); ParseInfo parse_info(shared_info);
CompilationInfo info(parse_info.zone(), &parse_info, CompilationInfo info(parse_info.zone(), shared_info->GetIsolate(),
shared_info->GetIsolate(), shared_info, parse_info.script(), shared_info,
Handle<JSFunction>::null()); Handle<JSFunction>::null());
if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled(); if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled();
info.MarkAsOptimizeFromBytecode(); info.MarkAsOptimizeFromBytecode();
if (!Compiler::EnsureBytecode(&info)) { if (!Compiler::EnsureBytecode(&parse_info, &info)) {
TRACE("Not inlining %s into %s because bytecode generation failed\n", TRACE("Not inlining %s into %s because bytecode generation failed\n",
shared_info->DebugName()->ToCString().get(), shared_info->DebugName()->ToCString().get(),
info_->shared_info()->DebugName()->ToCString().get()); info_->shared_info()->DebugName()->ToCString().get());
......
...@@ -574,12 +574,11 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info, ...@@ -574,12 +574,11 @@ PipelineStatistics* CreatePipelineStatistics(CompilationInfo* info,
if (FLAG_trace_turbo) { if (FLAG_trace_turbo) {
TurboJsonFile json_of(info, std::ios_base::trunc); TurboJsonFile json_of(info, std::ios_base::trunc);
std::unique_ptr<char[]> function_name = info->GetDebugName(); std::unique_ptr<char[]> function_name = info->GetDebugName();
int pos = info->parse_info() ? info->shared_info()->start_position() : 0; int pos = info->IsStub() ? 0 : info->shared_info()->start_position();
json_of << "{\"function\":\"" << function_name.get() json_of << "{\"function\":\"" << function_name.get()
<< "\", \"sourcePosition\":" << pos << ", \"source\":\""; << "\", \"sourcePosition\":" << pos << ", \"source\":\"";
Isolate* isolate = info->isolate(); Isolate* isolate = info->isolate();
Handle<Script> script = Handle<Script> script = info->script();
info->parse_info() ? info->script() : Handle<Script>::null();
if (!script.is_null() && !script->source()->IsUndefined(isolate)) { if (!script.is_null() && !script->source()->IsUndefined(isolate)) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
int start = info->shared_info()->start_position(); int start = info->shared_info()->start_position();
...@@ -604,13 +603,15 @@ class PipelineCompilationJob final : public CompilationJob { ...@@ -604,13 +603,15 @@ class PipelineCompilationJob final : public CompilationJob {
Handle<JSFunction> function) Handle<JSFunction> function)
// Note that the CompilationInfo is not initialized at the time we pass it // Note that the CompilationInfo is not initialized at the time we pass it
// to the CompilationJob constructor, but it is not dereferenced there. // to the CompilationJob constructor, but it is not dereferenced there.
: CompilationJob(function->GetIsolate(), &info_, "TurboFan"), : CompilationJob(function->GetIsolate(), parse_info, &compilation_info_,
"TurboFan"),
parse_info_(parse_info), parse_info_(parse_info),
zone_stats_(function->GetIsolate()->allocator()), zone_stats_(function->GetIsolate()->allocator()),
info_(parse_info_.get()->zone(), parse_info_.get(), compilation_info_(parse_info_.get()->zone(), function->GetIsolate(),
function->GetIsolate(), shared_info, function), parse_info_->script(), shared_info, function),
pipeline_statistics_(CreatePipelineStatistics(info(), &zone_stats_)), pipeline_statistics_(
data_(&zone_stats_, info(), pipeline_statistics_.get()), CreatePipelineStatistics(compilation_info(), &zone_stats_)),
data_(&zone_stats_, compilation_info(), pipeline_statistics_.get()),
pipeline_(&data_), pipeline_(&data_),
linkage_(nullptr) {} linkage_(nullptr) {}
...@@ -625,7 +626,7 @@ class PipelineCompilationJob final : public CompilationJob { ...@@ -625,7 +626,7 @@ class PipelineCompilationJob final : public CompilationJob {
private: private:
std::unique_ptr<ParseInfo> parse_info_; std::unique_ptr<ParseInfo> parse_info_;
ZoneStats zone_stats_; ZoneStats zone_stats_;
CompilationInfo info_; CompilationInfo compilation_info_;
std::unique_ptr<PipelineStatistics> pipeline_statistics_; std::unique_ptr<PipelineStatistics> pipeline_statistics_;
PipelineData data_; PipelineData data_;
PipelineImpl pipeline_; PipelineImpl pipeline_;
...@@ -635,45 +636,47 @@ class PipelineCompilationJob final : public CompilationJob { ...@@ -635,45 +636,47 @@ class PipelineCompilationJob final : public CompilationJob {
}; };
PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl() { PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl() {
if (info()->shared_info()->asm_function()) { if (compilation_info()->shared_info()->asm_function()) {
if (info()->osr_frame() && !info()->is_optimizing_from_bytecode()) { if (compilation_info()->osr_frame() &&
info()->MarkAsFrameSpecializing(); !compilation_info()->is_optimizing_from_bytecode()) {
compilation_info()->MarkAsFrameSpecializing();
} }
info()->MarkAsFunctionContextSpecializing(); compilation_info()->MarkAsFunctionContextSpecializing();
} else { } else {
if (!FLAG_always_opt) { if (!FLAG_always_opt) {
info()->MarkAsBailoutOnUninitialized(); compilation_info()->MarkAsBailoutOnUninitialized();
} }
if (FLAG_turbo_loop_peeling) { if (FLAG_turbo_loop_peeling) {
info()->MarkAsLoopPeelingEnabled(); compilation_info()->MarkAsLoopPeelingEnabled();
} }
} }
if (info()->is_optimizing_from_bytecode()) { if (compilation_info()->is_optimizing_from_bytecode()) {
info()->MarkAsDeoptimizationEnabled(); compilation_info()->MarkAsDeoptimizationEnabled();
if (FLAG_turbo_inlining) { if (FLAG_turbo_inlining) {
info()->MarkAsInliningEnabled(); compilation_info()->MarkAsInliningEnabled();
} }
if (FLAG_inline_accessors) { if (FLAG_inline_accessors) {
info()->MarkAsAccessorInliningEnabled(); compilation_info()->MarkAsAccessorInliningEnabled();
} }
if (info()->closure()->feedback_vector_cell()->map() == if (compilation_info()->closure()->feedback_vector_cell()->map() ==
isolate()->heap()->one_closure_cell_map()) { isolate()->heap()->one_closure_cell_map()) {
info()->MarkAsFunctionContextSpecializing(); compilation_info()->MarkAsFunctionContextSpecializing();
} }
info()->MarkAsInliningEnabled(); compilation_info()->MarkAsInliningEnabled();
} }
data_.set_start_source_position(info()->shared_info()->start_position()); data_.set_start_source_position(
compilation_info()->shared_info()->start_position());
linkage_ = new (info()->zone()) linkage_ = new (compilation_info()->zone()) Linkage(
Linkage(Linkage::ComputeIncoming(info()->zone(), info())); Linkage::ComputeIncoming(compilation_info()->zone(), compilation_info()));
if (!pipeline_.CreateGraph()) { if (!pipeline_.CreateGraph()) {
if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed.
return AbortOptimization(kGraphBuildingFailed); return AbortOptimization(kGraphBuildingFailed);
} }
if (info()->is_osr()) data_.InitializeOsrHelper(); if (compilation_info()->is_osr()) data_.InitializeOsrHelper();
// Make sure that we have generated the maximal number of deopt entries. // Make sure that we have generated the maximal number of deopt entries.
// This is in order to avoid triggering the generation of deopt entries later // This is in order to avoid triggering the generation of deopt entries later
...@@ -692,15 +695,15 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() { ...@@ -692,15 +695,15 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() {
PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() { PipelineCompilationJob::Status PipelineCompilationJob::FinalizeJobImpl() {
Handle<Code> code = pipeline_.FinalizeCode(); Handle<Code> code = pipeline_.FinalizeCode();
if (code.is_null()) { if (code.is_null()) {
if (info()->bailout_reason() == kNoReason) { if (compilation_info()->bailout_reason() == kNoReason) {
return AbortOptimization(kCodeGenerationFailed); return AbortOptimization(kCodeGenerationFailed);
} }
return FAILED; return FAILED;
} }
info()->dependencies()->Commit(code); compilation_info()->dependencies()->Commit(code);
info()->SetCode(code); compilation_info()->SetCode(code);
if (info()->is_deoptimization_enabled()) { if (compilation_info()->is_deoptimization_enabled()) {
info()->context()->native_context()->AddOptimizedCode(*code); compilation_info()->context()->native_context()->AddOptimizedCode(*code);
RegisterWeakObjectsInOptimizedCode(code); RegisterWeakObjectsInOptimizedCode(code);
} }
return SUCCEEDED; return SUCCEEDED;
...@@ -765,7 +768,7 @@ class PipelineWasmCompilationJob final : public CompilationJob { ...@@ -765,7 +768,7 @@ class PipelineWasmCompilationJob final : public CompilationJob {
SourcePositionTable* source_positions, SourcePositionTable* source_positions,
ZoneVector<trap_handler::ProtectedInstructionData>* protected_insts, ZoneVector<trap_handler::ProtectedInstructionData>* protected_insts,
wasm::ModuleOrigin wasm_origin) wasm::ModuleOrigin wasm_origin)
: CompilationJob(info->isolate(), info, "TurboFan", : CompilationJob(info->isolate(), nullptr, info, "TurboFan",
State::kReadyToExecute), State::kReadyToExecute),
zone_stats_(info->isolate()->allocator()), zone_stats_(info->isolate()->allocator()),
pipeline_statistics_(CreatePipelineStatistics(info, &zone_stats_)), pipeline_statistics_(CreatePipelineStatistics(info, &zone_stats_)),
...@@ -806,8 +809,8 @@ PipelineWasmCompilationJob::PrepareJobImpl() { ...@@ -806,8 +809,8 @@ PipelineWasmCompilationJob::PrepareJobImpl() {
PipelineWasmCompilationJob::Status PipelineWasmCompilationJob::Status
PipelineWasmCompilationJob::ExecuteJobImpl() { PipelineWasmCompilationJob::ExecuteJobImpl() {
if (FLAG_trace_turbo) { if (FLAG_trace_turbo) {
TurboJsonFile json_of(info(), std::ios_base::trunc); TurboJsonFile json_of(compilation_info(), std::ios_base::trunc);
json_of << "{\"function\":\"" << info()->GetDebugName().get() json_of << "{\"function\":\"" << compilation_info()->GetDebugName().get()
<< "\", \"source\":\"\",\n\"phases\":["; << "\", \"source\":\"\",\n\"phases\":[";
} }
...@@ -1873,7 +1876,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, ...@@ -1873,7 +1876,7 @@ Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
Code::Flags flags, Code::Flags flags,
const char* debug_name) { const char* debug_name) {
CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags);
if (isolate->serializer_enabled()) info.PrepareForSerializing(); if (isolate->serializer_enabled()) info.MarkAsSerializing();
// Construct a pipeline for scheduling and code generation. // Construct a pipeline for scheduling and code generation.
ZoneStats zone_stats(isolate->allocator()); ZoneStats zone_stats(isolate->allocator());
......
...@@ -29,8 +29,9 @@ namespace internal { ...@@ -29,8 +29,9 @@ namespace internal {
class FullCodegenCompilationJob final : public CompilationJob { class FullCodegenCompilationJob final : public CompilationJob {
public: public:
explicit FullCodegenCompilationJob(CompilationInfo* info) explicit FullCodegenCompilationJob(ParseInfo* parse_info,
: CompilationJob(info->isolate(), info, "Full-Codegen") {} CompilationInfo* info)
: CompilationJob(info->isolate(), parse_info, info, "Full-Codegen") {}
bool can_execute_on_background_thread() const override { return false; } bool can_execute_on_background_thread() const override { return false; }
...@@ -38,7 +39,9 @@ class FullCodegenCompilationJob final : public CompilationJob { ...@@ -38,7 +39,9 @@ class FullCodegenCompilationJob final : public CompilationJob {
CompilationJob::Status ExecuteJobImpl() final { CompilationJob::Status ExecuteJobImpl() final {
DCHECK(ThreadId::Current().Equals(isolate()->thread_id())); DCHECK(ThreadId::Current().Equals(isolate()->thread_id()));
return FullCodeGenerator::MakeCode(info(), stack_limit()) ? SUCCEEDED return FullCodeGenerator::MakeCode(parse_info(), compilation_info(),
stack_limit())
? SUCCEEDED
: FAILED; : FAILED;
} }
...@@ -70,17 +73,14 @@ FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm, ...@@ -70,17 +73,14 @@ FullCodeGenerator::FullCodeGenerator(MacroAssembler* masm,
} }
// static // static
CompilationJob* FullCodeGenerator::NewCompilationJob(CompilationInfo* info) { CompilationJob* FullCodeGenerator::NewCompilationJob(
return new FullCodegenCompilationJob(info); ParseInfo* parse_info, CompilationInfo* compilation_info) {
return new FullCodegenCompilationJob(parse_info, compilation_info);
} }
// static // static
bool FullCodeGenerator::MakeCode(CompilationInfo* info) { bool FullCodeGenerator::MakeCode(ParseInfo* parse_info, CompilationInfo* info,
return MakeCode(info, info->isolate()->stack_guard()->real_climit()); uintptr_t stack_limit) {
}
// static
bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
Isolate* isolate = info->isolate(); Isolate* isolate = info->isolate();
DCHECK(!info->literal()->must_use_ignition()); DCHECK(!info->literal()->must_use_ignition());
...@@ -96,7 +96,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) { ...@@ -96,7 +96,7 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info, uintptr_t stack_limit) {
int len = String::cast(script->source())->length(); int len = String::cast(script->source())->length();
isolate->counters()->total_full_codegen_source_size()->Increment(len); isolate->counters()->total_full_codegen_source_size()->Increment(len);
} }
CodeGenerator::MakeCodePrologue(info, "full"); CodeGenerator::MakeCodePrologue(parse_info, info, "full");
const int kInitialBufferSize = 4 * KB; const int kInitialBufferSize = 4 * KB;
MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize, MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize,
CodeObjectRequired::kYes); CodeObjectRequired::kYes);
......
...@@ -25,6 +25,7 @@ namespace internal { ...@@ -25,6 +25,7 @@ namespace internal {
class CompilationInfo; class CompilationInfo;
class CompilationJob; class CompilationJob;
class JumpPatchSite; class JumpPatchSite;
class ParseInfo;
class Scope; class Scope;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -37,10 +38,11 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> { ...@@ -37,10 +38,11 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
void Initialize(uintptr_t stack_limit); void Initialize(uintptr_t stack_limit);
static CompilationJob* NewCompilationJob(CompilationInfo* info); static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
static bool MakeCode(CompilationInfo* info, uintptr_t stack_limit); static bool MakeCode(ParseInfo* parse_info, CompilationInfo* info,
static bool MakeCode(CompilationInfo* info); uintptr_t stack_limit);
static const int kMaxBackEdgeWeight = 127; static const int kMaxBackEdgeWeight = 127;
......
...@@ -774,8 +774,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) ...@@ -774,8 +774,8 @@ BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope()); DCHECK_EQ(closure_scope(), closure_scope()->GetClosureScope());
if (info->is_block_coverage_enabled()) { if (info->is_block_coverage_enabled()) {
DCHECK(FLAG_block_coverage); DCHECK(FLAG_block_coverage);
block_coverage_builder_ = new (zone()) BlockCoverageBuilder( block_coverage_builder_ = new (zone())
zone(), builder(), info->parse_info()->source_range_map()); BlockCoverageBuilder(zone(), builder(), info->source_range_map());
} }
} }
......
...@@ -24,7 +24,8 @@ namespace interpreter { ...@@ -24,7 +24,8 @@ namespace interpreter {
class InterpreterCompilationJob final : public CompilationJob { class InterpreterCompilationJob final : public CompilationJob {
public: public:
explicit InterpreterCompilationJob(CompilationInfo* info); InterpreterCompilationJob(ParseInfo* pare_info,
CompilationInfo* compilation_info);
protected: protected:
Status PrepareJobImpl() final; Status PrepareJobImpl() final;
...@@ -143,15 +144,19 @@ bool ShouldPrintBytecode(Handle<SharedFunctionInfo> shared) { ...@@ -143,15 +144,19 @@ bool ShouldPrintBytecode(Handle<SharedFunctionInfo> shared) {
} // namespace } // namespace
InterpreterCompilationJob::InterpreterCompilationJob(CompilationInfo* info) InterpreterCompilationJob::InterpreterCompilationJob(
: CompilationJob(info->isolate(), info, "Ignition"), ParseInfo* parse_info, CompilationInfo* compilation_info)
generator_(info), : CompilationJob(compilation_info->isolate(), parse_info, compilation_info,
runtime_call_stats_(info->isolate()->counters()->runtime_call_stats()), "Ignition"),
generator_(compilation_info),
runtime_call_stats_(
compilation_info->isolate()->counters()->runtime_call_stats()),
background_execute_counter_("CompileBackgroundIgnition") {} background_execute_counter_("CompileBackgroundIgnition") {}
InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() { InterpreterCompilationJob::Status InterpreterCompilationJob::PrepareJobImpl() {
// TODO(5203): Move code out of codegen.cc once FCG goes away. // TODO(5203): Move code out of codegen.cc once FCG goes away.
CodeGenerator::MakeCodePrologue(info(), "interpreter"); CodeGenerator::MakeCodePrologue(parse_info(), compilation_info(),
"interpreter");
return SUCCEEDED; return SUCCEEDED;
} }
...@@ -186,22 +191,24 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() { ...@@ -186,22 +191,24 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::FinalizeJobImpl() {
return FAILED; return FAILED;
} }
if (ShouldPrintBytecode(info()->shared_info())) { if (ShouldPrintBytecode(compilation_info()->shared_info())) {
OFStream os(stdout); OFStream os(stdout);
std::unique_ptr<char[]> name = info()->GetDebugName(); std::unique_ptr<char[]> name = compilation_info()->GetDebugName();
os << "[generating bytecode for function: " << info()->GetDebugName().get() os << "[generating bytecode for function: "
<< "]" << std::endl; << compilation_info()->GetDebugName().get() << "]" << std::endl;
bytecodes->Disassemble(os); bytecodes->Disassemble(os);
os << std::flush; os << std::flush;
} }
info()->SetBytecodeArray(bytecodes); compilation_info()->SetBytecodeArray(bytecodes);
info()->SetCode(BUILTIN_CODE(info()->isolate(), InterpreterEntryTrampoline)); compilation_info()->SetCode(
BUILTIN_CODE(compilation_info()->isolate(), InterpreterEntryTrampoline));
return SUCCEEDED; return SUCCEEDED;
} }
CompilationJob* Interpreter::NewCompilationJob(CompilationInfo* info) { CompilationJob* Interpreter::NewCompilationJob(
return new InterpreterCompilationJob(info); ParseInfo* parse_info, CompilationInfo* compilation_info) {
return new InterpreterCompilationJob(parse_info, compilation_info);
} }
bool Interpreter::IsDispatchTableInitialized() { bool Interpreter::IsDispatchTableInitialized() {
......
...@@ -23,6 +23,7 @@ class Isolate; ...@@ -23,6 +23,7 @@ class Isolate;
class Callable; class Callable;
class CompilationInfo; class CompilationInfo;
class CompilationJob; class CompilationJob;
class ParseInfo;
class SetupIsolateDelegate; class SetupIsolateDelegate;
class RootVisitor; class RootVisitor;
...@@ -38,8 +39,10 @@ class Interpreter { ...@@ -38,8 +39,10 @@ class Interpreter {
// Returns the interrupt budget which should be used for the profiler counter. // Returns the interrupt budget which should be used for the profiler counter.
static int InterruptBudget(); static int InterruptBudget();
// Creates a compilation job which will generate bytecode for |info|. // Creates a compilation job which will generate bytecode for |parse_info| and
static CompilationJob* NewCompilationJob(CompilationInfo* info); // |compilation_info|.
static CompilationJob* NewCompilationJob(ParseInfo* parse_info,
CompilationInfo* compilation_info);
// Return bytecode handler for |bytecode|. // Return bytecode handler for |bytecode|.
Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale); Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);
......
...@@ -141,8 +141,8 @@ Handle<JSFunction> FunctionTester::ForMachineGraph(Graph* graph, ...@@ -141,8 +141,8 @@ Handle<JSFunction> FunctionTester::ForMachineGraph(Graph* graph,
Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) { Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(parse_info.zone(), function->GetIsolate(),
shared, function); parse_info.script(), shared, function);
info.SetOptimizing(); info.SetOptimizing();
if (flags_ & CompilationInfo::kInliningEnabled) { if (flags_ & CompilationInfo::kInliningEnabled) {
...@@ -154,7 +154,7 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) { ...@@ -154,7 +154,7 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
info.MarkAsDeoptimizationEnabled(); info.MarkAsDeoptimizationEnabled();
info.MarkAsOptimizeFromBytecode(); info.MarkAsOptimizeFromBytecode();
} else { } else {
CHECK(Compiler::ParseAndAnalyze(&info)); CHECK(Compiler::ParseAndAnalyze(&parse_info, shared, info.isolate()));
parse_info.ast_value_factory()->Internalize(info.isolate()); parse_info.ast_value_factory()->Internalize(info.isolate());
} }
JSFunction::EnsureLiterals(function); JSFunction::EnsureLiterals(function);
...@@ -172,11 +172,11 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) { ...@@ -172,11 +172,11 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) { Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) {
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(parse_info.zone(), function->GetIsolate(),
shared, function); parse_info.script(), shared, function);
CHECK(parsing::ParseFunction(info.parse_info(), info.shared_info(), CHECK(
info.isolate())); parsing::ParseFunction(&parse_info, info.shared_info(), info.isolate()));
info.SetOptimizing(); info.SetOptimizing();
Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph); Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph);
......
...@@ -46,8 +46,8 @@ TEST(TestLinkageCreate) { ...@@ -46,8 +46,8 @@ TEST(TestLinkageCreate) {
HandleAndZoneScope handles; HandleAndZoneScope handles;
Handle<JSFunction> function = Compile("a + b"); Handle<JSFunction> function = Compile("a + b");
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); Handle<Script> script(Script::cast(shared->script()));
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(handles.main_zone(), function->GetIsolate(), script,
shared, function); shared, function);
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info); CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
CHECK(descriptor); CHECK(descriptor);
...@@ -64,8 +64,8 @@ TEST(TestLinkageJSFunctionIncoming) { ...@@ -64,8 +64,8 @@ TEST(TestLinkageJSFunctionIncoming) {
Handle<JSFunction>::cast(v8::Utils::OpenHandle( Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(sources[i])))); *v8::Local<v8::Function>::Cast(CompileRun(sources[i]))));
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); Handle<Script> script(Script::cast(shared->script()));
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(handles.main_zone(), function->GetIsolate(), script,
shared, function); shared, function);
CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info); CallDescriptor* descriptor = Linkage::ComputeIncoming(info.zone(), &info);
CHECK(descriptor); CHECK(descriptor);
...@@ -82,8 +82,8 @@ TEST(TestLinkageJSCall) { ...@@ -82,8 +82,8 @@ TEST(TestLinkageJSCall) {
HandleAndZoneScope handles; HandleAndZoneScope handles;
Handle<JSFunction> function = Compile("a + c"); Handle<JSFunction> function = Compile("a + c");
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); Handle<Script> script(Script::cast(shared->script()));
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(handles.main_zone(), function->GetIsolate(), script,
shared, function); shared, function);
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
......
...@@ -35,11 +35,12 @@ struct TestHelper : public HandleAndZoneScope { ...@@ -35,11 +35,12 @@ struct TestHelper : public HandleAndZoneScope {
// TODO(titzer): don't scope analyze every single time. // TODO(titzer): don't scope analyze every single time.
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); ParseInfo parse_info(shared);
CompilationInfo info(parse_info.zone(), &parse_info, function->GetIsolate(), CompilationInfo info(parse_info.zone(), function->GetIsolate(),
shared, function); parse_info.script(), shared, function);
CHECK(parsing::ParseFunction(&parse_info, info.shared_info(), CHECK(parsing::ParseFunction(&parse_info, info.shared_info(),
info.isolate())); info.isolate()));
info.set_literal(parse_info.literal());
CHECK(Rewriter::Rewrite(&parse_info)); CHECK(Rewriter::Rewrite(&parse_info));
DeclarationScope::Analyze(&parse_info, info.isolate()); DeclarationScope::Analyze(&parse_info, info.isolate());
......
...@@ -118,13 +118,11 @@ class BytecodeGraphTester { ...@@ -118,13 +118,11 @@ class BytecodeGraphTester {
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function)); Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
CHECK(function->shared()->HasBytecodeArray()); CHECK(function->shared()->HasBytecodeArray());
// TODO(mstarzinger): We should be able to prime CompilationInfo without Zone zone(function->GetIsolate()->allocator(), ZONE_NAME);
// having to instantiate a ParseInfo first. Fix this!
Handle<SharedFunctionInfo> shared(function->shared()); Handle<SharedFunctionInfo> shared(function->shared());
ParseInfo parse_info(shared); Handle<Script> script(Script::cast(shared->script()));
CompilationInfo compilation_info(&zone, function->GetIsolate(), script,
CompilationInfo compilation_info(parse_info.zone(), &parse_info, shared, function);
function->GetIsolate(), shared, function);
compilation_info.SetOptimizing(); compilation_info.SetOptimizing();
compilation_info.MarkAsDeoptimizationEnabled(); compilation_info.MarkAsDeoptimizationEnabled();
compilation_info.MarkAsOptimizeFromBytecode(); compilation_info.MarkAsOptimizeFromBytecode();
......
...@@ -26,12 +26,12 @@ namespace { ...@@ -26,12 +26,12 @@ namespace {
class BlockingCompilationJob : public CompilationJob { class BlockingCompilationJob : public CompilationJob {
public: public:
BlockingCompilationJob(Isolate* isolate, Handle<JSFunction> function) BlockingCompilationJob(Isolate* isolate, Handle<JSFunction> function)
: CompilationJob(isolate, &info_, "BlockingCompilationJob", : CompilationJob(isolate, &parse_info_, &info_, "BlockingCompilationJob",
State::kReadyToExecute), State::kReadyToExecute),
shared_(function->shared()), shared_(function->shared()),
parse_info_(shared_), parse_info_(shared_),
info_(parse_info_.zone(), &parse_info_, function->GetIsolate(), shared_, info_(parse_info_.zone(), function->GetIsolate(), parse_info_.script(),
function), shared_, function),
blocking_(false), blocking_(false),
semaphore_(0) {} semaphore_(0) {}
~BlockingCompilationJob() override = default; ~BlockingCompilationJob() override = default;
......
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