diff --git a/src/assembler.cc b/src/assembler.cc index 9ad8bc613d..2343616a77 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -861,7 +861,8 @@ void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT os << " (" << Brief(target_object()) << ")"; } else if (rmode_ == EXTERNAL_REFERENCE) { ExternalReferenceEncoder ref_encoder(isolate); - os << " (" << ref_encoder.NameOfAddress(target_external_reference()) + os << " (" + << ref_encoder.NameOfAddress(isolate, target_external_reference()) << ") (" << static_cast(target_external_reference()) << ")"; } else if (IsCodeTarget(rmode_)) { diff --git a/src/disassembler.cc b/src/disassembler.cc index 37e0c83f80..9eff926653 100644 --- a/src/disassembler.cc +++ b/src/disassembler.cc @@ -185,8 +185,8 @@ static int DecodeIt(Isolate* isolate, std::ostream* os, SmartArrayPointer obj_name = accumulator.ToCString(); out.AddFormatted(" ;; object: %s", obj_name.get()); } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { - const char* reference_name = - ref_encoder.NameOfAddress(relocinfo.target_external_reference()); + const char* reference_name = ref_encoder.NameOfAddress( + isolate, relocinfo.target_external_reference()); out.AddFormatted(" ;; external reference (%s)", reference_name); } else if (RelocInfo::IsCodeTarget(rmode)) { out.AddFormatted(" ;; code:"); diff --git a/src/serialize.cc b/src/serialize.cc index f16ce10732..86bbfce3c7 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -32,20 +32,6 @@ namespace internal { // ----------------------------------------------------------------------------- // Coding of external references. -// The encoding of an external reference. The type is in the high word. -// The id is in the low word. -static uint32_t EncodeExternal(TypeCode type, uint16_t id) { - return static_cast(type) << 16 | id; -} - - -static int* GetInternalPointer(StatsCounter* counter) { - // All counters refer to dummy_counter, if deserializing happens without - // setting up counters. - static int dummy_counter = 0; - return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter; -} - ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) { ExternalReferenceTable* external_reference_table = @@ -58,63 +44,7 @@ ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) { } -void ExternalReferenceTable::AddFromId(TypeCode type, - uint16_t id, - const char* name, - Isolate* isolate) { - Address address; - switch (type) { - case C_BUILTIN: { - ExternalReference ref(static_cast(id), isolate); - address = ref.address(); - break; - } - case BUILTIN: { - ExternalReference ref(static_cast(id), isolate); - address = ref.address(); - break; - } - case RUNTIME_FUNCTION: { - ExternalReference ref(static_cast(id), isolate); - address = ref.address(); - break; - } - case IC_UTILITY: { - ExternalReference ref(IC_Utility(static_cast(id)), - isolate); - address = ref.address(); - break; - } - default: - UNREACHABLE(); - return; - } - Add(address, type, id, name); -} - - -void ExternalReferenceTable::Add(Address address, - TypeCode type, - uint16_t id, - const char* name) { - DCHECK_NOT_NULL(address); - ExternalReferenceEntry entry; - entry.address = address; - entry.code = EncodeExternal(type, id); - entry.name = name; - DCHECK_NE(0u, entry.code); - // Assert that the code is added in ascending order to rule out duplicates. - DCHECK((size() == 0) || (code(size() - 1) < entry.code)); - refs_.Add(entry); - if (id > max_id_[type]) max_id_[type] = id; -} - - -void ExternalReferenceTable::PopulateTable(Isolate* isolate) { - for (int type_code = 0; type_code < kTypeCodeCount; type_code++) { - max_id_[type_code] = 0; - } - +ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) { // Miscellaneous Add(ExternalReference::roots_array_start(isolate).address(), "Heap::roots_array_start()"); @@ -179,10 +109,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { Add(ExternalReference::get_make_code_young_function(isolate).address(), "Code::MakeCodeYoung"); Add(ExternalReference::cpu_features().address(), "cpu_features"); - Add(ExternalReference(Runtime::kAllocateInNewSpace, isolate).address(), - "Runtime::AllocateInNewSpace"); - Add(ExternalReference(Runtime::kAllocateInTargetSpace, isolate).address(), - "Runtime::AllocateInTargetSpace"); Add(ExternalReference::old_pointer_space_allocation_top_address(isolate) .address(), "Heap::OldPointerSpaceAllocationTopAddress"); @@ -218,9 +144,6 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { "double_constants.minus_one_half"); Add(ExternalReference::stress_deopt_count(isolate).address(), "Isolate::stress_deopt_count_address()"); - Add(ExternalReference::incremental_marking_record_write_function(isolate) - .address(), - "IncrementalMarking::RecordWriteFromCode"); // Debug addresses Add(ExternalReference::debug_after_break_target_address(isolate).address(), @@ -260,143 +183,151 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { // new references. struct RefTableEntry { - TypeCode type; uint16_t id; const char* name; }; - static const RefTableEntry ref_table[] = { - // Builtins -#define DEF_ENTRY_C(name, ignored) \ - { C_BUILTIN, \ - Builtins::c_##name, \ - "Builtins::" #name }, - - BUILTIN_LIST_C(DEF_ENTRY_C) + static const RefTableEntry c_builtins[] = { +#define DEF_ENTRY_C(name, ignored) \ + { Builtins::c_##name, "Builtins::" #name } \ + , + BUILTIN_LIST_C(DEF_ENTRY_C) #undef DEF_ENTRY_C + }; -#define DEF_ENTRY_C(name, ignored) \ - { BUILTIN, \ - Builtins::k##name, \ - "Builtins::" #name }, -#define DEF_ENTRY_A(name, kind, state, extra) DEF_ENTRY_C(name, ignored) + for (unsigned i = 0; i < arraysize(c_builtins); ++i) { + ExternalReference ref(static_cast(c_builtins[i].id), + isolate); + Add(ref.address(), c_builtins[i].name); + } - BUILTIN_LIST_C(DEF_ENTRY_C) - BUILTIN_LIST_A(DEF_ENTRY_A) - BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A) + static const RefTableEntry builtins[] = { +#define DEF_ENTRY_C(name, ignored) \ + { Builtins::k##name, "Builtins::" #name } \ + , +#define DEF_ENTRY_A(name, i1, i2, i3) \ + { Builtins::k##name, "Builtins::" #name } \ + , + BUILTIN_LIST_C(DEF_ENTRY_C) BUILTIN_LIST_A(DEF_ENTRY_A) + BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A) #undef DEF_ENTRY_C #undef DEF_ENTRY_A + }; - // Runtime functions -#define RUNTIME_ENTRY(name, nargs, ressize) \ - { RUNTIME_FUNCTION, \ - Runtime::k##name, \ - "Runtime::" #name }, + for (unsigned i = 0; i < arraysize(builtins); ++i) { + ExternalReference ref(static_cast(builtins[i].id), isolate); + Add(ref.address(), builtins[i].name); + } - RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) - INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY) + static const RefTableEntry runtime_functions[] = { +#define RUNTIME_ENTRY(name, i1, i2) \ + { Runtime::k##name, "Runtime::" #name } \ + , + RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY) + INLINE_OPTIMIZED_FUNCTION_LIST(RUNTIME_ENTRY) #undef RUNTIME_ENTRY + }; -#define INLINE_OPTIMIZED_ENTRY(name, nargs, ressize) \ - { RUNTIME_FUNCTION, \ - Runtime::kInlineOptimized##name, \ - "Runtime::" #name }, + for (unsigned i = 0; i < arraysize(runtime_functions); ++i) { + ExternalReference ref( + static_cast(runtime_functions[i].id), isolate); + Add(ref.address(), runtime_functions[i].name); + } - INLINE_OPTIMIZED_FUNCTION_LIST(INLINE_OPTIMIZED_ENTRY) -#undef INLINE_OPTIMIZED_ENTRY - - // IC utilities -#define IC_ENTRY(name) \ - { IC_UTILITY, \ - IC::k##name, \ - "IC::" #name }, - - IC_UTIL_LIST(IC_ENTRY) + static const RefTableEntry inline_caches[] = { +#define IC_ENTRY(name) \ + { IC::k##name, "IC::" #name } \ + , + IC_UTIL_LIST(IC_ENTRY) #undef IC_ENTRY - }; // end of ref_table[]. + }; - for (size_t i = 0; i < arraysize(ref_table); ++i) { - AddFromId(ref_table[i].type, - ref_table[i].id, - ref_table[i].name, - isolate); + for (unsigned i = 0; i < arraysize(inline_caches); ++i) { + ExternalReference ref( + IC_Utility(static_cast(inline_caches[i].id)), isolate); + Add(ref.address(), runtime_functions[i].name); } // Stat counters struct StatsRefTableEntry { StatsCounter* (Counters::*counter)(); - uint16_t id; const char* name; }; - const StatsRefTableEntry stats_ref_table[] = { -#define COUNTER_ENTRY(name, caption) \ - { &Counters::name, \ - Counters::k_##name, \ - "Counters::" #name }, - - STATS_COUNTER_LIST_1(COUNTER_ENTRY) - STATS_COUNTER_LIST_2(COUNTER_ENTRY) + static const StatsRefTableEntry stats_ref_table[] = { +#define COUNTER_ENTRY(name, caption) \ + { &Counters::name, "Counters::" #name } \ + , + STATS_COUNTER_LIST_1(COUNTER_ENTRY) STATS_COUNTER_LIST_2(COUNTER_ENTRY) #undef COUNTER_ENTRY - }; // end of stats_ref_table[]. + }; Counters* counters = isolate->counters(); - for (size_t i = 0; i < arraysize(stats_ref_table); ++i) { - Add(reinterpret_cast
(GetInternalPointer( - (counters->*(stats_ref_table[i].counter))())), - STATS_COUNTER, - stats_ref_table[i].id, - stats_ref_table[i].name); + for (unsigned i = 0; i < arraysize(stats_ref_table); ++i) { + // To make sure the indices are not dependent on whether counters are + // enabled, use a dummy address as filler. + Address address = NotAvailable(); + StatsCounter* counter = (counters->*(stats_ref_table[i].counter))(); + if (counter->Enabled()) { + address = reinterpret_cast
(counter->GetInternalPointer()); + } + Add(address, stats_ref_table[i].name); } // Top addresses - - const char* AddressNames[] = { -#define BUILD_NAME_LITERAL(CamelName, hacker_name) \ - "Isolate::" #hacker_name "_address", - FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) - NULL + static const char* address_names[] = { +#define BUILD_NAME_LITERAL(Name, name) "Isolate::" #name "_address", + FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) NULL #undef BUILD_NAME_LITERAL }; - for (uint16_t i = 0; i < Isolate::kIsolateAddressCount; ++i) { - Add(isolate->get_address_from_id((Isolate::AddressId)i), - TOP_ADDRESS, i, AddressNames[i]); + for (int i = 0; i < Isolate::kIsolateAddressCount; ++i) { + Add(isolate->get_address_from_id(static_cast(i)), + address_names[i]); } // Accessors -#define ACCESSOR_INFO_DECLARATION(name) \ - Add(FUNCTION_ADDR(&Accessors::name##Getter), ACCESSOR_CODE, \ - Accessors::k##name##Getter, "Accessors::" #name "Getter"); \ - Add(FUNCTION_ADDR(&Accessors::name##Setter), ACCESSOR_CODE, \ - Accessors::k##name##Setter, "Accessors::" #name "Setter"); - ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) + struct AccessorRefTable { + Address address; + const char* name; + }; + + static const AccessorRefTable accessors[] = { +#define ACCESSOR_INFO_DECLARATION(name) \ + { FUNCTION_ADDR(&Accessors::name##Getter), "Accessors::" #name "Getter" } \ + , {FUNCTION_ADDR(&Accessors::name##Setter), "Accessors::" #name "Setter"}, + ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION) #undef ACCESSOR_INFO_DECLARATION + }; + + for (unsigned i = 0; i < arraysize(accessors); ++i) { + Add(accessors[i].address, accessors[i].name); + } StubCache* stub_cache = isolate->stub_cache(); // Stub cache tables Add(stub_cache->key_reference(StubCache::kPrimary).address(), - STUB_CACHE_TABLE, 1, "StubCache::primary_->key"); + "StubCache::primary_->key"); Add(stub_cache->value_reference(StubCache::kPrimary).address(), - STUB_CACHE_TABLE, 2, "StubCache::primary_->value"); + "StubCache::primary_->value"); Add(stub_cache->map_reference(StubCache::kPrimary).address(), - STUB_CACHE_TABLE, 3, "StubCache::primary_->map"); + "StubCache::primary_->map"); Add(stub_cache->key_reference(StubCache::kSecondary).address(), - STUB_CACHE_TABLE, 4, "StubCache::secondary_->key"); + "StubCache::secondary_->key"); Add(stub_cache->value_reference(StubCache::kSecondary).address(), - STUB_CACHE_TABLE, 5, "StubCache::secondary_->value"); + "StubCache::secondary_->value"); Add(stub_cache->map_reference(StubCache::kSecondary).address(), - STUB_CACHE_TABLE, 6, "StubCache::secondary_->map"); + "StubCache::secondary_->map"); // Runtime entries Add(ExternalReference::delete_handle_scope_extensions(isolate).address(), - RUNTIME_ENTRY, 1, "HandleScope::DeleteExtensions"); + "HandleScope::DeleteExtensions"); Add(ExternalReference::incremental_marking_record_write_function(isolate) .address(), - RUNTIME_ENTRY, 2, "IncrementalMarking::RecordWrite"); + "IncrementalMarking::RecordWrite"); Add(ExternalReference::store_buffer_overflow_function(isolate).address(), - RUNTIME_ENTRY, 3, "StoreBuffer::StoreBufferOverflow"); + "StoreBuffer::StoreBufferOverflow"); // Add a small set of deopt entry addresses to encoder without generating the // deopt table code, which isn't possible at deserialization time. @@ -407,78 +338,44 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { entry, Deoptimizer::LAZY, Deoptimizer::CALCULATE_ENTRY_ADDRESS); - Add(address, LAZY_DEOPTIMIZATION, entry, "lazy_deopt"); + Add(address, "lazy_deopt"); } } ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) - : encodings_(HashMap::PointersMatch), - isolate_(isolate) { - ExternalReferenceTable* external_references = - ExternalReferenceTable::instance(isolate_); - for (int i = 0; i < external_references->size(); ++i) { - Put(external_references->address(i), i); + : map_(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); } } -uint32_t ExternalReferenceEncoder::Encode(Address key) const { - int index = IndexOf(key); - DCHECK(key == NULL || index >= 0); - return index >= 0 ? - ExternalReferenceTable::instance(isolate_)->code(index) : 0; -} - - -const char* ExternalReferenceEncoder::NameOfAddress(Address key) const { - int index = IndexOf(key); - return index >= 0 ? ExternalReferenceTable::instance(isolate_)->name(index) - : ""; -} - - -int ExternalReferenceEncoder::IndexOf(Address key) const { - if (key == NULL) return -1; +uint32_t ExternalReferenceEncoder::Encode(Address address) const { + DCHECK_NOT_NULL(address); HashMap::Entry* entry = - const_cast(encodings_).Lookup(key, Hash(key), false); - return entry == NULL - ? -1 - : static_cast(reinterpret_cast(entry->value)); + const_cast(map_).Lookup(address, Hash(address), false); + DCHECK_NOT_NULL(entry); + return static_cast(reinterpret_cast(entry->value)); } -void ExternalReferenceEncoder::Put(Address key, int index) { - HashMap::Entry* entry = encodings_.Lookup(key, Hash(key), true); - entry->value = reinterpret_cast(index); +const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, + Address address) const { + HashMap::Entry* entry = + 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); } -ExternalReferenceDecoder::ExternalReferenceDecoder(Isolate* isolate) - : encodings_(NewArray(kTypeCodeCount)), - isolate_(isolate) { - ExternalReferenceTable* external_references = - ExternalReferenceTable::instance(isolate_); - for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { - int max = external_references->max_id(type) + 1; - encodings_[type] = NewArray
(max + 1); - } - for (int i = 0; i < external_references->size(); ++i) { - Put(external_references->code(i), external_references->address(i)); - } -} - - -ExternalReferenceDecoder::~ExternalReferenceDecoder() { - for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) { - DeleteArray(encodings_[type]); - } - DeleteArray(encodings_); -} - - -RootIndexMap::RootIndexMap(Isolate* isolate) { - map_ = new HashMap(HashMap::PointersMatch); +RootIndexMap::RootIndexMap(Isolate* isolate) : map_(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); @@ -488,12 +385,12 @@ RootIndexMap::RootIndexMap(Isolate* isolate) { 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); } } } @@ -654,8 +551,10 @@ void Deserializer::Initialize(Isolate* isolate) { DCHECK_NULL(isolate_); DCHECK_NOT_NULL(isolate); isolate_ = isolate; - DCHECK_NULL(external_reference_decoder_); - external_reference_decoder_ = new ExternalReferenceDecoder(isolate); + DCHECK_NULL(external_reference_table_); + external_reference_table_ = ExternalReferenceTable::instance(isolate); + CHECK_EQ(magic_number_, + SerializedData::ComputeMagicNumber(external_reference_table_)); } @@ -751,10 +650,6 @@ MaybeHandle Deserializer::DeserializeCode( Deserializer::~Deserializer() { // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. // DCHECK(source_.AtEOF()); - if (external_reference_decoder_) { - delete external_reference_decoder_; - external_reference_decoder_ = NULL; - } attached_objects_.Dispose(); } @@ -1004,7 +899,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space, current = reinterpret_cast( \ reinterpret_cast
(current) + skip); \ int reference_id = source_.GetInt(); \ - Address address = external_reference_decoder_->Decode(reference_id); \ + Address address = external_reference_table_->address(reference_id); \ new_object = reinterpret_cast(address); \ } else if (where == kBackref) { \ emit_write_barrier = (space_number == NEW_SPACE); \ @@ -2387,7 +2282,7 @@ MaybeHandle CodeSerializer::Deserialize( HandleScope scope(isolate); SmartPointer scd( - SerializedCodeData::FromCachedData(cached_data, *source)); + SerializedCodeData::FromCachedData(isolate, cached_data, *source)); if (scd.is_empty()) { if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); DCHECK(cached_data->rejected()); @@ -2465,6 +2360,7 @@ SnapshotData::SnapshotData(const Serializer& ser) { AllocateData(size); // Set header values. + SetMagicNumber(ser.isolate()); SetHeaderValue(kCheckSumOffset, Version::Hash()); SetHeaderValue(kNumReservationsOffset, reservations.length()); SetHeaderValue(kPayloadLengthOffset, payload.length()); @@ -2555,7 +2451,7 @@ SerializedCodeData::SerializedCodeData(const List& payload, AllocateData(size); // Set header values. - SetHeaderValue(kMagicNumberOffset, kMagicNumber); + SetMagicNumber(cs.isolate()); SetHeaderValue(kVersionHashOffset, Version::Hash()); SetHeaderValue(kSourceHashOffset, SourceHash(cs.source())); SetHeaderValue(kCpuFeaturesOffset, @@ -2587,15 +2483,15 @@ SerializedCodeData::SerializedCodeData(const List& payload, SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( - String* source) const { - uint32_t magic_number = GetHeaderValue(kMagicNumberOffset); + Isolate* isolate, String* source) const { + uint32_t magic_number = GetMagicNumber(); uint32_t version_hash = GetHeaderValue(kVersionHashOffset); uint32_t source_hash = GetHeaderValue(kSourceHashOffset); uint32_t cpu_features = GetHeaderValue(kCpuFeaturesOffset); uint32_t flags_hash = GetHeaderValue(kFlagHashOffset); uint32_t c1 = GetHeaderValue(kChecksum1Offset); uint32_t c2 = GetHeaderValue(kChecksum2Offset); - if (magic_number != kMagicNumber) return MAGIC_NUMBER_MISMATCH; + if (magic_number != ComputeMagicNumber(isolate)) return MAGIC_NUMBER_MISMATCH; if (version_hash != Version::Hash()) return VERSION_MISMATCH; if (source_hash != SourceHash(source)) return SOURCE_MISMATCH; if (cpu_features != static_cast(CpuFeatures::SupportedFeatures())) { @@ -2655,11 +2551,12 @@ SerializedCodeData::SerializedCodeData(ScriptData* data) : SerializedData(const_cast(data->data()), data->length()) {} -SerializedCodeData* SerializedCodeData::FromCachedData(ScriptData* cached_data, +SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate, + ScriptData* cached_data, String* source) { DisallowHeapAllocation no_gc; SerializedCodeData* scd = new SerializedCodeData(cached_data); - SanityCheckResult r = scd->SanityCheck(source); + SanityCheckResult r = scd->SanityCheck(isolate, source); if (r == CHECK_SUCCESS) return scd; cached_data->Reject(); source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); diff --git a/src/serialize.h b/src/serialize.h index 06ed9fc4f2..ca748a7e33 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -15,30 +15,7 @@ namespace internal { class ScriptData; -// A TypeCode is used to distinguish different kinds of external reference. -// It is a single bit to make testing for types easy. -enum TypeCode { - UNCLASSIFIED, // One-of-a-kind references. - C_BUILTIN, - BUILTIN, - RUNTIME_FUNCTION, - IC_UTILITY, - STATS_COUNTER, - TOP_ADDRESS, - ACCESSOR_CODE, - STUB_CACHE_TABLE, - RUNTIME_ENTRY, - LAZY_DEOPTIMIZATION -}; - -const int kTypeCodeCount = LAZY_DEOPTIMIZATION + 1; -const int kFirstTypeCode = UNCLASSIFIED; - -const int kReferenceIdBits = 16; -const int kReferenceIdMask = (1 << kReferenceIdBits) - 1; -const int kReferenceTypeShift = kReferenceIdBits; - -const int kDeoptTableSerializeEntryCount = 64; +static const int kDeoptTableSerializeEntryCount = 64; // ExternalReferenceTable is a helper class that defines the relationship // between external references and their encodings. It is used to build @@ -47,46 +24,28 @@ class ExternalReferenceTable { public: static ExternalReferenceTable* instance(Isolate* isolate); - ~ExternalReferenceTable() { } - int size() const { return refs_.length(); } - Address address(int i) { return refs_[i].address; } - - uint32_t code(int i) { return refs_[i].code; } - const char* name(int i) { return refs_[i].name; } - int max_id(int code) { return max_id_[code]; } + inline static Address NotAvailable() { return NULL; } private: - explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) { - PopulateTable(isolate); - } - struct ExternalReferenceEntry { Address address; - uint32_t code; const char* name; }; - void PopulateTable(Isolate* isolate); - - // For a few types of references, we can get their address from their id. - void AddFromId(TypeCode type, - uint16_t id, - const char* name, - Isolate* isolate); - - // For other types of references, the caller will figure out the address. - void Add(Address address, TypeCode type, uint16_t id, const char* name); + explicit ExternalReferenceTable(Isolate* isolate); void Add(Address address, const char* name) { - Add(address, UNCLASSIFIED, ++max_id_[UNCLASSIFIED], name); + ExternalReferenceEntry entry = {address, name}; + refs_.Add(entry); } List refs_; - uint16_t max_id_[kTypeCodeCount]; + + DISALLOW_COPY_AND_ASSIGN(ExternalReferenceTable); }; @@ -96,47 +55,17 @@ class ExternalReferenceEncoder { uint32_t Encode(Address key) const; - const char* NameOfAddress(Address key) const; + const char* NameOfAddress(Isolate* isolate, Address address) const; private: - HashMap encodings_; static uint32_t Hash(Address key) { - return static_cast(reinterpret_cast(key) >> 2); + return static_cast(reinterpret_cast(key) >> + kPointerSizeLog2); } - int IndexOf(Address key) const; + HashMap map_; - void Put(Address key, int index); - - Isolate* isolate_; -}; - - -class ExternalReferenceDecoder { - public: - explicit ExternalReferenceDecoder(Isolate* isolate); - ~ExternalReferenceDecoder(); - - Address Decode(uint32_t key) const { - if (key == 0) return NULL; - return *Lookup(key); - } - - private: - Address** encodings_; - - Address* Lookup(uint32_t key) const { - int type = key >> kReferenceTypeShift; - DCHECK(kFirstTypeCode <= type && type < kTypeCodeCount); - int id = key & kReferenceIdMask; - return &encodings_[type][id]; - } - - void Put(uint32_t key, Address value) { - *Lookup(key) = value; - } - - Isolate* isolate_; + DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder); }; @@ -170,17 +99,16 @@ class RootIndexMap : public AddressMapBase { public: explicit RootIndexMap(Isolate* isolate); - ~RootIndexMap() { delete map_; } - 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); }; @@ -519,9 +447,16 @@ class SerializedData { if (owns_data_) DeleteArray(data_); } + uint32_t GetMagicNumber() const { return GetHeaderValue(kMagicNumberOffset); } + class ChunkSizeBits : public BitField {}; class IsLastChunkBits : public BitField {}; + static uint32_t ComputeMagicNumber(ExternalReferenceTable* table) { + uint32_t external_refs = table->size(); + return 0xC0DE0000 ^ external_refs; + } + protected: void SetHeaderValue(int offset, uint32_t value) { uint32_t* address = reinterpret_cast(data_ + offset); @@ -536,6 +471,16 @@ class SerializedData { void AllocateData(int size); + static uint32_t ComputeMagicNumber(Isolate* isolate) { + return ComputeMagicNumber(ExternalReferenceTable::instance(isolate)); + } + + void SetMagicNumber(Isolate* isolate) { + SetHeaderValue(kMagicNumberOffset, ComputeMagicNumber(isolate)); + } + + static const int kMagicNumberOffset = 0; + byte* data_; int size_; bool owns_data_; @@ -550,7 +495,8 @@ class Deserializer: public SerializerDeserializer { explicit Deserializer(Data* data) : isolate_(NULL), source_(data->Payload()), - external_reference_decoder_(NULL), + magic_number_(data->GetMagicNumber()), + external_reference_table_(NULL), deserialized_large_objects_(0), deserializing_user_code_(false) { DecodeReservation(data->Reservations()); @@ -624,6 +570,8 @@ class Deserializer: public SerializerDeserializer { Vector > attached_objects_; SnapshotByteSource source_; + uint32_t magic_number_; + // The address of the next object that will be allocated in each space. // Each space has a number of chunks reserved by the GC, with each chunk // fitting into a page. Deserialized objects are allocated into the @@ -632,7 +580,7 @@ class Deserializer: public SerializerDeserializer { uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; Address high_water_[kNumberOfPreallocatedSpaces]; - ExternalReferenceDecoder* external_reference_decoder_; + ExternalReferenceTable* external_reference_table_; List deserialized_large_objects_; @@ -945,13 +893,15 @@ class SnapshotData : public SerializedData { private: bool IsSane(); + // The data header consists of uint32_t-sized entries: - // [0] version hash - // [1] number of reservation size entries - // [2] payload length + // [0] magic number and external reference count + // [1] version hash + // [2] number of reservation size entries + // [3] payload length // ... reservations // ... serialized payload - static const int kCheckSumOffset = 0; + static const int kCheckSumOffset = kMagicNumberOffset + kInt32Size; static const int kNumReservationsOffset = kCheckSumOffset + kInt32Size; static const int kPayloadLengthOffset = kNumReservationsOffset + kInt32Size; static const int kHeaderSize = kPayloadLengthOffset + kInt32Size; @@ -962,7 +912,8 @@ class SnapshotData : public SerializedData { class SerializedCodeData : public SerializedData { public: // Used when consuming. - static SerializedCodeData* FromCachedData(ScriptData* cached_data, + static SerializedCodeData* FromCachedData(Isolate* isolate, + ScriptData* cached_data, String* source); // Used when producing. @@ -990,14 +941,12 @@ class SerializedCodeData : public SerializedData { CHECKSUM_MISMATCH = 6 }; - SanityCheckResult SanityCheck(String* source) const; + SanityCheckResult SanityCheck(Isolate* isolate, String* source) const; uint32_t SourceHash(String* source) const { return source->length(); } - static const uint32_t kMagicNumber = 0xC0D1F1ED; - // The data header consists of uint32_t-sized entries: - // [ 0] magic number + // [ 0] magic number and external reference count // [ 1] version hash // [ 2] source hash // [ 3] cpu features @@ -1011,7 +960,6 @@ class SerializedCodeData : public SerializedData { // ... reservations // ... code stub keys // ... serialized payload - static const int kMagicNumberOffset = 0; static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size; static const int kSourceHashOffset = kVersionHashOffset + kInt32Size; static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size; diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc index 3f75498b7e..18d91cd41c 100644 --- a/test/cctest/test-serialize.cc +++ b/test/cctest/test-serialize.cc @@ -71,74 +71,6 @@ class TestIsolate : public Isolate { }; -template -static Address AddressOf(T id) { - return ExternalReference(id, CcTest::i_isolate()).address(); -} - - -template -static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) { - return encoder.Encode(AddressOf(id)); -} - - -static uint32_t make_code(TypeCode type, int id) { - return static_cast(type) << kReferenceTypeShift | id; -} - - -TEST(ExternalReferenceEncoder) { - Isolate* isolate = CcTest::i_isolate(); - v8::V8::Initialize(); - - ExternalReferenceEncoder encoder(isolate); - CHECK_EQ(make_code(BUILTIN, Builtins::kArrayCode), - Encode(encoder, Builtins::kArrayCode)); - CHECK_EQ(make_code(v8::internal::RUNTIME_FUNCTION, Runtime::kAbort), - Encode(encoder, Runtime::kAbort)); - ExternalReference stack_limit_address = - ExternalReference::address_of_stack_limit(isolate); - CHECK_EQ(make_code(UNCLASSIFIED, 2), - encoder.Encode(stack_limit_address.address())); - ExternalReference real_stack_limit_address = - ExternalReference::address_of_real_stack_limit(isolate); - CHECK_EQ(make_code(UNCLASSIFIED, 3), - encoder.Encode(real_stack_limit_address.address())); - CHECK_EQ(make_code(UNCLASSIFIED, 8), - encoder.Encode(ExternalReference::debug_break(isolate).address())); - CHECK_EQ( - make_code(UNCLASSIFIED, 4), - encoder.Encode(ExternalReference::new_space_start(isolate).address())); - CHECK_EQ( - make_code(UNCLASSIFIED, 1), - encoder.Encode(ExternalReference::roots_array_start(isolate).address())); - CHECK_EQ(make_code(UNCLASSIFIED, 33), - encoder.Encode(ExternalReference::cpu_features().address())); -} - - -TEST(ExternalReferenceDecoder) { - Isolate* isolate = CcTest::i_isolate(); - v8::V8::Initialize(); - - ExternalReferenceDecoder decoder(isolate); - CHECK_EQ(AddressOf(Builtins::kArrayCode), - decoder.Decode(make_code(BUILTIN, Builtins::kArrayCode))); - CHECK_EQ(AddressOf(Runtime::kAbort), - decoder.Decode(make_code(v8::internal::RUNTIME_FUNCTION, - Runtime::kAbort))); - CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(), - decoder.Decode(make_code(UNCLASSIFIED, 2))); - CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), - decoder.Decode(make_code(UNCLASSIFIED, 3))); - CHECK_EQ(ExternalReference::debug_break(isolate).address(), - decoder.Decode(make_code(UNCLASSIFIED, 8))); - CHECK_EQ(ExternalReference::new_space_start(isolate).address(), - decoder.Decode(make_code(UNCLASSIFIED, 4))); -} - - void WritePayload(const Vector& payload, const char* file_name) { FILE* file = v8::base::OS::FOpen(file_name, "wb"); if (file == NULL) {