// Copyright 2019 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 --turbofan --no-always-turbofan "use strict"; const mathAbs = Math.abs; const mathImul = Math.imul; // Testing: FunctionPrototypeApply function TestFunctionPrototypeApplyHelper() { return mathAbs.apply(undefined, arguments); } function TestFunctionPrototypeApply(x) { return TestFunctionPrototypeApplyHelper(x); } %PrepareFunctionForOptimization(TestFunctionPrototypeApplyHelper); %PrepareFunctionForOptimization(TestFunctionPrototypeApply); assertEquals(TestFunctionPrototypeApply(-13), 13); assertEquals(TestFunctionPrototypeApply(42), 42); %OptimizeFunctionOnNextCall(TestFunctionPrototypeApply); assertEquals(TestFunctionPrototypeApply(-13), 13); assertOptimized(TestFunctionPrototypeApply); TestFunctionPrototypeApply("abc"); assertUnoptimized(TestFunctionPrototypeApply); // Testing: FunctionPrototypeApply with non-HeapConstant Receiver var MathMin = (function() { return Math.min.apply(null, arguments); }) function TestFunctionPrototypeApplyReceiver(func, x, y) { return func(x, y); } %PrepareFunctionForOptimization(MathMin); %PrepareFunctionForOptimization(TestFunctionPrototypeApplyReceiver); assertEquals(-13, TestFunctionPrototypeApplyReceiver(MathMin, -13, 42)); assertEquals(-4, TestFunctionPrototypeApplyReceiver(MathMin, 3, -4)); %OptimizeFunctionOnNextCall(TestFunctionPrototypeApplyReceiver); assertEquals(7, TestFunctionPrototypeApplyReceiver(MathMin, 7, 9)); assertOptimized(TestFunctionPrototypeApplyReceiver); TestFunctionPrototypeApplyReceiver(MathMin, "abc"); assertUnoptimized(TestFunctionPrototypeApplyReceiver); // Testing: FunctionPrototypeApply with non-HeapConstant Receiver won't cause // deopt loop (function() { var F; function foo() { return F.apply(null, arguments); } function test(x, y) { return foo(x, y); } F = Math.min; %PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(test); assertEquals(-13, test(-13, 42)); %OptimizeFunctionOnNextCall(test); assertEquals(-13, test(-13, 42)); assertOptimized(test); %PrepareFunctionForOptimization(test); F = Math.max; assertEquals(42, test(-13, 42)); assertUnoptimized(test); %OptimizeFunctionOnNextCall(test); assertEquals(42, test(-13, 42)); F = Math.min; assertEquals(-13, test(-13, 42)); assertOptimized(test); })(); // Testing: FunctionPrototypeCall function TestFunctionPrototypeCall(x) { return mathAbs.call(undefined, x); } %PrepareFunctionForOptimization(TestFunctionPrototypeCall); TestFunctionPrototypeCall(42); TestFunctionPrototypeCall(52); %OptimizeFunctionOnNextCall(TestFunctionPrototypeCall); TestFunctionPrototypeCall(12); assertOptimized(TestFunctionPrototypeCall); TestFunctionPrototypeCall("abc"); assertUnoptimized(TestFunctionPrototypeCall); // Testing: ArrayForEach function TestArrayForEach(x) { x.forEach(mathAbs); } %PrepareFunctionForOptimization(TestArrayForEach); TestArrayForEach([1, 3, -4]); TestArrayForEach([-9, 9, 0]); %OptimizeFunctionOnNextCall(TestArrayForEach); TestArrayForEach([1, 3, -4]); assertOptimized(TestArrayForEach); TestArrayForEach(["abc", "xy"]); assertUnoptimized(TestArrayForEach); // Testing: ArrayReduce function TestArrayReduce(x) { return x.reduce(mathImul); } %PrepareFunctionForOptimization(TestArrayReduce); assertEquals(TestArrayReduce([1, 2, -3, 4]), -24); assertEquals(TestArrayReduce([3, 5, 7]), 105); %OptimizeFunctionOnNextCall(TestArrayReduce); assertEquals(TestArrayReduce([1, 2, -3, 4]), -24); assertOptimized(TestArrayReduce); TestArrayReduce(["abc", "xy"]); assertUnoptimized(TestArrayReduce); // Testing: ArrayReduceRight function TestArrayReduceRight(x) { return x.reduceRight(mathImul); } %PrepareFunctionForOptimization(TestArrayReduceRight); assertEquals(TestArrayReduceRight([1, 2, -3, 4]), -24); assertEquals(TestArrayReduceRight([3, 5, 7]), 105); %OptimizeFunctionOnNextCall(TestArrayReduceRight); assertEquals(TestArrayReduceRight([1, 2, -3, 4]), -24); assertOptimized(TestArrayReduceRight); TestArrayReduceRight(["abc", "xy"]); assertUnoptimized(TestArrayReduceRight); // Testing: ArrayMap function TestArrayMap(x) { return x.map(mathAbs); } %PrepareFunctionForOptimization(TestArrayMap); assertEquals(TestArrayMap([1, -2, -3, 4]), [1, 2, 3, 4]); assertEquals(TestArrayMap([5, -5, 5, -5]), [5, 5, 5, 5]); %OptimizeFunctionOnNextCall(TestArrayMap); assertEquals(TestArrayMap([1, -2, 3, -4]), [1, 2, 3, 4]); assertOptimized(TestArrayMap); TestArrayMap(["abc", "xy"]); assertUnoptimized(TestArrayMap); // Testing: ArrayFilter function TestArrayFilter(x) { return x.filter(mathAbs); } %PrepareFunctionForOptimization(TestArrayFilter); assertEquals(TestArrayFilter([-2, 0, 3, -4]), [-2, 3, -4]); assertEquals(TestArrayFilter([0, 1, 1, 0]), [1, 1]); %OptimizeFunctionOnNextCall(TestArrayFilter); assertEquals(TestArrayFilter([-2, 0, 3, -4]), [-2, 3, -4]); assertOptimized(TestArrayFilter); TestArrayFilter(["abc", "xy"]); assertUnoptimized(TestArrayFilter); // Testing: ArrayFind function TestArrayFind(x) { return x.find(mathAbs); } %PrepareFunctionForOptimization(TestArrayFind); assertEquals(TestArrayFind([0, 0, -3, 12]), -3); assertEquals(TestArrayFind([0, -18]), -18); %OptimizeFunctionOnNextCall(TestArrayFind); assertEquals(TestArrayFind([0, 0, -3, 12]), -3); assertOptimized(TestArrayFind); TestArrayFind(["", "abc", "xy"]); assertUnoptimized(TestArrayFind); // Testing: ArrayFindIndex function TestArrayFindIndex(x) { return x.findIndex(mathAbs); } %PrepareFunctionForOptimization(TestArrayFindIndex); assertEquals(TestArrayFindIndex([0, 0, -3, 12]), 2); assertEquals(TestArrayFindIndex([0, -18]), 1); %OptimizeFunctionOnNextCall(TestArrayFindIndex); assertEquals(TestArrayFindIndex([0, 0, -3, 12]), 2); assertOptimized(TestArrayFindIndex); TestArrayFindIndex(["", "abc", "xy"]); assertUnoptimized(TestArrayFindIndex); // Testing: ArrayEvery function TestArrayEvery(x) { return x.every(mathAbs); } %PrepareFunctionForOptimization(TestArrayEvery); assertEquals(TestArrayEvery([3, 0, -9]), false); assertEquals(TestArrayEvery([2, 12, -1]), true); %OptimizeFunctionOnNextCall(TestArrayEvery); assertEquals(TestArrayEvery([3, 0, -9]), false); assertOptimized(TestArrayEvery); TestArrayEvery(["abc", "xy"]); assertUnoptimized(TestArrayEvery); // Testing: ArraySome function TestArraySome(x) { return x.some(mathAbs); } %PrepareFunctionForOptimization(TestArraySome); assertEquals(TestArraySome([3, 0, -9]), true); assertEquals(TestArraySome([0, 0]), false); %OptimizeFunctionOnNextCall(TestArraySome); assertEquals(TestArraySome([3, 0, -9]), true); assertOptimized(TestArraySome); TestArraySome(["abc", "xy"]); assertUnoptimized(TestArraySome); // Testing: JSCall (JSFunction) const boundMathImul = mathImul.bind(undefined, -3); function TestJSCallWithJSFunction(x) { return boundMathImul(x); } %PrepareFunctionForOptimization(TestJSCallWithJSFunction); assertEquals(TestJSCallWithJSFunction(-14), 42); assertEquals(TestJSCallWithJSFunction(14), -42); %OptimizeFunctionOnNextCall(TestJSCallWithJSFunction); assertEquals(TestJSCallWithJSFunction(-14), 42); assertOptimized(TestJSCallWithJSFunction); TestJSCallWithJSFunction("abc"); assertUnoptimized(TestJSCallWithJSFunction); // Testing: JSCall (JSBoundFunction) function TestJSCallWithJSBoundFunction(x) { return mathImul.bind(undefined, -3)(x); } %PrepareFunctionForOptimization(TestJSCallWithJSBoundFunction); assertEquals(TestJSCallWithJSBoundFunction(-14), 42); assertEquals(TestJSCallWithJSBoundFunction(14), -42); %OptimizeFunctionOnNextCall(TestJSCallWithJSBoundFunction); assertEquals(TestJSCallWithJSBoundFunction(-14), 42); assertOptimized(TestJSCallWithJSBoundFunction); TestJSCallWithJSBoundFunction("abc"); assertUnoptimized(TestJSCallWithJSBoundFunction); // Testing: ReflectApply function TestReflectApplyHelper() { return Reflect.apply(mathAbs, undefined, arguments); } function TestReflectApply(x) { return TestReflectApplyHelper(x); } %PrepareFunctionForOptimization(TestReflectApplyHelper); %PrepareFunctionForOptimization(TestReflectApply); assertEquals(TestReflectApply(-9), 9); assertEquals(TestReflectApply(7), 7); %OptimizeFunctionOnNextCall(TestReflectApply); assertEquals(TestReflectApply(-9), 9); assertOptimized(TestReflectApply); TestReflectApply("abc"); assertUnoptimized(TestReflectApply); // Testing: CallWithSpread function TestCallWithSpreadHelper() { return mathImul(...arguments); } function TestCallWithSpread(x) { return TestCallWithSpreadHelper(x, x); } %PrepareFunctionForOptimization(TestCallWithSpreadHelper); %PrepareFunctionForOptimization(TestCallWithSpread); assertEquals(TestCallWithSpread(-13), 169); assertEquals(TestCallWithSpread(7), 49); %OptimizeFunctionOnNextCall(TestCallWithSpread); assertEquals(TestCallWithSpread(-13), 169); assertOptimized(TestCallWithSpread); TestCallWithSpread("abc"); assertUnoptimized(TestCallWithSpread);