Commit 6be614fb authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

Reland "[turbofan] Disable speculation for JSCall nodes by default"

This is a reland of ccbbdb93.

Original change's description:
> [turbofan] Disable speculation for JSCall nodes by default
>
> Change-Id: I7360601f4e1b419cf8d35480b068418bdd700be9
> Reviewed-on: https://chromium-review.googlesource.com/928649
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#51467}

Bug: v8:7340

Change-Id: I5557afcdad0c7f9610a396dcfa45f8985a13c1ba
Reviewed-on: https://chromium-review.googlesource.com/931546Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51496}
parent 6e589034
......@@ -757,6 +757,8 @@ const Operator* JSOperatorBuilder::Call(size_t arity, CallFrequency frequency,
VectorSlotPair const& feedback,
ConvertReceiverMode convert_mode,
SpeculationMode speculation_mode) {
DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
feedback.IsValid());
CallParameters parameters(arity, frequency, feedback, convert_mode,
speculation_mode);
return new (zone()) Operator1<CallParameters>( // --
......@@ -777,6 +779,8 @@ const Operator* JSOperatorBuilder::CallWithArrayLike(CallFrequency frequency) {
const Operator* JSOperatorBuilder::CallWithSpread(
uint32_t arity, CallFrequency frequency, VectorSlotPair const& feedback,
SpeculationMode speculation_mode) {
DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
feedback.IsValid());
CallParameters parameters(arity, frequency, feedback,
ConvertReceiverMode::kAny, speculation_mode);
return new (zone()) Operator1<CallParameters>( // --
......
......@@ -679,12 +679,12 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
size_t arity, CallFrequency frequency = CallFrequency(),
VectorSlotPair const& feedback = VectorSlotPair(),
ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
SpeculationMode speculation_mode = SpeculationMode::kAllowSpeculation);
SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation);
const Operator* CallWithArrayLike(CallFrequency frequency);
const Operator* CallWithSpread(
uint32_t arity, CallFrequency frequency = CallFrequency(),
VectorSlotPair const& feedback = VectorSlotPair(),
SpeculationMode speculation_mode = SpeculationMode::kAllowSpeculation);
SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation);
const Operator* CallRuntime(Runtime::FunctionId id);
const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
......
......@@ -1753,7 +1753,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
if (p.convert_mode() != convert_mode) {
NodeProperties::ChangeOp(
node, javascript()->Call(p.arity(), p.frequency(), p.feedback(),
convert_mode));
convert_mode, p.speculation_mode()));
return Changed(node);
}
......
......@@ -206,8 +206,8 @@ class FeedbackVector : public HeapObject {
FeedbackSlot GetTypeProfileSlot() const;
static Handle<FeedbackVector> New(Isolate* isolate,
Handle<SharedFunctionInfo> shared);
V8_EXPORT_PRIVATE static Handle<FeedbackVector> New(
Isolate* isolate, Handle<SharedFunctionInfo> shared);
static Handle<FeedbackVector> Copy(Isolate* isolate,
Handle<FeedbackVector> vector);
......@@ -431,8 +431,8 @@ class FeedbackMetadata : public FixedArray {
FeedbackSlotKind GetKind(FeedbackSlot slot) const;
// If {spec} is null, then it is considered empty.
static Handle<FeedbackMetadata> New(Isolate* isolate,
const FeedbackVectorSpec* spec = nullptr);
V8_EXPORT_PRIVATE static Handle<FeedbackMetadata> New(
Isolate* isolate, const FeedbackVectorSpec* spec = nullptr);
#ifdef OBJECT_PRINT
// For gdb debugging.
......
// Copyright 2018 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 --opt --no-always-opt
(()=> {
function f(a, b, c) {
return String.prototype.indexOf.call(a, b, c);
}
f("abc", "de", 1);
f("abc", "de", 1);
%OptimizeFunctionOnNextCall(f);
f("abc", "de", {});
%OptimizeFunctionOnNextCall(f);
f("abc", "de", {});
assertOptimized(f);
})();
(()=> {
function f(a, b, c) {
return String.prototype.indexOf.apply(a, [b, c]);
}
f("abc", "de", 1);
f("abc", "de", 1);
%OptimizeFunctionOnNextCall(f);
f("abc", {}, 1);
%OptimizeFunctionOnNextCall(f);
f("abc", {}, 1);
assertOptimized(f);
})();
(()=> {
function f(a, b, c) {
return Reflect.apply(String.prototype.indexOf, a, [b, c]);
}
f("abc", "de", 1);
f("abc", "de", 1);
%OptimizeFunctionOnNextCall(f);
f({}, "de", 1);
%OptimizeFunctionOnNextCall(f);
f({}, "de", 1);
assertOptimized(f);
})();
(()=> {
function f(a, b) {
return String.fromCharCode.call(a, b);
}
f("abc", 1);
f("abc", 1);
%OptimizeFunctionOnNextCall(f);
f("abc", {});
%OptimizeFunctionOnNextCall(f);
f({}, {});
assertOptimized(f);
})();
(()=> {
function f(a, b) {
return String.fromCharCode.apply(undefined, [b, {}]);
}
f("abc", 1);
f("abc", 1);
%OptimizeFunctionOnNextCall(f);
f("abc", {});
%OptimizeFunctionOnNextCall(f);
f("abc", {});
assertOptimized(f);
})();
(()=> {
function f(a, b) {
return Reflect.apply(String.fromCharCode, a, [b, {}]);
}
f("abc", 1);
f("abc", 1);
%OptimizeFunctionOnNextCall(f);
f("abc", {});
%OptimizeFunctionOnNextCall(f);
f("abc", {});
assertOptimized(f);
})();
......@@ -8,6 +8,8 @@
#include "src/compiler/js-call-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/simplified-operator.h"
#include "src/factory.h"
#include "src/feedback-vector.h"
#include "src/isolate.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
......@@ -72,6 +74,21 @@ class JSCallReducerTest : public TypedGraphTest {
string_fnc.substr(1, std::string::npos);
}
const Operator* Call(int arity) {
FeedbackVectorSpec spec(zone());
spec.AddCallICSlot();
Handle<FeedbackMetadata> metadata = FeedbackMetadata::New(isolate(), &spec);
Handle<SharedFunctionInfo> shared =
isolate()->factory()->NewSharedFunctionInfo(
isolate()->factory()->empty_string(), MaybeHandle<Code>(), false);
shared->set_feedback_metadata(*metadata);
Handle<FeedbackVector> vector = FeedbackVector::New(isolate(), shared);
VectorSlotPair feedback(vector, FeedbackSlot(0));
return javascript()->Call(arity, CallFrequency(), feedback,
ConvertReceiverMode::kAny,
SpeculationMode::kAllowSpeculation);
}
private:
JSOperatorBuilder javascript_;
CompilationDependencies deps_;
......@@ -180,9 +197,8 @@ TEST_F(JSCallReducerTest, MathUnaryWithNumber) {
Node* frame_state = graph()->start();
Node* jsfunction = MathFunction(fnc);
Node* p0 = Parameter(Type::Any(), 0);
Node* call =
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(),
p0, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
......@@ -209,9 +225,8 @@ TEST_F(JSCallReducerTest, MathBinaryWithNumber) {
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 0);
Node* call =
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(),
p0, p1, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
p1, context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -231,9 +246,8 @@ TEST_F(JSCallReducerTest, MathClz32WithUnsigned32) {
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Unsigned32(), 0);
Node* call =
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(),
p0, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -248,9 +262,8 @@ TEST_F(JSCallReducerTest, MathClz32WithUnsigned32NoArg) {
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
Node* call =
graph()->NewNode(javascript()->Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -269,9 +282,8 @@ TEST_F(JSCallReducerTest, MathImulWithUnsigned32) {
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Unsigned32(), 0);
Node* p1 = Parameter(Type::Unsigned32(), 1);
Node* call =
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(),
p0, p1, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
p1, context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -288,9 +300,8 @@ TEST_F(JSCallReducerTest, MathMinWithNoArguments) {
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
Node* call =
graph()->NewNode(javascript()->Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -304,9 +315,8 @@ TEST_F(JSCallReducerTest, MathMinWithNumber) {
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0);
Node* call =
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(),
p0, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -321,9 +331,8 @@ TEST_F(JSCallReducerTest, MathMinWithTwoArguments) {
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 1);
Node* call =
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(),
p0, p1, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
p1, context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -341,9 +350,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNoArguments) {
Node* control = graph()->start();
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
Node* call =
graph()->NewNode(javascript()->Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -357,9 +365,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNumber) {
Node* context = UndefinedConstant();
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0);
Node* call =
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(),
p0, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......@@ -375,9 +382,8 @@ TEST_F(JSCallReducerTest, MathMaxWithTwoArguments) {
Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 1);
Node* call =
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(),
p0, p1, context, frame_state, effect, control);
Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
p1, context, frame_state, effect, control);
Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment