| 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 |