1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/snapshot/serializer-common.h" 6 7 #include "src/external-reference-table.h" 8 #include "src/ic/stub-cache.h" 9 #include "src/list-inl.h" 10 #include "src/objects-inl.h" 11 12 namespace v8 { 13 namespace internal { 14 ExternalReferenceEncoder(Isolate * isolate)15ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) { 16 map_ = isolate->external_reference_map(); 17 #ifdef DEBUG 18 table_ = ExternalReferenceTable::instance(isolate); 19 #endif // DEBUG 20 if (map_ != nullptr) return; 21 map_ = new AddressToIndexHashMap(); 22 ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate); 23 for (uint32_t i = 0; i < table->size(); ++i) { 24 Address addr = table->address(i); 25 // Ignore duplicate API references. 26 if (table->is_api_reference(i) && !map_->Get(addr).IsNothing()) continue; 27 DCHECK(map_->Get(addr).IsNothing()); 28 map_->Set(addr, i); 29 DCHECK(map_->Get(addr).IsJust()); 30 } 31 isolate->set_external_reference_map(map_); 32 } 33 Encode(Address address) const34uint32_t ExternalReferenceEncoder::Encode(Address address) const { 35 Maybe<uint32_t> maybe_index = map_->Get(address); 36 if (maybe_index.IsNothing()) { 37 void* addr = address; 38 v8::base::OS::PrintError("Unknown external reference %p.\n", addr); 39 v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr)); 40 v8::base::OS::Abort(); 41 } 42 #ifdef DEBUG 43 table_->increment_count(maybe_index.FromJust()); 44 #endif // DEBUG 45 return maybe_index.FromJust(); 46 } 47 NameOfAddress(Isolate * isolate,Address address) const48const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, 49 Address address) const { 50 Maybe<uint32_t> maybe_index = map_->Get(address); 51 if (maybe_index.IsNothing()) return "<unknown>"; 52 return ExternalReferenceTable::instance(isolate)->name( 53 maybe_index.FromJust()); 54 } 55 AllocateData(int size)56void SerializedData::AllocateData(int size) { 57 DCHECK(!owns_data_); 58 data_ = NewArray<byte>(size); 59 size_ = size; 60 owns_data_ = true; 61 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment)); 62 } 63 64 // The partial snapshot cache is terminated by undefined. We visit the 65 // partial snapshot... 66 // - during deserialization to populate it. 67 // - during normal GC to keep its content alive. 68 // - not during serialization. The partial serializer adds to it explicitly. 69 DISABLE_CFI_PERF Iterate(Isolate * isolate,ObjectVisitor * visitor)70void SerializerDeserializer::Iterate(Isolate* isolate, ObjectVisitor* visitor) { 71 List<Object*>* cache = isolate->partial_snapshot_cache(); 72 for (int i = 0;; ++i) { 73 // Extend the array ready to get a value when deserializing. 74 if (cache->length() <= i) cache->Add(Smi::kZero); 75 // During deserialization, the visitor populates the partial snapshot cache 76 // and eventually terminates the cache with undefined. 77 visitor->VisitPointer(&cache->at(i)); 78 if (cache->at(i)->IsUndefined(isolate)) break; 79 } 80 } 81 CanBeDeferred(HeapObject * o)82bool SerializerDeserializer::CanBeDeferred(HeapObject* o) { 83 return !o->IsString() && !o->IsScript(); 84 } 85 RestoreExternalReferenceRedirectors(List<AccessorInfo * > * accessor_infos)86void SerializerDeserializer::RestoreExternalReferenceRedirectors( 87 List<AccessorInfo*>* accessor_infos) { 88 // Restore wiped accessor infos. 89 for (AccessorInfo* info : *accessor_infos) { 90 Foreign::cast(info->js_getter()) 91 ->set_foreign_address(info->redirected_getter()); 92 } 93 } 94 95 } // namespace internal 96 } // namespace v8 97