Added %NeverOptimize runtime call that can disable optimizations for a method for...
authortitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 11 Jul 2013 14:17:56 +0000 (14:17 +0000)
committertitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 11 Jul 2013 14:17:56 +0000 (14:17 +0000)
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15632 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

15 files changed:
src/hydrogen.cc
src/runtime.cc
src/runtime.h
test/mjsunit/compiler/inline-arguments.js
test/mjsunit/elements-kind.js
test/mjsunit/elide-double-hole-check-9.js
test/mjsunit/generated-transition-stub.js
test/mjsunit/never-optimize.js [new file with mode: 0644]
test/mjsunit/opt-elements-kind.js
test/mjsunit/osr-elements-kind.js
test/mjsunit/regress/regress-1713b.js [new file with mode: 0644]
test/mjsunit/regress/regress-97116b.js [new file with mode: 0644]
test/mjsunit/regress/regress-crbug-173907b.js [new file with mode: 0644]
test/mjsunit/regress/regress-deopt-gcb.js [new file with mode: 0644]
test/mjsunit/regress/regress-mul-canoverflowb.js [new file with mode: 0644]

index 5ea04b9..863a8cc 100644 (file)
@@ -7435,6 +7435,14 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
 
   const Runtime::Function* function = expr->function();
   ASSERT(function != NULL);
+
+  if (static_cast<int>(function->function_id)
+      == static_cast<int>(Runtime::kNeverOptimize)
+      && expr->arguments()->length() == 0) {
+    // %NeverOptimize() without arguments marks the caller as never optimize.
+    return Bailout("function marked itself as never optimize");
+  }
+
   if (function->intrinsic_type == Runtime::INLINE) {
     ASSERT(expr->name()->length() > 0);
     ASSERT(expr->name()->Get(0) == '_');
index 6e04560..87cc031 100644 (file)
@@ -8346,6 +8346,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NeverOptimize) {
+  HandleScope scope(isolate);
+
+  if (args.length() == 0) {
+    // Disable optimization for the calling function.
+    JavaScriptFrameIterator it(isolate);
+    if (!it.done()) {
+      JSFunction *function = JSFunction::cast(it.frame()->function());
+      function->shared()->set_optimization_disabled(true);
+    }
+    return isolate->heap()->undefined_value();
+  }
+
+  // Disable optimization for the functions passed.
+  for (int i = 0; i < args.length(); i++) {
+    CONVERT_ARG_CHECKED(JSFunction, function, i);
+    function->shared()->set_optimization_disabled(true);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompleteOptimization) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
index 70568f9..4777c3c 100644 (file)
@@ -97,6 +97,7 @@ namespace internal {
   F(RunningInSimulator, 0, 1) \
   F(IsParallelRecompilationSupported, 0, 1) \
   F(OptimizeFunctionOnNextCall, -1, 1) \
+  F(NeverOptimize, -1, 1) \
   F(CompleteOptimization, 1, 1) \
   F(GetOptimizationStatus, 1, 1) \
   F(GetOptimizationCount, 1, 1) \
index 75d01b5..7de412d 100644 (file)
@@ -117,7 +117,7 @@ F4(1);
 // Test arguments access from the inlined function.
 function uninlinable(v) {
   assertEquals(0, v);
-  try { } catch (e) { }
+  %NeverOptimize();
   return 0;
 }
 
index 247aa89..90ec7ab 100644 (file)
@@ -171,21 +171,21 @@ monomorphic(smi_only);
 
 if (support_smi_only_arrays) {
   function construct_smis() {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     var a = [0, 0, 0];
     a[0] = 0;  // Send the COW array map to the steak house.
     assertKind(elements_kind.fast_smi_only, a);
     return a;
   }
   function construct_doubles() {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     var a = construct_smis();
     a[0] = 1.5;
     assertKind(elements_kind.fast_double, a);
     return a;
   }
   function construct_objects() {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     var a = construct_smis();
     a[0] = "one";
     assertKind(elements_kind.fast, a);
@@ -194,7 +194,7 @@ if (support_smi_only_arrays) {
 
   // Test crankshafted transition SMI->DOUBLE.
   function convert_to_double(array) {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     array[1] = 2.5;
     assertKind(elements_kind.fast_double, array);
     assertEquals(2.5, array[1]);
@@ -206,7 +206,7 @@ if (support_smi_only_arrays) {
   convert_to_double(smis);
   // Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
   function convert_to_fast(array) {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     array[1] = "two";
     assertKind(elements_kind.fast, array);
     assertEquals("two", array[1]);
@@ -223,7 +223,7 @@ if (support_smi_only_arrays) {
   // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
   // transition to FAST directly).
   function convert_mixed(array, value, kind) {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     array[1] = value;
     assertKind(kind, array);
     assertEquals(value, array[1]);
index 4d277af..773f6d9 100644 (file)
@@ -30,7 +30,7 @@
 var do_set = false;
 
 function set_proto_elements() {
-  try {} catch (e) {}  // Don't optimize or inline
+  %NeverOptimize();
   if (do_set) Array.prototype[1] = 1.5;
 }
 
index 072ce9c..6299a22 100644 (file)
@@ -27,7 +27,7 @@
 
 // Flags: --allow-natives-syntax --compiled_transitions
 
-try {} catch (e) {}
+%NeverOptimize();
 
 var iteration_count = 1;
 
diff --git a/test/mjsunit/never-optimize.js b/test/mjsunit/never-optimize.js
new file mode 100644 (file)
index 0000000..553cd17
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function o1() {
+}
+
+if (%GetOptimizationStatus(o1) != 4) {
+  // 4 == optimization disabled.
+  o1(); o1();
+  %OptimizeFunctionOnNextCall(o1);
+  o1();
+
+  // check that the given function was optimized.
+  var o1_status = %GetOptimizationStatus(o1);
+  assertTrue(o1_status == 1    // optimized
+          || o1_status == 3    // optimized (always opt)
+          || o1_status == 5);  // lazy recompile requested
+
+  // Test the %NeverOptimize runtime call.
+  function u1() {
+    %NeverOptimize();
+  }
+
+  function u2() {
+  }
+
+  %NeverOptimize(u2);
+
+  u1(); u1();
+  u2(); u2();
+
+  %OptimizeFunctionOnNextCall(u1);
+  %OptimizeFunctionOnNextCall(u2);
+
+  u1(); u1();
+  u2(); u2();
+
+  // 2 => not optimized.
+  assertEquals(2, %GetOptimizationStatus(u1));
+  assertEquals(2, %GetOptimizationStatus(u2));
+
+}
\ No newline at end of file
index 3df1d9b..b0f94f2 100644 (file)
@@ -109,7 +109,7 @@ function assertKind(expected, obj, name_opt) {
 }
 
 function construct_smis() {
-  try {} catch (e) {} // TODO(titzer): DisableOptimization
+  %NeverOptimize();
   var a = [0, 0, 0];
   a[0] = 0;  // Send the COW array map to the steak house.
   assertKind(elements_kind.fast_smi_only, a);
@@ -117,7 +117,7 @@ function construct_smis() {
 }
 
 function construct_doubles() {
-  try {} catch (e) {} // TODO(titzer): DisableOptimization
+  %NeverOptimize();
   var a = construct_smis();
   a[0] = 1.5;
   assertKind(elements_kind.fast_double, a);
@@ -125,7 +125,7 @@ function construct_doubles() {
 }
 
 function convert_mixed(array, value, kind) {
-  try {} catch (e) {} // TODO(titzer): DisableOptimization
+  %NeverOptimize();
   array[1] = value;
   assertKind(kind, array);
   assertEquals(value, array[1]);
index 9b0f506..e59262e 100644 (file)
@@ -113,14 +113,14 @@ for (var i = 0; i < 1000000; i++) { }
 
 if (support_smi_only_arrays) {
   function construct_smis() {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     var a = [0, 0, 0];
     a[0] = 0;  // Send the COW array map to the steak house.
     assertKind(elements_kind.fast_smi_only, a);
     return a;
   }
   function construct_doubles() {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     var a = construct_smis();
     a[0] = 1.5;
     assertKind(elements_kind.fast_double, a);
@@ -130,7 +130,7 @@ if (support_smi_only_arrays) {
   // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
   // transition to FAST directly).
   function convert_mixed(array, value, kind) {
-    try {} catch (e) {} // TODO(titzer): DisableOptimization
+    %NeverOptimize();
     array[1] = value;
     assertKind(kind, array);
     assertEquals(value, array[1]);
diff --git a/test/mjsunit/regress/regress-1713b.js b/test/mjsunit/regress/regress-1713b.js
new file mode 100644 (file)
index 0000000..2e35fa4
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --always-compact --expose-gc
+
+var O = { get f() { return 0; } };
+
+var CODE = [];
+
+var R = [];
+
+function Allocate4Kb(N) {
+  var arr = [];
+  do {arr.push(new Array(1024));} while (--N > 0);
+  return arr;
+}
+
+function AllocateXMb(X) {
+  return Allocate4Kb((1024 * X) / 4);
+}
+
+function Node(v, next) { this.v = v; this.next = next; }
+
+Node.prototype.execute = function (O) {
+  var n = this;
+  while (n.next !== null) n = n.next;
+  n.v(O);
+};
+
+function LongList(N, x) {
+  if (N == 0) return new Node(x, null);
+  return new Node(new Array(1024), LongList(N - 1, x));
+}
+
+var L = LongList(1024, function (O) {
+  for (var i = 0; i < 5; i++) O.f;
+});
+
+
+
+function Incremental(O, x) {
+  if (!x) {
+    return;
+  }
+  function CreateCode(i) {
+    var f = new Function("return O.f_" + i);
+    CODE.push(f);
+    f(); // compile
+    f(); // compile
+    f(); // compile
+  }
+
+  for (var i = 0; i < 1e4; i++) CreateCode(i);
+  gc();
+  gc();
+  gc();
+
+  print(">>> 1 <<<");
+
+  L.execute(O);
+
+  %NeverOptimize();
+
+  L = null;
+  print(">>> 2 <<<");
+  AllocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+
+}
+
+function foo(O, x) {
+  Incremental(O, x);
+
+  print('f');
+
+  for (var i = 0; i < 5; i++) O.f;
+
+
+  print('g');
+
+  bar(x);
+}
+
+function bar(x) {
+  if (!x) return;
+  %DeoptimizeFunction(foo);
+  AllocateXMb(8);
+  AllocateXMb(8);
+}
+
+var O1 = {};
+var O2 = {};
+var O3 = {};
+var O4 = {f:0};
+
+foo(O1, false);
+foo(O2, false);
+foo(O3, false);
+%OptimizeFunctionOnNextCall(foo);
+foo(O4, true);
diff --git a/test/mjsunit/regress/regress-97116b.js b/test/mjsunit/regress/regress-97116b.js
new file mode 100644 (file)
index 0000000..e8b7331
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --allow-natives-syntax
+
+// Check that we are not flushing code for inlined functions that
+// have a pending lazy deoptimization on the stack.
+
+function deopt() {
+  %NeverOptimize();
+  %DeoptimizeFunction(outer);
+  for (var i = 0; i < 10; i++) gc();  // Force code flushing.
+}
+
+function outer(should_deopt) {
+  inner(should_deopt);
+}
+
+function inner(should_deopt) {
+  if (should_deopt) deopt();
+}
+
+outer(false);
+outer(false);
+%OptimizeFunctionOnNextCall(outer);
+outer(true);
diff --git a/test/mjsunit/regress/regress-crbug-173907b.js b/test/mjsunit/regress/regress-crbug-173907b.js
new file mode 100644 (file)
index 0000000..698527b
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var X = 1.1;
+var K = 0.5;
+
+var O = 0;
+var result = new Float64Array(2);
+
+function spill() {
+  %NeverOptimize();
+}
+
+function buggy() {
+  var v = X;
+  var phi1 = v + K;
+  var phi2 = v - K;
+
+  spill();  // At this point initial values for phi1 and phi2 are spilled.
+
+  var xmm1 = v;
+  var xmm2 = v*v*v;
+  var xmm3 = v*v*v*v;
+  var xmm4 = v*v*v*v*v;
+  var xmm5 = v*v*v*v*v*v;
+  var xmm6 = v*v*v*v*v*v*v;
+  var xmm7 = v*v*v*v*v*v*v*v;
+  var xmm8 = v*v*v*v*v*v*v*v*v;
+
+  // All registers are blocked and phis for phi1 and phi2 are spilled because
+  // their left (incoming) value is spilled, there are no free registers,
+  // and phis themselves have only ANY-policy uses.
+
+  for (var x = 0; x < 2; x++) {
+    xmm1 += xmm1 * xmm6;
+    xmm2 += xmm1 * xmm5;
+    xmm3 += xmm1 * xmm4;
+    xmm4 += xmm1 * xmm3;
+    xmm5 += xmm1 * xmm2;
+
+    // Now swap values of phi1 and phi2 to create cycle between phis.
+    var t = phi1;
+    phi1 = phi2;
+    phi2 = t;
+  }
+
+  // Now we want to get values of phi1 and phi2. However we would like to
+  // do it in a way that does not produce any uses of phi1&phi2 that have
+  // a register beneficial policy. How? We just hide these uses behind phis.
+  result[0] = (O === 0) ? phi1 : phi2;
+  result[1] = (O !== 0) ? phi1 : phi2;
+}
+
+function test() {
+  buggy();
+  assertArrayEquals([X + K, X - K], result);
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(buggy);
+test();
diff --git a/test/mjsunit/regress/regress-deopt-gcb.js b/test/mjsunit/regress/regress-deopt-gcb.js
new file mode 100644 (file)
index 0000000..95bb450
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+// This tests that we can correctly handle a GC immediately after a function
+// has been deoptimized, even when we have an activation of this function on
+// the stack.
+
+// Ensure that there is code objects before the code for the opt_me function.
+(function() { var a = 10; a++; })();
+
+function opt_me() {
+  deopt();
+}
+
+function deopt() {
+  // Make sure we don't inline this function
+  %NeverOptimize();
+  %DeoptimizeFunction(opt_me);
+  gc();
+}
+
+
+opt_me();
diff --git a/test/mjsunit/regress/regress-mul-canoverflowb.js b/test/mjsunit/regress/regress-mul-canoverflowb.js
new file mode 100644 (file)
index 0000000..2332e94
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function boom(a) {
+  return ((a | 0) * (a | 0)) | 0;
+}
+function boom_unoptimized(a) {
+  %NeverOptimize();
+  return ((a | 0) * (a | 0)) | 0;
+}
+
+boom(1, 1);
+boom(2, 2);
+
+%OptimizeFunctionOnNextCall(boom);
+var big_int = 0x5F00000F;
+var expected = boom_unoptimized(big_int);
+var actual = boom(big_int)
+assertEquals(expected, actual);