Reviewers: Hannes Payer,
Message:
PTAL. The slots recording was omitted before because maps don't move. Now
they
replaced by weakcells, which can move.
Description:
Reland "Replace ad-hoc weakness in prototype transitions with WeakCell."
Added missing slots recording.
This reverts commit fd2e3344d3116cd9ca11a14a1f4d800effba25ba.
BUG=
Please review this at https://codereview.chromium.org/1169743002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+30, -28 lines):
M src/heap/mark-compact.cc
M src/heap/objects-visiting-inl.h
M src/transitions.h
M src/transitions.cc
M test/cctest/test-heap.cc
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index
53bd132ac0be4da9bc3241c4800e9ccc65dcd3d6..5a4a1a7036739a6aa79154c924a182b72a7442f0
100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -2404,11 +2404,13 @@ void
MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
const int header = TransitionArray::kProtoTransitionHeaderSize;
int new_number_of_transitions = 0;
for (int i = 0; i < number_of_transitions; i++) {
- Object* cached_map = prototype_transitions->get(header + i);
- if (IsMarked(cached_map)) {
+ Object* cell = prototype_transitions->get(header + i);
+ if (!WeakCell::cast(cell)->cleared()) {
if (new_number_of_transitions != i) {
- prototype_transitions->set(header + new_number_of_transitions,
- cached_map, SKIP_WRITE_BARRIER);
+ prototype_transitions->set(header + new_number_of_transitions,
cell);
+ Object** slot = prototype_transitions->RawFieldOfElementAt(
+ header + new_number_of_transitions);
+ RecordSlot(slot, slot, cell);
}
new_number_of_transitions++;
}
Index: src/heap/objects-visiting-inl.h
diff --git a/src/heap/objects-visiting-inl.h
b/src/heap/objects-visiting-inl.h
index
d1d52a4c7a7b0c548838d566fb2195364a4ceb7a..7f83f483ba750e9e149da2c8ed580f5f6fe0dee0
100644
--- a/src/heap/objects-visiting-inl.h
+++ b/src/heap/objects-visiting-inl.h
@@ -571,13 +571,8 @@ void
StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray(
if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return;
if (transitions->HasPrototypeTransitions()) {
- // Mark prototype transitions array but do not push it onto marking
- // stack, this will make references from it weak. We will clean dead
- // prototype transitions in ClearNonLiveReferences.
- Object** slot = transitions->GetPrototypeTransitionsSlot();
- HeapObject* obj = HeapObject::cast(*slot);
- heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
- StaticVisitor::MarkObjectWithoutPush(heap, obj);
+ StaticVisitor::VisitPointer(heap,
+
transitions->GetPrototypeTransitionsSlot());
}
int num_transitions = TransitionArray::NumberOfTransitions(transitions);
Index: src/transitions.cc
diff --git a/src/transitions.cc b/src/transitions.cc
index
63bb7fa68f515db5bb90e64fc4629e1807c6b898..c39534bbb566a2930934d2a56482517a2d18e1c6
100644
--- a/src/transitions.cc
+++ b/src/transitions.cc
@@ -233,17 +233,19 @@ bool
TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
// static
-Handle<Map> TransitionArray::PutPrototypeTransition(Handle<Map> map,
- Handle<Object>
prototype,
- Handle<Map>
target_map) {
+void TransitionArray::PutPrototypeTransition(Handle<Map> map,
+ Handle<Object> prototype,
+ Handle<Map> target_map) {
DCHECK(HeapObject::cast(*prototype)->map()->IsMap());
// Don't cache prototype transition if this map is either shared, or a
map of
// a prototype.
- if (map->is_prototype_map()) return map;
- if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions)
return map;
+ if (map->is_prototype_map()) return;
+ if (map->is_dictionary_map() || !FLAG_cache_prototype_transitions)
return;
const int header = kProtoTransitionHeaderSize;
+ Handle<WeakCell> target_cell = Map::WeakCellForMap(target_map);
+
Handle<FixedArray> cache(GetPrototypeTransitions(*map));
int capacity = cache->length() - header;
int transitions = NumberOfPrototypeTransitions(*cache) + 1;
@@ -251,7 +253,7 @@ Handle<Map>
TransitionArray::PutPrototypeTransition(Handle<Map> map,
if (transitions > capacity) {
// Grow array by factor 2 up to MaxCachedPrototypeTransitions.
int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions *
2);
- if (new_capacity == capacity) return map;
+ if (new_capacity == capacity) return;
cache = FixedArray::CopySize(cache, header + new_capacity);
if (capacity < 0) {
@@ -267,10 +269,8 @@ Handle<Map>
TransitionArray::PutPrototypeTransition(Handle<Map> map,
int last = NumberOfPrototypeTransitions(*cache);
int entry = header + last;
- cache->set(entry, *target_map);
+ cache->set(entry, *target_cell);
SetNumberOfPrototypeTransitions(*cache, last + 1);
-
- return map;
}
@@ -281,8 +281,12 @@ Handle<Map>
TransitionArray::GetPrototypeTransition(Handle<Map> map,
FixedArray* cache = GetPrototypeTransitions(*map);
int number_of_transitions = NumberOfPrototypeTransitions(cache);
for (int i = 0; i < number_of_transitions; i++) {
- Map* target = Map::cast(cache->get(kProtoTransitionHeaderSize + i));
- if (target->prototype() == *prototype) return handle(target);
+ WeakCell* target_cell =
+ WeakCell::cast(cache->get(kProtoTransitionHeaderSize + i));
+ if (!target_cell->cleared() &&
+ Map::cast(target_cell->value())->prototype() == *prototype) {
+ return handle(Map::cast(target_cell->value()));
+ }
}
return Handle<Map>();
}
@@ -436,8 +440,9 @@ void
TransitionArray::TraverseTransitionTreeInternal(Map* map,
FixedArray* proto_trans = transitions->GetPrototypeTransitions();
for (int i = 0; i < NumberOfPrototypeTransitions(proto_trans); ++i) {
int index = TransitionArray::kProtoTransitionHeaderSize + i;
- TraverseTransitionTreeInternal(Map::cast(proto_trans->get(index)),
- callback, data);
+ WeakCell* cell = WeakCell::cast(proto_trans->get(index));
+ TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
+ data);
}
}
for (int i = 0; i < transitions->number_of_transitions(); ++i) {
Index: src/transitions.h
diff --git a/src/transitions.h b/src/transitions.h
index
1cb91a222e6fec33133c3c3fd060102cb01a3750..b0aab9502e5d2e08dd810ae16aac23cc5edd7bf5
100644
--- a/src/transitions.h
+++ b/src/transitions.h
@@ -92,9 +92,8 @@ class TransitionArray: public FixedArray {
// 0: finger - index of the first free cell in the cache
// 1 + i: target map
static const int kMaxCachedPrototypeTransitions = 256;
- static Handle<Map> PutPrototypeTransition(Handle<Map> map,
- Handle<Object> prototype,
- Handle<Map> target_map);
+ static void PutPrototypeTransition(Handle<Map> map, Handle<Object>
prototype,
+ Handle<Map> target_map);
static Handle<Map> GetPrototypeTransition(Handle<Map> map,
Handle<Object> prototype);
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index
f0dc643fc60f3a06b65e190bdc534ff7aca9735b..0a4cf2b1e4006a7983ef6cd158a252d116ea94e3
100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -2521,7 +2521,8 @@ TEST(PrototypeTransitionClearing) {
TransitionArray::GetPrototypeTransitions(baseObject->map());
for (int i = initialTransitions; i < initialTransitions + transitions;
i++) {
int j = TransitionArray::kProtoTransitionHeaderSize + i;
- CHECK(trans->get(j)->IsMap());
+ CHECK(trans->get(j)->IsWeakCell());
+ CHECK(WeakCell::cast(trans->get(j))->value()->IsMap());
}
// Make sure next prototype is placed on an old-space evacuation
candidate.
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.