Index: src/compiler.cc |
diff --git a/src/compiler.cc b/src/compiler.cc |
index 7b0faf0b92d3155dbbb7e649d6c1566f65cc5738..b552baeb78c3863cf8fb53bba13388b1363c926f 100644 |
--- a/src/compiler.cc |
+++ b/src/compiler.cc |
@@ -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. |