Commit eb502fe5 authored by jarin@chromium.org's avatar jarin@chromium.org

Binary operation deoptimization fix.

R=jkummerow@chromium.org
BUG=

Review URL: https://codereview.chromium.org/132453009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6df537d6
...@@ -5980,7 +5980,8 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { ...@@ -5980,7 +5980,8 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
HValue* right = Pop(); HValue* right = Pop();
HValue* left = Pop(); HValue* left = Pop();
Push(BuildBinaryOperation(operation, left, right)); Push(BuildBinaryOperation(operation, left, right, PUSH_BEFORE_SIMULATE));
BuildStore(expr, prop, expr->id(), BuildStore(expr, prop, expr->id(),
expr->AssignmentId(), expr->IsUninitialized()); expr->AssignmentId(), expr->IsUninitialized());
} else { } else {
...@@ -9056,7 +9057,8 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) { ...@@ -9056,7 +9057,8 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) {
HValue* HOptimizedGraphBuilder::BuildBinaryOperation( HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
BinaryOperation* expr, BinaryOperation* expr,
HValue* left, HValue* left,
HValue* right) { HValue* right,
PushBeforeSimulateBehavior push_sim_result) {
Type* left_type = expr->left()->bounds().lower; Type* left_type = expr->left()->bounds().lower;
Type* right_type = expr->right()->bounds().lower; Type* right_type = expr->right()->bounds().lower;
Type* result_type = expr->bounds().lower; Type* result_type = expr->bounds().lower;
...@@ -9080,10 +9082,15 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation( ...@@ -9080,10 +9082,15 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
// after phis, which are the result of BuildBinaryOperation when we // after phis, which are the result of BuildBinaryOperation when we
// inlined some complex subgraph. // inlined some complex subgraph.
if (result->HasObservableSideEffects() || result->IsPhi()) { if (result->HasObservableSideEffects() || result->IsPhi()) {
if (push_sim_result == NO_PUSH_BEFORE_SIMULATE) {
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
} else {
ASSERT(push_sim_result == PUSH_BEFORE_SIMULATE);
Push(result); Push(result);
Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
Drop(1); Drop(1);
} }
}
return result; return result;
} }
...@@ -9462,7 +9469,10 @@ void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { ...@@ -9462,7 +9469,10 @@ void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
HValue* right = Pop(); HValue* right = Pop();
HValue* left = Pop(); HValue* left = Pop();
HValue* result = BuildBinaryOperation(expr, left, right); HValue* result =
BuildBinaryOperation(expr, left, right,
ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE
: PUSH_BEFORE_SIMULATE);
if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) {
HBinaryOperation::cast(result)->SetOperandPositions( HBinaryOperation::cast(result)->SetOperandPositions(
zone(), expr->left()->position(), expr->right()->position()); zone(), expr->left()->position(), expr->right()->position());
......
...@@ -2435,9 +2435,16 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { ...@@ -2435,9 +2435,16 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
HInstruction* BuildStringCharCodeAt(HValue* string, HInstruction* BuildStringCharCodeAt(HValue* string,
HValue* index); HValue* index);
HValue* BuildBinaryOperation(BinaryOperation* expr,
enum PushBeforeSimulateBehavior {
PUSH_BEFORE_SIMULATE,
NO_PUSH_BEFORE_SIMULATE
};
HValue* BuildBinaryOperation(
BinaryOperation* expr,
HValue* left, HValue* left,
HValue* right); HValue* right,
PushBeforeSimulateBehavior push_sim_result);
HInstruction* BuildIncrement(bool returns_original_input, HInstruction* BuildIncrement(bool returns_original_input,
CountOperation* expr); CountOperation* expr);
HInstruction* BuildLoadKeyedGeneric(HValue* object, HInstruction* BuildLoadKeyedGeneric(HValue* object,
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
(function BinopInEffectContextDeoptAndOsr() {
function f(a, deopt, osr) {
var result = (a + 10, "result");
var dummy = deopt + 0;
if (osr) while (%GetOptimizationStatus(f) == 2) {}
return result;
}
assertEquals("result", f(true, 3, false));
assertEquals("result", f(true, 3, false));
%OptimizeFunctionOnNextCall(f);
assertEquals("result", f(true, "foo", true));
})();
(function BinopInEffectContextLazyDeopt() {
function deopt_f() {
%DeoptimizeFunction(f);
return "dummy";
}
function h() {
return { toString : deopt_f };
}
function g(x) {
}
function f() {
return g(void(h() + ""));
};
f();
%OptimizeFunctionOnNextCall(f);
f();
})();
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