OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "double.h" | 30 #include "double.h" |
31 #include "factory.h" | 31 #include "factory.h" |
32 #include "hydrogen.h" | 32 #include "hydrogen-infer-representation.h" |
33 | 33 |
34 #if V8_TARGET_ARCH_IA32 | 34 #if V8_TARGET_ARCH_IA32 |
35 #include "ia32/lithium-ia32.h" | 35 #include "ia32/lithium-ia32.h" |
36 #elif V8_TARGET_ARCH_X64 | 36 #elif V8_TARGET_ARCH_X64 |
37 #include "x64/lithium-x64.h" | 37 #include "x64/lithium-x64.h" |
38 #elif V8_TARGET_ARCH_A64 | 38 #elif V8_TARGET_ARCH_A64 |
39 #include "a64/lithium-a64.h" | 39 #include "a64/lithium-a64.h" |
40 #elif V8_TARGET_ARCH_ARM | 40 #elif V8_TARGET_ARCH_ARM |
41 #include "arm/lithium-arm.h" | 41 #include "arm/lithium-arm.h" |
42 #elif V8_TARGET_ARCH_MIPS | 42 #elif V8_TARGET_ARCH_MIPS |
(...skipping 30 matching lines...) Expand all Loading... |
73 void HValue::AssumeRepresentation(Representation r) { | 73 void HValue::AssumeRepresentation(Representation r) { |
74 if (CheckFlag(kFlexibleRepresentation)) { | 74 if (CheckFlag(kFlexibleRepresentation)) { |
75 ChangeRepresentation(r); | 75 ChangeRepresentation(r); |
76 // The representation of the value is dictated by type feedback and | 76 // The representation of the value is dictated by type feedback and |
77 // will not be changed later. | 77 // will not be changed later. |
78 ClearFlag(kFlexibleRepresentation); | 78 ClearFlag(kFlexibleRepresentation); |
79 } | 79 } |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 void HValue::InferRepresentation(HInferRepresentation* h_infer) { | 83 void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { |
84 ASSERT(CheckFlag(kFlexibleRepresentation)); | 84 ASSERT(CheckFlag(kFlexibleRepresentation)); |
85 Representation new_rep = RepresentationFromInputs(); | 85 Representation new_rep = RepresentationFromInputs(); |
86 UpdateRepresentation(new_rep, h_infer, "inputs"); | 86 UpdateRepresentation(new_rep, h_infer, "inputs"); |
87 new_rep = RepresentationFromUses(); | 87 new_rep = RepresentationFromUses(); |
88 UpdateRepresentation(new_rep, h_infer, "uses"); | 88 UpdateRepresentation(new_rep, h_infer, "uses"); |
89 new_rep = RepresentationFromUseRequirements(); | 89 new_rep = RepresentationFromUseRequirements(); |
90 if (new_rep.fits_into(Representation::Integer32())) { | 90 if (new_rep.fits_into(Representation::Integer32())) { |
91 UpdateRepresentation(new_rep, h_infer, "use requirements"); | 91 UpdateRepresentation(new_rep, h_infer, "use requirements"); |
92 } | 92 } |
93 } | 93 } |
(...skipping 25 matching lines...) Expand all Loading... |
119 if (tagged_count > 0) return Representation::Tagged(); | 119 if (tagged_count > 0) return Representation::Tagged(); |
120 if (double_count > 0) return Representation::Double(); | 120 if (double_count > 0) return Representation::Double(); |
121 if (int32_count > 0) return Representation::Integer32(); | 121 if (int32_count > 0) return Representation::Integer32(); |
122 if (smi_count > 0) return Representation::Smi(); | 122 if (smi_count > 0) return Representation::Smi(); |
123 | 123 |
124 return Representation::None(); | 124 return Representation::None(); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 void HValue::UpdateRepresentation(Representation new_rep, | 128 void HValue::UpdateRepresentation(Representation new_rep, |
129 HInferRepresentation* h_infer, | 129 HInferRepresentationPhase* h_infer, |
130 const char* reason) { | 130 const char* reason) { |
131 Representation r = representation(); | 131 Representation r = representation(); |
132 if (new_rep.is_more_general_than(r)) { | 132 if (new_rep.is_more_general_than(r)) { |
133 if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return; | 133 if (CheckFlag(kCannotBeTagged) && new_rep.IsTagged()) return; |
134 if (FLAG_trace_representation) { | 134 if (FLAG_trace_representation) { |
135 PrintF("Changing #%d %s representation %s -> %s based on %s\n", | 135 PrintF("Changing #%d %s representation %s -> %s based on %s\n", |
136 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); | 136 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); |
137 } | 137 } |
138 ChangeRepresentation(new_rep); | 138 ChangeRepresentation(new_rep); |
139 AddDependantsToWorklist(h_infer); | 139 AddDependantsToWorklist(h_infer); |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 | 143 |
144 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) { | 144 void HValue::AddDependantsToWorklist(HInferRepresentationPhase* h_infer) { |
145 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 145 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
146 h_infer->AddToWorklist(it.value()); | 146 h_infer->AddToWorklist(it.value()); |
147 } | 147 } |
148 for (int i = 0; i < OperandCount(); ++i) { | 148 for (int i = 0; i < OperandCount(); ++i) { |
149 h_infer->AddToWorklist(OperandAt(i)); | 149 h_infer->AddToWorklist(OperandAt(i)); |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 | 153 |
154 // This method is recursive but it is guaranteed to terminate because | 154 // This method is recursive but it is guaranteed to terminate because |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 stream->Add("index"); | 1145 stream->Add("index"); |
1146 } | 1146 } |
1147 stream->Add(" + %d) >> %d)", offset(), scale()); | 1147 stream->Add(" + %d) >> %d)", offset(), scale()); |
1148 } | 1148 } |
1149 if (skip_check()) { | 1149 if (skip_check()) { |
1150 stream->Add(" [DISABLED]"); | 1150 stream->Add(" [DISABLED]"); |
1151 } | 1151 } |
1152 } | 1152 } |
1153 | 1153 |
1154 | 1154 |
1155 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { | 1155 void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { |
1156 ASSERT(CheckFlag(kFlexibleRepresentation)); | 1156 ASSERT(CheckFlag(kFlexibleRepresentation)); |
1157 HValue* actual_index = index()->ActualValue(); | 1157 HValue* actual_index = index()->ActualValue(); |
1158 HValue* actual_length = length()->ActualValue(); | 1158 HValue* actual_length = length()->ActualValue(); |
1159 Representation index_rep = actual_index->representation(); | 1159 Representation index_rep = actual_index->representation(); |
1160 Representation length_rep = actual_length->representation(); | 1160 Representation length_rep = actual_length->representation(); |
1161 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { | 1161 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { |
1162 index_rep = Representation::Smi(); | 1162 index_rep = Representation::Smi(); |
1163 } | 1163 } |
1164 if (length_rep.IsTagged() && actual_length->type().IsSmi()) { | 1164 if (length_rep.IsTagged() && actual_length->type().IsSmi()) { |
1165 length_rep = Representation::Smi(); | 1165 length_rep = Representation::Smi(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 HUnaryCall::PrintDataTo(stream); | 1220 HUnaryCall::PrintDataTo(stream); |
1221 } | 1221 } |
1222 | 1222 |
1223 | 1223 |
1224 void HCallKnownGlobal::PrintDataTo(StringStream* stream) { | 1224 void HCallKnownGlobal::PrintDataTo(StringStream* stream) { |
1225 stream->Add("%o ", target()->shared()->DebugName()); | 1225 stream->Add("%o ", target()->shared()->DebugName()); |
1226 stream->Add("#%d", argument_count()); | 1226 stream->Add("#%d", argument_count()); |
1227 } | 1227 } |
1228 | 1228 |
1229 | 1229 |
| 1230 void HCallNewArray::PrintDataTo(StringStream* stream) { |
| 1231 stream->Add(ElementsKindToString(elements_kind())); |
| 1232 stream->Add(" "); |
| 1233 HBinaryCall::PrintDataTo(stream); |
| 1234 } |
| 1235 |
| 1236 |
1230 void HCallRuntime::PrintDataTo(StringStream* stream) { | 1237 void HCallRuntime::PrintDataTo(StringStream* stream) { |
1231 stream->Add("%o ", *name()); | 1238 stream->Add("%o ", *name()); |
1232 stream->Add("#%d", argument_count()); | 1239 stream->Add("#%d", argument_count()); |
1233 } | 1240 } |
1234 | 1241 |
1235 | 1242 |
1236 void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 1243 void HClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
1237 stream->Add("class_of_test("); | 1244 stream->Add("class_of_test("); |
1238 value()->PrintNameTo(stream); | 1245 value()->PrintNameTo(stream); |
1239 stream->Add(", \"%o\")", *class_name()); | 1246 stream->Add(", \"%o\")", *class_name()); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); | 1564 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); |
1558 if (new_left == NULL && | 1565 if (new_left == NULL && |
1559 hdiv->observed_input_representation(1).IsSmiOrInteger32()) { | 1566 hdiv->observed_input_representation(1).IsSmiOrInteger32()) { |
1560 new_left = new(block()->zone()) | 1567 new_left = new(block()->zone()) |
1561 HChange(left, Representation::Integer32(), false, false); | 1568 HChange(left, Representation::Integer32(), false, false); |
1562 HChange::cast(new_left)->InsertBefore(this); | 1569 HChange::cast(new_left)->InsertBefore(this); |
1563 } | 1570 } |
1564 HValue* new_right = | 1571 HValue* new_right = |
1565 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); | 1572 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); |
1566 if (new_right == NULL && | 1573 if (new_right == NULL && |
1567 #ifdef V8_TARGET_ARCH_ARM | 1574 #if V8_TARGET_ARCH_ARM |
1568 CpuFeatures::IsSupported(SUDIV) && | 1575 CpuFeatures::IsSupported(SUDIV) && |
1569 #endif | 1576 #endif |
1570 hdiv->observed_input_representation(2).IsSmiOrInteger32()) { | 1577 hdiv->observed_input_representation(2).IsSmiOrInteger32()) { |
1571 new_right = new(block()->zone()) | 1578 new_right = new(block()->zone()) |
1572 HChange(right, Representation::Integer32(), false, false); | 1579 HChange(right, Representation::Integer32(), false, false); |
1573 HChange::cast(new_right)->InsertBefore(this); | 1580 HChange::cast(new_right)->InsertBefore(this); |
1574 } | 1581 } |
1575 | 1582 |
1576 // Return if left or right are not optimizable. | 1583 // Return if left or right are not optimizable. |
1577 if ((new_left == NULL) || (new_right == NULL)) return this; | 1584 if ((new_left == NULL) || (new_right == NULL)) return this; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1682 stream->Add("]"); | 1689 stream->Add("]"); |
1683 } | 1690 } |
1684 | 1691 |
1685 | 1692 |
1686 void HCheckFunction::PrintDataTo(StringStream* stream) { | 1693 void HCheckFunction::PrintDataTo(StringStream* stream) { |
1687 value()->PrintNameTo(stream); | 1694 value()->PrintNameTo(stream); |
1688 stream->Add(" %p", *target()); | 1695 stream->Add(" %p", *target()); |
1689 } | 1696 } |
1690 | 1697 |
1691 | 1698 |
| 1699 HValue* HCheckFunction::Canonicalize() { |
| 1700 return (value()->IsConstant() && |
| 1701 HConstant::cast(value())->UniqueValueIdsMatch(target_unique_id_)) |
| 1702 ? NULL |
| 1703 : this; |
| 1704 } |
| 1705 |
| 1706 |
1692 const char* HCheckInstanceType::GetCheckName() { | 1707 const char* HCheckInstanceType::GetCheckName() { |
1693 switch (check_) { | 1708 switch (check_) { |
1694 case IS_SPEC_OBJECT: return "object"; | 1709 case IS_SPEC_OBJECT: return "object"; |
1695 case IS_JS_ARRAY: return "array"; | 1710 case IS_JS_ARRAY: return "array"; |
1696 case IS_STRING: return "string"; | 1711 case IS_STRING: return "string"; |
1697 case IS_INTERNALIZED_STRING: return "internalized_string"; | 1712 case IS_INTERNALIZED_STRING: return "internalized_string"; |
1698 } | 1713 } |
1699 UNREACHABLE(); | 1714 UNREACHABLE(); |
1700 return ""; | 1715 return ""; |
1701 } | 1716 } |
1702 | 1717 |
| 1718 |
1703 void HCheckInstanceType::PrintDataTo(StringStream* stream) { | 1719 void HCheckInstanceType::PrintDataTo(StringStream* stream) { |
1704 stream->Add("%s ", GetCheckName()); | 1720 stream->Add("%s ", GetCheckName()); |
1705 HUnaryOperation::PrintDataTo(stream); | 1721 HUnaryOperation::PrintDataTo(stream); |
1706 } | 1722 } |
1707 | 1723 |
1708 | 1724 |
1709 void HCheckPrototypeMaps::PrintDataTo(StringStream* stream) { | 1725 void HCheckPrototypeMaps::PrintDataTo(StringStream* stream) { |
1710 stream->Add("[receiver_prototype=%p,holder=%p]%s", | 1726 stream->Add("[receiver_prototype=%p,holder=%p]%s", |
1711 *prototypes_.first(), *prototypes_.last(), | 1727 *prototypes_.first(), *prototypes_.last(), |
1712 CanOmitPrototypeChecks() ? " (omitted)" : ""); | 1728 CanOmitPrototypeChecks() ? " (omitted)" : ""); |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2166 | 2182 |
2167 | 2183 |
2168 HConstant::HConstant(Handle<Object> handle, Representation r) | 2184 HConstant::HConstant(Handle<Object> handle, Representation r) |
2169 : handle_(handle), | 2185 : handle_(handle), |
2170 unique_id_(), | 2186 unique_id_(), |
2171 has_smi_value_(false), | 2187 has_smi_value_(false), |
2172 has_int32_value_(false), | 2188 has_int32_value_(false), |
2173 has_double_value_(false), | 2189 has_double_value_(false), |
2174 is_internalized_string_(false), | 2190 is_internalized_string_(false), |
2175 is_not_in_new_space_(true), | 2191 is_not_in_new_space_(true), |
| 2192 is_cell_(false), |
2176 boolean_value_(handle->BooleanValue()) { | 2193 boolean_value_(handle->BooleanValue()) { |
2177 if (handle_->IsHeapObject()) { | 2194 if (handle_->IsHeapObject()) { |
2178 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); | 2195 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); |
2179 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2196 is_not_in_new_space_ = !heap->InNewSpace(*handle); |
2180 } | 2197 } |
2181 if (handle_->IsNumber()) { | 2198 if (handle_->IsNumber()) { |
2182 double n = handle_->Number(); | 2199 double n = handle_->Number(); |
2183 has_int32_value_ = IsInteger32(n); | 2200 has_int32_value_ = IsInteger32(n); |
2184 int32_value_ = DoubleToInt32(n); | 2201 int32_value_ = DoubleToInt32(n); |
2185 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2202 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2186 double_value_ = n; | 2203 double_value_ = n; |
2187 has_double_value_ = true; | 2204 has_double_value_ = true; |
2188 } else { | 2205 } else { |
2189 type_from_value_ = HType::TypeFromValue(handle_); | 2206 type_from_value_ = HType::TypeFromValue(handle_); |
2190 is_internalized_string_ = handle_->IsInternalizedString(); | 2207 is_internalized_string_ = handle_->IsInternalizedString(); |
2191 } | 2208 } |
| 2209 |
| 2210 is_cell_ = !handle_.is_null() && |
| 2211 (handle_->IsCell() || handle_->IsPropertyCell()); |
2192 Initialize(r); | 2212 Initialize(r); |
2193 } | 2213 } |
2194 | 2214 |
2195 | 2215 |
2196 HConstant::HConstant(Handle<Object> handle, | 2216 HConstant::HConstant(Handle<Object> handle, |
2197 UniqueValueId unique_id, | 2217 UniqueValueId unique_id, |
2198 Representation r, | 2218 Representation r, |
2199 HType type, | 2219 HType type, |
2200 bool is_internalize_string, | 2220 bool is_internalize_string, |
2201 bool is_not_in_new_space, | 2221 bool is_not_in_new_space, |
| 2222 bool is_cell, |
2202 bool boolean_value) | 2223 bool boolean_value) |
2203 : handle_(handle), | 2224 : handle_(handle), |
2204 unique_id_(unique_id), | 2225 unique_id_(unique_id), |
2205 has_smi_value_(false), | 2226 has_smi_value_(false), |
2206 has_int32_value_(false), | 2227 has_int32_value_(false), |
2207 has_double_value_(false), | 2228 has_double_value_(false), |
2208 is_internalized_string_(is_internalize_string), | 2229 is_internalized_string_(is_internalize_string), |
2209 is_not_in_new_space_(is_not_in_new_space), | 2230 is_not_in_new_space_(is_not_in_new_space), |
| 2231 is_cell_(is_cell), |
2210 boolean_value_(boolean_value), | 2232 boolean_value_(boolean_value), |
2211 type_from_value_(type) { | 2233 type_from_value_(type) { |
2212 ASSERT(!handle.is_null()); | 2234 ASSERT(!handle.is_null()); |
2213 ASSERT(!type.IsUninitialized()); | 2235 ASSERT(!type.IsUninitialized()); |
2214 ASSERT(!type.IsTaggedNumber()); | 2236 ASSERT(!type.IsTaggedNumber()); |
2215 Initialize(r); | 2237 Initialize(r); |
2216 } | 2238 } |
2217 | 2239 |
2218 | 2240 |
2219 HConstant::HConstant(int32_t integer_value, | 2241 HConstant::HConstant(int32_t integer_value, |
2220 Representation r, | 2242 Representation r, |
2221 bool is_not_in_new_space, | 2243 bool is_not_in_new_space, |
2222 Handle<Object> optional_handle) | 2244 Handle<Object> optional_handle) |
2223 : handle_(optional_handle), | 2245 : handle_(optional_handle), |
2224 unique_id_(), | 2246 unique_id_(), |
2225 has_int32_value_(true), | 2247 has_int32_value_(true), |
2226 has_double_value_(true), | 2248 has_double_value_(true), |
2227 is_internalized_string_(false), | 2249 is_internalized_string_(false), |
2228 is_not_in_new_space_(is_not_in_new_space), | 2250 is_not_in_new_space_(is_not_in_new_space), |
| 2251 is_cell_(false), |
2229 boolean_value_(integer_value != 0), | 2252 boolean_value_(integer_value != 0), |
2230 int32_value_(integer_value), | 2253 int32_value_(integer_value), |
2231 double_value_(FastI2D(integer_value)) { | 2254 double_value_(FastI2D(integer_value)) { |
2232 has_smi_value_ = Smi::IsValid(int32_value_); | 2255 has_smi_value_ = Smi::IsValid(int32_value_); |
2233 Initialize(r); | 2256 Initialize(r); |
2234 } | 2257 } |
2235 | 2258 |
2236 | 2259 |
2237 HConstant::HConstant(double double_value, | 2260 HConstant::HConstant(double double_value, |
2238 Representation r, | 2261 Representation r, |
2239 bool is_not_in_new_space, | 2262 bool is_not_in_new_space, |
2240 Handle<Object> optional_handle) | 2263 Handle<Object> optional_handle) |
2241 : handle_(optional_handle), | 2264 : handle_(optional_handle), |
2242 unique_id_(), | 2265 unique_id_(), |
2243 has_int32_value_(IsInteger32(double_value)), | 2266 has_int32_value_(IsInteger32(double_value)), |
2244 has_double_value_(true), | 2267 has_double_value_(true), |
2245 is_internalized_string_(false), | 2268 is_internalized_string_(false), |
2246 is_not_in_new_space_(is_not_in_new_space), | 2269 is_not_in_new_space_(is_not_in_new_space), |
| 2270 is_cell_(false), |
2247 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2271 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
2248 int32_value_(DoubleToInt32(double_value)), | 2272 int32_value_(DoubleToInt32(double_value)), |
2249 double_value_(double_value) { | 2273 double_value_(double_value) { |
2250 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2274 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2251 Initialize(r); | 2275 Initialize(r); |
2252 } | 2276 } |
2253 | 2277 |
2254 | 2278 |
2255 void HConstant::Initialize(Representation r) { | 2279 void HConstant::Initialize(Representation r) { |
2256 if (r.IsNone()) { | 2280 if (r.IsNone()) { |
2257 if (has_smi_value_) { | 2281 if (has_smi_value_) { |
2258 r = Representation::Smi(); | 2282 r = Representation::Smi(); |
2259 } else if (has_int32_value_) { | 2283 } else if (has_int32_value_) { |
2260 r = Representation::Integer32(); | 2284 r = Representation::Integer32(); |
2261 } else if (has_double_value_) { | 2285 } else if (has_double_value_) { |
2262 r = Representation::Double(); | 2286 r = Representation::Double(); |
2263 } else { | 2287 } else { |
2264 r = Representation::Tagged(); | 2288 r = Representation::Tagged(); |
2265 } | 2289 } |
2266 } | 2290 } |
2267 set_representation(r); | 2291 set_representation(r); |
2268 SetFlag(kUseGVN); | 2292 SetFlag(kUseGVN); |
2269 if (representation().IsInteger32()) { | |
2270 ClearGVNFlag(kDependsOnOsrEntries); | |
2271 } | |
2272 } | 2293 } |
2273 | 2294 |
2274 | 2295 |
| 2296 bool HConstant::EmitAtUses() { |
| 2297 ASSERT(IsLinked()); |
| 2298 if (block()->graph()->has_osr()) { |
| 2299 return block()->graph()->IsStandardConstant(this); |
| 2300 } |
| 2301 if (IsCell()) return false; |
| 2302 if (representation().IsDouble()) return false; |
| 2303 return true; |
| 2304 } |
| 2305 |
| 2306 |
2275 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2307 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
2276 if (r.IsSmi() && !has_smi_value_) return NULL; | 2308 if (r.IsSmi() && !has_smi_value_) return NULL; |
2277 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2309 if (r.IsInteger32() && !has_int32_value_) return NULL; |
2278 if (r.IsDouble() && !has_double_value_) return NULL; | 2310 if (r.IsDouble() && !has_double_value_) return NULL; |
2279 if (has_int32_value_) { | 2311 if (has_int32_value_) { |
2280 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_); | 2312 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_); |
2281 } | 2313 } |
2282 if (has_double_value_) { | 2314 if (has_double_value_) { |
2283 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_); | 2315 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_); |
2284 } | 2316 } |
2285 ASSERT(!handle_.is_null()); | 2317 ASSERT(!handle_.is_null()); |
2286 return new(zone) HConstant(handle_, | 2318 return new(zone) HConstant(handle_, |
2287 unique_id_, | 2319 unique_id_, |
2288 r, | 2320 r, |
2289 type_from_value_, | 2321 type_from_value_, |
2290 is_internalized_string_, | 2322 is_internalized_string_, |
2291 is_not_in_new_space_, | 2323 is_not_in_new_space_, |
| 2324 is_cell_, |
2292 boolean_value_); | 2325 boolean_value_); |
2293 } | 2326 } |
2294 | 2327 |
2295 | 2328 |
2296 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { | 2329 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { |
2297 if (has_int32_value_) { | 2330 if (has_int32_value_) { |
2298 return new(zone) HConstant(int32_value_, | 2331 return new(zone) HConstant(int32_value_, |
2299 Representation::Integer32(), | 2332 Representation::Integer32(), |
2300 is_not_in_new_space_, | 2333 is_not_in_new_space_, |
2301 handle_); | 2334 handle_); |
(...skipping 21 matching lines...) Expand all Loading... |
2323 | 2356 |
2324 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 2357 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
2325 left()->PrintNameTo(stream); | 2358 left()->PrintNameTo(stream); |
2326 stream->Add(" "); | 2359 stream->Add(" "); |
2327 right()->PrintNameTo(stream); | 2360 right()->PrintNameTo(stream); |
2328 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 2361 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
2329 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 2362 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
2330 } | 2363 } |
2331 | 2364 |
2332 | 2365 |
2333 void HBinaryOperation::InferRepresentation(HInferRepresentation* h_infer) { | 2366 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
2334 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2367 ASSERT(CheckFlag(kFlexibleRepresentation)); |
2335 Representation new_rep = RepresentationFromInputs(); | 2368 Representation new_rep = RepresentationFromInputs(); |
2336 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2369 UpdateRepresentation(new_rep, h_infer, "inputs"); |
2337 // When the operation has information about its own output type, don't look | 2370 // When the operation has information about its own output type, don't look |
2338 // at uses. | 2371 // at uses. |
2339 if (!observed_output_representation_.IsNone()) return; | 2372 if (!observed_output_representation_.IsNone()) return; |
2340 new_rep = RepresentationFromUses(); | 2373 new_rep = RepresentationFromUses(); |
2341 UpdateRepresentation(new_rep, h_infer, "uses"); | 2374 UpdateRepresentation(new_rep, h_infer, "uses"); |
2342 new_rep = RepresentationFromUseRequirements(); | 2375 new_rep = RepresentationFromUseRequirements(); |
2343 if (new_rep.fits_into(Representation::Integer32())) { | 2376 if (new_rep.fits_into(Representation::Integer32())) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2386 } | 2419 } |
2387 | 2420 |
2388 | 2421 |
2389 void HBinaryOperation::AssumeRepresentation(Representation r) { | 2422 void HBinaryOperation::AssumeRepresentation(Representation r) { |
2390 set_observed_input_representation(1, r); | 2423 set_observed_input_representation(1, r); |
2391 set_observed_input_representation(2, r); | 2424 set_observed_input_representation(2, r); |
2392 HValue::AssumeRepresentation(r); | 2425 HValue::AssumeRepresentation(r); |
2393 } | 2426 } |
2394 | 2427 |
2395 | 2428 |
2396 void HMathMinMax::InferRepresentation(HInferRepresentation* h_infer) { | 2429 void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) { |
2397 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2430 ASSERT(CheckFlag(kFlexibleRepresentation)); |
2398 Representation new_rep = RepresentationFromInputs(); | 2431 Representation new_rep = RepresentationFromInputs(); |
2399 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2432 UpdateRepresentation(new_rep, h_infer, "inputs"); |
2400 // Do not care about uses. | 2433 // Do not care about uses. |
2401 } | 2434 } |
2402 | 2435 |
2403 | 2436 |
2404 Range* HBitwise::InferRange(Zone* zone) { | 2437 Range* HBitwise::InferRange(Zone* zone) { |
2405 if (op() == Token::BIT_XOR) { | 2438 if (op() == Token::BIT_XOR) { |
2406 if (left()->HasRange() && right()->HasRange()) { | 2439 if (left()->HasRange() && right()->HasRange()) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2532 } | 2565 } |
2533 | 2566 |
2534 | 2567 |
2535 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { | 2568 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { |
2536 stream->Add(Token::Name(token())); | 2569 stream->Add(Token::Name(token())); |
2537 stream->Add(" "); | 2570 stream->Add(" "); |
2538 HControlInstruction::PrintDataTo(stream); | 2571 HControlInstruction::PrintDataTo(stream); |
2539 } | 2572 } |
2540 | 2573 |
2541 | 2574 |
2542 void HCompareIDAndBranch::AddInformativeDefinitions() { | 2575 void HCompareNumericAndBranch::AddInformativeDefinitions() { |
2543 NumericRelation r = NumericRelation::FromToken(token()); | 2576 NumericRelation r = NumericRelation::FromToken(token()); |
2544 if (r.IsNone()) return; | 2577 if (r.IsNone()) return; |
2545 | 2578 |
2546 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first()); | 2579 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first()); |
2547 HNumericConstraint::AddToGraph( | 2580 HNumericConstraint::AddToGraph( |
2548 left(), r.Negated(), right(), SuccessorAt(1)->first()); | 2581 left(), r.Negated(), right(), SuccessorAt(1)->first()); |
2549 } | 2582 } |
2550 | 2583 |
2551 | 2584 |
2552 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { | 2585 void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) { |
2553 stream->Add(Token::Name(token())); | 2586 stream->Add(Token::Name(token())); |
2554 stream->Add(" "); | 2587 stream->Add(" "); |
2555 left()->PrintNameTo(stream); | 2588 left()->PrintNameTo(stream); |
2556 stream->Add(" "); | 2589 stream->Add(" "); |
2557 right()->PrintNameTo(stream); | 2590 right()->PrintNameTo(stream); |
2558 HControlInstruction::PrintDataTo(stream); | 2591 HControlInstruction::PrintDataTo(stream); |
2559 } | 2592 } |
2560 | 2593 |
2561 | 2594 |
2562 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { | 2595 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { |
2563 left()->PrintNameTo(stream); | 2596 left()->PrintNameTo(stream); |
2564 stream->Add(" "); | 2597 stream->Add(" "); |
2565 right()->PrintNameTo(stream); | 2598 right()->PrintNameTo(stream); |
2566 HControlInstruction::PrintDataTo(stream); | 2599 HControlInstruction::PrintDataTo(stream); |
2567 } | 2600 } |
2568 | 2601 |
2569 | 2602 |
2570 void HGoto::PrintDataTo(StringStream* stream) { | 2603 void HGoto::PrintDataTo(StringStream* stream) { |
2571 stream->Add("B%d", SuccessorAt(0)->block_id()); | 2604 stream->Add("B%d", SuccessorAt(0)->block_id()); |
2572 } | 2605 } |
2573 | 2606 |
2574 | 2607 |
2575 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { | 2608 void HCompareNumericAndBranch::InferRepresentation( |
| 2609 HInferRepresentationPhase* h_infer) { |
2576 Representation left_rep = left()->representation(); | 2610 Representation left_rep = left()->representation(); |
2577 Representation right_rep = right()->representation(); | 2611 Representation right_rep = right()->representation(); |
2578 Representation observed_left = observed_input_representation(0); | 2612 Representation observed_left = observed_input_representation(0); |
2579 Representation observed_right = observed_input_representation(1); | 2613 Representation observed_right = observed_input_representation(1); |
2580 | 2614 |
2581 Representation rep = Representation::None(); | 2615 Representation rep = Representation::None(); |
2582 rep = rep.generalize(observed_left); | 2616 rep = rep.generalize(observed_left); |
2583 rep = rep.generalize(observed_right); | 2617 rep = rep.generalize(observed_right); |
2584 if (rep.IsNone() || rep.IsSmiOrInteger32()) { | 2618 if (rep.IsNone() || rep.IsSmiOrInteger32()) { |
2585 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); | 2619 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); |
2586 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); | 2620 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); |
2587 } else { | 2621 } else { |
2588 rep = Representation::Double(); | 2622 rep = Representation::Double(); |
2589 } | 2623 } |
2590 | 2624 |
2591 if (rep.IsDouble()) { | 2625 if (rep.IsDouble()) { |
2592 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === | 2626 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === |
2593 // and !=) have special handling of undefined, e.g. undefined == undefined | 2627 // and !=) have special handling of undefined, e.g. undefined == undefined |
2594 // is 'true'. Relational comparisons have a different semantic, first | 2628 // is 'true'. Relational comparisons have a different semantic, first |
2595 // calling ToPrimitive() on their arguments. The standard Crankshaft | 2629 // calling ToPrimitive() on their arguments. The standard Crankshaft |
2596 // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs | 2630 // tagged-to-double conversion to ensure the HCompareNumericAndBranch's |
2597 // are doubles caused 'undefined' to be converted to NaN. That's compatible | 2631 // inputs are doubles caused 'undefined' to be converted to NaN. That's |
2598 // out-of-the box with ordered relational comparisons (<, >, <=, | 2632 // compatible out-of-the box with ordered relational comparisons (<, >, <=, |
2599 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), | 2633 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), |
2600 // it is not consistent with the spec. For example, it would cause undefined | 2634 // it is not consistent with the spec. For example, it would cause undefined |
2601 // == undefined (should be true) to be evaluated as NaN == NaN | 2635 // == undefined (should be true) to be evaluated as NaN == NaN |
2602 // (false). Therefore, any comparisons other than ordered relational | 2636 // (false). Therefore, any comparisons other than ordered relational |
2603 // comparisons must cause a deopt when one of their arguments is undefined. | 2637 // comparisons must cause a deopt when one of their arguments is undefined. |
2604 // See also v8:1434 | 2638 // See also v8:1434 |
2605 if (Token::IsOrderedRelationalCompareOp(token_)) { | 2639 if (Token::IsOrderedRelationalCompareOp(token_)) { |
2606 SetFlag(kAllowUndefinedAsNaN); | 2640 SetFlag(kAllowUndefinedAsNaN); |
2607 } | 2641 } |
2608 } | 2642 } |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 HType HCheckFunction::CalculateInferredType() { | 3103 HType HCheckFunction::CalculateInferredType() { |
3070 return value()->type(); | 3104 return value()->type(); |
3071 } | 3105 } |
3072 | 3106 |
3073 | 3107 |
3074 HType HCheckHeapObject::CalculateInferredType() { | 3108 HType HCheckHeapObject::CalculateInferredType() { |
3075 return HType::NonPrimitive(); | 3109 return HType::NonPrimitive(); |
3076 } | 3110 } |
3077 | 3111 |
3078 | 3112 |
| 3113 HType HCheckSmi::CalculateInferredType() { |
| 3114 return HType::Smi(); |
| 3115 } |
| 3116 |
| 3117 |
3079 HType HPhi::CalculateInferredType() { | 3118 HType HPhi::CalculateInferredType() { |
3080 HType result = HType::Uninitialized(); | 3119 HType result = HType::Uninitialized(); |
3081 for (int i = 0; i < OperandCount(); ++i) { | 3120 for (int i = 0; i < OperandCount(); ++i) { |
3082 HType current = OperandAt(i)->type(); | 3121 HType current = OperandAt(i)->type(); |
3083 result = result.Combine(current); | 3122 result = result.Combine(current); |
3084 } | 3123 } |
3085 return result; | 3124 return result; |
3086 } | 3125 } |
3087 | 3126 |
3088 | 3127 |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3670 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 3709 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
3671 HValue* use = it.value(); | 3710 HValue* use = it.value(); |
3672 if (use->IsBinaryOperation()) { | 3711 if (use->IsBinaryOperation()) { |
3673 HBinaryOperation::cast(use)->set_observed_input_representation( | 3712 HBinaryOperation::cast(use)->set_observed_input_representation( |
3674 it.index(), Representation::Integer32()); | 3713 it.index(), Representation::Integer32()); |
3675 } | 3714 } |
3676 } | 3715 } |
3677 } | 3716 } |
3678 | 3717 |
3679 | 3718 |
3680 void HPhi::InferRepresentation(HInferRepresentation* h_infer) { | 3719 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { |
3681 ASSERT(CheckFlag(kFlexibleRepresentation)); | 3720 ASSERT(CheckFlag(kFlexibleRepresentation)); |
3682 Representation new_rep = RepresentationFromInputs(); | 3721 Representation new_rep = RepresentationFromInputs(); |
3683 UpdateRepresentation(new_rep, h_infer, "inputs"); | 3722 UpdateRepresentation(new_rep, h_infer, "inputs"); |
3684 new_rep = RepresentationFromUses(); | 3723 new_rep = RepresentationFromUses(); |
3685 UpdateRepresentation(new_rep, h_infer, "uses"); | 3724 UpdateRepresentation(new_rep, h_infer, "uses"); |
3686 new_rep = RepresentationFromUseRequirements(); | 3725 new_rep = RepresentationFromUseRequirements(); |
3687 UpdateRepresentation(new_rep, h_infer, "use requirements"); | 3726 UpdateRepresentation(new_rep, h_infer, "use requirements"); |
3688 } | 3727 } |
3689 | 3728 |
3690 | 3729 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3815 int offset = (index * kPointerSize) + map->instance_size(); | 3854 int offset = (index * kPointerSize) + map->instance_size(); |
3816 return HObjectAccess(kInobject, offset); | 3855 return HObjectAccess(kInobject, offset); |
3817 } else { | 3856 } else { |
3818 // Non-negative property indices are in the properties array. | 3857 // Non-negative property indices are in the properties array. |
3819 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 3858 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
3820 return HObjectAccess(kBackingStore, offset, name); | 3859 return HObjectAccess(kBackingStore, offset, name); |
3821 } | 3860 } |
3822 } | 3861 } |
3823 | 3862 |
3824 | 3863 |
| 3864 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) { |
| 3865 return HObjectAccess( |
| 3866 kInobject, Cell::kValueOffset, |
| 3867 Handle<String>(isolate->heap()->cell_value_string())); |
| 3868 } |
| 3869 |
| 3870 |
3825 void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { | 3871 void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) { |
3826 // set the appropriate GVN flags for a given load or store instruction | 3872 // set the appropriate GVN flags for a given load or store instruction |
3827 if (is_store) { | 3873 if (is_store) { |
3828 // track dominating allocations in order to eliminate write barriers | 3874 // track dominating allocations in order to eliminate write barriers |
3829 instr->SetGVNFlag(kDependsOnNewSpacePromotion); | 3875 instr->SetGVNFlag(kDependsOnNewSpacePromotion); |
3830 instr->SetFlag(HValue::kTrackSideEffectDominators); | 3876 instr->SetFlag(HValue::kTrackSideEffectDominators); |
3831 } else { | 3877 } else { |
3832 // try to GVN loads, but don't hoist above map changes | 3878 // try to GVN loads, but don't hoist above map changes |
3833 instr->SetFlag(HValue::kUseGVN); | 3879 instr->SetFlag(HValue::kUseGVN); |
3834 instr->SetGVNFlag(kDependsOnMaps); | 3880 instr->SetGVNFlag(kDependsOnMaps); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3884 case kBackingStore: | 3930 case kBackingStore: |
3885 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); | 3931 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); |
3886 stream->Add("[backing-store]"); | 3932 stream->Add("[backing-store]"); |
3887 break; | 3933 break; |
3888 } | 3934 } |
3889 | 3935 |
3890 stream->Add("@%d", offset()); | 3936 stream->Add("@%d", offset()); |
3891 } | 3937 } |
3892 | 3938 |
3893 } } // namespace v8::internal | 3939 } } // namespace v8::internal |
OLD | NEW |