[crankshaft] Always force number representation for increment.

BUG=chromium:664087

Review-Url: https://codereview.chromium.org/2491333002
Cr-Commit-Position: refs/heads/master@{#40900}
This commit is contained in:
jarin 2016-11-10 06:50:57 -08:00 committed by Commit bot
parent 6f4464ecb6
commit c71e5e1294
3 changed files with 34 additions and 19 deletions

View File

@ -10386,28 +10386,23 @@ static Representation RepresentationFor(AstType* type) {
return Representation::Tagged();
}
HInstruction* HOptimizedGraphBuilder::BuildIncrement(
bool returns_original_input,
CountOperation* expr) {
HInstruction* HOptimizedGraphBuilder::BuildIncrement(CountOperation* expr) {
// The input to the count operation is on top of the expression stack.
Representation rep = RepresentationFor(expr->type());
if (rep.IsNone() || rep.IsTagged()) {
rep = Representation::Smi();
}
if (returns_original_input) {
// We need an explicit HValue representing ToNumber(input). The
// actual HChange instruction we need is (sometimes) added in a later
// phase, so it is not available now to be used as an input to HAdd and
// as the return value.
HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep);
if (!rep.IsDouble()) {
number_input->SetFlag(HInstruction::kFlexibleRepresentation);
number_input->SetFlag(HInstruction::kCannotBeTagged);
}
Push(number_input);
// We need an explicit HValue representing ToNumber(input). The
// actual HChange instruction we need is (sometimes) added in a later
// phase, so it is not available now to be used as an input to HAdd and
// as the return value.
HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep);
if (!rep.IsDouble()) {
number_input->SetFlag(HInstruction::kFlexibleRepresentation);
number_input->SetFlag(HInstruction::kCannotBeTagged);
}
Push(number_input);
// The addition has no side effects, so we do not need
// to simulate the expression stack after this instruction.
@ -10466,7 +10461,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
DCHECK(prop == NULL);
CHECK_ALIVE(VisitForValue(target));
after = BuildIncrement(returns_original_input, expr);
after = BuildIncrement(expr);
input = returns_original_input ? Top() : Pop();
Push(after);
@ -10519,7 +10514,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
CHECK_ALIVE(PushLoad(prop, object, key));
after = BuildIncrement(returns_original_input, expr);
after = BuildIncrement(expr);
if (returns_original_input) {
input = Pop();

View File

@ -2687,8 +2687,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
HValue* left,
HValue* right,
PushBeforeSimulateBehavior push_sim_result);
HInstruction* BuildIncrement(bool returns_original_input,
CountOperation* expr);
HInstruction* BuildIncrement(CountOperation* expr);
HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
Expression* expr, FeedbackVectorSlot slot,
HValue* object, HValue* key, HValue* value);

View File

@ -0,0 +1,21 @@
// 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
function g() {
throw 1;
}
var v = { valueOf : g };
function foo(v) {
v++;
}
%NeverOptimizeFunction(g);
assertThrows(function () { foo(v); });
assertThrows(function () { foo(v); });
%OptimizeFunctionOnNextCall(foo);
assertThrows(function () { foo(v); });