[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}
This commit is contained in:
parent
15c0c3a8ba
commit
ccbbdb93a1
@ -756,6 +756,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>( // --
|
||||
@ -776,6 +778,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>( // --
|
||||
|
@ -677,12 +677,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.
|
||||
|
84
test/mjsunit/default-nospec.js
Normal file
84
test/mjsunit/default-nospec.js
Normal file
@ -0,0 +1,84 @@
|
||||
// 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());
|
||||
@ -253,9 +267,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());
|
||||
@ -272,9 +285,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());
|
||||
@ -288,9 +300,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());
|
||||
@ -305,9 +316,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());
|
||||
@ -325,9 +335,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());
|
||||
@ -341,9 +350,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());
|
||||
@ -359,9 +367,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());
|
||||
|
Loading…
Reference in New Issue
Block a user