Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Unified Diff: src/compiler.cc

Issue 151603004: A64: Synchronize with r16587. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index 7212475383a848c9c99fe7577cb4ac27364a5da4..c37596fad3929b9fb3aa4bec0826411ca6c0ef2a 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -58,7 +58,8 @@ CompilationInfo::CompilationInfo(Handle<Script> script,
Zone* zone)
: flags_(LanguageModeField::encode(CLASSIC_MODE)),
script_(script),
- osr_ast_id_(BailoutId::None()) {
+ osr_ast_id_(BailoutId::None()),
+ osr_pc_offset_(0) {
Initialize(script->GetIsolate(), BASE, zone);
}
@@ -68,7 +69,8 @@ CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
: flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
shared_info_(shared_info),
script_(Handle<Script>(Script::cast(shared_info->script()))),
- osr_ast_id_(BailoutId::None()) {
+ osr_ast_id_(BailoutId::None()),
+ osr_pc_offset_(0) {
Initialize(script_->GetIsolate(), BASE, zone);
}
@@ -80,7 +82,8 @@ CompilationInfo::CompilationInfo(Handle<JSFunction> closure,
shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
script_(Handle<Script>(Script::cast(shared_info_->script()))),
context_(closure->context()),
- osr_ast_id_(BailoutId::None()) {
+ osr_ast_id_(BailoutId::None()),
+ osr_pc_offset_(0) {
Initialize(script_->GetIsolate(), BASE, zone);
}
@@ -90,7 +93,8 @@ CompilationInfo::CompilationInfo(HydrogenCodeStub* stub,
Zone* zone)
: flags_(LanguageModeField::encode(CLASSIC_MODE) |
IsLazy::encode(true)),
- osr_ast_id_(BailoutId::None()) {
+ osr_ast_id_(BailoutId::None()),
+ osr_pc_offset_(0) {
Initialize(isolate, STUB, zone);
code_stub_ = stub;
}
@@ -119,7 +123,7 @@ void CompilationInfo::Initialize(Isolate* isolate,
mode_ = STUB;
return;
}
- mode_ = V8::UseCrankshaft() ? mode : NONOPT;
+ mode_ = isolate->use_crankshaft() ? mode : NONOPT;
abort_due_to_dependency_ = false;
if (script_->type()->value() == Script::TYPE_NATIVE) {
MarkAsNative();
@@ -226,7 +230,7 @@ bool CompilationInfo::ShouldSelfOptimize() {
return FLAG_self_optimization &&
FLAG_crankshaft &&
!function()->flags()->Contains(kDontSelfOptimize) &&
- !function()->flags()->Contains(kDontOptimize) &&
+ !function()->dont_optimize() &&
function()->scope()->AllowsLazyCompilation() &&
(shared_info().is_null() || !shared_info()->optimization_disabled());
}
@@ -242,7 +246,7 @@ bool CompilationInfo::ShouldSelfOptimize() {
// break points has actually been set.
static bool IsDebuggerActive(Isolate* isolate) {
#ifdef ENABLE_DEBUGGER_SUPPORT
- return V8::UseCrankshaft() ?
+ return isolate->use_crankshaft() ?
isolate->debug()->has_break_points() :
isolate->debugger()->IsDebuggerActive();
#else
@@ -310,7 +314,7 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
- ASSERT(V8::UseCrankshaft());
+ ASSERT(isolate()->use_crankshaft());
ASSERT(info()->IsOptimizing());
ASSERT(!info()->IsCompilingForDebugging());
@@ -503,12 +507,14 @@ OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
info()->SetCode(optimized_code);
}
RecordOptimizationStats();
+ // Add to the weak list of optimized code objects.
+ info()->context()->native_context()->AddOptimizedCode(*info()->code());
return SetLastStatus(SUCCEEDED);
}
static bool GenerateCode(CompilationInfo* info) {
- bool is_optimizing = V8::UseCrankshaft() &&
+ bool is_optimizing = info->isolate()->use_crankshaft() &&
!info->IsCompilingForDebugging() &&
info->IsOptimizing();
if (is_optimizing) {
@@ -843,11 +849,11 @@ static bool InstallFullCode(CompilationInfo* info) {
// Check the function has compiled code.
ASSERT(shared->is_compiled());
- shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
+ shared->set_dont_optimize_reason(lit->dont_optimize_reason());
shared->set_dont_inline(lit->flags()->Contains(kDontInline));
shared->set_ast_node_count(lit->ast_node_count());
- if (V8::UseCrankshaft() &&
+ if (info->isolate()->use_crankshaft() &&
!function.is_null() &&
!shared->optimization_disabled()) {
// If we're asked to always optimize, we compile the optimized
@@ -884,9 +890,10 @@ static void InstallCodeCommon(CompilationInfo* info) {
static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
Handle<Code> code = info->code();
- if (FLAG_cache_optimized_code &&
- info->osr_ast_id().IsNone() &&
- code->kind() == Code::OPTIMIZED_FUNCTION) {
+ if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
+
+ // Cache non-OSR optimized code.
+ if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) {
Handle<JSFunction> function = info->closure();
Handle<SharedFunctionInfo> shared(function->shared());
Handle<FixedArray> literals(function->literals());
@@ -898,9 +905,10 @@ static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
- if (FLAG_cache_optimized_code &&
- info->osr_ast_id().IsNone() &&
- info->IsOptimizing()) {
+ if (!info->IsOptimizing()) return false; // Nothing to look up.
+
+ // Lookup non-OSR optimized code.
+ if (FLAG_cache_optimized_code && info->osr_ast_id().IsNone()) {
Handle<SharedFunctionInfo> shared = info->shared_info();
Handle<JSFunction> function = info->closure();
ASSERT(!function.is_null());
@@ -972,8 +980,9 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
}
-void Compiler::RecompileConcurrent(Handle<JSFunction> closure) {
- ASSERT(closure->IsMarkedForConcurrentRecompilation());
+bool Compiler::RecompileConcurrent(Handle<JSFunction> closure,
+ uint32_t osr_pc_offset) {
+ bool compiling_for_osr = (osr_pc_offset != 0);
Isolate* isolate = closure->GetIsolate();
// Here we prepare compile data for the concurrent recompilation thread, but
@@ -987,23 +996,39 @@ void Compiler::RecompileConcurrent(Handle<JSFunction> closure) {
closure->PrintName();
PrintF(" on next run.\n");
}
- return;
+ return false;
}
SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
+ Handle<SharedFunctionInfo> shared = info->shared_info();
+
+ if (compiling_for_osr) {
+ BailoutId osr_ast_id =
+ shared->code()->TranslatePcOffsetToAstId(osr_pc_offset);
+ ASSERT(!osr_ast_id.IsNone());
+ info->SetOptimizing(osr_ast_id);
+ info->set_osr_pc_offset(osr_pc_offset);
+
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - attempt to queue ");
+ closure->PrintName();
+ PrintF(" at AST id %d]\n", osr_ast_id.ToInt());
+ }
+ } else {
+ info->SetOptimizing(BailoutId::None());
+ }
+
VMState<COMPILER> state(isolate);
PostponeInterruptsScope postpone(isolate);
- Handle<SharedFunctionInfo> shared = info->shared_info();
int compiled_size = shared->end_position() - shared->start_position();
isolate->counters()->total_compile_size()->Increment(compiled_size);
- info->SetOptimizing(BailoutId::None());
{
CompilationHandleScope handle_scope(*info);
- if (InstallCodeFromOptimizedCodeMap(*info)) {
- return;
+ if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(*info)) {
+ return true;
}
if (Parser::Parse(*info)) {
@@ -1020,6 +1045,8 @@ void Compiler::RecompileConcurrent(Handle<JSFunction> closure) {
info.Detach();
shared->code()->set_profiler_ticks(0);
isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
+ ASSERT(!isolate->has_pending_exception());
+ return true;
} else if (status == OptimizingCompiler::BAILED_OUT) {
isolate->clear_pending_exception();
InstallFullCode(*info);
@@ -1028,19 +1055,12 @@ void Compiler::RecompileConcurrent(Handle<JSFunction> closure) {
}
}
- if (shared->code()->back_edges_patched_for_osr()) {
- // At this point we either put the function on recompilation queue or
- // aborted optimization. In either case we want to continue executing
- // the unoptimized code without running into OSR. If the unoptimized
- // code has been patched for OSR, unpatch it.
- Deoptimizer::RevertInterruptCode(isolate, shared->code());
- }
-
if (isolate->has_pending_exception()) isolate->clear_pending_exception();
+ return false;
}
-void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
+bool Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
SmartPointer<CompilationInfo> info(optimizing_compiler->info());
// The function may have already been optimized by OSR. Simply continue.
// Except when OSR already disabled optimization for some reason.
@@ -1053,7 +1073,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
PrintF(" as it has been disabled.\n");
}
ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
- return;
+ return false;
}
Isolate* isolate = info->isolate();
@@ -1100,6 +1120,168 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
// profiler ticks to prevent too soon re-opt after a deopt.
info->shared_info()->code()->set_profiler_ticks(0);
ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
+ return status == OptimizingCompiler::SUCCEEDED;
+}
+
+
+static uint32_t CurrentPcOffset(Isolate* isolate,
+ Handle<JSFunction> function,
+ Handle<Code> unoptimized) {
+ JavaScriptFrameIterator it(isolate);
+ JavaScriptFrame* frame = it.frame();
+ ASSERT(frame->function() == *function);
+ ASSERT(frame->LookupCode() == *unoptimized);
+ ASSERT(unoptimized->contains(frame->pc()));
+
+ // Use linear search of the unoptimized code's back edge table to find
+ // the AST id matching the PC.
+ return static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start());
+}
+
+
+static bool IsSuitableForOnStackReplacement(Isolate* isolate,
+ Handle<JSFunction> function,
+ Handle<Code> unoptimized) {
+ // Keep track of whether we've succeeded in optimizing.
+ if (!unoptimized->optimizable()) return false;
+ // If we are trying to do OSR when there are already optimized
+ // activations of the function, it means (a) the function is directly or
+ // indirectly recursive and (b) an optimized invocation has been
+ // deoptimized so that we are currently in an unoptimized activation.
+ // Check for optimized activations of this function.
+ for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
+ JavaScriptFrame* frame = it.frame();
+ if (frame->is_optimized() && frame->function() == *function) return false;
+ }
+
+ return true;
+}
+
+
+BailoutId Compiler::CompileForOnStackReplacement(Handle<JSFunction> function) {
+ Isolate* isolate = function->GetIsolate();
+ // We have hit a back edge in an unoptimized frame for a function that was
+ // selected for on-stack replacement. Find the unoptimized code object.
+ Handle<Code> unoptimized(function->shared()->code(), isolate);
+
+ Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
+ if (FLAG_trace_osr) {
+ PrintF("[OSR - restored original interrupt calls in ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+
+ if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
+ return BailoutId::None();
+ }
+
+ uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
+
+ BailoutId ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
+ ASSERT(!ast_id.IsNone());
+ if (FLAG_trace_osr) {
+ PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
+ function->PrintName();
+ PrintF("]\n");
+ }
+
+ // Try to compile the optimized code. A true return value from
+ // CompileOptimized means that compilation succeeded, not necessarily
+ // that optimization succeeded.
+ if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
+ function->IsOptimized()) {
+ DeoptimizationInputData* data = DeoptimizationInputData::cast(
+ function->code()->deoptimization_data());
+ if (data->OsrPcOffset()->value() >= 0) {
+ if (FLAG_trace_osr) {
+ PrintF("[OSR - entry, offset %d in optimized code]\n",
+ data->OsrPcOffset()->value());
+ }
+ ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
+ return ast_id;
+ }
+ } else {
+ if (FLAG_trace_osr) {
+ PrintF("[OSR - optimization failed for ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ }
+ return BailoutId::None();
+}
+
+
+BailoutId Compiler::CompileForConcurrentOSR(Handle<JSFunction> function) {
+ Isolate* isolate = function->GetIsolate();
+ Handle<Code> unoptimized(function->shared()->code(), isolate);
+
+ uint32_t pc_offset = CurrentPcOffset(isolate, function, unoptimized);
+
+ if (isolate->optimizing_compiler_thread()->
+ IsQueuedForOSR(function, pc_offset)) {
+ // Still waiting for the optimizing compiler thread to finish. Carry on.
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - polling recompile tasks for ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ return BailoutId::None();
+ }
+
+ OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
+ FindReadyOSRCandidate(function, pc_offset);
+
+ if (compiler != NULL) {
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - optimization complete for ");
+ function->PrintName();
+ PrintF(", restoring interrupt calls]\n");
+ }
+ Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
+
+ BailoutId ast_id = compiler->info()->osr_ast_id();
+
+ bool succeeded = InstallOptimizedCode(compiler);
+
+ isolate->optimizing_compiler_thread()->RemoveStaleOSRCandidates();
+
+ if (!succeeded) {
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - optimization failed for ");
+ function->PrintName();
+ PrintF("]\n");
+ }
+ return BailoutId::None();
+ }
+
+ DeoptimizationInputData* data = DeoptimizationInputData::cast(
+ function->code()->deoptimization_data());
+
+ if (data->OsrPcOffset()->value() >= 0) {
+ ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - entry at AST id %d, offset %d in optimized code]\n",
+ ast_id.ToInt(), data->OsrPcOffset()->value());
+ }
+ return ast_id;
+ }
+ return BailoutId::None();
+ }
+
+ if (!IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
+ if (FLAG_trace_osr) {
+ PrintF("[COSR - ");
+ function->PrintName();
+ PrintF(" is unsuitable, restoring interrupt calls]\n");
+ }
+ Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
+ return BailoutId::None();
+ }
+
+ if (!RecompileConcurrent(function, pc_offset)) {
+ Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
+ }
+ return BailoutId::None();
}
@@ -1187,7 +1369,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
function_info->set_ast_node_count(lit->ast_node_count());
function_info->set_is_function(lit->is_function());
- function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
+ function_info->set_dont_optimize_reason(lit->dont_optimize_reason());
function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
function_info->set_is_generator(lit->is_generator());
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698