Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 2778133003: [turbofan] Add support for extending properties backing store. (Closed)
Patch Set: Fix invalid write barrier kind. Allocate can turn into old-space during allocation folding. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-native-context-specialization.cc
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index 602446f651622fc4aa7d071d7feea2b7f51740d9..842b002da7d68dca87c3df8f8f762ec214c5cc09 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -1623,19 +1623,42 @@ JSNativeContextSpecialization::BuildPropertyAccess(
UNREACHABLE();
break;
}
+ // Check if we need to perform a transitioning store.
Handle<Map> transition_map;
if (access_info.transition_map().ToHandle(&transition_map)) {
+ // Check if we need to grow the properties backing store
+ // with this transitioning store.
+ Handle<Map> original_map(Map::cast(transition_map->GetBackPointer()),
+ isolate());
+ if (original_map->unused_property_fields() == 0) {
+ DCHECK(!field_index.is_inobject());
+
+ // Reallocate the properties {storage}.
+ storage = effect = BuildExtendPropertiesBackingStore(
+ original_map, storage, effect, control);
+
+ // Perform the actual store.
+ effect = graph()->NewNode(simplified()->StoreField(field_access),
+ storage, value, effect, control);
+
+ // Atomically switch to the new properties below.
+ field_access = AccessBuilder::ForJSObjectProperties();
+ value = storage;
+ storage = receiver;
+ }
effect = graph()->NewNode(
common()->BeginRegion(RegionObservability::kObservable), effect);
effect = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForMap()), receiver,
jsgraph()->Constant(transition_map), effect, control);
- }
- effect = graph()->NewNode(simplified()->StoreField(field_access), storage,
- value, effect, control);
- if (access_info.HasTransitionMap()) {
+ effect = graph()->NewNode(simplified()->StoreField(field_access),
+ storage, value, effect, control);
effect = graph()->NewNode(common()->FinishRegion(),
jsgraph()->UndefinedConstant(), effect);
+ } else {
+ // Regular non-transitioning field store.
+ effect = graph()->NewNode(simplified()->StoreField(field_access),
+ storage, value, effect, control);
}
}
} else {
@@ -2163,6 +2186,45 @@ Node* JSNativeContextSpecialization::BuildCheckMaps(
effect, control);
}
+Node* JSNativeContextSpecialization::BuildExtendPropertiesBackingStore(
+ Handle<Map> map, Node* properties, Node* effect, Node* control) {
+ DCHECK_EQ(0, map->unused_property_fields());
+ // Compute the length of the old {properties} and the new properties.
+ int length = map->NextFreePropertyIndex() - map->GetInObjectProperties();
+ int new_length = length + JSObject::kFieldsAdded;
+ // Collect the field values from the {properties}.
+ ZoneVector<Node*> values(zone());
+ values.reserve(new_length);
+ for (int i = 0; i < length; ++i) {
+ Node* value = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForFixedArraySlot(i)),
+ properties, effect, control);
+ values.push_back(value);
+ }
+ // Initialize the new fields to undefined.
+ for (int i = 0; i < JSObject::kFieldsAdded; ++i) {
+ values.push_back(jsgraph()->UndefinedConstant());
+ }
+ // Allocate and initialize the new properties.
+ effect = graph()->NewNode(
+ common()->BeginRegion(RegionObservability::kNotObservable), effect);
+ Node* new_properties = effect = graph()->NewNode(
+ simplified()->Allocate(Type::OtherInternal(), NOT_TENURED),
+ jsgraph()->Constant(FixedArray::SizeFor(new_length)), effect, control);
+ effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
+ new_properties, jsgraph()->FixedArrayMapConstant(),
+ effect, control);
+ effect = graph()->NewNode(
+ simplified()->StoreField(AccessBuilder::ForFixedArrayLength()),
+ new_properties, jsgraph()->Constant(new_length), effect, control);
+ for (int i = 0; i < new_length; ++i) {
+ effect = graph()->NewNode(
+ simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)),
+ new_properties, values[i], effect, control);
+ }
+ return graph()->NewNode(common()->FinishRegion(), new_properties, effect);
+}
+
void JSNativeContextSpecialization::AssumePrototypesStable(
std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) {
// Determine actual holder and perform prototype chain checks.
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698