diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/v8/src/snapshot | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/v8/src/snapshot')
-rw-r--r-- | chromium/v8/src/snapshot/OWNERS | 2 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/deserializer.cc | 69 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/deserializer.h | 18 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/partial-serializer.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/partial-serializer.h | 8 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer-common.cc | 4 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer-common.h | 8 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer.cc | 7 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/serializer.h | 26 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot-common.cc | 13 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot-source-sink.cc | 6 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot-source-sink.h | 5 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/snapshot.h | 12 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/startup-serializer.cc | 18 | ||||
-rw-r--r-- | chromium/v8/src/snapshot/startup-serializer.h | 8 |
15 files changed, 193 insertions, 48 deletions
diff --git a/chromium/v8/src/snapshot/OWNERS b/chromium/v8/src/snapshot/OWNERS index 6c84c07df77..752ee3c8f60 100644 --- a/chromium/v8/src/snapshot/OWNERS +++ b/chromium/v8/src/snapshot/OWNERS @@ -3,3 +3,5 @@ set noparent verwaest@chromium.org vogelheim@chromium.org yangguo@chromium.org + +# COMPONENT: Blink>JavaScript>Runtime diff --git a/chromium/v8/src/snapshot/deserializer.cc b/chromium/v8/src/snapshot/deserializer.cc index c76e4eca542..a01fa67c881 100644 --- a/chromium/v8/src/snapshot/deserializer.cc +++ b/chromium/v8/src/snapshot/deserializer.cc @@ -116,15 +116,19 @@ void Deserializer::Deserialize(Isolate* isolate) { isolate_->heap()->undefined_value()); } - // If needed, print the dissassembly of deserialized code objects. - PrintDisassembledCodeObjects(); - // Issue code events for newly deserialized code objects. LOG_CODE_EVENT(isolate_, LogCodeObjects()); LOG_CODE_EVENT(isolate_, LogBytecodeHandlers()); LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); isolate_->builtins()->MarkInitialized(); + + // If needed, print the dissassembly of deserialized code objects. + // Needs to be called after the builtins are marked as initialized, in order + // to display the builtin names. + PrintDisassembledCodeObjects(); + + if (FLAG_rehash_snapshot && can_rehash_) Rehash(); } MaybeHandle<Object> Deserializer::DeserializePartial( @@ -155,6 +159,9 @@ MaybeHandle<Object> Deserializer::DeserializePartial( // changed and logging should be added to notify the profiler et al of the // new code, which also has to be flushed from instruction cache. CHECK_EQ(start_address, code_space->top()); + + if (FLAG_rehash_snapshot && can_rehash_) RehashContext(Context::cast(root)); + return Handle<Object>(root, isolate); } @@ -181,6 +188,30 @@ MaybeHandle<HeapObject> Deserializer::DeserializeObject(Isolate* isolate) { } } +void Deserializer::Rehash() { + DCHECK(can_rehash_); + isolate_->heap()->InitializeHashSeed(); + isolate_->heap()->string_table()->Rehash(); + isolate_->heap()->weak_object_to_code_table()->Rehash(); + SortMapDescriptors(); +} + +void Deserializer::RehashContext(Context* context) { + DCHECK(can_rehash_); + for (const auto& array : transition_arrays_) array->Sort(); + context->global_object()->global_dictionary()->Rehash(); + SortMapDescriptors(); +} + +void Deserializer::SortMapDescriptors() { + for (const auto& address : allocated_maps_) { + Map* map = Map::cast(HeapObject::FromAddress(address)); + if (map->instance_descriptors()->number_of_descriptors() > 1) { + map->instance_descriptors()->Sort(); + } + } +} + Deserializer::~Deserializer() { #ifdef DEBUG // Do not perform checks if we aborted deserialization. @@ -281,34 +312,33 @@ void Deserializer::PrintDisassembledCodeObjects() { } // Used to insert a deserialized internalized string into the string table. -class StringTableInsertionKey : public HashTableKey { +class StringTableInsertionKey : public StringTableKey { public: explicit StringTableInsertionKey(String* string) - : string_(string), hash_(HashForObject(string)) { + : StringTableKey(ComputeHashField(string)), string_(string) { DCHECK(string->IsInternalizedString()); } bool IsMatch(Object* string) override { // We know that all entries in a hash table had their hash keys created. // Use that knowledge to have fast failure. - if (hash_ != HashForObject(string)) return false; + if (Hash() != String::cast(string)->Hash()) return false; // We want to compare the content of two internalized strings here. return string_->SlowEquals(String::cast(string)); } - uint32_t Hash() override { return hash_; } - - uint32_t HashForObject(Object* key) override { - return String::cast(key)->Hash(); - } - - MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) override { + MUST_USE_RESULT Handle<String> AsHandle(Isolate* isolate) override { return handle(string_, isolate); } private: + uint32_t ComputeHashField(String* string) { + // Make sure hash_field() is computed. + string->Hash(); + return string->hash_field(); + } + String* string_; - uint32_t hash_; DisallowHeapAllocation no_gc; }; @@ -338,7 +368,6 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { } } if (obj->IsAllocationSite()) { - DCHECK(obj->IsAllocationSite()); // Allocation sites are present in the snapshot, and must be linked into // a list at deserialization time. AllocationSite* site = AllocationSite::cast(obj); @@ -371,6 +400,16 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { string->resource())); isolate_->heap()->RegisterExternalString(string); } + if (FLAG_rehash_snapshot && can_rehash_ && !deserializing_user_code()) { + if (obj->IsString()) { + // Uninitialize hash field as we are going to reinitialize the hash seed. + String* string = String::cast(obj); + string->set_hash_field(String::kEmptyHashField); + } else if (obj->IsTransitionArray() && + TransitionArray::cast(obj)->number_of_entries() > 1) { + transition_arrays_.Add(TransitionArray::cast(obj)); + } + } // Check alignment. DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment())); return obj; diff --git a/chromium/v8/src/snapshot/deserializer.h b/chromium/v8/src/snapshot/deserializer.h index a56adb67d48..3a650d99743 100644 --- a/chromium/v8/src/snapshot/deserializer.h +++ b/chromium/v8/src/snapshot/deserializer.h @@ -39,7 +39,8 @@ class Deserializer : public SerializerDeserializer { external_reference_table_(NULL), deserialized_large_objects_(0), deserializing_user_code_(deserializing_user_code), - next_alignment_(kWordAligned) { + next_alignment_(kWordAligned), + can_rehash_(false) { DecodeReservation(data->Reservations()); } @@ -62,6 +63,8 @@ class Deserializer : public SerializerDeserializer { attached_objects_.Add(attached_object); } + void SetRehashability(bool v) { can_rehash_ = v; } + private: void VisitRootPointers(Root root, Object** start, Object** end) override; @@ -115,6 +118,15 @@ class Deserializer : public SerializerDeserializer { // snapshot by chunk index and offset. HeapObject* GetBackReferencedObject(int space); + // Rehash after deserializing an isolate. + void Rehash(); + + // Rehash after deserializing a context. + void RehashContext(Context* context); + + // Sort descriptors of deserialized maps using new string hashes. + void SortMapDescriptors(); + // Cached current isolate. Isolate* isolate_; @@ -142,11 +154,15 @@ class Deserializer : public SerializerDeserializer { List<AccessorInfo*> accessor_infos_; List<Handle<String> > new_internalized_strings_; List<Handle<Script> > new_scripts_; + List<TransitionArray*> transition_arrays_; bool deserializing_user_code_; AllocationAlignment next_alignment_; + // TODO(6593): generalize rehashing, and remove this flag. + bool can_rehash_; + DISALLOW_COPY_AND_ASSIGN(Deserializer); }; diff --git a/chromium/v8/src/snapshot/partial-serializer.cc b/chromium/v8/src/snapshot/partial-serializer.cc index d3e60e0e4e3..bbd829eddfe 100644 --- a/chromium/v8/src/snapshot/partial-serializer.cc +++ b/chromium/v8/src/snapshot/partial-serializer.cc @@ -15,7 +15,9 @@ PartialSerializer::PartialSerializer( v8::SerializeEmbedderFieldsCallback callback) : Serializer(isolate), startup_serializer_(startup_serializer), - serialize_embedder_fields_(callback) { + serialize_embedder_fields_(callback), + rehashable_global_dictionary_(nullptr), + can_be_rehashed_(true) { InitializeCodeAddressMap(); } @@ -24,7 +26,7 @@ PartialSerializer::~PartialSerializer() { } void PartialSerializer::Serialize(Object** o, bool include_global_proxy) { - if ((*o)->IsContext()) { + if ((*o)->IsNativeContext()) { Context* context = Context::cast(*o); reference_map()->AddAttachedReference(context->global_proxy()); // The bootstrap snapshot has a code-stub context. When serializing the @@ -32,14 +34,18 @@ void PartialSerializer::Serialize(Object** o, bool include_global_proxy) { // and it's next context pointer may point to the code-stub context. Clear // it before serializing, it will get re-added to the context list // explicitly when it's loaded. - if (context->IsNativeContext()) { - context->set(Context::NEXT_CONTEXT_LINK, - isolate_->heap()->undefined_value()); - DCHECK(!context->global_object()->IsUndefined(context->GetIsolate())); - // Reset math random cache to get fresh random numbers. - context->set_math_random_index(Smi::kZero); - context->set_math_random_cache(isolate_->heap()->undefined_value()); - } + context->set(Context::NEXT_CONTEXT_LINK, + isolate_->heap()->undefined_value()); + DCHECK(!context->global_object()->IsUndefined(context->GetIsolate())); + // Reset math random cache to get fresh random numbers. + context->set_math_random_index(Smi::kZero); + context->set_math_random_cache(isolate_->heap()->undefined_value()); + DCHECK_NULL(rehashable_global_dictionary_); + rehashable_global_dictionary_ = + context->global_object()->global_dictionary(); + } else { + // We only do rehashing for native contexts. + can_be_rehashed_ = false; } VisitRootPointer(Root::kPartialSnapshotCache, o); SerializeDeferredObjects(); @@ -104,6 +110,8 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, } } + if (obj->IsHashTable()) CheckRehashability(obj); + // Object has not yet been serialized. Serialize it here. ObjectSerializer serializer(this, obj, &sink_, how_to_code, where_to_point); serializer.Serialize(); @@ -152,5 +160,14 @@ void PartialSerializer::SerializeEmbedderFields() { sink_.Put(kSynchronize, "Finished with embedder fields data"); } +void PartialSerializer::CheckRehashability(HeapObject* table) { + DCHECK(table->IsHashTable()); + if (!can_be_rehashed_) return; + // We can only correctly rehash if the global dictionary is the only hash + // table that we deserialize. + if (table == rehashable_global_dictionary_) return; + can_be_rehashed_ = false; +} + } // namespace internal } // namespace v8 diff --git a/chromium/v8/src/snapshot/partial-serializer.h b/chromium/v8/src/snapshot/partial-serializer.h index 313a8000425..4b3035f9e54 100644 --- a/chromium/v8/src/snapshot/partial-serializer.h +++ b/chromium/v8/src/snapshot/partial-serializer.h @@ -23,6 +23,8 @@ class PartialSerializer : public Serializer { // Serialize the objects reachable from a single object pointer. void Serialize(Object** o, bool include_global_proxy); + bool can_be_rehashed() const { return can_be_rehashed_; } + private: void SerializeObject(HeapObject* o, HowToCode how_to_code, WhereToPoint where_to_point, int skip) override; @@ -31,9 +33,15 @@ class PartialSerializer : public Serializer { void SerializeEmbedderFields(); + void CheckRehashability(HeapObject* table); + StartupSerializer* startup_serializer_; List<JSObject*> embedder_field_holders_; v8::SerializeEmbedderFieldsCallback serialize_embedder_fields_; + GlobalDictionary* rehashable_global_dictionary_; + // Indicates whether we only serialized hash tables that we can rehash. + // TODO(yangguo): generalize rehashing, and remove this flag. + bool can_be_rehashed_; DISALLOW_COPY_AND_ASSIGN(PartialSerializer); }; diff --git a/chromium/v8/src/snapshot/serializer-common.cc b/chromium/v8/src/snapshot/serializer-common.cc index 05a18ab727c..5d931b2af50 100644 --- a/chromium/v8/src/snapshot/serializer-common.cc +++ b/chromium/v8/src/snapshot/serializer-common.cc @@ -24,7 +24,11 @@ ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) { Address addr = table->address(i); // Ignore duplicate API references. if (table->is_api_reference(i) && !map_->Get(addr).IsNothing()) continue; +#ifndef V8_OS_WIN + // TODO(yangguo): On Windows memcpy and memmove can end up at the same + // address due to ICF. See http://crbug.com/726896. DCHECK(map_->Get(addr).IsNothing()); +#endif map_->Set(addr, i); DCHECK(map_->Get(addr).IsJust()); } diff --git a/chromium/v8/src/snapshot/serializer-common.h b/chromium/v8/src/snapshot/serializer-common.h index d445cb95c97..b011c7777ae 100644 --- a/chromium/v8/src/snapshot/serializer-common.h +++ b/chromium/v8/src/snapshot/serializer-common.h @@ -6,6 +6,7 @@ #define V8_SNAPSHOT_SERIALIZER_COMMON_H_ #include "src/address-map.h" +#include "src/base/bits.h" #include "src/external-reference-table.h" #include "src/globals.h" #include "src/visitors.h" @@ -63,7 +64,7 @@ class HotObjectsList { static const int kSize = 8; private: - STATIC_ASSERT(IS_POWER_OF_TWO(kSize)); + static_assert(base::bits::IsPowerOfTwo(kSize), "kSize must be power of two"); static const int kSizeMask = kSize - 1; HeapObject* circular_queue_[kSize]; int index_; @@ -271,13 +272,12 @@ class SerializedData { protected: void SetHeaderValue(int offset, uint32_t value) { - uint32_t* address = reinterpret_cast<uint32_t*>(data_ + offset); - memcpy(reinterpret_cast<uint32_t*>(address), &value, sizeof(value)); + memcpy(data_ + offset, &value, sizeof(value)); } uint32_t GetHeaderValue(int offset) const { uint32_t value; - memcpy(&value, reinterpret_cast<int*>(data_ + offset), sizeof(value)); + memcpy(&value, data_ + offset, sizeof(value)); return value; } diff --git a/chromium/v8/src/snapshot/serializer.cc b/chromium/v8/src/snapshot/serializer.cc index a63d888d116..5808ab6ba44 100644 --- a/chromium/v8/src/snapshot/serializer.cc +++ b/chromium/v8/src/snapshot/serializer.cc @@ -147,6 +147,13 @@ bool Serializer::BackReferenceIsAlreadyAllocated( } } } + +void Serializer::PrintStack() { + for (const auto& o : stack_) { + o->Print(); + PrintF("\n"); + } +} #endif // DEBUG bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code, diff --git a/chromium/v8/src/snapshot/serializer.h b/chromium/v8/src/snapshot/serializer.h index cc4d30bfc54..bcb308df717 100644 --- a/chromium/v8/src/snapshot/serializer.h +++ b/chromium/v8/src/snapshot/serializer.h @@ -186,8 +186,6 @@ class Serializer : public SerializerDeserializer { } } - bool BackReferenceIsAlreadyAllocated(SerializerReference back_reference); - // This will return the space for an object. SerializerReference AllocateLargeObject(int size); SerializerReference AllocateMap(); @@ -222,6 +220,14 @@ class Serializer : public SerializerDeserializer { void OutputStatistics(const char* name); +#ifdef DEBUG + void PushStack(HeapObject* o) { stack_.Add(o); } + void PopStack() { stack_.RemoveLast(); } + void PrintStack(); + + bool BackReferenceIsAlreadyAllocated(SerializerReference back_reference); +#endif // DEBUG + Isolate* isolate_; SnapshotByteSink sink_; @@ -264,6 +270,10 @@ class Serializer : public SerializerDeserializer { size_t* instance_type_size_; #endif // OBJECT_PRINT +#ifdef DEBUG + List<HeapObject*> stack_; +#endif // DEBUG + DISALLOW_COPY_AND_ASSIGN(Serializer); }; @@ -277,8 +287,16 @@ class Serializer::ObjectSerializer : public ObjectVisitor { sink_(sink), reference_representation_(how_to_code + where_to_point), bytes_processed_so_far_(0), - code_has_been_output_(false) {} - ~ObjectSerializer() override {} + code_has_been_output_(false) { +#ifdef DEBUG + serializer_->PushStack(obj); +#endif // DEBUG + } + ~ObjectSerializer() override { +#ifdef DEBUG + serializer_->PopStack(); +#endif // DEBUG + } void Serialize(); void SerializeContent(); void SerializeDeferred(); diff --git a/chromium/v8/src/snapshot/snapshot-common.cc b/chromium/v8/src/snapshot/snapshot-common.cc index 9350ec6b540..9f299e697ee 100644 --- a/chromium/v8/src/snapshot/snapshot-common.cc +++ b/chromium/v8/src/snapshot/snapshot-common.cc @@ -41,6 +41,7 @@ bool Snapshot::Initialize(Isolate* isolate) { Vector<const byte> startup_data = ExtractStartupData(blob); SnapshotData snapshot_data(startup_data); Deserializer deserializer(&snapshot_data); + deserializer.SetRehashability(ExtractRehashability(blob)); bool success = isolate->Init(&deserializer); if (FLAG_profile_deserialization) { double ms = timer.Elapsed().InMillisecondsF(); @@ -62,6 +63,7 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot( ExtractContextData(blob, static_cast<int>(context_index)); SnapshotData snapshot_data(context_data); Deserializer deserializer(&snapshot_data); + deserializer.SetRehashability(ExtractRehashability(blob)); MaybeHandle<Object> maybe_context = deserializer.DeserializePartial( isolate, global_proxy, embedder_fields_deserializer); @@ -98,7 +100,7 @@ void ProfileDeserialization(const SnapshotData* startup_snapshot, v8::StartupData Snapshot::CreateSnapshotBlob( const SnapshotData* startup_snapshot, - const List<SnapshotData*>* context_snapshots) { + const List<SnapshotData*>* context_snapshots, bool can_be_rehashed) { int num_contexts = context_snapshots->length(); int startup_snapshot_offset = StartupSnapshotOffset(num_contexts); int total_length = startup_snapshot_offset; @@ -111,6 +113,8 @@ v8::StartupData Snapshot::CreateSnapshotBlob( char* data = new char[total_length]; memcpy(data + kNumberOfContextsOffset, &num_contexts, kInt32Size); + int rehashability = can_be_rehashed ? 1 : 0; + memcpy(data + kRehashabilityOffset, &rehashability, kInt32Size); int payload_offset = StartupSnapshotOffset(num_contexts); int payload_length = startup_snapshot->RawData().length(); memcpy(data + payload_offset, startup_snapshot->RawData().start(), @@ -143,6 +147,13 @@ int Snapshot::ExtractNumContexts(const v8::StartupData* data) { return num_contexts; } +bool Snapshot::ExtractRehashability(const v8::StartupData* data) { + CHECK_LT(kRehashabilityOffset, data->raw_size); + int rehashability; + memcpy(&rehashability, data->data + kRehashabilityOffset, kInt32Size); + return rehashability != 0; +} + Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) { int num_contexts = ExtractNumContexts(data); int startup_offset = StartupSnapshotOffset(num_contexts); diff --git a/chromium/v8/src/snapshot/snapshot-source-sink.cc b/chromium/v8/src/snapshot/snapshot-source-sink.cc index 66a14bc5997..5399fe11f28 100644 --- a/chromium/v8/src/snapshot/snapshot-source-sink.cc +++ b/chromium/v8/src/snapshot/snapshot-source-sink.cc @@ -12,12 +12,6 @@ namespace v8 { namespace internal { -void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) { - memcpy(to, data_ + position_, number_of_bytes); - position_ += number_of_bytes; -} - - void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { DCHECK(integer < 1 << 30); integer <<= 2; diff --git a/chromium/v8/src/snapshot/snapshot-source-sink.h b/chromium/v8/src/snapshot/snapshot-source-sink.h index 5d4c08d43a0..4922ebc74b8 100644 --- a/chromium/v8/src/snapshot/snapshot-source-sink.h +++ b/chromium/v8/src/snapshot/snapshot-source-sink.h @@ -38,7 +38,10 @@ class SnapshotByteSource final { void Advance(int by) { position_ += by; } - void CopyRaw(byte* to, int number_of_bytes); + void CopyRaw(byte* to, int number_of_bytes) { + memcpy(to, data_ + position_, number_of_bytes); + position_ += number_of_bytes; + } inline int GetInt() { // This way of decoding variable-length encoded integers does not diff --git a/chromium/v8/src/snapshot/snapshot.h b/chromium/v8/src/snapshot/snapshot.h index 7d9082e6d21..91d60cfa89d 100644 --- a/chromium/v8/src/snapshot/snapshot.h +++ b/chromium/v8/src/snapshot/snapshot.h @@ -71,7 +71,7 @@ class Snapshot : public AllStatic { static v8::StartupData CreateSnapshotBlob( const SnapshotData* startup_snapshot, - const List<SnapshotData*>* context_snapshots); + const List<SnapshotData*>* context_snapshots, bool can_be_rehashed); #ifdef DEBUG static bool SnapshotIsValid(v8::StartupData* snapshot_blob); @@ -79,14 +79,16 @@ class Snapshot : public AllStatic { private: static int ExtractNumContexts(const v8::StartupData* data); + static bool ExtractRehashability(const v8::StartupData* data); static Vector<const byte> ExtractStartupData(const v8::StartupData* data); static Vector<const byte> ExtractContextData(const v8::StartupData* data, int index); // Snapshot blob layout: // [0] number of contexts N - // [1] offset to context 0 - // [2] offset to context 1 + // [1] rehashability + // [2] offset to context 0 + // [3] offset to context 1 // ... // ... offset to context N - 1 // ... startup snapshot data @@ -94,8 +96,10 @@ class Snapshot : public AllStatic { // ... context 1 snapshot data static const int kNumberOfContextsOffset = 0; + // TODO(yangguo): generalize rehashing, and remove this flag. + static const int kRehashabilityOffset = kNumberOfContextsOffset + kInt32Size; static const int kFirstContextOffsetOffset = - kNumberOfContextsOffset + kInt32Size; + kRehashabilityOffset + kInt32Size; static int StartupSnapshotOffset(int num_contexts) { return kFirstContextOffsetOffset + num_contexts * kInt32Size; diff --git a/chromium/v8/src/snapshot/startup-serializer.cc b/chromium/v8/src/snapshot/startup-serializer.cc index dfc02036d80..34bb390735b 100644 --- a/chromium/v8/src/snapshot/startup-serializer.cc +++ b/chromium/v8/src/snapshot/startup-serializer.cc @@ -16,7 +16,8 @@ StartupSerializer::StartupSerializer( : Serializer(isolate), clear_function_code_(function_code_handling == v8::SnapshotCreator::FunctionCodeHandling::kClear), - serializing_builtins_(false) { + serializing_builtins_(false), + can_be_rehashed_(true) { InitializeCodeAddressMap(); } @@ -47,7 +48,6 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, Code* code = Code::cast(obj); if (code->kind() == Code::FUNCTION) { code->ClearInlineCaches(); - code->set_profiler_ticks(0); } } @@ -78,6 +78,8 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, isolate_->heap()->uninitialized_symbol()); } + if (obj->IsHashTable()) CheckRehashability(obj); + // Object has not yet been serialized. Serialize it here. ObjectSerializer object_serializer(this, obj, &sink_, how_to_code, where_to_point); @@ -189,5 +191,17 @@ bool StartupSerializer::RootShouldBeSkipped(int root_index) { serializing_immortal_immovables_roots_; } +void StartupSerializer::CheckRehashability(HeapObject* table) { + DCHECK(table->IsHashTable()); + if (!can_be_rehashed_) return; + // We can only correctly rehash if the four hash tables below are the only + // ones that we deserialize. + if (table == isolate_->heap()->empty_slow_element_dictionary()) return; + if (table == isolate_->heap()->empty_property_dictionary()) return; + if (table == isolate_->heap()->weak_object_to_code_table()) return; + if (table == isolate_->heap()->string_table()) return; + can_be_rehashed_ = false; +} + } // namespace internal } // namespace v8 diff --git a/chromium/v8/src/snapshot/startup-serializer.h b/chromium/v8/src/snapshot/startup-serializer.h index 223e1c7bff3..c58454d0667 100644 --- a/chromium/v8/src/snapshot/startup-serializer.h +++ b/chromium/v8/src/snapshot/startup-serializer.h @@ -29,6 +29,8 @@ class StartupSerializer : public Serializer { int PartialSnapshotCacheIndex(HeapObject* o); + bool can_be_rehashed() const { return can_be_rehashed_; } + private: class PartialCacheIndexMap { public: @@ -68,12 +70,18 @@ class StartupSerializer : public Serializer { // roots. In the second pass, we serialize the rest. bool RootShouldBeSkipped(int root_index); + void CheckRehashability(HeapObject* hashtable); + bool clear_function_code_; bool serializing_builtins_; bool serializing_immortal_immovables_roots_; std::bitset<Heap::kStrongRootListLength> root_has_been_serialized_; PartialCacheIndexMap partial_cache_index_map_; List<AccessorInfo*> accessor_infos_; + // Indicates whether we only serialized hash tables that we can rehash. + // TODO(yangguo): generalize rehashing, and remove this flag. + bool can_be_rehashed_; + DISALLOW_COPY_AND_ASSIGN(StartupSerializer); }; |