Version 3.15.1
Put incremental code flushing behind a flag. (Chromium issue 159140)
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@12864 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index 3239597..9113e7b 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -420,6 +420,10 @@
gc_count_++;
unflattened_strings_length_ = 0;
+ if (FLAG_flush_code && FLAG_flush_code_incrementally) {
+ mark_compact_collector()->EnableCodeFlushing(true);
+ }
+
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
@@ -1319,6 +1323,12 @@
}
}
+ // Copy objects reachable from the code flushing candidates list.
+ MarkCompactCollector* collector = mark_compact_collector();
+ if (collector->is_code_flushing_enabled()) {
+ collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor);
+ }
+
// Scavenge object reachable from the native contexts list directly.
scavenge_visitor.VisitPointer(BitCast<Object**>(&native_contexts_list_));
@@ -1562,13 +1572,21 @@
void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
AssertNoAllocation no_allocation;
- class VisitorAdapter : public ObjectVisitor {
+ // Both the external string table and the symbol table may contain
+ // external strings, but neither lists them exhaustively, nor is the
+ // intersection set empty. Therefore we iterate over the external string
+ // table first, ignoring symbols, and then over the symbol table.
+
+ class ExternalStringTableVisitorAdapter : public ObjectVisitor {
public:
- explicit VisitorAdapter(v8::ExternalResourceVisitor* visitor)
- : visitor_(visitor) {}
+ explicit ExternalStringTableVisitorAdapter(
+ v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
virtual void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
- if ((*p)->IsExternalString()) {
+ // Visit non-symbol external strings,
+ // since symbols are listed in the symbol table.
+ if (!(*p)->IsSymbol()) {
+ ASSERT((*p)->IsExternalString());
visitor_->VisitExternalString(Utils::ToLocal(
Handle<String>(String::cast(*p))));
}
@@ -1576,8 +1594,28 @@
}
private:
v8::ExternalResourceVisitor* visitor_;
- } visitor_adapter(visitor);
- external_string_table_.Iterate(&visitor_adapter);
+ } external_string_table_visitor(visitor);
+
+ external_string_table_.Iterate(&external_string_table_visitor);
+
+ class SymbolTableVisitorAdapter : public ObjectVisitor {
+ public:
+ explicit SymbolTableVisitorAdapter(
+ v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
+ virtual void VisitPointers(Object** start, Object** end) {
+ for (Object** p = start; p < end; p++) {
+ if ((*p)->IsExternalString()) {
+ ASSERT((*p)->IsSymbol());
+ visitor_->VisitExternalString(Utils::ToLocal(
+ Handle<String>(String::cast(*p))));
+ }
+ }
+ }
+ private:
+ v8::ExternalResourceVisitor* visitor_;
+ } symbol_table_visitor(visitor);
+
+ symbol_table()->IterateElements(&symbol_table_visitor);
}
@@ -2489,6 +2527,14 @@
}
set_message_object_map(Map::cast(obj));
+ Map* external_map;
+ { MaybeObject* maybe_obj =
+ AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
+ if (!maybe_obj->To(&external_map)) return false;
+ }
+ external_map->set_is_extensible(false);
+ set_external_map(external_map);
+
ASSERT(!InNewSpace(empty_fixed_array()));
return true;
}
@@ -5091,6 +5137,20 @@
}
+MaybeObject* Heap::AllocateExternal(void* value) {
+ Foreign* foreign;
+ { MaybeObject* maybe_result = AllocateForeign(static_cast<Address>(value));
+ if (!maybe_result->To(&foreign)) return maybe_result;
+ }
+ JSObject* external;
+ { MaybeObject* maybe_result = AllocateJSObjectFromMap(external_map());
+ if (!maybe_result->To(&external)) return maybe_result;
+ }
+ external->SetInternalField(0, foreign);
+ return external;
+}
+
+
MaybeObject* Heap::AllocateStruct(InstanceType type) {
Map* map;
switch (type) {
@@ -5534,6 +5594,7 @@
return symbol_table()->LookupSymbolIfExists(string, symbol);
}
+
void Heap::ZapFromSpace() {
NewSpacePageIterator it(new_space_.FromSpaceStart(),
new_space_.FromSpaceEnd());