[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:
jarin 2016-12-23 06:29:00 -08:00 committed by Commit bot
parent 0d5561b64d
commit e92118bbc2
3 changed files with 39 additions and 13 deletions

View File

@ -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.

View 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();

View File

@ -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));
}
}
}