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

Unified Diff: src/transitions.cc

Issue 1470773003: Optimize ClearNonLiveReferences: do not compact prototype transitions in GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments Created 5 years, 1 month 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/transitions.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/transitions.cc
diff --git a/src/transitions.cc b/src/transitions.cc
index 64b8133528eafebb0f4bd7e4b98acdef614b5b5b..27dbc7a811656d1822c7ebf13566a74f9d4781f7 100644
--- a/src/transitions.cc
+++ b/src/transitions.cc
@@ -234,6 +234,61 @@ bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
// static
+bool TransitionArray::CompactPrototypeTransitionArray(FixedArray* array) {
+ const int header = kProtoTransitionHeaderSize;
+ int number_of_transitions = NumberOfPrototypeTransitions(array);
+ if (number_of_transitions == 0) {
+ // Empty array cannot be compacted.
+ return false;
+ }
+ int new_number_of_transitions = 0;
+ for (int i = 0; i < number_of_transitions; i++) {
+ Object* cell = array->get(header + i);
+ if (!WeakCell::cast(cell)->cleared()) {
+ if (new_number_of_transitions != i) {
+ array->set(header + new_number_of_transitions, cell);
+ }
+ new_number_of_transitions++;
+ }
+ }
+ // Fill slots that became free with undefined value.
+ for (int i = new_number_of_transitions; i < number_of_transitions; i++) {
+ array->set_undefined(header + i);
+ }
+ if (number_of_transitions != new_number_of_transitions) {
+ SetNumberOfPrototypeTransitions(array, new_number_of_transitions);
+ }
+ return new_number_of_transitions < number_of_transitions;
+}
+
+
+// static
+Handle<FixedArray> TransitionArray::GrowPrototypeTransitionArray(
+ Handle<FixedArray> array, int new_capacity, Isolate* isolate) {
+ // Grow array by factor 2 up to MaxCachedPrototypeTransitions.
+ int capacity = array->length() - kProtoTransitionHeaderSize;
+ new_capacity = Min(kMaxCachedPrototypeTransitions, new_capacity);
+ DCHECK_GT(new_capacity, capacity);
+ int grow_by = new_capacity - capacity;
+ array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by);
+ if (capacity < 0) {
+ // There was no prototype transitions array before, so the size
+ // couldn't be copied. Initialize it explicitly.
+ SetNumberOfPrototypeTransitions(*array, 0);
+ }
+ return array;
+}
+
+
+// static
+int TransitionArray::NumberOfPrototypeTransitionsForTest(Map* map) {
+ FixedArray* transitions = GetPrototypeTransitions(map);
+ CompactPrototypeTransitionArray(transitions);
+ return TransitionArray::NumberOfPrototypeTransitions(transitions);
+}
+
+
+// static
void TransitionArray::PutPrototypeTransition(Handle<Map> map,
Handle<Object> prototype,
Handle<Map> target_map) {
@@ -252,23 +307,16 @@ void TransitionArray::PutPrototypeTransition(Handle<Map> map,
int transitions = NumberOfPrototypeTransitions(*cache) + 1;
if (transitions > capacity) {
- // Grow array by factor 2 up to MaxCachedPrototypeTransitions.
- int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions * 2);
- if (new_capacity == capacity) return;
- int grow_by = new_capacity - capacity;
-
- Isolate* isolate = map->GetIsolate();
- cache = isolate->factory()->CopyFixedArrayAndGrow(cache, grow_by);
- if (capacity < 0) {
- // There was no prototype transitions array before, so the size
- // couldn't be copied. Initialize it explicitly.
- SetNumberOfPrototypeTransitions(*cache, 0);
+ // Grow the array if compacting it doesn't free space.
+ if (!CompactPrototypeTransitionArray(*cache)) {
+ if (capacity == kMaxCachedPrototypeTransitions) return;
+ cache = GrowPrototypeTransitionArray(cache, 2 * transitions,
+ map->GetIsolate());
+ SetPrototypeTransitions(map, cache);
}
-
- SetPrototypeTransitions(map, cache);
}
- // Reload number of transitions as GC might shrink them.
+ // Reload number of transitions as they might have been compacted.
int last = NumberOfPrototypeTransitions(*cache);
int entry = header + last;
@@ -387,25 +435,9 @@ void TransitionArray::ReplaceTransitions(Handle<Map> map,
}
-static void ZapPrototypeTransitions(Object* raw_transitions) {
- DCHECK(TransitionArray::IsFullTransitionArray(raw_transitions));
- TransitionArray* transitions = TransitionArray::cast(raw_transitions);
- if (!transitions->HasPrototypeTransitions()) return;
- FixedArray* proto_transitions = transitions->GetPrototypeTransitions();
- MemsetPointer(proto_transitions->data_start(),
- proto_transitions->GetHeap()->the_hole_value(),
- proto_transitions->length());
-}
-
-
void TransitionArray::SetPrototypeTransitions(
Handle<Map> map, Handle<FixedArray> proto_transitions) {
EnsureHasFullTransitionArray(map);
- if (Heap::ShouldZapGarbage()) {
- Object* raw_transitions = map->raw_transitions();
- DCHECK(raw_transitions != *proto_transitions);
- ZapPrototypeTransitions(raw_transitions);
- }
TransitionArray* transitions = TransitionArray::cast(map->raw_transitions());
transitions->SetPrototypeTransitions(*proto_transitions);
}
@@ -444,8 +476,10 @@ void TransitionArray::TraverseTransitionTreeInternal(Map* map,
for (int i = 0; i < NumberOfPrototypeTransitions(proto_trans); ++i) {
int index = TransitionArray::kProtoTransitionHeaderSize + i;
WeakCell* cell = WeakCell::cast(proto_trans->get(index));
- TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
- data);
+ if (!cell->cleared()) {
+ TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
+ data);
+ }
}
}
for (int i = 0; i < transitions->number_of_transitions(); ++i) {
« no previous file with comments | « src/transitions.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698