Fix bug in Runtime_CompileOptimized resulting from stack overflow.
authortitzer <titzer@chromium.org>
Wed, 7 Jan 2015 13:43:31 +0000 (05:43 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 7 Jan 2015 13:43:44 +0000 (13:43 +0000)
R=jarin@chromium.org
BUG=chromium:446389
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#25974}

src/runtime/runtime-compiler.cc
test/mjsunit/regress/regress-446389.js [new file with mode: 0644]

index ebd0c13..6526dcf 100644 (file)
@@ -69,9 +69,20 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized) {
       concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
   Handle<Code> code;
   if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
+    // Optimization succeeded, return optimized code.
     function->ReplaceCode(*code);
   } else {
-    function->ReplaceCode(function->shared()->code());
+    // 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);
   }
 
   DCHECK(function->code()->kind() == Code::FUNCTION ||
diff --git a/test/mjsunit/regress/regress-446389.js b/test/mjsunit/regress/regress-446389.js
new file mode 100644 (file)
index 0000000..d600638
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function runNearStackLimit(f) { function t() { try { t(); } catch(e) { f(); } }; try { t(); } catch(e) {} }
+%OptimizeFunctionOnNextCall(__f_3);
+function __f_3() {
+    var __v_5 = a[0];
+}
+runNearStackLimit(function() { __f_3(); });