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

Unified Diff: src/objects-inl.h

Issue 982143002: Revert of Simplify and compact transitions storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 41bf13e265cc22f3d39b99983bf85b405f5efa53..a5b2b352d79174ac87f08b4f6bc2d6e5f349f3a9 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1874,6 +1874,41 @@
void JSObject::initialize_elements() {
FixedArrayBase* elements = map()->GetInitialElements();
WRITE_FIELD(this, kElementsOffset, elements);
+}
+
+
+Handle<String> Map::ExpectedTransitionKey(Handle<Map> map) {
+ DisallowHeapAllocation no_gc;
+ if (!map->HasTransitionArray()) return Handle<String>::null();
+ TransitionArray* transitions = map->transitions();
+ if (!transitions->IsSimpleTransition()) return Handle<String>::null();
+ int transition = TransitionArray::kSimpleTransitionIndex;
+ PropertyDetails details = transitions->GetTargetDetails(transition);
+ Name* name = transitions->GetKey(transition);
+ if (details.type() != DATA) return Handle<String>::null();
+ if (details.attributes() != NONE) return Handle<String>::null();
+ if (!name->IsString()) return Handle<String>::null();
+ return Handle<String>(String::cast(name));
+}
+
+
+Handle<Map> Map::ExpectedTransitionTarget(Handle<Map> map) {
+ DCHECK(!ExpectedTransitionKey(map).is_null());
+ return Handle<Map>(map->transitions()->GetTarget(
+ TransitionArray::kSimpleTransitionIndex));
+}
+
+
+Handle<Map> Map::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
+ DisallowHeapAllocation no_allocation;
+ if (!map->HasTransitionArray()) return Handle<Map>::null();
+ TransitionArray* transitions = map->transitions();
+ int transition = transitions->Search(kData, *key, NONE);
+ if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
+ PropertyDetails details = transitions->GetTargetDetails(transition);
+ if (details.type() != DATA) return Handle<Map>::null();
+ DCHECK_EQ(NONE, details.attributes());
+ return Handle<Map>(transitions->GetTarget(transition));
}
@@ -3002,7 +3037,7 @@
return empty_array;
} else if (has_fixed_typed_array_elements()) {
FixedTypedArrayBase* empty_array =
- GetHeap()->EmptyFixedTypedArrayForMap(this);
+ GetHeap()->EmptyFixedTypedArrayForMap(this);
DCHECK(!GetHeap()->InNewSpace(empty_array));
return empty_array;
} else {
@@ -5220,6 +5255,22 @@
}
+// If the descriptor is using the empty transition array, install a new empty
+// transition array that will have place for an element transition.
+static void EnsureHasTransitionArray(Handle<Map> map) {
+ Handle<TransitionArray> transitions;
+ if (!map->HasTransitionArray()) {
+ transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
+ transitions->set_back_pointer_storage(map->GetBackPointer());
+ } else if (!map->transitions()->IsFullTransitionArray()) {
+ transitions = TransitionArray::ExtendToFullTransitionArray(map);
+ } else {
+ return;
+ }
+ map->set_transitions(*transitions);
+}
+
+
LayoutDescriptor* Map::layout_descriptor_gc_safe() {
Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
return LayoutDescriptor::cast_gc_safe(layout_desc);
@@ -5322,13 +5373,127 @@
}
-Map* Map::ElementsTransitionMap() {
- return TransitionArray::SearchSpecial(
- this, GetHeap()->elements_transition_symbol());
-}
-
-
-ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset)
+bool Map::HasElementsTransition() {
+ return HasTransitionArray() && transitions()->HasElementsTransition();
+}
+
+
+bool Map::HasTransitionArray() const {
+ Object* object = READ_FIELD(this, kTransitionsOffset);
+ return object->IsTransitionArray();
+}
+
+
+Map* Map::elements_transition_map() {
+ int index =
+ transitions()->SearchSpecial(GetHeap()->elements_transition_symbol());
+ return transitions()->GetTarget(index);
+}
+
+
+bool Map::CanHaveMoreTransitions() {
+ if (!HasTransitionArray()) return true;
+ return transitions()->number_of_transitions() <
+ TransitionArray::kMaxNumberOfTransitions;
+}
+
+
+Map* Map::GetTransition(int transition_index) {
+ return transitions()->GetTarget(transition_index);
+}
+
+
+int Map::SearchSpecialTransition(Symbol* name) {
+ if (HasTransitionArray()) {
+ return transitions()->SearchSpecial(name);
+ }
+ return TransitionArray::kNotFound;
+}
+
+
+int Map::SearchTransition(PropertyKind kind, Name* name,
+ PropertyAttributes attributes) {
+ if (HasTransitionArray()) {
+ return transitions()->Search(kind, name, attributes);
+ }
+ return TransitionArray::kNotFound;
+}
+
+
+FixedArray* Map::GetPrototypeTransitions() {
+ if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
+ if (!transitions()->HasPrototypeTransitions()) {
+ return GetHeap()->empty_fixed_array();
+ }
+ return transitions()->GetPrototypeTransitions();
+}
+
+
+void Map::SetPrototypeTransitions(
+ Handle<Map> map, Handle<FixedArray> proto_transitions) {
+ EnsureHasTransitionArray(map);
+ int old_number_of_transitions = map->NumberOfProtoTransitions();
+ if (Heap::ShouldZapGarbage() && map->HasPrototypeTransitions()) {
+ DCHECK(map->GetPrototypeTransitions() != *proto_transitions);
+ map->ZapPrototypeTransitions();
+ }
+ map->transitions()->SetPrototypeTransitions(*proto_transitions);
+ map->SetNumberOfProtoTransitions(old_number_of_transitions);
+}
+
+
+bool Map::HasPrototypeTransitions() {
+ return HasTransitionArray() && transitions()->HasPrototypeTransitions();
+}
+
+
+TransitionArray* Map::transitions() const {
+ DCHECK(HasTransitionArray());
+ Object* object = READ_FIELD(this, kTransitionsOffset);
+ return TransitionArray::cast(object);
+}
+
+
+void Map::set_transitions(TransitionArray* transition_array,
+ WriteBarrierMode mode) {
+ // Transition arrays are not shared. When one is replaced, it should not
+ // keep referenced objects alive, so we zap it.
+ // When there is another reference to the array somewhere (e.g. a handle),
+ // not zapping turns from a waste of memory into a source of crashes.
+ if (HasTransitionArray()) {
+#ifdef DEBUG
+ for (int i = 0; i < transitions()->number_of_transitions(); i++) {
+ Map* target = transitions()->GetTarget(i);
+ if (target->instance_descriptors() == instance_descriptors()) {
+ Name* key = transitions()->GetKey(i);
+ int new_target_index;
+ if (TransitionArray::IsSpecialTransition(key)) {
+ new_target_index = transition_array->SearchSpecial(Symbol::cast(key));
+ } else {
+ PropertyDetails details =
+ TransitionArray::GetTargetDetails(key, target);
+ new_target_index = transition_array->Search(details.kind(), key,
+ details.attributes());
+ }
+ DCHECK_NE(TransitionArray::kNotFound, new_target_index);
+ DCHECK_EQ(target, transition_array->GetTarget(new_target_index));
+ }
+ }
+#endif
+ DCHECK(transitions() != transition_array);
+ ZapTransitions();
+ }
+
+ WRITE_FIELD(this, kTransitionsOffset, transition_array);
+ CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTransitionsOffset,
+ transition_array, mode);
+}
+
+
+void Map::init_transitions(Object* undefined) {
+ DCHECK(undefined->IsUndefined());
+ WRITE_FIELD(this, kTransitionsOffset, undefined);
+}
void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
@@ -5347,7 +5512,6 @@
ACCESSORS(Map, constructor_or_backpointer, Object,
kConstructorOrBackPointerOffset)
-
Object* Map::GetConstructor() const {
Object* maybe_constructor = constructor_or_backpointer();
// Follow any back pointers.
@@ -5357,14 +5521,11 @@
}
return maybe_constructor;
}
-
-
void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) {
// Never overwrite a back pointer with a constructor.
DCHECK(!constructor_or_backpointer()->IsMap());
set_constructor_or_backpointer(constructor, mode);
}
-
ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698