summaryrefslogtreecommitdiff
path: root/chromium/v8/src/snapshot
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-18 14:34:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-04 11:15:27 +0000
commite6430e577f105ad8813c92e75c54660c4985026e (patch)
tree88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/v8/src/snapshot
parent53d399fe6415a96ea6986ec0d402a9c07da72453 (diff)
downloadqtwebengine-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/OWNERS2
-rw-r--r--chromium/v8/src/snapshot/deserializer.cc69
-rw-r--r--chromium/v8/src/snapshot/deserializer.h18
-rw-r--r--chromium/v8/src/snapshot/partial-serializer.cc37
-rw-r--r--chromium/v8/src/snapshot/partial-serializer.h8
-rw-r--r--chromium/v8/src/snapshot/serializer-common.cc4
-rw-r--r--chromium/v8/src/snapshot/serializer-common.h8
-rw-r--r--chromium/v8/src/snapshot/serializer.cc7
-rw-r--r--chromium/v8/src/snapshot/serializer.h26
-rw-r--r--chromium/v8/src/snapshot/snapshot-common.cc13
-rw-r--r--chromium/v8/src/snapshot/snapshot-source-sink.cc6
-rw-r--r--chromium/v8/src/snapshot/snapshot-source-sink.h5
-rw-r--r--chromium/v8/src/snapshot/snapshot.h12
-rw-r--r--chromium/v8/src/snapshot/startup-serializer.cc18
-rw-r--r--chromium/v8/src/snapshot/startup-serializer.h8
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);
};