[compiler] Reduce number of entry points into compiler API.

This removes the entry point to the compiler API which allows requesting
lazily compiled full-codegen code. The aim is to eventually allow the
decisions of which baseline compiler should be used (e.g. Ignition or
full-codegen) be centralized within the compiler pipeline.

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#34489}
This commit is contained in:
mstarzinger 2016-03-04 02:44:31 -08:00 committed by Commit bot
parent 7011ddd652
commit d0b67b984e
3 changed files with 71 additions and 78 deletions

View File

@ -66,6 +66,19 @@ PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info)
#undef PARSE_INFO_GETTER
#undef PARSE_INFO_GETTER_WITH_DEFAULT
// A wrapper around a CompilationInfo that detaches the Handles from
// the underlying DeferredHandleScope and stores them in info_ on
// destruction.
class CompilationHandleScope BASE_EMBEDDED {
public:
explicit CompilationHandleScope(CompilationInfo* info)
: deferred_(info->isolate()), info_(info) {}
~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); }
private:
DeferredHandleScope deferred_;
CompilationInfo* info_;
};
// Exactly like a CompilationInfo, except being allocated via {new} and it also
// creates and enters a Zone on construction and deallocates it on destruction.
@ -927,8 +940,9 @@ bool Compiler::ParseAndAnalyze(ParseInfo* info) {
return Compiler::Analyze(info);
}
namespace {
static bool GetOptimizedCodeNow(CompilationInfo* info) {
bool GetOptimizedCodeNow(CompilationInfo* info) {
Isolate* isolate = info->isolate();
CanonicalHandleScope canonical(isolate);
TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
@ -959,8 +973,7 @@ static bool GetOptimizedCodeNow(CompilationInfo* info) {
return true;
}
static bool GetOptimizedCodeLater(CompilationInfo* info) {
bool GetOptimizedCodeLater(CompilationInfo* info) {
Isolate* isolate = info->isolate();
CanonicalHandleScope canonical(isolate);
TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
@ -1002,8 +1015,7 @@ static bool GetOptimizedCodeLater(CompilationInfo* info) {
return true;
}
MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
MaybeHandle<Code> GetUnoptimizedCode(Handle<JSFunction> function) {
DCHECK(!function->GetIsolate()->has_pending_exception());
DCHECK(!function->is_compiled());
if (function->shared()->is_compiled()) {
@ -1018,8 +1030,7 @@ MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) {
return result;
}
MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) {
Isolate* isolate = function->GetIsolate();
DCHECK(!isolate->has_pending_exception());
DCHECK(!function->is_compiled());
@ -1067,10 +1078,11 @@ MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
return result;
}
} // namespace
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
if (function->is_compiled()) return true;
MaybeHandle<Code> maybe_code = Compiler::GetLazyCode(function);
MaybeHandle<Code> maybe_code = GetLazyCode(function);
Handle<Code> code;
if (!maybe_code.ToHandle(&code)) {
if (flag == CLEAR_EXCEPTION) {
@ -1078,11 +1090,41 @@ bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
}
return false;
}
DCHECK(code->IsJavaScriptCode());
function->ReplaceCode(*code);
DCHECK(function->is_compiled());
return true;
}
bool Compiler::CompileOptimized(Handle<JSFunction> function,
ConcurrencyMode mode) {
Handle<Code> code;
if (Compiler::GetOptimizedCode(function, mode).ToHandle(&code)) {
// Optimization succeeded, return optimized code.
function->ReplaceCode(*code);
} else {
// Optimization failed, get unoptimized code.
Isolate* isolate = function->GetIsolate();
if (isolate->has_pending_exception()) { // Possible stack overflow.
return false;
}
code = Handle<Code>(function->shared()->code(), isolate);
if (code->kind() != Code::FUNCTION &&
code->kind() != Code::OPTIMIZED_FUNCTION) {
if (!GetUnoptimizedCode(function).ToHandle(&code)) {
return false;
}
}
function->ReplaceCode(*code);
}
DCHECK(function->code()->kind() == Code::FUNCTION ||
function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
(function->code()->is_interpreter_entry_trampoline() &&
function->shared()->HasBytecodeArray()) ||
function->IsInOptimizationQueue());
return true;
}
// TODO(turbofan): In the future, unoptimized code with deopt support could
// be generated lazily once deopt is triggered.

View File

@ -491,23 +491,6 @@ class CompilationInfo {
};
// A wrapper around a CompilationInfo that detaches the Handles from
// the underlying DeferredHandleScope and stores them in info_ on
// destruction.
class CompilationHandleScope BASE_EMBEDDED {
public:
explicit CompilationHandleScope(CompilationInfo* info)
: deferred_(info->isolate()), info_(info) {}
~CompilationHandleScope() {
info_->set_deferred_handles(deferred_.Detach());
}
private:
DeferredHandleScope deferred_;
CompilationInfo* info_;
};
class HGraph;
class LChunk;
@ -602,12 +585,10 @@ class OptimizedCompileJob: public ZoneObject {
class Compiler : public AllStatic {
public:
MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
Handle<JSFunction> function);
MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode(
Handle<JSFunction> function);
enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode);
static bool CompileDebugCode(Handle<JSFunction> function);
static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
static void CompileForLiveEdit(Handle<Script> script);
@ -648,8 +629,6 @@ class Compiler : public AllStatic {
static Handle<SharedFunctionInfo> GetSharedFunctionInfoForNative(
v8::Extension* extension, Handle<String> name);
enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
// Generate and return optimized code or start a concurrent optimization job.
// In the latter case, return the InOptimizationQueue builtin. On failure,
// return the empty handle.

View File

@ -21,6 +21,7 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
PrintF("[unoptimized: ");
@ -28,63 +29,28 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
PrintF("]\n");
}
#endif
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
// Compile the target function.
DCHECK(function->shared()->allows_lazy_compilation());
Handle<Code> code;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
Compiler::GetLazyCode(function));
DCHECK(code->IsJavaScriptCode());
function->ReplaceCode(*code);
return *code;
}
namespace {
Object* CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
Compiler::ConcurrencyMode mode) {
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
Handle<Code> code;
if (Compiler::GetOptimizedCode(function, mode).ToHandle(&code)) {
// Optimization succeeded, return optimized code.
function->ReplaceCode(*code);
} else {
// Optimization failed, get unoptimized code.
if (isolate->has_pending_exception()) { // Possible stack overflow.
return isolate->heap()->exception();
}
code = Handle<Code>(function->shared()->code(), isolate);
if (code->kind() != Code::FUNCTION &&
code->kind() != Code::OPTIMIZED_FUNCTION) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, code, Compiler::GetUnoptimizedCode(function));
}
function->ReplaceCode(*code);
if (!Compiler::Compile(function, KEEP_EXCEPTION)) {
return isolate->heap()->exception();
}
DCHECK(function->code()->kind() == Code::FUNCTION ||
function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
(function->code()->is_interpreter_entry_trampoline() &&
function->shared()->HasBytecodeArray()) ||
function->IsInOptimizationQueue());
DCHECK(function->is_compiled());
return function->code();
}
} // namespace
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return CompileOptimized(isolate, function, Compiler::CONCURRENT);
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
if (!Compiler::CompileOptimized(function, Compiler::CONCURRENT)) {
return isolate->heap()->exception();
}
DCHECK(function->is_compiled());
return function->code();
}
@ -92,7 +58,13 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return CompileOptimized(isolate, function, Compiler::NOT_CONCURRENT);
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow();
if (!Compiler::CompileOptimized(function, Compiler::NOT_CONCURRENT)) {
return isolate->heap()->exception();
}
DCHECK(function->is_compiled());
return function->code();
}