summaryrefslogtreecommitdiff
path: root/deps/v8/src/mark-compact.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mark-compact.cc')
-rw-r--r--deps/v8/src/mark-compact.cc74
1 files changed, 64 insertions, 10 deletions
diff --git a/deps/v8/src/mark-compact.cc b/deps/v8/src/mark-compact.cc
index 7a5353745..81819b7f6 100644
--- a/deps/v8/src/mark-compact.cc
+++ b/deps/v8/src/mark-compact.cc
@@ -155,8 +155,6 @@ void MarkCompactCollector::Finish() {
// objects (empty string, illegal builtin).
StubCache::Clear();
- ExternalStringTable::CleanUp();
-
// If we've just compacted old space there's no reason to check the
// fragmentation limit. Just return.
if (HasCompacted()) return;
@@ -371,18 +369,41 @@ class RootMarkingVisitor : public ObjectVisitor {
class SymbolTableCleaner : public ObjectVisitor {
public:
SymbolTableCleaner() : pointers_removed_(0) { }
-
- virtual void VisitPointers(Object** start, Object** end) {
+ void VisitPointers(Object** start, Object** end) {
// Visit all HeapObject pointers in [start, end).
for (Object** p = start; p < end; p++) {
if ((*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked()) {
// Check if the symbol being pruned is an external symbol. We need to
// delete the associated external data as this symbol is going away.
+ // Since the object is not marked we can access its map word safely
+ // without having to worry about marking bits in the object header.
+ Map* map = HeapObject::cast(*p)->map();
// Since no objects have yet been moved we can safely access the map of
// the object.
- if ((*p)->IsExternalString()) {
- Heap::FinalizeExternalString(String::cast(*p));
+ uint32_t type = map->instance_type();
+ bool is_external = (type & kStringRepresentationMask) ==
+ kExternalStringTag;
+ if (is_external) {
+ bool is_two_byte = (type & kStringEncodingMask) == kTwoByteStringTag;
+ byte* resource_addr = reinterpret_cast<byte*>(*p) +
+ ExternalString::kResourceOffset -
+ kHeapObjectTag;
+ if (is_two_byte) {
+ v8::String::ExternalStringResource** resource =
+ reinterpret_cast<v8::String::ExternalStringResource**>
+ (resource_addr);
+ delete *resource;
+ // Clear the resource pointer in the symbol.
+ *resource = NULL;
+ } else {
+ v8::String::ExternalAsciiStringResource** resource =
+ reinterpret_cast<v8::String::ExternalAsciiStringResource**>
+ (resource_addr);
+ delete *resource;
+ // Clear the resource pointer in the symbol.
+ *resource = NULL;
+ }
}
// Set the entry to null_value (as deleted).
*p = Heap::raw_unchecked_null_value();
@@ -525,7 +546,34 @@ bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
}
+class SymbolMarkingVisitor : public ObjectVisitor {
+ public:
+ void VisitPointers(Object** start, Object** end) {
+ MarkingVisitor marker;
+ for (Object** p = start; p < end; p++) {
+ if (!(*p)->IsHeapObject()) continue;
+
+ HeapObject* object = HeapObject::cast(*p);
+ // If the object is marked, we have marked or are in the process
+ // of marking subparts.
+ if (object->IsMarked()) continue;
+
+ // The object is unmarked, we do not need to unmark to use its
+ // map.
+ Map* map = object->map();
+ object->IterateBody(map->instance_type(),
+ object->SizeFromMap(map),
+ &marker);
+ }
+ }
+};
+
+
void MarkCompactCollector::MarkSymbolTable() {
+ // Objects reachable from symbols are marked as live so as to ensure
+ // that if the symbol itself remains alive after GC for any reason,
+ // and if it is a cons string backed by an external string (even indirectly),
+ // then the external string does not receive a weak reference callback.
SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
// Mark the symbol table itself.
SetMark(symbol_table);
@@ -533,6 +581,11 @@ void MarkCompactCollector::MarkSymbolTable() {
MarkingVisitor marker;
symbol_table->IteratePrefix(&marker);
ProcessMarkingStack(&marker);
+ // Mark subparts of the symbols but not the symbols themselves
+ // (unless reachable from another symbol).
+ SymbolMarkingVisitor symbol_marker;
+ symbol_table->IterateElements(&symbol_marker);
+ ProcessMarkingStack(&marker);
}
@@ -721,8 +774,6 @@ void MarkCompactCollector::MarkLiveObjects() {
SymbolTableCleaner v;
symbol_table->IterateElements(&v);
symbol_table->ElementsRemoved(v.PointersRemoved());
- ExternalStringTable::Iterate(&v);
- ExternalStringTable::CleanUp();
// Remove object groups after marking phase.
GlobalHandles::RemoveObjectGroups();
@@ -836,8 +887,11 @@ void MarkCompactCollector::ClearNonLiveTransitions() {
// space are encoded in their map pointer word (along with an encoding of
// their map pointers).
//
-// The excact encoding is described in the comments for class MapWord in
-// objects.h.
+// 31 21 20 10 9 0
+// +-----------------+------------------+-----------------+
+// |forwarding offset|page offset of map|page index of map|
+// +-----------------+------------------+-----------------+
+// 11 bits 11 bits 10 bits
//
// An address range [start, end) can have both live and non-live objects.
// Maximal non-live regions are marked so they can be skipped on subsequent