From 2a440ef46a9b84463b67c92bde74a1821dedef92 Mon Sep 17 00:00:00 2001 From: yangguo Date: Fri, 20 Mar 2015 04:17:09 -0700 Subject: [PATCH] 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} --- src/heap/heap.cc | 1 + src/isolate.cc | 15 ++++++++++++--- src/isolate.h | 5 ++++- src/serialize.cc | 28 +++++++++++++++++----------- src/serialize.h | 10 +++++----- src/snapshot-source-sink.cc | 2 +- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 054ebce..483b091 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -803,6 +803,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(); diff --git a/src/isolate.cc b/src/isolate.cc index 462065c..ca38e9f 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -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() { TRACE_ISOLATE(deinit); @@ -1845,6 +1855,8 @@ void Isolate::Deinit() { heap_profiler_ = NULL; delete cpu_profiler_; cpu_profiler_ = NULL; + + ClearSerializerData(); } @@ -1933,9 +1945,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; diff --git a/src/isolate.h b/src/isolate.h index 1fc089d..fcb629e 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -376,8 +376,9 @@ typedef List 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(); diff --git a/src/serialize.cc b/src/serialize.cc index 848055e..b5b5f54 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -338,23 +338,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(i); + DCHECK_NULL(map_->Lookup(addr, Hash(addr), false)); + map_->Lookup(addr, Hash(addr), true)->value = reinterpret_cast(i); } + isolate->set_external_reference_map(map_); } uint32_t ExternalReferenceEncoder::Encode(Address address) const { DCHECK_NOT_NULL(address); HashMap::Entry* entry = - const_cast(map_).Lookup(address, Hash(address), false); + const_cast(map_)->Lookup(address, Hash(address), false); DCHECK_NOT_NULL(entry); return static_cast(reinterpret_cast(entry->value)); } @@ -363,14 +366,17 @@ uint32_t ExternalReferenceEncoder::Encode(Address address) const { const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, Address address) const { HashMap::Entry* entry = - const_cast(map_).Lookup(address, Hash(address), false); + const_cast(map_)->Lookup(address, Hash(address), false); if (entry == NULL) return ""; uint32_t i = static_cast(reinterpret_cast(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(i); @@ -380,15 +386,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_); } @@ -1202,7 +1209,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), @@ -1218,7 +1225,6 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) Serializer::~Serializer() { - delete external_reference_encoder_; if (code_address_map_ != NULL) delete code_address_map_; } diff --git a/src/serialize.h b/src/serialize.h index 1614ecd..3f56c53 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_; diff --git a/src/snapshot-source-sink.cc b/src/snapshot-source-sink.cc index 0054aec..eedcee6 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; } -- 2.7.4