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

Unified Diff: src/heap.cc

Issue 467037: External string table. (Closed)
Patch Set: Created 11 years 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/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 4e4cd1c051e570621916663aa5a88cc342b41682..17cb8a1cb177ace7355c84388bfc58ac8d592bd2 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -733,7 +733,7 @@ void Heap::Scavenge() {
ScavengeVisitor scavenge_visitor;
// Copy roots.
- IterateRoots(&scavenge_visitor, VISIT_ALL);
+ IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
// Copy objects reachable from the old generation. By definition,
// there are no intergenerational pointers in code or data spaces.
@@ -753,6 +753,63 @@ void Heap::Scavenge() {
}
}
+ new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
+
+ ScavengeExternalStringTable();
+ ASSERT(new_space_front == new_space_.top());
+
+ // Set age mark.
+ new_space_.set_age_mark(new_space_.top());
+
+ // Update how much has survived scavenge.
+ survived_since_last_expansion_ +=
+ (PromotedSpaceSize() - survived_watermark) + new_space_.Size();
+
+ LOG(ResourceEvent("scavenge", "end"));
+
+ gc_state_ = NOT_IN_GC;
+}
+
+
+void Heap::ScavengeExternalStringTable() {
+ ExternalStringTable::Verify();
+
+ if (ExternalStringTable::new_space_strings_.is_empty()) return;
+
+ Object** start = &ExternalStringTable::new_space_strings_[0];
+ Object** end = start + ExternalStringTable::new_space_strings_.length();
+ Object** last = start;
+
+ for (Object** p = start; p < end; ++p) {
+ ASSERT(Heap::InFromSpace(*p));
+ MapWord first_word = HeapObject::cast(*p)->map_word();
+
+ if (!first_word.IsForwardingAddress()) {
+ // Unreachable external string can be finalized.
+ FinalizeExternalString(String::cast(*p));
+ continue;
+ }
+
+ // String is still reachable.
+ String* target = String::cast(first_word.ToForwardingAddress());
+ ASSERT(target->IsExternalString());
+
+ if (Heap::InNewSpace(target)) {
+ // String is still in new space. Update the table entry.
+ *last = target;
+ ++last;
+ } else {
+ // String got promoted. Move it to the old string list.
+ ExternalStringTable::AddOldString(target);
+ }
+ }
+
+ ExternalStringTable::ShrinkNewStrings(last - start);
+}
+
+
+Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
+ Address new_space_front) {
do {
ASSERT(new_space_front <= new_space_.top());
@@ -761,7 +818,7 @@ void Heap::Scavenge() {
// queue is empty.
while (new_space_front < new_space_.top()) {
HeapObject* object = HeapObject::FromAddress(new_space_front);
- object->Iterate(&scavenge_visitor);
+ object->Iterate(scavenge_visitor);
new_space_front += object->Size();
}
@@ -783,7 +840,7 @@ void Heap::Scavenge() {
RecordCopiedObject(target);
#endif
// Visit the newly copied object for pointers to new space.
- target->Iterate(&scavenge_visitor);
+ target->Iterate(scavenge_visitor);
UpdateRSet(target);
}
@@ -791,16 +848,7 @@ void Heap::Scavenge() {
// (there are currently no more unswept promoted objects).
} while (new_space_front < new_space_.top());
- // Set age mark.
- new_space_.set_age_mark(new_space_.top());
-
- // Update how much has survived scavenge.
- survived_since_last_expansion_ +=
- (PromotedSpaceSize() - survived_watermark) + new_space_.Size();
-
- LOG(ResourceEvent("scavenge", "end"));
-
- gc_state_ = NOT_IN_GC;
+ return new_space_front;
}
@@ -3175,6 +3223,11 @@ void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
IterateStrongRoots(v, mode);
v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
v->Synchronize("symbol_table");
+ if (mode != VISIT_ALL_IN_SCAVENGE) {
+ // Scavenge collections have special processing for this.
+ ExternalStringTable::Iterate(v);
+ }
+ v->Synchronize("external_string_table");
}
@@ -3203,11 +3256,12 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
HandleScopeImplementer::Iterate(v);
v->Synchronize("handlescope");
- // Iterate over the builtin code objects and code stubs in the heap. Note
- // that it is not strictly necessary to iterate over code objects on
- // scavenge collections. We still do it here because this same function
- // is used by the mark-sweep collector and the deserializer.
- Builtins::IterateBuiltins(v);
+ // Iterate over the builtin code objects and code stubs in the
+ // heap. Note that it is not necessary to iterate over code objects
+ // on scavenge collections.
+ if (mode != VISIT_ALL_IN_SCAVENGE) {
+ Builtins::IterateBuiltins(v);
+ }
v->Synchronize("builtins");
// Iterate over global handles.
@@ -3424,6 +3478,8 @@ void Heap::SetStackLimits() {
void Heap::TearDown() {
GlobalHandles::TearDown();
+ ExternalStringTable::TearDown();
+
new_space_.TearDown();
if (old_pointer_space_ != NULL) {
@@ -3839,8 +3895,8 @@ class MarkRootVisitor: public ObjectVisitor {
// Triggers a depth-first traversal of reachable objects from roots
// and finds a path to a specific heap object and prints it.
-void Heap::TracePathToObject() {
- search_target = NULL;
+void Heap::TracePathToObject(Object* target) {
+ search_target = target;
search_for_any_global = false;
MarkRootVisitor root_visitor;
@@ -3991,4 +4047,37 @@ void TranscendentalCache::Clear() {
}
+void ExternalStringTable::CleanUp() {
+ CleanUpList(true);
+ CleanUpList(false);
+ Verify();
+}
+
+
+void ExternalStringTable::CleanUpList(bool new_to_old) {
+ List<Object*>& source = new_to_old ? new_space_strings_ : old_space_strings_;
+ if (source.is_empty()) return;
+ List<Object*>& target = new_to_old ? old_space_strings_ : new_space_strings_;
Mads Ager (chromium) 2009/12/08 16:18:40 Use old_space_strings_ as the target always? It s
Vitaly Repeshko 2009/12/09 14:33:23 Makes sense. Done.
+ int last = 0;
+ for (int i = 0; i < source.length(); ++i) {
+ if (source[i] == Heap::raw_unchecked_null_value()) continue;
+ if (Heap::InNewSpace(source[i]) == new_to_old) {
+ source[last++] = source[i];
+ } else {
+ target.Add(source[i]);
+ }
+ }
+ source.Rewind(last);
+}
+
+
+void ExternalStringTable::TearDown() {
+ new_space_strings_.Free();
+ old_space_strings_.Free();
+}
+
+
+List<Object*> ExternalStringTable::new_space_strings_;
+List<Object*> ExternalStringTable::old_space_strings_;
+
} } // namespace v8::internal
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698