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 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 | 1577 |
1578 | 1578 |
1579 void HCheckMaps::SetSideEffectDominator(GVNFlag side_effect, | 1579 void HCheckMaps::SetSideEffectDominator(GVNFlag side_effect, |
1580 HValue* dominator) { | 1580 HValue* dominator) { |
1581 ASSERT(side_effect == kChangesMaps); | 1581 ASSERT(side_effect == kChangesMaps); |
1582 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once | 1582 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once |
1583 // type information is rich enough we should generalize this to any HType | 1583 // type information is rich enough we should generalize this to any HType |
1584 // for which the map is known. | 1584 // for which the map is known. |
1585 if (HasNoUses() && dominator->IsStoreNamedField()) { | 1585 if (HasNoUses() && dominator->IsStoreNamedField()) { |
1586 HStoreNamedField* store = HStoreNamedField::cast(dominator); | 1586 HStoreNamedField* store = HStoreNamedField::cast(dominator); |
1587 Handle<Map> map = store->transition(); | 1587 UniqueValueId map_unique_id = store->transition_unique_id(); |
1588 if (map.is_null() || store->object() != value()) return; | 1588 if (!map_unique_id.IsInitialized() || store->object() != value()) return; |
1589 for (int i = 0; i < map_set()->length(); i++) { | 1589 for (int i = 0; i < map_set()->length(); i++) { |
1590 if (map.is_identical_to(map_set()->at(i))) { | 1590 if (map_unique_id == map_unique_ids_.at(i)) { |
1591 DeleteAndReplaceWith(NULL); | 1591 DeleteAndReplaceWith(NULL); |
1592 return; | 1592 return; |
1593 } | 1593 } |
1594 } | 1594 } |
1595 } | 1595 } |
1596 } | 1596 } |
1597 | 1597 |
1598 | 1598 |
1599 void HLoadElements::PrintDataTo(StringStream* stream) { | 1599 void HLoadElements::PrintDataTo(StringStream* stream) { |
1600 value()->PrintNameTo(stream); | 1600 value()->PrintNameTo(stream); |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2040 | 2040 |
2041 | 2041 |
2042 static bool IsInteger32(double value) { | 2042 static bool IsInteger32(double value) { |
2043 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 2043 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
2044 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 2044 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
2045 } | 2045 } |
2046 | 2046 |
2047 | 2047 |
2048 HConstant::HConstant(Handle<Object> handle, Representation r) | 2048 HConstant::HConstant(Handle<Object> handle, Representation r) |
2049 : handle_(handle), | 2049 : handle_(handle), |
| 2050 unique_id_(), |
2050 has_int32_value_(false), | 2051 has_int32_value_(false), |
2051 has_double_value_(false), | 2052 has_double_value_(false), |
2052 is_internalized_string_(false), | 2053 is_internalized_string_(false), |
2053 boolean_value_(handle->BooleanValue()) { | 2054 boolean_value_(handle->BooleanValue()) { |
2054 if (handle_->IsNumber()) { | 2055 if (handle_->IsNumber()) { |
2055 double n = handle_->Number(); | 2056 double n = handle_->Number(); |
2056 has_int32_value_ = IsInteger32(n); | 2057 has_int32_value_ = IsInteger32(n); |
2057 int32_value_ = DoubleToInt32(n); | 2058 int32_value_ = DoubleToInt32(n); |
2058 double_value_ = n; | 2059 double_value_ = n; |
2059 has_double_value_ = true; | 2060 has_double_value_ = true; |
2060 } else { | 2061 } else { |
2061 type_from_value_ = HType::TypeFromValue(handle_); | 2062 type_from_value_ = HType::TypeFromValue(handle_); |
2062 is_internalized_string_ = handle_->IsInternalizedString(); | 2063 is_internalized_string_ = handle_->IsInternalizedString(); |
2063 } | 2064 } |
2064 if (r.IsNone()) { | 2065 if (r.IsNone()) { |
2065 if (has_int32_value_) { | 2066 if (has_int32_value_) { |
2066 r = Representation::Integer32(); | 2067 r = Representation::Integer32(); |
2067 } else if (has_double_value_) { | 2068 } else if (has_double_value_) { |
2068 r = Representation::Double(); | 2069 r = Representation::Double(); |
2069 } else { | 2070 } else { |
2070 r = Representation::Tagged(); | 2071 r = Representation::Tagged(); |
2071 } | 2072 } |
2072 } | 2073 } |
2073 Initialize(r); | 2074 Initialize(r); |
2074 } | 2075 } |
2075 | 2076 |
2076 | 2077 |
2077 HConstant::HConstant(Handle<Object> handle, | 2078 HConstant::HConstant(Handle<Object> handle, |
| 2079 UniqueValueId unique_id, |
2078 Representation r, | 2080 Representation r, |
2079 HType type, | 2081 HType type, |
2080 bool is_internalize_string, | 2082 bool is_internalize_string, |
2081 bool boolean_value) | 2083 bool boolean_value) |
2082 : handle_(handle), | 2084 : handle_(handle), |
| 2085 unique_id_(unique_id), |
2083 has_int32_value_(false), | 2086 has_int32_value_(false), |
2084 has_double_value_(false), | 2087 has_double_value_(false), |
2085 is_internalized_string_(is_internalize_string), | 2088 is_internalized_string_(is_internalize_string), |
2086 boolean_value_(boolean_value), | 2089 boolean_value_(boolean_value), |
2087 type_from_value_(type) { | 2090 type_from_value_(type) { |
2088 ASSERT(!handle.is_null()); | 2091 ASSERT(!handle.is_null()); |
2089 ASSERT(!type.IsUninitialized()); | 2092 ASSERT(!type.IsUninitialized()); |
2090 ASSERT(!type.IsTaggedNumber()); | 2093 ASSERT(!type.IsTaggedNumber()); |
2091 Initialize(r); | 2094 Initialize(r); |
2092 } | 2095 } |
2093 | 2096 |
2094 | 2097 |
2095 HConstant::HConstant(int32_t integer_value, | 2098 HConstant::HConstant(int32_t integer_value, |
2096 Representation r, | 2099 Representation r, |
2097 Handle<Object> optional_handle) | 2100 Handle<Object> optional_handle) |
2098 : has_int32_value_(true), | 2101 : handle_(optional_handle), |
| 2102 unique_id_(), |
| 2103 has_int32_value_(true), |
2099 has_double_value_(true), | 2104 has_double_value_(true), |
2100 is_internalized_string_(false), | 2105 is_internalized_string_(false), |
2101 boolean_value_(integer_value != 0), | 2106 boolean_value_(integer_value != 0), |
2102 int32_value_(integer_value), | 2107 int32_value_(integer_value), |
2103 double_value_(FastI2D(integer_value)) { | 2108 double_value_(FastI2D(integer_value)) { |
2104 Initialize(r); | 2109 Initialize(r); |
2105 } | 2110 } |
2106 | 2111 |
2107 | 2112 |
2108 HConstant::HConstant(double double_value, | 2113 HConstant::HConstant(double double_value, |
2109 Representation r, | 2114 Representation r, |
2110 Handle<Object> optional_handle) | 2115 Handle<Object> optional_handle) |
2111 : has_int32_value_(IsInteger32(double_value)), | 2116 : handle_(optional_handle), |
| 2117 unique_id_(), |
| 2118 has_int32_value_(IsInteger32(double_value)), |
2112 has_double_value_(true), | 2119 has_double_value_(true), |
2113 is_internalized_string_(false), | 2120 is_internalized_string_(false), |
2114 boolean_value_(double_value != 0 && !isnan(double_value)), | 2121 boolean_value_(double_value != 0 && !isnan(double_value)), |
2115 int32_value_(DoubleToInt32(double_value)), | 2122 int32_value_(DoubleToInt32(double_value)), |
2116 double_value_(double_value) { | 2123 double_value_(double_value) { |
2117 Initialize(r); | 2124 Initialize(r); |
2118 } | 2125 } |
2119 | 2126 |
2120 | 2127 |
2121 void HConstant::Initialize(Representation r) { | 2128 void HConstant::Initialize(Representation r) { |
2122 set_representation(r); | 2129 set_representation(r); |
2123 SetFlag(kUseGVN); | 2130 SetFlag(kUseGVN); |
2124 if (representation().IsInteger32()) { | 2131 if (representation().IsInteger32()) { |
2125 ClearGVNFlag(kDependsOnOsrEntries); | 2132 ClearGVNFlag(kDependsOnOsrEntries); |
2126 } | 2133 } |
2127 } | 2134 } |
2128 | 2135 |
2129 | 2136 |
2130 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2137 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
2131 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2138 if (r.IsInteger32() && !has_int32_value_) return NULL; |
2132 if (r.IsDouble() && !has_double_value_) return NULL; | 2139 if (r.IsDouble() && !has_double_value_) return NULL; |
2133 if (has_int32_value_) return new(zone) HConstant(int32_value_, r, handle_); | 2140 if (has_int32_value_) return new(zone) HConstant(int32_value_, r, handle_); |
2134 if (has_double_value_) return new(zone) HConstant(double_value_, r, handle_); | 2141 if (has_double_value_) return new(zone) HConstant(double_value_, r, handle_); |
2135 ASSERT(!handle_.is_null()); | 2142 ASSERT(!handle_.is_null()); |
2136 return new(zone) HConstant( | 2143 return new(zone) HConstant(handle_, |
2137 handle_, r, type_from_value_, is_internalized_string_, boolean_value_); | 2144 unique_id_, |
| 2145 r, |
| 2146 type_from_value_, |
| 2147 is_internalized_string_, |
| 2148 boolean_value_); |
2138 } | 2149 } |
2139 | 2150 |
2140 | 2151 |
2141 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { | 2152 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { |
2142 if (has_int32_value_) { | 2153 if (has_int32_value_) { |
2143 return new(zone) HConstant( | 2154 return new(zone) HConstant( |
2144 int32_value_, Representation::Integer32(), handle_); | 2155 int32_value_, Representation::Integer32(), handle_); |
2145 } | 2156 } |
2146 if (has_double_value_) { | 2157 if (has_double_value_) { |
2147 return new(zone) HConstant( | 2158 return new(zone) HConstant( |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 } | 2463 } |
2453 | 2464 |
2454 | 2465 |
2455 HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, | 2466 HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, |
2456 HValue* object, | 2467 HValue* object, |
2457 SmallMapList* types, | 2468 SmallMapList* types, |
2458 Handle<String> name, | 2469 Handle<String> name, |
2459 Zone* zone) | 2470 Zone* zone) |
2460 : types_(Min(types->length(), kMaxLoadPolymorphism), zone), | 2471 : types_(Min(types->length(), kMaxLoadPolymorphism), zone), |
2461 name_(name), | 2472 name_(name), |
| 2473 types_unique_ids_(0, zone), |
| 2474 name_unique_id_(), |
2462 need_generic_(false) { | 2475 need_generic_(false) { |
2463 SetOperandAt(0, context); | 2476 SetOperandAt(0, context); |
2464 SetOperandAt(1, object); | 2477 SetOperandAt(1, object); |
2465 set_representation(Representation::Tagged()); | 2478 set_representation(Representation::Tagged()); |
2466 SetGVNFlag(kDependsOnMaps); | 2479 SetGVNFlag(kDependsOnMaps); |
2467 SmallMapList negative_lookups; | 2480 SmallMapList negative_lookups; |
2468 for (int i = 0; | 2481 for (int i = 0; |
2469 i < types->length() && types_.length() < kMaxLoadPolymorphism; | 2482 i < types->length() && types_.length() < kMaxLoadPolymorphism; |
2470 ++i) { | 2483 ++i) { |
2471 Handle<Map> map = types->at(i); | 2484 Handle<Map> map = types->at(i); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2518 // We don't have an easy way to handle both a call (to the generic stub) and | 2531 // We don't have an easy way to handle both a call (to the generic stub) and |
2519 // a deopt in the same hydrogen instruction, so in this case we don't add | 2532 // a deopt in the same hydrogen instruction, so in this case we don't add |
2520 // the negative lookups which can deopt - just let the generic stub handle | 2533 // the negative lookups which can deopt - just let the generic stub handle |
2521 // them. | 2534 // them. |
2522 SetAllSideEffects(); | 2535 SetAllSideEffects(); |
2523 need_generic_ = true; | 2536 need_generic_ = true; |
2524 } | 2537 } |
2525 } | 2538 } |
2526 | 2539 |
2527 | 2540 |
| 2541 void HCheckMaps::FinalizeUniqueValueId() { |
| 2542 if (!map_unique_ids_.is_empty()) return; |
| 2543 Zone* zone = block()->zone(); |
| 2544 map_unique_ids_.Initialize(map_set_.length(), zone); |
| 2545 for (int i = 0; i < map_set_.length(); i++) { |
| 2546 map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone); |
| 2547 } |
| 2548 } |
| 2549 |
| 2550 |
| 2551 void HLoadNamedFieldPolymorphic::FinalizeUniqueValueId() { |
| 2552 if (!types_unique_ids_.is_empty()) return; |
| 2553 Zone* zone = block()->zone(); |
| 2554 types_unique_ids_.Initialize(types_.length(), zone); |
| 2555 for (int i = 0; i < types_.length(); i++) { |
| 2556 types_unique_ids_.Add(UniqueValueId(types_.at(i)), zone); |
| 2557 } |
| 2558 name_unique_id_ = UniqueValueId(name_); |
| 2559 } |
| 2560 |
| 2561 |
2528 bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) { | 2562 bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) { |
| 2563 ASSERT_EQ(types_.length(), types_unique_ids_.length()); |
2529 HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value); | 2564 HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value); |
2530 if (types_.length() != other->types()->length()) return false; | 2565 if (name_unique_id_ != other->name_unique_id_) return false; |
2531 if (!name_.is_identical_to(other->name())) return false; | 2566 if (types_unique_ids_.length() != other->types_unique_ids_.length()) { |
| 2567 return false; |
| 2568 } |
2532 if (need_generic_ != other->need_generic_) return false; | 2569 if (need_generic_ != other->need_generic_) return false; |
2533 for (int i = 0; i < types_.length(); i++) { | 2570 for (int i = 0; i < types_unique_ids_.length(); i++) { |
2534 bool found = false; | 2571 bool found = false; |
2535 for (int j = 0; j < types_.length(); j++) { | 2572 for (int j = 0; j < types_unique_ids_.length(); j++) { |
2536 if (types_.at(j).is_identical_to(other->types()->at(i))) { | 2573 if (types_unique_ids_.at(j) == other->types_unique_ids_.at(i)) { |
2537 found = true; | 2574 found = true; |
2538 break; | 2575 break; |
2539 } | 2576 } |
2540 } | 2577 } |
2541 if (!found) return false; | 2578 if (!found) return false; |
2542 } | 2579 } |
2543 return true; | 2580 return true; |
2544 } | 2581 } |
2545 | 2582 |
2546 | 2583 |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3533 | 3570 |
3534 | 3571 |
3535 void HCheckFunction::Verify() { | 3572 void HCheckFunction::Verify() { |
3536 HInstruction::Verify(); | 3573 HInstruction::Verify(); |
3537 ASSERT(HasNoUses()); | 3574 ASSERT(HasNoUses()); |
3538 } | 3575 } |
3539 | 3576 |
3540 #endif | 3577 #endif |
3541 | 3578 |
3542 } } // namespace v8::internal | 3579 } } // namespace v8::internal |
OLD | NEW |