Commit 2a440ef4 authored by yangguo's avatar yangguo Committed by Commit bot

Serializer: cache hashmaps on the isolate.

This speeds up multiple uses of the serializer quite a bit.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/1003363003

Cr-Commit-Position: refs/heads/master@{#27340}
parent d0e20d82
...@@ -803,6 +803,7 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) { ...@@ -803,6 +803,7 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) {
DisallowHeapAllocation no_recursive_gc; DisallowHeapAllocation no_recursive_gc;
isolate()->optimizing_compiler_thread()->Flush(); isolate()->optimizing_compiler_thread()->Flush();
} }
isolate()->ClearSerializerData();
mark_compact_collector()->SetFlags(kMakeHeapIterableMask | mark_compact_collector()->SetFlags(kMakeHeapIterableMask |
kReduceMemoryFootprintMask); kReduceMemoryFootprintMask);
isolate_->compilation_cache()->Clear(); isolate_->compilation_cache()->Clear();
......
...@@ -1798,6 +1798,16 @@ void Isolate::GlobalTearDown() { ...@@ -1798,6 +1798,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() { void Isolate::Deinit() {
TRACE_ISOLATE(deinit); TRACE_ISOLATE(deinit);
...@@ -1845,6 +1855,8 @@ void Isolate::Deinit() { ...@@ -1845,6 +1855,8 @@ void Isolate::Deinit() {
heap_profiler_ = NULL; heap_profiler_ = NULL;
delete cpu_profiler_; delete cpu_profiler_;
cpu_profiler_ = NULL; cpu_profiler_ = NULL;
ClearSerializerData();
} }
...@@ -1933,9 +1945,6 @@ Isolate::~Isolate() { ...@@ -1933,9 +1945,6 @@ Isolate::~Isolate() {
delete string_stream_debug_object_cache_; delete string_stream_debug_object_cache_;
string_stream_debug_object_cache_ = NULL; string_stream_debug_object_cache_ = NULL;
delete external_reference_table_;
external_reference_table_ = NULL;
delete random_number_generator_; delete random_number_generator_;
random_number_generator_ = NULL; random_number_generator_ = NULL;
......
...@@ -376,8 +376,9 @@ typedef List<HeapObject*> DebugObjectCache; ...@@ -376,8 +376,9 @@ typedef List<HeapObject*> DebugObjectCache;
V(Relocatable*, relocatable_top, NULL) \ V(Relocatable*, relocatable_top, NULL) \
V(DebugObjectCache*, string_stream_debug_object_cache, NULL) \ V(DebugObjectCache*, string_stream_debug_object_cache, NULL) \
V(Object*, string_stream_current_security_token, NULL) \ V(Object*, string_stream_current_security_token, NULL) \
/* Serializer state. */ \
V(ExternalReferenceTable*, external_reference_table, NULL) \ 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(int, pending_microtask_count, 0) \
V(bool, autorun_microtasks, true) \ V(bool, autorun_microtasks, true) \
V(HStatistics*, hstatistics, NULL) \ V(HStatistics*, hstatistics, NULL) \
...@@ -527,6 +528,8 @@ class Isolate { ...@@ -527,6 +528,8 @@ class Isolate {
static void GlobalTearDown(); static void GlobalTearDown();
void ClearSerializerData();
// Find the PerThread for this particular (isolate, thread) combination // Find the PerThread for this particular (isolate, thread) combination
// If one does not yet exist, return null. // If one does not yet exist, return null.
PerIsolateThreadData* FindPerThreadDataForThisThread(); PerIsolateThreadData* FindPerThreadDataForThisThread();
......
...@@ -338,23 +338,26 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) { ...@@ -338,23 +338,26 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
} }
ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
: map_(HashMap::PointersMatch) { map_ = isolate->external_reference_map();
if (map_ != NULL) return;
map_ = new HashMap(HashMap::PointersMatch);
ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate); ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
for (int i = 0; i < table->size(); ++i) { for (int i = 0; i < table->size(); ++i) {
Address addr = table->address(i); Address addr = table->address(i);
if (addr == ExternalReferenceTable::NotAvailable()) continue; if (addr == ExternalReferenceTable::NotAvailable()) continue;
// We expect no duplicate external references entries in the table. // We expect no duplicate external references entries in the table.
DCHECK_NULL(map_.Lookup(addr, Hash(addr), false)); DCHECK_NULL(map_->Lookup(addr, Hash(addr), false));
map_.Lookup(addr, Hash(addr), true)->value = reinterpret_cast<void*>(i); map_->Lookup(addr, Hash(addr), true)->value = reinterpret_cast<void*>(i);
} }
isolate->set_external_reference_map(map_);
} }
uint32_t ExternalReferenceEncoder::Encode(Address address) const { uint32_t ExternalReferenceEncoder::Encode(Address address) const {
DCHECK_NOT_NULL(address); DCHECK_NOT_NULL(address);
HashMap::Entry* entry = 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); DCHECK_NOT_NULL(entry);
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
} }
...@@ -363,14 +366,17 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const { ...@@ -363,14 +366,17 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const {
const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
Address address) const { Address address) const {
HashMap::Entry* entry = 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>"; if (entry == NULL) return "<unknown>";
uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
return ExternalReferenceTable::instance(isolate)->name(i); 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(); Object** root_array = isolate->heap()->roots_array_start();
for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i); Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
...@@ -380,15 +386,16 @@ RootIndexMap::RootIndexMap(Isolate* isolate) : map_(HashMap::PointersMatch) { ...@@ -380,15 +386,16 @@ RootIndexMap::RootIndexMap(Isolate* isolate) : map_(HashMap::PointersMatch) {
if (root->IsHeapObject() && if (root->IsHeapObject() &&
isolate->heap()->RootCanBeTreatedAsConstant(root_index)) { isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
HeapObject* heap_object = HeapObject::cast(root); 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) { if (entry != NULL) {
// Some are initialized to a previous value in the root list. // Some are initialized to a previous value in the root list.
DCHECK_LT(GetValue(entry), i); DCHECK_LT(GetValue(entry), i);
} else { } else {
SetValue(LookupEntry(&map_, heap_object, true), i); SetValue(LookupEntry(map_, heap_object, true), i);
} }
} }
} }
isolate->set_root_index_map(map_);
} }
...@@ -1202,7 +1209,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space, ...@@ -1202,7 +1209,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
: isolate_(isolate), : isolate_(isolate),
sink_(sink), sink_(sink),
external_reference_encoder_(new ExternalReferenceEncoder(isolate)), external_reference_encoder_(isolate),
root_index_map_(isolate), root_index_map_(isolate),
code_address_map_(NULL), code_address_map_(NULL),
large_objects_total_size_(0), large_objects_total_size_(0),
...@@ -1218,7 +1225,6 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) ...@@ -1218,7 +1225,6 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
Serializer::~Serializer() { Serializer::~Serializer() {
delete external_reference_encoder_;
if (code_address_map_ != NULL) delete code_address_map_; if (code_address_map_ != NULL) delete code_address_map_;
} }
......
...@@ -63,7 +63,7 @@ class ExternalReferenceEncoder { ...@@ -63,7 +63,7 @@ class ExternalReferenceEncoder {
kPointerSizeLog2); kPointerSizeLog2);
} }
HashMap map_; HashMap* map_;
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder); DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
}; };
...@@ -102,13 +102,13 @@ class RootIndexMap : public AddressMapBase { ...@@ -102,13 +102,13 @@ class RootIndexMap : public AddressMapBase {
static const int kInvalidRootIndex = -1; static const int kInvalidRootIndex = -1;
int Lookup(HeapObject* obj) { int Lookup(HeapObject* obj) {
HashMap::Entry* entry = LookupEntry(&map_, obj, false); HashMap::Entry* entry = LookupEntry(map_, obj, false);
if (entry) return GetValue(entry); if (entry) return GetValue(entry);
return kInvalidRootIndex; return kInvalidRootIndex;
} }
private: private:
HashMap map_; HashMap* map_;
DISALLOW_COPY_AND_ASSIGN(RootIndexMap); DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
}; };
...@@ -687,7 +687,7 @@ class Serializer : public SerializerDeserializer { ...@@ -687,7 +687,7 @@ class Serializer : public SerializerDeserializer {
BackReference AllocateLargeObject(int size); BackReference AllocateLargeObject(int size);
BackReference Allocate(AllocationSpace space, int size); BackReference Allocate(AllocationSpace space, int size);
int EncodeExternalReference(Address addr) { 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. // GetInt reads 4 bytes at once, requiring padding at the end.
...@@ -714,7 +714,7 @@ class Serializer : public SerializerDeserializer { ...@@ -714,7 +714,7 @@ class Serializer : public SerializerDeserializer {
Isolate* isolate_; Isolate* isolate_;
SnapshotByteSink* sink_; SnapshotByteSink* sink_;
ExternalReferenceEncoder* external_reference_encoder_; ExternalReferenceEncoder external_reference_encoder_;
BackReferenceMap back_reference_map_; BackReferenceMap back_reference_map_;
RootIndexMap root_index_map_; RootIndexMap root_index_map_;
......
...@@ -14,7 +14,7 @@ namespace v8 { ...@@ -14,7 +14,7 @@ namespace v8 {
namespace internal { namespace internal {
void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) { 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; position_ += number_of_bytes;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment