[turbofan] Optimize store to typed arrays only if the value is plain primitive.
BUG=v8:5756 Review-Url: https://codereview.chromium.org/2596843002 Cr-Commit-Position: refs/heads/master@{#41942}
This commit is contained in:
parent
0d5561b64d
commit
e92118bbc2
@ -1254,6 +1254,9 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
|
||||
Node* value = NodeProperties::GetValueInput(node, 2);
|
||||
Type* key_type = NodeProperties::GetType(key);
|
||||
Type* value_type = NodeProperties::GetType(value);
|
||||
|
||||
if (!value_type->Is(Type::PlainPrimitive())) return NoChange();
|
||||
|
||||
HeapObjectMatcher mbase(base);
|
||||
if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
|
||||
Handle<JSTypedArray> const array =
|
||||
@ -1272,7 +1275,6 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
|
||||
Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
|
||||
Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
|
||||
Node* length = jsgraph()->Constant(byte_length);
|
||||
Node* context = NodeProperties::GetContextInput(node);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
// Convert to a number first.
|
||||
@ -1281,12 +1283,8 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
|
||||
if (number_reduction.Changed()) {
|
||||
value = number_reduction.replacement();
|
||||
} else {
|
||||
Node* frame_state_for_to_number =
|
||||
NodeProperties::FindFrameStateBefore(node);
|
||||
value = effect =
|
||||
graph()->NewNode(javascript()->ToNumber(), value, context,
|
||||
frame_state_for_to_number, effect, control);
|
||||
control = graph()->NewNode(common()->IfSuccess(), value);
|
||||
value =
|
||||
graph()->NewNode(simplified()->PlainPrimitiveToNumber(), value);
|
||||
}
|
||||
}
|
||||
// Check if we can avoid the bounds check.
|
||||
|
31
test/mjsunit/compiler/regress-v8-5756.js
Normal file
31
test/mjsunit/compiler/regress-v8-5756.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2016 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
|
||||
|
||||
z = {};
|
||||
t = new Uint8Array(3);
|
||||
var m = 0;
|
||||
var x = 10;
|
||||
|
||||
function k() {
|
||||
++m;
|
||||
if (m % 10 != 9) {
|
||||
if (m > 20) // This if is to just force it to deoptimize.
|
||||
x = '1'; // this deoptimizes during the second invocation of k.
|
||||
// This causes two deopts, one eager at x = 1 and the
|
||||
// other lazy at t[2] = z.
|
||||
t[2] = z; // since we are assigning to Uint8Array, ToNumber
|
||||
// is called which calls this funciton again.
|
||||
}
|
||||
}
|
||||
|
||||
function f1() {
|
||||
z.toString = k;
|
||||
z.toString();
|
||||
z.toString();
|
||||
%OptimizeFunctionOnNextCall(k);
|
||||
z.toString();
|
||||
}
|
||||
f1();
|
@ -717,7 +717,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
||||
Node* key = Parameter(
|
||||
Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
|
||||
Node* base = HeapConstant(array);
|
||||
Node* value = Parameter(Type::Any());
|
||||
Node* value = Parameter(Type::PlainPrimitive());
|
||||
Node* context = UndefinedConstant();
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
@ -737,10 +737,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
||||
: IsNumberShiftLeft(
|
||||
key, IsNumberConstant(WhichPowerOf2(element_size)));
|
||||
|
||||
Matcher<Node*> value_matcher =
|
||||
IsToNumber(value, context, checkpoint, control);
|
||||
Matcher<Node*> effect_matcher = value_matcher;
|
||||
Matcher<Node*> control_matcher = IsIfSuccess(value_matcher);
|
||||
Matcher<Node*> value_matcher = IsPlainPrimitiveToNumber(value);
|
||||
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
@ -749,7 +746,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
|
||||
BufferAccess(type),
|
||||
IsPointerConstant(bit_cast<intptr_t>(&backing_store[0])),
|
||||
offset_matcher, IsNumberConstant(array->byte_length()->Number()),
|
||||
value_matcher, effect_matcher, control_matcher));
|
||||
value_matcher, checkpoint, control));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user