Reviewers: mvstanton,
Description:
Serializer: cache hashmaps on the isolate.
This speeds up multiple uses of the serializer quite a bit.
[email protected]
Please review this at https://codereview.chromium.org/1003363003/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+68, -21 lines):
M src/heap/heap.cc
M src/isolate.h
M src/isolate.cc
M src/serialize.h
M src/serialize.cc
M src/snapshot-source-sink.cc
M test/cctest/test-serialize.cc
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index
66f98ced9816c26714e874e22b99d0232c87c53b..19b0fa8f3537d8d1c26ad73e5cc240996933973c
100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -784,6 +784,7 @@ void Heap::CollectAllAvailableGarbage(const char*
gc_reason) {
DisallowHeapAllocation no_recursive_gc;
isolate()->optimizing_compiler_thread()->Flush();
}
+ isolate()->ClearSerializerData();
mark_compact_collector()->SetFlags(kMakeHeapIterableMask |
kReduceMemoryFootprintMask);
isolate_->compilation_cache()->Clear();
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index
62dad8df706c2b265eab7e43f24e72c07c22c1c0..cc114c977cf5af69db3e1013f339fcc6c90f2059
100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1816,6 +1816,16 @@ void Isolate::GlobalTearDown() {
}
+void Isolate::ClearSerializerData() {
+ delete external_reference_table_;
+ external_reference_table_ = NULL;
+ delete external_reference_map_;
+ external_reference_map_ = NULL;
+ delete root_index_map_;
+ root_index_map_ = NULL;
+}
+
+
void Isolate::Deinit() {
TRACE_ISOLATE(deinit);
@@ -1863,6 +1873,8 @@ void Isolate::Deinit() {
heap_profiler_ = NULL;
delete cpu_profiler_;
cpu_profiler_ = NULL;
+
+ ClearSerializerData();
}
@@ -1951,9 +1963,6 @@ Isolate::~Isolate() {
delete string_stream_debug_object_cache_;
string_stream_debug_object_cache_ = NULL;
- delete external_reference_table_;
- external_reference_table_ = NULL;
-
delete random_number_generator_;
random_number_generator_ = NULL;
Index: src/isolate.h
diff --git a/src/isolate.h b/src/isolate.h
index
e13409c536a11d7531b5785c9cce6faea3c588db..2b34b73555dc2a8bf0ae7c95aca664c23744a747
100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -376,8 +376,9 @@ typedef List<HeapObject*> DebugObjectCache;
V(Relocatable*, relocatable_top,
NULL) \
V(DebugObjectCache*, string_stream_debug_object_cache,
NULL) \
V(Object*, string_stream_current_security_token,
NULL) \
- /* Serializer state.
*/ \
V(ExternalReferenceTable*, external_reference_table,
NULL) \
+ V(HashMap*, external_reference_map,
NULL) \
+ V(HashMap*, root_index_map,
NULL) \
V(int, pending_microtask_count,
0) \
V(bool, autorun_microtasks,
true) \
V(HStatistics*, hstatistics,
NULL) \
@@ -527,6 +528,8 @@ class Isolate {
static void GlobalTearDown();
+ void ClearSerializerData();
+
// Find the PerThread for this particular (isolate, thread) combination
// If one does not yet exist, return null.
PerIsolateThreadData* FindPerThreadDataForThisThread();
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index
1d33f4f0623e3a38f2f46247b06a6e64eb93f60b..7d28f18caa43dc838ecec8aaabcb1bc54c0bcd01
100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -330,23 +330,26 @@
ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
}
-ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate)
- : map_(HashMap::PointersMatch) {
+ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
+ map_ = isolate->external_reference_map();
+ if (map_ != NULL) return;
+ map_ = new HashMap(HashMap::PointersMatch);
ExternalReferenceTable* table =
ExternalReferenceTable::instance(isolate);
for (int i = 0; i < table->size(); ++i) {
Address addr = table->address(i);
if (addr == ExternalReferenceTable::NotAvailable()) continue;
// We expect no duplicate external references entries in the table.
- DCHECK_NULL(map_.Lookup(addr, Hash(addr), false));
- map_.Lookup(addr, Hash(addr), true)->value =
reinterpret_cast<void*>(i);
+ DCHECK_NULL(map_->Lookup(addr, Hash(addr), false));
+ map_->Lookup(addr, Hash(addr), true)->value =
reinterpret_cast<void*>(i);
}
+ isolate->set_external_reference_map(map_);
}
uint32_t ExternalReferenceEncoder::Encode(Address address) const {
DCHECK_NOT_NULL(address);
HashMap::Entry* entry =
- const_cast<HashMap&>(map_).Lookup(address, Hash(address), false);
+ const_cast<HashMap*>(map_)->Lookup(address, Hash(address), false);
DCHECK_NOT_NULL(entry);
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
}
@@ -355,14 +358,17 @@ uint32_t ExternalReferenceEncoder::Encode(Address
address) const {
const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
Address address) const
{
HashMap::Entry* entry =
- const_cast<HashMap&>(map_).Lookup(address, Hash(address), false);
+ const_cast<HashMap*>(map_)->Lookup(address, Hash(address), false);
if (entry == NULL) return "<unknown>";
uint32_t i =
static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
return ExternalReferenceTable::instance(isolate)->name(i);
}
-RootIndexMap::RootIndexMap(Isolate* isolate) :
map_(HashMap::PointersMatch) {
+RootIndexMap::RootIndexMap(Isolate* isolate) {
+ map_ = isolate->root_index_map();
+ if (map_ != NULL) return;
+ map_ = new HashMap(HashMap::PointersMatch);
Object** root_array = isolate->heap()->roots_array_start();
for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
@@ -372,15 +378,16 @@ RootIndexMap::RootIndexMap(Isolate* isolate) :
map_(HashMap::PointersMatch) {
if (root->IsHeapObject() &&
isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
HeapObject* heap_object = HeapObject::cast(root);
- HashMap::Entry* entry = LookupEntry(&map_, heap_object, false);
+ HashMap::Entry* entry = LookupEntry(map_, heap_object, false);
if (entry != NULL) {
// Some are initialized to a previous value in the root list.
DCHECK_LT(GetValue(entry), i);
} else {
- SetValue(LookupEntry(&map_, heap_object, true), i);
+ SetValue(LookupEntry(map_, heap_object, true), i);
}
}
}
+ isolate->set_root_index_map(map_);
}
@@ -1192,7 +1199,7 @@ void Deserializer::ReadData(Object** current,
Object** limit, int source_space,
Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
: isolate_(isolate),
sink_(sink),
- external_reference_encoder_(new ExternalReferenceEncoder(isolate)),
+ external_reference_encoder_(isolate),
root_index_map_(isolate),
code_address_map_(NULL),
large_objects_total_size_(0),
@@ -1208,7 +1215,6 @@ Serializer::Serializer(Isolate* isolate,
SnapshotByteSink* sink)
Serializer::~Serializer() {
- delete external_reference_encoder_;
if (code_address_map_ != NULL) delete code_address_map_;
}
Index: src/serialize.h
diff --git a/src/serialize.h b/src/serialize.h
index
1614ecd45459099ad78de707895cacd0492b75b4..3f56c53b9878120aa1664ded41c173fa156f1d52
100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -63,7 +63,7 @@ class ExternalReferenceEncoder {
kPointerSizeLog2);
}
- HashMap map_;
+ HashMap* map_;
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
};
@@ -102,13 +102,13 @@ class RootIndexMap : public AddressMapBase {
static const int kInvalidRootIndex = -1;
int Lookup(HeapObject* obj) {
- HashMap::Entry* entry = LookupEntry(&map_, obj, false);
+ HashMap::Entry* entry = LookupEntry(map_, obj, false);
if (entry) return GetValue(entry);
return kInvalidRootIndex;
}
private:
- HashMap map_;
+ HashMap* map_;
DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
};
@@ -687,7 +687,7 @@ class Serializer : public SerializerDeserializer {
BackReference AllocateLargeObject(int size);
BackReference Allocate(AllocationSpace space, int size);
int EncodeExternalReference(Address addr) {
- return external_reference_encoder_->Encode(addr);
+ return external_reference_encoder_.Encode(addr);
}
// GetInt reads 4 bytes at once, requiring padding at the end.
@@ -714,7 +714,7 @@ class Serializer : public SerializerDeserializer {
Isolate* isolate_;
SnapshotByteSink* sink_;
- ExternalReferenceEncoder* external_reference_encoder_;
+ ExternalReferenceEncoder external_reference_encoder_;
BackReferenceMap back_reference_map_;
RootIndexMap root_index_map_;
Index: src/snapshot-source-sink.cc
diff --git a/src/snapshot-source-sink.cc b/src/snapshot-source-sink.cc
index
0054aec27c154afd795199361ef28a2d24e2a51c..eedcee6a9cebc52beea08338e7f9152eafd0b6c1
100644
--- a/src/snapshot-source-sink.cc
+++ b/src/snapshot-source-sink.cc
@@ -14,7 +14,7 @@ namespace v8 {
namespace internal {
void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) {
- MemCopy(to, data_ + position_, number_of_bytes);
+ memcpy(to, data_ + position_, number_of_bytes);
position_ += number_of_bytes;
}
Index: test/cctest/test-serialize.cc
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index
9fadddf4c27a199564430b786307cc4f4a3aee77..2849e7262db199f7b1b26776dddbf13b3c5b3cbd
100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -1549,3 +1549,31 @@ TEST(SerializeInternalReference) {
}
isolate->Dispose();
}
+
+
+TEST(DeserializePerf) {
+ FLAG_serialize_toplevel = true;
+
+ const char* source = "function f() { return 'abc'; }; f() + 'def'";
+ v8::ScriptCompiler::CachedData* cache = ProduceCache(source);
+
+ v8::Isolate* isolate2 = v8::Isolate::New();
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::HandleScope scope(isolate2);
+ v8::Local<v8::Context> context = v8::Context::New(isolate2);
+ reinterpret_cast<Isolate*>(isolate2)->compilation_cache()->Disable();
+ v8::Context::Scope context_scope(context);
+
+ v8::Local<v8::String> source_str = v8_str(source);
+ v8::ScriptOrigin origin(v8_str("test"));
+ v8::ScriptCompiler::Source source(source_str, origin, cache);
+ v8::Local<v8::UnboundScript> script;
+ for (int i = 0; i < 100000; i++) {
+ DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
+ script = v8::ScriptCompiler::CompileUnbound(
+ isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache);
+ }
+ }
+ isolate2->Dispose();
+}
--
--
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.