[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:
parent
7011ddd652
commit
d0b67b984e
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user