Commit ccbbdb93 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[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: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51467}
parent 15c0c3a8
...@@ -756,6 +756,8 @@ const Operator* JSOperatorBuilder::Call(size_t arity, CallFrequency frequency, ...@@ -756,6 +756,8 @@ const Operator* JSOperatorBuilder::Call(size_t arity, CallFrequency frequency,
VectorSlotPair const& feedback, VectorSlotPair const& feedback,
ConvertReceiverMode convert_mode, ConvertReceiverMode convert_mode,
SpeculationMode speculation_mode) { SpeculationMode speculation_mode) {
DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
feedback.IsValid());
CallParameters parameters(arity, frequency, feedback, convert_mode, CallParameters parameters(arity, frequency, feedback, convert_mode,
speculation_mode); speculation_mode);
return new (zone()) Operator1<CallParameters>( // -- return new (zone()) Operator1<CallParameters>( // --
...@@ -776,6 +778,8 @@ const Operator* JSOperatorBuilder::CallWithArrayLike(CallFrequency frequency) { ...@@ -776,6 +778,8 @@ const Operator* JSOperatorBuilder::CallWithArrayLike(CallFrequency frequency) {
const Operator* JSOperatorBuilder::CallWithSpread( const Operator* JSOperatorBuilder::CallWithSpread(
uint32_t arity, CallFrequency frequency, VectorSlotPair const& feedback, uint32_t arity, CallFrequency frequency, VectorSlotPair const& feedback,
SpeculationMode speculation_mode) { SpeculationMode speculation_mode) {
DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
feedback.IsValid());
CallParameters parameters(arity, frequency, feedback, CallParameters parameters(arity, frequency, feedback,
ConvertReceiverMode::kAny, speculation_mode); ConvertReceiverMode::kAny, speculation_mode);
return new (zone()) Operator1<CallParameters>( // -- return new (zone()) Operator1<CallParameters>( // --
......
...@@ -677,12 +677,12 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -677,12 +677,12 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
size_t arity, CallFrequency frequency = CallFrequency(), size_t arity, CallFrequency frequency = CallFrequency(),
VectorSlotPair const& feedback = VectorSlotPair(), VectorSlotPair const& feedback = VectorSlotPair(),
ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny, ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
SpeculationMode speculation_mode = SpeculationMode::kAllowSpeculation); SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation);
const Operator* CallWithArrayLike(CallFrequency frequency); const Operator* CallWithArrayLike(CallFrequency frequency);
const Operator* CallWithSpread( const Operator* CallWithSpread(
uint32_t arity, CallFrequency frequency = CallFrequency(), uint32_t arity, CallFrequency frequency = CallFrequency(),
VectorSlotPair const& feedback = VectorSlotPair(), 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);
const Operator* CallRuntime(Runtime::FunctionId id, size_t arity); const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
const Operator* CallRuntime(const Runtime::Function* function, size_t arity); const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
......
...@@ -1753,7 +1753,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) { ...@@ -1753,7 +1753,7 @@ Reduction JSTypedLowering::ReduceJSCall(Node* node) {
if (p.convert_mode() != convert_mode) { if (p.convert_mode() != convert_mode) {
NodeProperties::ChangeOp( NodeProperties::ChangeOp(
node, javascript()->Call(p.arity(), p.frequency(), p.feedback(), node, javascript()->Call(p.arity(), p.frequency(), p.feedback(),
convert_mode)); convert_mode, p.speculation_mode()));
return Changed(node); return Changed(node);
} }
......
...@@ -206,8 +206,8 @@ class FeedbackVector : public HeapObject { ...@@ -206,8 +206,8 @@ class FeedbackVector : public HeapObject {
FeedbackSlot GetTypeProfileSlot() const; FeedbackSlot GetTypeProfileSlot() const;
static Handle<FeedbackVector> New(Isolate* isolate, V8_EXPORT_PRIVATE static Handle<FeedbackVector> New(
Handle<SharedFunctionInfo> shared); Isolate* isolate, Handle<SharedFunctionInfo> shared);
static Handle<FeedbackVector> Copy(Isolate* isolate, static Handle<FeedbackVector> Copy(Isolate* isolate,
Handle<FeedbackVector> vector); Handle<FeedbackVector> vector);
...@@ -431,8 +431,8 @@ class FeedbackMetadata : public FixedArray { ...@@ -431,8 +431,8 @@ class FeedbackMetadata : public FixedArray {
FeedbackSlotKind GetKind(FeedbackSlot slot) const; FeedbackSlotKind GetKind(FeedbackSlot slot) const;
// If {spec} is null, then it is considered empty. // If {spec} is null, then it is considered empty.
static Handle<FeedbackMetadata> New(Isolate* isolate, V8_EXPORT_PRIVATE static Handle<FeedbackMetadata> New(
const FeedbackVectorSpec* spec = nullptr); Isolate* isolate, const FeedbackVectorSpec* spec = nullptr);
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
// For gdb debugging. // 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 @@ ...@@ -8,6 +8,8 @@
#include "src/compiler/js-call-reducer.h" #include "src/compiler/js-call-reducer.h"
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
#include "src/factory.h"
#include "src/feedback-vector.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "test/unittests/compiler/graph-unittest.h" #include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h" #include "test/unittests/compiler/node-test-utils.h"
...@@ -72,6 +74,21 @@ class JSCallReducerTest : public TypedGraphTest { ...@@ -72,6 +74,21 @@ class JSCallReducerTest : public TypedGraphTest {
string_fnc.substr(1, std::string::npos); 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: private:
JSOperatorBuilder javascript_; JSOperatorBuilder javascript_;
CompilationDependencies deps_; CompilationDependencies deps_;
...@@ -180,9 +197,8 @@ TEST_F(JSCallReducerTest, MathUnaryWithNumber) { ...@@ -180,9 +197,8 @@ TEST_F(JSCallReducerTest, MathUnaryWithNumber) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* jsfunction = MathFunction(fnc); Node* jsfunction = MathFunction(fnc);
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* call = Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
p0, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())), EXPECT_THAT(std::string(IrOpcode::Mnemonic(r.replacement()->opcode())),
...@@ -209,9 +225,8 @@ TEST_F(JSCallReducerTest, MathBinaryWithNumber) { ...@@ -209,9 +225,8 @@ TEST_F(JSCallReducerTest, MathBinaryWithNumber) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 0); Node* p1 = Parameter(Type::Any(), 0);
Node* call = Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(), p1, context, frame_state, effect, control);
p0, p1, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -231,9 +246,8 @@ TEST_F(JSCallReducerTest, MathClz32WithUnsigned32) { ...@@ -231,9 +246,8 @@ TEST_F(JSCallReducerTest, MathClz32WithUnsigned32) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Unsigned32(), 0); Node* p0 = Parameter(Type::Unsigned32(), 0);
Node* call = Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
p0, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -253,9 +267,8 @@ TEST_F(JSCallReducerTest, MathImulWithUnsigned32) { ...@@ -253,9 +267,8 @@ TEST_F(JSCallReducerTest, MathImulWithUnsigned32) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Unsigned32(), 0); Node* p0 = Parameter(Type::Unsigned32(), 0);
Node* p1 = Parameter(Type::Unsigned32(), 1); Node* p1 = Parameter(Type::Unsigned32(), 1);
Node* call = Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(), p1, context, frame_state, effect, control);
p0, p1, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -272,9 +285,8 @@ TEST_F(JSCallReducerTest, MathMinWithNoArguments) { ...@@ -272,9 +285,8 @@ TEST_F(JSCallReducerTest, MathMinWithNoArguments) {
Node* control = graph()->start(); Node* control = graph()->start();
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* call = Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
graph()->NewNode(javascript()->Call(2), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -288,9 +300,8 @@ TEST_F(JSCallReducerTest, MathMinWithNumber) { ...@@ -288,9 +300,8 @@ TEST_F(JSCallReducerTest, MathMinWithNumber) {
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* call = Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
p0, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -305,9 +316,8 @@ TEST_F(JSCallReducerTest, MathMinWithTwoArguments) { ...@@ -305,9 +316,8 @@ TEST_F(JSCallReducerTest, MathMinWithTwoArguments) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 1); Node* p1 = Parameter(Type::Any(), 1);
Node* call = Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(), p1, context, frame_state, effect, control);
p0, p1, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -325,9 +335,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNoArguments) { ...@@ -325,9 +335,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNoArguments) {
Node* control = graph()->start(); Node* control = graph()->start();
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* call = Node* call = graph()->NewNode(Call(2), jsfunction, UndefinedConstant(),
graph()->NewNode(javascript()->Call(2), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -341,9 +350,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNumber) { ...@@ -341,9 +350,8 @@ TEST_F(JSCallReducerTest, MathMaxWithNumber) {
Node* context = UndefinedConstant(); Node* context = UndefinedConstant();
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* call = Node* call = graph()->NewNode(Call(3), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(3), jsfunction, UndefinedConstant(), context, frame_state, effect, control);
p0, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
...@@ -359,9 +367,8 @@ TEST_F(JSCallReducerTest, MathMaxWithTwoArguments) { ...@@ -359,9 +367,8 @@ TEST_F(JSCallReducerTest, MathMaxWithTwoArguments) {
Node* frame_state = graph()->start(); Node* frame_state = graph()->start();
Node* p0 = Parameter(Type::Any(), 0); Node* p0 = Parameter(Type::Any(), 0);
Node* p1 = Parameter(Type::Any(), 1); Node* p1 = Parameter(Type::Any(), 1);
Node* call = Node* call = graph()->NewNode(Call(4), jsfunction, UndefinedConstant(), p0,
graph()->NewNode(javascript()->Call(4), jsfunction, UndefinedConstant(), p1, context, frame_state, effect, control);
p0, p1, context, frame_state, effect, control);
Reduction r = Reduce(call); Reduction r = Reduce(call);
ASSERT_TRUE(r.Changed()); 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