From 7753ace1354ac231374da0446a5057b6b40780db Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Thu, 23 Oct 2014 08:25:42 +0000 Subject: [PATCH] Small fixes for the code serializer. - assertions regarding max heap object size. - ensure string table capacity upfront. R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/671843003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24824 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 10 ++++++++++ src/objects.h | 2 ++ src/serialize.cc | 19 +++++++++++++++---- src/serialize.h | 29 ++++++++++++++++++++--------- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 2685a5c..371931c 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -14769,6 +14769,16 @@ MaybeHandle StringTable::LookupTwoCharsStringIfExists( } +void StringTable::EnsureCapacityForDeserialization(Isolate* isolate, + int expected) { + Handle table = isolate->factory()->string_table(); + // We need a key instance for the virtual hash function. + InternalizedStringKey dummy_key(Handle::null()); + table = StringTable::EnsureCapacity(table, expected, &dummy_key); + isolate->factory()->set_string_table(table); +} + + Handle StringTable::LookupString(Isolate* isolate, Handle string) { InternalizedStringKey key(string); diff --git a/src/objects.h b/src/objects.h index 7e509e7..b2b64c2 100644 --- a/src/objects.h +++ b/src/objects.h @@ -3446,6 +3446,8 @@ class StringTable: public HashTableIsInternalizedString(); if (object_->IsExternalOneByteString()) { - map = isolate->heap()->one_byte_internalized_string_map(); + map = internalized ? isolate->heap()->one_byte_internalized_string_map() + : isolate->heap()->one_byte_string_map(); size = SeqOneByteString::SizeFor(length); resource = ExternalOneByteString::cast(string)->resource()->data(); } else { - map = isolate->heap()->internalized_string_map(); + map = internalized ? isolate->heap()->internalized_string_map() + : isolate->heap()->string_map(); size = SeqTwoByteString::SizeFor(length); resource = reinterpret_cast( ExternalTwoByteString::cast(string)->resource()->data()); @@ -1910,7 +1913,7 @@ uint32_t Serializer::AllocateLargeObject(int size) { uint32_t Serializer::Allocate(int space, int size) { CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); - DCHECK(size > 0 && size < Page::kMaxRegularHeapObjectSize); + DCHECK(size > 0 && size <= Page::kMaxRegularHeapObjectSize); uint32_t new_chunk_size = pending_chunk_[space] + size; uint32_t allocation; if (new_chunk_size > static_cast(Page::kMaxRegularHeapObjectSize)) { @@ -2081,6 +2084,8 @@ void CodeSerializer::SerializeHeapObject(HeapObject* heap_object, PrintF("\n"); } + if (heap_object->IsInternalizedString()) num_internalized_strings_++; + // Object has not yet been serialized. Serialize it here. ObjectSerializer serializer(this, heap_object, sink_, how_to_code, where_to_point); @@ -2201,6 +2206,11 @@ MaybeHandle CodeSerializer::Deserialize( SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); Deserializer deserializer(&payload); + // Eagerly expand string table to avoid allocations during deserialization. + StringTable::EnsureCapacityForDeserialization(isolate, + scd.NumInternalizedStrings()); + + // Set reservations. STATIC_ASSERT(NEW_SPACE == 0); int current_space = NEW_SPACE; Vector res = scd.Reservations(); @@ -2254,7 +2264,7 @@ SerializedCodeData::SerializedCodeData(List* payload, CodeSerializer* cs) Vector chunks = cs->FinalAllocationChunks(i); for (int j = 0; j < chunks.length(); j++) { DCHECK(i == LO_SPACE || - chunks[j] < + chunks[j] <= static_cast(Page::kMaxRegularHeapObjectSize)); uint32_t chunk = ChunkSizeBits::encode(chunks[j]) | IsLastChunkBits::encode(j == chunks.length() - 1); @@ -2277,6 +2287,7 @@ SerializedCodeData::SerializedCodeData(List* payload, CodeSerializer* cs) // Set header values. SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); + SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings()); SetHeaderValue(kReservationsOffset, reservations.length()); SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); SetHeaderValue(kPayloadLengthOffset, payload->length()); diff --git a/src/serialize.h b/src/serialize.h index 47a244f..df6723c 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -264,7 +264,7 @@ class Deserializer: public SerializerDeserializer { DCHECK(space >= 0); DCHECK(space < kNumberOfSpaces); DCHECK(space == LO_SPACE || - chunk < static_cast(Page::kMaxRegularHeapObjectSize)); + chunk <= static_cast(Page::kMaxRegularHeapObjectSize)); reservations_[space].Add({chunk, NULL, NULL}); } @@ -619,17 +619,21 @@ class CodeSerializer : public Serializer { static const int kSourceObjectIndex = 0; static const int kCodeStubsBaseIndex = 1; - String* source() { + String* source() const { DCHECK(!AllowHeapAllocation::IsAllowed()); return source_; } List* stub_keys() { return &stub_keys_; } + int num_internalized_strings() const { return num_internalized_strings_; } private: CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source, Code* main_code) - : Serializer(isolate, sink), source_(source), main_code_(main_code) { + : Serializer(isolate, sink), + source_(source), + main_code_(main_code), + num_internalized_strings_(0) { set_root_index_wave_front(Heap::kStrongRootListLength); InitializeCodeAddressMap(); } @@ -652,6 +656,7 @@ class CodeSerializer : public Serializer { DisallowHeapAllocation no_gc_; String* source_; Code* main_code_; + int num_internalized_strings_; List stub_keys_; DISALLOW_COPY_AND_ASSIGN(CodeSerializer); }; @@ -694,6 +699,10 @@ class SerializedCodeData { DISALLOW_COPY_AND_ASSIGN(Reservation); }; + int NumInternalizedStrings() const { + return GetHeaderValue(kNumInternalizedStringsOffset); + } + Vector Reservations() const { return Vector(reinterpret_cast( script_data_->data() + kHeaderSize), @@ -737,13 +746,15 @@ class SerializedCodeData { // The data header consists of int-sized entries: // [0] version hash - // [1] number of code stub keys - // [2] payload length - // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. + // [1] number of internalized strings + // [2] number of code stub keys + // [3] payload length + // [4..10] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. static const int kCheckSumOffset = 0; - static const int kReservationsOffset = 1; - static const int kNumCodeStubKeysOffset = 2; - static const int kPayloadLengthOffset = 3; + static const int kNumInternalizedStringsOffset = 1; + static const int kReservationsOffset = 2; + static const int kNumCodeStubKeysOffset = 3; + static const int kPayloadLengthOffset = 4; static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; class ChunkSizeBits : public BitField {}; -- 2.7.4