Revision: 8260
Author: [email protected]
Date: Fri Jun 10 04:33:25 2011
Log: Merge r8237 to V8 3.2 branch. Fix bug v8:1434, optimized compare
of undefined can fail.
Review URL: http://codereview.chromium.org/7134067
http://code.google.com/p/v8/source/detail?r=8260
Added:
/branches/3.2/test/mjsunit/regress/regress-1434.js
Modified:
/branches/3.2/src/arm/lithium-arm.h
/branches/3.2/src/arm/lithium-codegen-arm.cc
/branches/3.2/src/arm/lithium-codegen-arm.h
/branches/3.2/src/hydrogen-instructions.cc
/branches/3.2/src/hydrogen-instructions.h
/branches/3.2/src/hydrogen.cc
/branches/3.2/src/hydrogen.h
/branches/3.2/src/ia32/lithium-codegen-ia32.cc
/branches/3.2/src/ia32/lithium-codegen-ia32.h
/branches/3.2/src/ia32/lithium-ia32.h
/branches/3.2/src/version.cc
/branches/3.2/src/x64/lithium-codegen-x64.cc
/branches/3.2/src/x64/lithium-codegen-x64.h
/branches/3.2/src/x64/lithium-x64.h
=======================================
--- /dev/null
+++ /branches/3.2/test/mjsunit/regress/regress-1434.js Fri Jun 10 04:33:25
2011
@@ -0,0 +1,36 @@
+// Copyright 2011 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 compare(a, b) {
+ return a === b;
+}
+
+compare(1.5, 2.5);
+%OptimizeFunctionOnNextCall(compare);
+assertTrue(compare(undefined, undefined));
=======================================
--- /branches/3.2/src/arm/lithium-arm.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/arm/lithium-arm.h Fri Jun 10 04:33:25 2011
@@ -1583,6 +1583,7 @@
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
};
=======================================
--- /branches/3.2/src/arm/lithium-codegen-arm.cc Wed Apr 13 01:46:07 2011
+++ /branches/3.2/src/arm/lithium-codegen-arm.cc Fri Jun 10 04:33:25 2011
@@ -3560,6 +3560,7 @@
void LCodeGen::EmitNumberUntagD(Register input_reg,
DoubleRegister result_reg,
+ bool deoptimize_on_undefined,
LEnvironment* env) {
Register scratch = scratch0();
SwVfpRegister flt_scratch = s0;
@@ -3575,20 +3576,25 @@
__ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
__ cmp(scratch, Operand(ip));
- __ b(eq, &heap_number);
-
- __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
- __ cmp(input_reg, Operand(ip));
- DeoptimizeIf(ne, env);
-
- // Convert undefined to NaN.
- __ LoadRoot(ip, Heap::kNanValueRootIndex);
- __ sub(ip, ip, Operand(kHeapObjectTag));
- __ vldr(result_reg, ip, HeapNumber::kValueOffset);
- __ jmp(&done);
-
+ if (deoptimize_on_undefined) {
+ DeoptimizeIf(ne, env);
+ } else {
+ Label heap_number;
+ __ b(eq, &heap_number);
+
+ __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+ __ cmp(input_reg, Operand(ip));
+ DeoptimizeIf(ne, env);
+
+ // Convert undefined to NaN.
+ __ LoadRoot(ip, Heap::kNanValueRootIndex);
+ __ sub(ip, ip, Operand(kHeapObjectTag));
+ __ vldr(result_reg, ip, HeapNumber::kValueOffset);
+ __ jmp(&done);
+
+ __ bind(&heap_number);
+ }
// Heap number to double register conversion.
- __ bind(&heap_number);
__ sub(ip, input_reg, Operand(kHeapObjectTag));
__ vldr(result_reg, ip, HeapNumber::kValueOffset);
__ jmp(&done);
@@ -3717,7 +3723,9 @@
Register input_reg = ToRegister(input);
DoubleRegister result_reg = ToDoubleRegister(result);
- EmitNumberUntagD(input_reg, result_reg, instr->environment());
+ EmitNumberUntagD(input_reg, result_reg,
+ instr->hydrogen()->deoptimize_on_undefined(),
+ instr->environment());
}
=======================================
--- /branches/3.2/src/arm/lithium-codegen-arm.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/arm/lithium-codegen-arm.h Fri Jun 10 04:33:25 2011
@@ -262,6 +262,7 @@
void EmitCmpI(LOperand* left, LOperand* right);
void EmitNumberUntagD(Register input,
DoubleRegister result,
+ bool deoptimize_on_undefined,
LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
=======================================
--- /branches/3.2/src/hydrogen-instructions.cc Thu Jun 9 04:42:22 2011
+++ /branches/3.2/src/hydrogen-instructions.cc Fri Jun 10 04:33:25 2011
@@ -1157,6 +1157,10 @@
if (r.IsTagged()) {
SetAllSideEffects();
ClearFlag(kUseGVN);
+ } else if (r.IsDouble()) {
+ SetFlag(kDeoptimizeOnUndefined);
+ ClearAllSideEffects();
+ SetFlag(kUseGVN);
} else {
ClearAllSideEffects();
SetFlag(kUseGVN);
=======================================
--- /branches/3.2/src/hydrogen-instructions.h Thu Jun 9 04:42:22 2011
+++ /branches/3.2/src/hydrogen-instructions.h Fri Jun 10 04:33:25 2011
@@ -424,6 +424,7 @@
kCanOverflow,
kBailoutOnMinusZero,
kCanBeDivByZero,
+ kDeoptimizeOnUndefined,
kIsArguments,
kTruncatingToInt32,
kLastFlag = kTruncatingToInt32
@@ -938,8 +939,11 @@
HChange(HValue* value,
Representation from,
Representation to,
- bool is_truncating)
- : HUnaryOperation(value), from_(from) {
+ bool is_truncating,
+ bool deoptimize_on_undefined)
+ : HUnaryOperation(value),
+ from_(from),
+ deoptimize_on_undefined_(deoptimize_on_undefined) {
ASSERT(!from.IsNone() && !to.IsNone());
ASSERT(!from.Equals(to));
set_representation(to);
@@ -955,6 +959,7 @@
Representation from() const { return from_; }
Representation to() const { return representation(); }
+ bool deoptimize_on_undefined() const { return deoptimize_on_undefined_; }
virtual Representation RequiredInputRepresentation(int index) const {
return from_;
}
@@ -971,11 +976,13 @@
if (!other->IsChange()) return false;
HChange* change = HChange::cast(other);
return value() == change->value()
- && to().Equals(change->to());
+ && to().Equals(change->to())
+ && deoptimize_on_undefined() == change->deoptimize_on_undefined();
}
private:
Representation from_;
+ bool deoptimize_on_undefined_;
};
=======================================
--- /branches/3.2/src/hydrogen.cc Thu Jun 9 04:42:22 2011
+++ /branches/3.2/src/hydrogen.cc Fri Jun 10 04:33:25 2011
@@ -1765,6 +1765,7 @@
// change instructions for them.
HInstruction* new_value = NULL;
bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32);
+ bool deoptimize_on_undefined =
use->CheckFlag(HValue::kDeoptimizeOnUndefined);
if (value->IsConstant()) {
HConstant* constant = HConstant::cast(value);
// Try to create a new copy of the constant with the new
representation.
@@ -1774,8 +1775,8 @@
}
if (new_value == NULL) {
- new_value =
- new(zone()) HChange(value, value->representation(), to,
is_truncating);
+ new_value = new(zone()) HChange(value, value->representation(), to,
+ is_truncating,
deoptimize_on_undefined);
}
new_value->InsertBefore(next);
@@ -1914,6 +1915,41 @@
}
}
}
+
+
+void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) {
+ if (phi->CheckFlag(HValue::kDeoptimizeOnUndefined)) return;
+ phi->SetFlag(HValue::kDeoptimizeOnUndefined);
+ for (int i = 0; i < phi->OperandCount(); ++i) {
+ HValue* input = phi->OperandAt(i);
+ if (input->IsPhi()) {
+ RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input));
+ }
+ }
+}
+
+
+void HGraph::MarkDeoptimizeOnUndefined() {
+ HPhase phase("MarkDeoptimizeOnUndefined", this);
+ // Compute DeoptimizeOnUndefined flag for phis.
+ // Any phi that can reach a use with DeoptimizeOnUndefined set must
+ // have DeoptimizeOnUndefined set. Currently only HCompare, with
+ // double input representation, has this flag set.
+ // The flag is used by HChange tagged->double, which must deoptimize
+ // if one of its uses has this flag set.
+ for (int i = 0; i < phi_list()->length(); i++) {
+ HPhi* phi = phi_list()->at(i);
+ if (phi->representation().IsDouble()) {
+ for (int j = 0; j < phi->uses()->length(); j++) {
+ HValue* use = phi->uses()->at(j);
+ if (use->CheckFlag(HValue::kDeoptimizeOnUndefined)) {
+ RecursivelyMarkPhiDeoptimizeOnUndefined(phi);
+ break;
+ }
+ }
+ }
+ }
+}
void HGraph::ComputeMinusZeroChecks() {
@@ -2234,6 +2270,7 @@
graph()->InitializeInferredTypes();
graph()->Canonicalize();
+ graph()->MarkDeoptimizeOnUndefined();
graph()->InsertRepresentationChanges();
graph()->ComputeMinusZeroChecks();
=======================================
--- /branches/3.2/src/hydrogen.h Thu Jun 9 04:42:22 2011
+++ /branches/3.2/src/hydrogen.h Fri Jun 10 04:33:25 2011
@@ -214,6 +214,7 @@
void InitializeInferredTypes();
void InsertTypeConversions();
void InsertRepresentationChanges();
+ void MarkDeoptimizeOnUndefined();
void ComputeMinusZeroChecks();
bool ProcessArgumentsObject();
void EliminateRedundantPhis();
@@ -277,6 +278,7 @@
void InsertTypeConversions(HInstruction* instr);
void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
+ void RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi);
void InsertRepresentationChangeForUse(HValue* value,
HValue* use,
Representation to);
=======================================
--- /branches/3.2/src/ia32/lithium-codegen-ia32.cc Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/ia32/lithium-codegen-ia32.cc Fri Jun 10 04:33:25 2011
@@ -3424,8 +3424,9 @@
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
+ bool deoptimize_on_undefined,
LEnvironment* env) {
- NearLabel load_smi, heap_number, done;
+ NearLabel load_smi, done;
// Smi check.
__ test(input_reg, Immediate(kSmiTagMask));
@@ -3434,18 +3435,22 @@
// Heap number map check.
__ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
factory()->heap_number_map());
- __ j(equal, &heap_number);
-
- __ cmp(input_reg, factory()->undefined_value());
- DeoptimizeIf(not_equal, env);
-
- // Convert undefined to NaN.
- ExternalReference nan = ExternalReference::address_of_nan();
- __ movdbl(result_reg, Operand::StaticVariable(nan));
- __ jmp(&done);
-
+ if (deoptimize_on_undefined) {
+ DeoptimizeIf(not_equal, env);
+ } else {
+ NearLabel heap_number;
+ __ j(equal, &heap_number);
+ __ cmp(input_reg, factory()->undefined_value());
+ DeoptimizeIf(not_equal, env);
+
+ // Convert undefined to NaN.
+ ExternalReference nan = ExternalReference::address_of_nan();
+ __ movdbl(result_reg, Operand::StaticVariable(nan));
+ __ jmp(&done);
+
+ __ bind(&heap_number);
+ }
// Heap number to XMM conversion.
- __ bind(&heap_number);
__ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ jmp(&done);
@@ -3578,7 +3583,9 @@
Register input_reg = ToRegister(input);
XMMRegister result_reg = ToDoubleRegister(result);
- EmitNumberUntagD(input_reg, result_reg, instr->environment());
+ EmitNumberUntagD(input_reg, result_reg,
+ instr->hydrogen()->deoptimize_on_undefined(),
+ instr->environment());
}
=======================================
--- /branches/3.2/src/ia32/lithium-codegen-ia32.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/ia32/lithium-codegen-ia32.h Fri Jun 10 04:33:25 2011
@@ -256,7 +256,10 @@
void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
void EmitBranch(int left_block, int right_block, Condition cc);
void EmitCmpI(LOperand* left, LOperand* right);
- void EmitNumberUntagD(Register input, XMMRegister result, LEnvironment*
env);
+ void EmitNumberUntagD(Register input,
+ XMMRegister result,
+ bool deoptimize_on_undefined,
+ LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
=======================================
--- /branches/3.2/src/ia32/lithium-ia32.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/ia32/lithium-ia32.h Fri Jun 10 04:33:25 2011
@@ -1635,6 +1635,7 @@
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
+ DECLARE_HYDROGEN_ACCESSOR(Change);
};
=======================================
--- /branches/3.2/src/version.cc Thu Jun 9 04:42:22 2011
+++ /branches/3.2/src/version.cc Fri Jun 10 04:33:25 2011
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 2
#define BUILD_NUMBER 10
-#define PATCH_LEVEL 17
+#define PATCH_LEVEL 18
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.2/src/x64/lithium-codegen-x64.cc Wed Apr 13 01:46:07 2011
+++ /branches/3.2/src/x64/lithium-codegen-x64.cc Fri Jun 10 04:33:25 2011
@@ -3362,8 +3362,9 @@
void LCodeGen::EmitNumberUntagD(Register input_reg,
XMMRegister result_reg,
+ bool deoptimize_on_undefined,
LEnvironment* env) {
- NearLabel load_smi, heap_number, done;
+ NearLabel load_smi, done;
// Smi check.
__ JumpIfSmi(input_reg, &load_smi);
@@ -3371,18 +3372,22 @@
// Heap number map check.
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
- __ j(equal, &heap_number);
-
- __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
- DeoptimizeIf(not_equal, env);
-
- // Convert undefined to NaN. Compute NaN as 0/0.
- __ xorpd(result_reg, result_reg);
- __ divsd(result_reg, result_reg);
- __ jmp(&done);
-
+ if (deoptimize_on_undefined) {
+ DeoptimizeIf(not_equal, env);
+ } else {
+ NearLabel heap_number;
+ __ j(equal, &heap_number);
+ __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
+ DeoptimizeIf(not_equal, env);
+
+ // Convert undefined to NaN. Compute NaN as 0/0.
+ __ xorpd(result_reg, result_reg);
+ __ divsd(result_reg, result_reg);
+ __ jmp(&done);
+
+ __ bind(&heap_number);
+ }
// Heap number to XMM conversion.
- __ bind(&heap_number);
__ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
__ jmp(&done);
@@ -3473,7 +3478,9 @@
Register input_reg = ToRegister(input);
XMMRegister result_reg = ToDoubleRegister(result);
- EmitNumberUntagD(input_reg, result_reg, instr->environment());
+ EmitNumberUntagD(input_reg, result_reg,
+ instr->hydrogen()->deoptimize_on_undefined(),
+ instr->environment());
}
=======================================
--- /branches/3.2/src/x64/lithium-codegen-x64.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/x64/lithium-codegen-x64.h Fri Jun 10 04:33:25 2011
@@ -244,7 +244,10 @@
void EmitGoto(int block, LDeferredCode* deferred_stack_check = NULL);
void EmitBranch(int left_block, int right_block, Condition cc);
void EmitCmpI(LOperand* left, LOperand* right);
- void EmitNumberUntagD(Register input, XMMRegister result, LEnvironment*
env);
+ void EmitNumberUntagD(Register input,
+ XMMRegister result,
+ bool deoptimize_on_undefined,
+ LEnvironment* env);
// Emits optimized code for typeof x == "y". Modifies input register.
// Returns the condition on which a final split to
=======================================
--- /branches/3.2/src/x64/lithium-x64.h Mon Apr 11 05:33:05 2011
+++ /branches/3.2/src/x64/lithium-x64.h Fri Jun 10 04:33:25 2011
@@ -1559,6 +1559,7 @@
}
DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
+ DECLARE_HYDROGEN_ACCESSOR(Change);
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev