OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 case MachineRepresentation::kWord32: | 1616 case MachineRepresentation::kWord32: |
1617 case MachineRepresentation::kWord64: | 1617 case MachineRepresentation::kWord64: |
1618 case MachineRepresentation::kFloat32: | 1618 case MachineRepresentation::kFloat32: |
1619 case MachineRepresentation::kSimd128: | 1619 case MachineRepresentation::kSimd128: |
1620 case MachineRepresentation::kSimd1x4: | 1620 case MachineRepresentation::kSimd1x4: |
1621 case MachineRepresentation::kSimd1x8: | 1621 case MachineRepresentation::kSimd1x8: |
1622 case MachineRepresentation::kSimd1x16: | 1622 case MachineRepresentation::kSimd1x16: |
1623 UNREACHABLE(); | 1623 UNREACHABLE(); |
1624 break; | 1624 break; |
1625 } | 1625 } |
| 1626 // Check if we need to perform a transitioning store. |
1626 Handle<Map> transition_map; | 1627 Handle<Map> transition_map; |
1627 if (access_info.transition_map().ToHandle(&transition_map)) { | 1628 if (access_info.transition_map().ToHandle(&transition_map)) { |
| 1629 // Check if we need to grow the properties backing store |
| 1630 // with this transitioning store. |
| 1631 Handle<Map> original_map(Map::cast(transition_map->GetBackPointer()), |
| 1632 isolate()); |
| 1633 if (original_map->unused_property_fields() == 0) { |
| 1634 DCHECK(!field_index.is_inobject()); |
| 1635 |
| 1636 // Reallocate the properties {storage}. |
| 1637 storage = effect = BuildExtendPropertiesBackingStore( |
| 1638 original_map, storage, effect, control); |
| 1639 |
| 1640 // Perform the actual store. |
| 1641 effect = graph()->NewNode(simplified()->StoreField(field_access), |
| 1642 storage, value, effect, control); |
| 1643 |
| 1644 // Atomically switch to the new properties below. |
| 1645 field_access = AccessBuilder::ForJSObjectProperties(); |
| 1646 value = storage; |
| 1647 storage = receiver; |
| 1648 } |
1628 effect = graph()->NewNode( | 1649 effect = graph()->NewNode( |
1629 common()->BeginRegion(RegionObservability::kObservable), effect); | 1650 common()->BeginRegion(RegionObservability::kObservable), effect); |
1630 effect = graph()->NewNode( | 1651 effect = graph()->NewNode( |
1631 simplified()->StoreField(AccessBuilder::ForMap()), receiver, | 1652 simplified()->StoreField(AccessBuilder::ForMap()), receiver, |
1632 jsgraph()->Constant(transition_map), effect, control); | 1653 jsgraph()->Constant(transition_map), effect, control); |
1633 } | 1654 effect = graph()->NewNode(simplified()->StoreField(field_access), |
1634 effect = graph()->NewNode(simplified()->StoreField(field_access), storage, | 1655 storage, value, effect, control); |
1635 value, effect, control); | |
1636 if (access_info.HasTransitionMap()) { | |
1637 effect = graph()->NewNode(common()->FinishRegion(), | 1656 effect = graph()->NewNode(common()->FinishRegion(), |
1638 jsgraph()->UndefinedConstant(), effect); | 1657 jsgraph()->UndefinedConstant(), effect); |
| 1658 } else { |
| 1659 // Regular non-transitioning field store. |
| 1660 effect = graph()->NewNode(simplified()->StoreField(field_access), |
| 1661 storage, value, effect, control); |
1639 } | 1662 } |
1640 } | 1663 } |
1641 } else { | 1664 } else { |
1642 DCHECK(access_info.IsGeneric()); | 1665 DCHECK(access_info.IsGeneric()); |
1643 DCHECK_EQ(AccessMode::kStore, access_mode); | 1666 DCHECK_EQ(AccessMode::kStore, access_mode); |
1644 DCHECK(vector->IsStoreIC(slot)); | 1667 DCHECK(vector->IsStoreIC(slot)); |
1645 DCHECK_EQ(vector->GetLanguageMode(slot), language_mode); | 1668 DCHECK_EQ(vector->GetLanguageMode(slot), language_mode); |
1646 Callable callable = | 1669 Callable callable = |
1647 CodeFactory::StoreICInOptimizedCode(isolate(), language_mode); | 1670 CodeFactory::StoreICInOptimizedCode(isolate(), language_mode); |
1648 const CallInterfaceDescriptor& descriptor = callable.descriptor(); | 1671 const CallInterfaceDescriptor& descriptor = callable.descriptor(); |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 for (Handle<Map> map : receiver_maps) { | 2179 for (Handle<Map> map : receiver_maps) { |
2157 maps.insert(map, graph()->zone()); | 2180 maps.insert(map, graph()->zone()); |
2158 if (map->is_migration_target()) { | 2181 if (map->is_migration_target()) { |
2159 flags |= CheckMapsFlag::kTryMigrateInstance; | 2182 flags |= CheckMapsFlag::kTryMigrateInstance; |
2160 } | 2183 } |
2161 } | 2184 } |
2162 return graph()->NewNode(simplified()->CheckMaps(flags, maps), receiver, | 2185 return graph()->NewNode(simplified()->CheckMaps(flags, maps), receiver, |
2163 effect, control); | 2186 effect, control); |
2164 } | 2187 } |
2165 | 2188 |
| 2189 Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore( |
| 2190 Handle<Map> map, Node* properties, Node* effect, Node* control) { |
| 2191 DCHECK_EQ(0, map->unused_property_fields()); |
| 2192 // Compute the length of the old {properties} and the new properties. |
| 2193 int length = map->NextFreePropertyIndex() - map->GetInObjectProperties(); |
| 2194 int new_length = length + JSObject::kFieldsAdded; |
| 2195 // Collect the field values from the {properties}. |
| 2196 ZoneVector<Node*> values(zone()); |
| 2197 values.reserve(new_length); |
| 2198 for (int i = 0; i < length; ++i) { |
| 2199 Node* value = effect = graph()->NewNode( |
| 2200 simplified()->LoadField(AccessBuilder::ForFixedArraySlot(i)), |
| 2201 properties, effect, control); |
| 2202 values.push_back(value); |
| 2203 } |
| 2204 // Initialize the new fields to undefined. |
| 2205 for (int i = 0; i < JSObject::kFieldsAdded; ++i) { |
| 2206 values.push_back(jsgraph()->UndefinedConstant()); |
| 2207 } |
| 2208 // Allocate and initialize the new properties. |
| 2209 effect = graph()->NewNode( |
| 2210 common()->BeginRegion(RegionObservability::kNotObservable), effect); |
| 2211 Node* new_properties = effect = graph()->NewNode( |
| 2212 simplified()->Allocate(Type::OtherInternal(), NOT_TENURED), |
| 2213 jsgraph()->Constant(FixedArray::SizeFor(new_length)), effect, control); |
| 2214 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
| 2215 new_properties, jsgraph()->FixedArrayMapConstant(), |
| 2216 effect, control); |
| 2217 effect = graph()->NewNode( |
| 2218 simplified()->StoreField(AccessBuilder::ForFixedArrayLength()), |
| 2219 new_properties, jsgraph()->Constant(new_length), effect, control); |
| 2220 for (int i = 0; i < new_length; ++i) { |
| 2221 effect = graph()->NewNode( |
| 2222 simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), |
| 2223 new_properties, values[i], effect, control); |
| 2224 } |
| 2225 return graph()->NewNode(common()->FinishRegion(), new_properties, effect); |
| 2226 } |
| 2227 |
2166 void JSNativeContextSpecialization::AssumePrototypesStable( | 2228 void JSNativeContextSpecialization::AssumePrototypesStable( |
2167 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) { | 2229 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) { |
2168 // Determine actual holder and perform prototype chain checks. | 2230 // Determine actual holder and perform prototype chain checks. |
2169 for (auto map : receiver_maps) { | 2231 for (auto map : receiver_maps) { |
2170 // Perform the implicit ToObject for primitives here. | 2232 // Perform the implicit ToObject for primitives here. |
2171 // Implemented according to ES6 section 7.3.2 GetV (V, P). | 2233 // Implemented according to ES6 section 7.3.2 GetV (V, P). |
2172 Handle<JSFunction> constructor; | 2234 Handle<JSFunction> constructor; |
2173 if (Map::GetConstructorFunction(map, native_context()) | 2235 if (Map::GetConstructorFunction(map, native_context()) |
2174 .ToHandle(&constructor)) { | 2236 .ToHandle(&constructor)) { |
2175 map = handle(constructor->initial_map(), isolate()); | 2237 map = handle(constructor->initial_map(), isolate()); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2315 return jsgraph()->javascript(); | 2377 return jsgraph()->javascript(); |
2316 } | 2378 } |
2317 | 2379 |
2318 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2380 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
2319 return jsgraph()->simplified(); | 2381 return jsgraph()->simplified(); |
2320 } | 2382 } |
2321 | 2383 |
2322 } // namespace compiler | 2384 } // namespace compiler |
2323 } // namespace internal | 2385 } // namespace internal |
2324 } // namespace v8 | 2386 } // namespace v8 |
OLD | NEW |