Revision: 14765
Author: [email protected]
Date: Thu May 23 01:32:07 2013
Log: Implement HChange support for Smis and use it in
Load/StoreNameField
BUG=
[email protected]
Review URL: https://chromiumcodereview.appspot.com/15303004
Patch from Daniel Clifford <[email protected]>.
http://code.google.com/p/v8/source/detail?r=14765
Added:
/branches/bleeding_edge/test/mjsunit/smi-representation.js
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.h
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/lithium-allocator.cc
/branches/bleeding_edge/src/lithium.h
/branches/bleeding_edge/src/property-details.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.h
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/smi-representation.js Thu May 23
01:32:07 2013
@@ -0,0 +1,68 @@
+// Copyright 2013 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: --track-fields --track-double-fields --allow-natives-syntax
+
+function smi_field() {
+ return {"smi":0};
+}
+
+function check_smi_repr(o, d1, d2) {
+ var s = o.smi;
+ var d = d1 - d2;
+ s = s + d;
+ o.smi = s;
+ return o;
+}
+
+var test = smi_field();
+check_smi_repr(smi_field(), 5, 3);
+check_smi_repr(smi_field(), 6, 2);
+%OptimizeFunctionOnNextCall(check_smi_repr);
+var val = check_smi_repr(smi_field(), 8, 1);
+assertTrue(%HaveSameMap(val, test));
+
+function tagged_smi_field() {
+ var o = {"tag":false};
+ o.tag = 10;
+ return o;
+}
+
+function check_smi_repr_from_tagged(o, o2) {
+ var t = o2.tag;
+ o.smi = t;
+ return o;
+}
+
+check_smi_repr_from_tagged(smi_field(), tagged_smi_field());
+check_smi_repr_from_tagged(smi_field(), tagged_smi_field());
+%OptimizeFunctionOnNextCall(check_smi_repr_from_tagged);
+var val = check_smi_repr_from_tagged(smi_field(), tagged_smi_field());
+assertTrue(%HaveSameMap(val, test));
+var overflow = tagged_smi_field();
+overflow.tag = 0x80000000;
+var val = check_smi_repr_from_tagged(smi_field(), overflow);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Wed May 22 09:32:33 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Thu May 23 01:32:07 2013
@@ -1887,12 +1887,24 @@
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ if (from.IsSmi()) {
+ if (to.IsTagged()) {
+ LOperand* value = UseRegister(instr->value());
+ return DefineSameAsFirst(new(zone()) LDummyUse(value));
+ }
+ from = Representation::Tagged();
+ }
if (from.IsTagged()) {
if (to.IsDouble()) {
info()->MarkAsDeferredCalling();
LOperand* value = UseRegister(instr->value());
LNumberUntagD* res = new(zone()) LNumberUntagD(value);
return AssignEnvironment(DefineAsRegister(res));
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegisterAtStart(val);
+ return AssignEnvironment(
+ DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
LOperand* value = NULL;
@@ -1934,6 +1946,10 @@
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
Define(result, result_temp);
return AssignPointerMap(result);
+ } else if (to.IsSmi()) {
+ LOperand* value = UseRegister(instr->value());
+ return AssignEnvironment(DefineAsRegister(new(zone())
LDoubleToSmi(value,
+ TempRegister(), TempRegister())));
} else {
ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value());
@@ -1956,6 +1972,15 @@
LNumberTagI* result = new(zone()) LNumberTagI(value);
return
AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
}
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegister(val);
+ LInstruction* result =
+ DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
+ if (val->HasRange() && val->range()->IsInSmiRange()) {
+ return result;
+ }
+ return AssignEnvironment(result);
} else {
ASSERT(to.IsDouble());
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
@@ -2049,7 +2074,7 @@
return DefineAsRegister(new(zone()) LConstantI);
} else if (r.IsDouble()) {
return DefineAsRegister(new(zone()) LConstantD);
- } else if (r.IsTagged()) {
+ } else if (r.IsTagged() || r.IsSmi()) {
return DefineAsRegister(new(zone()) LConstantT);
} else {
UNREACHABLE();
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Wed May 22 09:32:33 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Thu May 23 01:32:07 2013
@@ -95,6 +95,7 @@
V(Deoptimize) \
V(DivI) \
V(DoubleToI) \
+ V(DoubleToSmi) \
V(DummyUse) \
V(ElementsKind) \
V(FixedArrayBaseLength) \
@@ -111,6 +112,7 @@
V(InstanceSize) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Integer32ToSmi) \
V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
@@ -1954,6 +1956,19 @@
};
+class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LInteger32ToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
class LUint32ToDouble: public LTemplateInstruction<1, 1, 0> {
public:
explicit LUint32ToDouble(LOperand* value) {
@@ -2007,6 +2022,25 @@
};
+class LDoubleToSmi: public LTemplateInstruction<1, 1, 2> {
+ public:
+ LDoubleToSmi(LOperand* value, LOperand* temp, LOperand* temp2) {
+ inputs_[0] = value;
+ temps_[0] = temp;
+ temps_[1] = temp2;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+ LOperand* temp2() { return temps_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
+
+ bool truncating() { return hydrogen()->CanTruncateToInt32(); }
+};
+
+
// Sometimes truncating conversion from a tagged value to an int32.
class LDoubleToI: public LTemplateInstruction<1, 1, 2> {
public:
@@ -2353,7 +2387,7 @@
};
-class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
+class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
public:
explicit LCheckSmi(LOperand* value) {
inputs_[0] = value;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed May 22
09:32:33 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu May 23
01:32:07 2013
@@ -518,7 +518,7 @@
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
- ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
+ ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
return constant->handle();
}
@@ -526,6 +526,11 @@
bool LCodeGen::IsInteger32(LConstantOperand* op) const {
return chunk_->LookupLiteralRepresentation(op).IsInteger32();
}
+
+
+bool LCodeGen::IsSmi(LConstantOperand* op) const {
+ return chunk_->LookupLiteralRepresentation(op).IsSmi();
+}
int LCodeGen::ToInteger32(LConstantOperand* op) const {
@@ -2207,7 +2212,7 @@
int false_block = chunk_->LookupDestination(instr->false_block_id());
Representation r = instr->hydrogen()->value()->representation();
- if (r.IsInteger32()) {
+ if (r.IsInteger32() || r.IsSmi()) {
Register reg = ToRegister(instr->value());
__ cmp(reg, Operand::Zero());
EmitBranch(true_block, false_block, ne);
@@ -4210,14 +4215,8 @@
Handle<Map> transition = instr->transition();
- if (FLAG_track_fields && representation.IsSmi()) {
+ if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
Register value = ToRegister(instr->value());
- __ SmiTag(value, value, SetCC);
- if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
- DeoptimizeIf(vs, instr->environment());
- }
- } else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
- Register value = ToRegister(instr->value());
if (!instr->hydrogen()->value()->type().IsHeapObject()) {
__ SmiTst(value);
DeoptimizeIf(eq, instr->environment());
@@ -4700,6 +4699,19 @@
}
__ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
}
+
+
+void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister());
+ LOperand* output = instr->result();
+ ASSERT(output->IsRegister());
+ __ SmiTag(ToRegister(output), ToRegister(input), SetCC);
+ if (!instr->hydrogen()->value()->HasRange() ||
+ !instr->hydrogen()->value()->range()->IsInSmiRange()) {
+ DeoptimizeIf(vs, instr->environment());
+ }
+}
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
@@ -5139,7 +5151,33 @@
DwVfpRegister double_input = ToDoubleRegister(instr->value());
DwVfpRegister double_scratch = double_scratch0();
- Label done;
+ if (instr->truncating()) {
+ Register scratch3 = ToRegister(instr->temp2());
+ __ ECMAToInt32(result_reg, double_input,
+ scratch1, scratch2, scratch3, double_scratch);
+ } else {
+ __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
+ // Deoptimize if the input wasn't a int32 (inside a double).
+ DeoptimizeIf(ne, instr->environment());
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label done;
+ __ cmp(result_reg, Operand::Zero());
+ __ b(ne, &done);
+ __ vmov(scratch1, double_input.high());
+ __ tst(scratch1, Operand(HeapNumber::kSignMask));
+ DeoptimizeIf(ne, instr->environment());
+ __ bind(&done);
+ }
+ }
+}
+
+
+void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
+ Register result_reg = ToRegister(instr->result());
+ Register scratch1 = scratch0();
+ Register scratch2 = ToRegister(instr->temp());
+ DwVfpRegister double_input = ToDoubleRegister(instr->value());
+ DwVfpRegister double_scratch = double_scratch0();
if (instr->truncating()) {
Register scratch3 = ToRegister(instr->temp2());
@@ -5149,8 +5187,18 @@
__ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
// Deoptimize if the input wasn't a int32 (inside a double).
DeoptimizeIf(ne, instr->environment());
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ Label done;
+ __ cmp(result_reg, Operand::Zero());
+ __ b(ne, &done);
+ __ vmov(scratch1, double_input.high());
+ __ tst(scratch1, Operand(HeapNumber::kSignMask));
+ DeoptimizeIf(ne, instr->environment());
+ __ bind(&done);
+ }
}
- __ bind(&done);
+ __ SmiTag(result_reg, SetCC);
+ DeoptimizeIf(vs, instr->environment());
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Tue May 14
04:45:33 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Thu May 23
01:32:07 2013
@@ -126,6 +126,7 @@
MemOperand ToHighMemOperand(LOperand* op) const;
bool IsInteger32(LConstantOperand* op) const;
+ bool IsSmi(LConstantOperand* op) const;
Handle<Object> ToHandle(LConstantOperand* op) const;
// Try to generate code for the entire chunk, but it may fail if the
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Thu May 16
07:27:39 2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Thu May 23
01:32:07 2013
@@ -1687,7 +1687,7 @@
Range* HChange::InferRange(Zone* zone) {
Range* input_range = value()->range();
if (from().IsInteger32() &&
- to().IsTagged() &&
+ to().IsSmiOrTagged() &&
!value()->CheckFlag(HInstruction::kUint32) &&
input_range != NULL && input_range->IsInSmiRange()) {
set_type(HType::Smi());
@@ -3563,7 +3563,7 @@
HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value();
if (hint_value != NULL) {
Representation hint = hint_value->representation();
- if (hint.IsTagged()) return hint;
+ if (hint.IsSmiOrTagged()) return hint;
if (hint.IsDouble()) double_occurred = true;
if (hint.IsInteger32()) int32_occurred = true;
}
@@ -3571,7 +3571,7 @@
}
if (value->representation().IsDouble()) double_occurred = true;
if (value->representation().IsInteger32()) int32_occurred = true;
- if (value->representation().IsTagged()) {
+ if (value->representation().IsSmiOrTagged()) {
if (value->IsConstant()) {
HConstant* constant = HConstant::cast(value);
if (constant->IsConvertibleToInteger()) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed May 22 09:32:33
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Thu May 23 01:32:07
2013
@@ -5209,7 +5209,7 @@
if (FLAG_track_fields && field_representation.IsSmi()) {
set_type(HType::Smi());
- set_representation(Representation::Tagged());
+ set_representation(field_representation);
} else if (FLAG_track_double_fields &&
field_representation.IsDouble()) {
set_representation(field_representation);
} else if (FLAG_track_heap_object_fields &&
@@ -5604,7 +5604,7 @@
return field_representation_;
} else if (FLAG_track_fields &&
index == 1 && field_representation_.IsSmi()) {
- return Representation::Integer32();
+ return field_representation_;
}
return Representation::Tagged();
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Thu May 23 01:17:03 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Thu May 23 01:32:07 2013
@@ -4399,7 +4399,9 @@
Representation from = change->value()->representation();
ASSERT(from.Equals(change->from()));
if (from.IsInteger32()) {
- ASSERT(change->to().IsTagged() || change->to().IsDouble());
+ ASSERT(change->to().IsTagged() ||
+ change->to().IsDouble() ||
+ change->to().IsSmi());
ASSERT(visited.IsEmpty());
PropagateMinusZeroChecks(change->value(), &visited);
visited.Clear();
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed May 22
09:32:33 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu May 23
01:32:07 2013
@@ -590,7 +590,7 @@
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
- ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
+ ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
return constant->handle();
}
@@ -605,6 +605,11 @@
bool LCodeGen::IsInteger32(LConstantOperand* op) const {
return chunk_->LookupLiteralRepresentation(op).IsInteger32();
}
+
+
+bool LCodeGen::IsSmi(LConstantOperand* op) const {
+ return chunk_->LookupLiteralRepresentation(op).IsSmi();
+}
Operand LCodeGen::ToOperand(LOperand* op) const {
@@ -2101,7 +2106,7 @@
CpuFeatureScope scope(masm(), SSE2);
Representation r = instr->hydrogen()->value()->representation();
- if (r.IsInteger32()) {
+ if (r.IsInteger32() || r.IsSmi()) {
Register reg = ToRegister(instr->value());
__ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero);
@@ -4220,15 +4225,9 @@
if (FLAG_track_fields && representation.IsSmi()) {
if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
- if (!IsInteger32(operand_value)) {
+ if (!IsSmi(operand_value)) {
DeoptimizeIf(no_condition, instr->environment());
}
- } else {
- Register value = ToRegister(instr->value());
- __ SmiTag(value);
- if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
- DeoptimizeIf(overflow, instr->environment());
- }
}
} else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
if (instr->value()->IsConstantOperand()) {
@@ -4293,12 +4292,7 @@
if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
- if (IsInteger32(operand_value)) {
- // In lithium register preparation, we made sure that the constant
integer
- // operand fits into smi range.
- Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
- __ mov(FieldOperand(write_register, offset), Immediate(smi_value));
- } else if (operand_value->IsRegister()) {
+ if (operand_value->IsRegister()) {
__ mov(FieldOperand(write_register, offset),
ToRegister(operand_value));
} else {
Handle<Object> handle_value = ToHandle(operand_value);
@@ -4767,6 +4761,16 @@
UNREACHABLE();
}
}
+
+
+void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
+ Register input = ToRegister(instr->value());
+ __ SmiTag(input);
+ if (!instr->hydrogen()->value()->HasRange() ||
+ !instr->hydrogen()->value()->range()->IsInSmiRange()) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+}
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
@@ -5635,6 +5639,41 @@
__ bind(&done);
}
}
+
+
+void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
+ LOperand* input = instr->value();
+ ASSERT(input->IsDoubleRegister());
+ LOperand* result = instr->result();
+ ASSERT(result->IsRegister());
+ CpuFeatureScope scope(masm(), SSE2);
+
+ XMMRegister input_reg = ToDoubleRegister(input);
+ Register result_reg = ToRegister(result);
+
+ Label done;
+ __ cvttsd2si(result_reg, Operand(input_reg));
+ __ cvtsi2sd(xmm0, Operand(result_reg));
+ __ ucomisd(xmm0, input_reg);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // The integer converted back is equal to the original. We
+ // only have to test if we got -0 as an input.
+ __ test(result_reg, Operand(result_reg));
+ __ j(not_zero, &done, Label::kNear);
+ __ movmskpd(result_reg, input_reg);
+ // Bit 0 contains the sign of the double in input_reg.
+ // If input was positive, we are ok and return 0, otherwise
+ // deoptimize.
+ __ and_(result_reg, 1);
+ DeoptimizeIf(not_zero, instr->environment());
+ __ bind(&done);
+ }
+ __ SmiTag(result_reg);
+ DeoptimizeIf(overflow, instr->environment());
+}
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Tue May 14
04:45:33 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Thu May 23
01:32:07 2013
@@ -111,6 +111,7 @@
bool IsX87TopOfStack(LOperand* op) const;
bool IsInteger32(LConstantOperand* op) const;
+ bool IsSmi(LConstantOperand* op) const;
Immediate ToInteger32Immediate(LOperand* op) const {
return Immediate(ToInteger32(LConstantOperand::cast(op)));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed May 22 09:32:33
2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu May 23 01:32:07
2013
@@ -1908,6 +1908,13 @@
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ if (from.IsSmi()) {
+ if (to.IsTagged()) {
+ LOperand* value = UseRegister(instr->value());
+ return DefineSameAsFirst(new(zone()) LDummyUse(value));
+ }
+ from = Representation::Tagged();
+ }
// Only mark conversions that might need to allocate as calling rather
than
// all changes. This makes simple, non-allocating conversion not have to
force
// building a stack frame.
@@ -1925,6 +1932,11 @@
} else {
return AssignEnvironment(DefineX87TOS(res));
}
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegisterAtStart(val);
+ return AssignEnvironment(
+ DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
if (instr->value()->type().IsSmi()) {
@@ -1970,6 +1982,10 @@
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
+ } else if (to.IsSmi()) {
+ LOperand* value = UseRegister(instr->value());
+ return AssignEnvironment(
+ DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
bool truncating = instr->CanTruncateToInt32();
@@ -1994,6 +2010,15 @@
LNumberTagI* result = new(zone()) LNumberTagI(value);
return
AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
}
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegister(val);
+ LInstruction* result =
+ DefineSameAsFirst(new(zone()) LInteger32ToSmi(value));
+ if (val->HasRange() && val->range()->IsInSmiRange()) {
+ return result;
+ }
+ return AssignEnvironment(result);
} else {
ASSERT(to.IsDouble());
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
@@ -2034,13 +2059,13 @@
LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
LOperand* value = UseAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckSmi(value));
+ return AssignEnvironment(DefineSameAsFirst(new(zone())
LCheckSmi(value)));
}
LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) {
LOperand* value = UseAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckSmi(value));
+ return AssignEnvironment(DefineSameAsFirst(new(zone())
LCheckSmi(value)));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed May 22 09:32:33 2013
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Thu May 23 01:32:07 2013
@@ -90,6 +90,7 @@
V(Deoptimize) \
V(DivI) \
V(DoubleToI) \
+ V(DoubleToSmi) \
V(DummyUse) \
V(ElementsKind) \
V(FixedArrayBaseLength) \
@@ -106,6 +107,7 @@
V(InstanceSize) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Integer32ToSmi) \
V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
@@ -1998,6 +2000,19 @@
};
+class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LInteger32ToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> {
public:
explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
@@ -2069,6 +2084,19 @@
};
+class LDoubleToSmi: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
+};
+
+
// Truncating conversion from a tagged value to an int32.
class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
public:
@@ -2433,7 +2461,7 @@
};
-class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
+class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
public:
explicit LCheckSmi(LOperand* value) {
inputs_[0] = value;
=======================================
--- /branches/bleeding_edge/src/lithium-allocator.cc Wed May 8 07:18:30
2013
+++ /branches/bleeding_edge/src/lithium-allocator.cc Thu May 23 01:32:07
2013
@@ -1057,7 +1057,7 @@
LInstruction* branch =
InstructionAt(cur_block->last_instruction_index());
if (branch->HasPointerMap()) {
- if (phi->representation().IsTagged()) {
+ if (phi->representation().IsSmiOrTagged()) {
branch->pointer_map()->RecordPointer(phi_operand, zone());
} else if (!phi->representation().IsDouble()) {
branch->pointer_map()->RecordUntagged(phi_operand, zone());
@@ -1640,7 +1640,7 @@
bool LAllocator::HasTaggedValue(int virtual_register) const {
HValue* value = graph_->LookupValue(virtual_register);
if (value == NULL) return false;
- return value->representation().IsTagged();
+ return value->representation().IsSmiOrTagged();
}
=======================================
--- /branches/bleeding_edge/src/lithium.h Thu May 2 04:22:32 2013
+++ /branches/bleeding_edge/src/lithium.h Thu May 23 01:32:07 2013
@@ -558,7 +558,7 @@
Representation representation,
bool is_uint32) {
values_.Add(operand, zone());
- if (representation.IsTagged()) {
+ if (representation.IsSmiOrTagged()) {
ASSERT(!is_uint32);
is_tagged_.Add(values_.length() - 1);
}
=======================================
--- /branches/bleeding_edge/src/property-details.h Thu May 23 00:05:58 2013
+++ /branches/bleeding_edge/src/property-details.h Thu May 23 01:32:07 2013
@@ -131,6 +131,7 @@
bool IsNone() const { return kind_ == kNone; }
bool IsTagged() const { return kind_ == kTagged; }
bool IsSmi() const { return kind_ == kSmi; }
+ bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
bool IsInteger32() const { return kind_ == kInteger32; }
bool IsDouble() const { return kind_ == kDouble; }
bool IsHeapObject() const { return kind_ == kHeapObject; }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed May 22
09:32:33 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu May 23
01:32:07 2013
@@ -433,6 +433,12 @@
return op->IsConstantOperand() &&
chunk_->LookupLiteralRepresentation(op).IsInteger32();
}
+
+
+bool LCodeGen::IsSmiConstant(LConstantOperand* op) const {
+ return op->IsConstantOperand() &&
+ chunk_->LookupLiteralRepresentation(op).IsSmi();
+}
bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
@@ -456,7 +462,7 @@
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
- ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
+ ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
return constant->handle();
}
@@ -1876,6 +1882,10 @@
if (r.IsInteger32()) {
Register reg = ToRegister(instr->value());
__ testl(reg, reg);
+ EmitBranch(true_block, false_block, not_zero);
+ } else if (r.IsSmi()) {
+ Register reg = ToRegister(instr->value());
+ __ testq(reg, reg);
EmitBranch(true_block, false_block, not_zero);
} else if (r.IsDouble()) {
XMMRegister reg = ToDoubleRegister(instr->value());
@@ -3905,12 +3915,9 @@
if (FLAG_track_fields && representation.IsSmi()) {
if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
- if (!IsInteger32Constant(operand_value)) {
+ if (!IsSmiConstant(operand_value)) {
DeoptimizeIf(no_condition, instr->environment());
}
- } else {
- Register value = ToRegister(instr->value());
- __ Integer32ToSmi(value, value);
}
} else if (FLAG_track_heap_object_fields &&
representation.IsHeapObject()) {
if (instr->value()->IsConstantOperand()) {
@@ -3968,12 +3975,7 @@
if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
- if (IsInteger32Constant(operand_value)) {
- // In lithium register preparation, we made sure that the constant
integer
- // operand fits into smi range.
- Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
- __ Move(FieldOperand(write_register, offset), smi_value);
- } else if (operand_value->IsRegister()) {
+ if (operand_value->IsRegister()) {
__ movq(FieldOperand(write_register, offset),
ToRegister(operand_value));
} else {
@@ -4432,6 +4434,18 @@
__ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
}
}
+
+
+void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
+ LOperand* input = instr->value();
+ ASSERT(input->IsRegister());
+ LOperand* output = instr->result();
+ __ Integer32ToSmi(ToRegister(output), ToRegister(input));
+ if (!instr->hydrogen()->value()->HasRange() ||
+ !instr->hydrogen()->value()->range()->IsInSmiRange()) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+}
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
@@ -4839,6 +4853,41 @@
}
}
}
+
+
+void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
+ LOperand* input = instr->value();
+ ASSERT(input->IsDoubleRegister());
+ LOperand* result = instr->result();
+ ASSERT(result->IsRegister());
+ CpuFeatureScope scope(masm(), SSE2);
+
+ XMMRegister input_reg = ToDoubleRegister(input);
+ Register result_reg = ToRegister(result);
+
+ Label done;
+ __ cvttsd2si(result_reg, input_reg);
+ __ cvtlsi2sd(xmm0, result_reg);
+ __ ucomisd(xmm0, input_reg);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // The integer converted back is equal to the original. We
+ // only have to test if we got -0 as an input.
+ __ testl(result_reg, result_reg);
+ __ j(not_zero, &done, Label::kNear);
+ __ movmskpd(result_reg, input_reg);
+ // Bit 0 contains the sign of the double in input_reg.
+ // If input was positive, we are ok and return 0, otherwise
+ // deoptimize.
+ __ andl(result_reg, Immediate(1));
+ DeoptimizeIf(not_zero, instr->environment());
+ __ bind(&done);
+ }
+ __ Integer32ToSmi(result_reg, result_reg);
+ DeoptimizeIf(overflow, instr->environment());
+}
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Tue May 14
04:45:33 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Thu May 23
01:32:07 2013
@@ -104,6 +104,7 @@
Register ToRegister(LOperand* op) const;
XMMRegister ToDoubleRegister(LOperand* op) const;
bool IsInteger32Constant(LConstantOperand* op) const;
+ bool IsSmiConstant(LConstantOperand* op) const;
int ToInteger32(LConstantOperand* op) const;
double ToDouble(LConstantOperand* op) const;
bool IsTaggedConstant(LConstantOperand* op) const;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Wed May 22 09:32:33 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Thu May 23 01:32:07 2013
@@ -1812,6 +1812,13 @@
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
+ if (from.IsSmi()) {
+ if (to.IsTagged()) {
+ LOperand* value = UseRegister(instr->value());
+ return DefineSameAsFirst(new(zone()) LDummyUse(value));
+ }
+ from = Representation::Tagged();
+ }
// Only mark conversions that might need to allocate as calling rather
than
// all changes. This makes simple, non-allocating conversion not have to
force
// building a stack frame.
@@ -1821,6 +1828,11 @@
LOperand* value = UseRegister(instr->value());
LNumberUntagD* res = new(zone()) LNumberUntagD(value);
return AssignEnvironment(DefineAsRegister(res));
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegisterAtStart(val);
+ return AssignEnvironment(
+ DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value());
@@ -1852,10 +1864,15 @@
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
+ } else if (to.IsSmi()) {
+ LOperand* value = UseRegister(instr->value());
+ return AssignEnvironment(
+ DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value());
- return AssignEnvironment(DefineAsRegister(new(zone())
LDoubleToI(value)));
+ return AssignEnvironment(
+ DefineAsRegister(new(zone()) LDoubleToI(value)));
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
@@ -1872,6 +1889,15 @@
LNumberTagI* result = new(zone()) LNumberTagI(value);
return
AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
}
+ } else if (to.IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegister(val);
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LInteger32ToSmi(value));
+ if (val->HasRange() && val->range()->IsInSmiRange()) {
+ return result;
+ }
+ return AssignEnvironment(result);
} else {
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
LOperand* temp = FixedTemp(xmm1);
@@ -1911,13 +1937,13 @@
LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckSmi(value));
+ return AssignEnvironment(DefineSameAsFirst(new(zone())
LCheckSmi(value)));
}
LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) {
LOperand* value = UseRegisterAtStart(instr->value());
- return AssignEnvironment(new(zone()) LCheckSmi(value));
+ return AssignEnvironment(DefineSameAsFirst(new(zone())
LCheckSmi(value)));
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Wed May 22 09:32:33 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Thu May 23 01:32:07 2013
@@ -95,6 +95,7 @@
V(Deoptimize) \
V(DivI) \
V(DoubleToI) \
+ V(DoubleToSmi) \
V(DummyUse) \
V(ElementsKind) \
V(FixedArrayBaseLength) \
@@ -112,6 +113,7 @@
V(InstanceSize) \
V(InstructionGap) \
V(Integer32ToDouble) \
+ V(Integer32ToSmi) \
V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
@@ -1887,6 +1889,19 @@
};
+class LInteger32ToSmi: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LInteger32ToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Integer32ToSmi, "int32-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
class LUint32ToDouble: public LTemplateInstruction<1, 1, 1> {
public:
explicit LUint32ToDouble(LOperand* value, LOperand* temp) {
@@ -1958,6 +1973,19 @@
};
+class LDoubleToSmi: public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleToSmi(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
+ DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
+};
+
+
// Truncating conversion from a tagged value to an int32.
class LTaggedToI: public LTemplateInstruction<1, 1, 1> {
public:
@@ -2266,7 +2294,7 @@
};
-class LCheckSmi: public LTemplateInstruction<0, 1, 0> {
+class LCheckSmi: public LTemplateInstruction<1, 1, 0> {
public:
explicit LCheckSmi(LOperand* value) {
inputs_[0] = value;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.