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