Line data Source code
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 :
15 847 : ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
16 847 : map_ = isolate->external_reference_map();
17 : #ifdef DEBUG
18 : table_ = ExternalReferenceTable::instance(isolate);
19 : #endif // DEBUG
20 1694 : if (map_ != nullptr) return;
21 1234 : map_ = new AddressToIndexHashMap();
22 798506 : ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
23 1597012 : for (uint32_t i = 0; i < table->size(); ++i) {
24 : Address addr = table->address(i);
25 : // Ignore duplicate API references.
26 797889 : if (table->is_api_reference(i) && !map_->Get(addr).IsNothing()) continue;
27 : DCHECK(map_->Get(addr).IsNothing());
28 797871 : map_->Set(addr, i);
29 : DCHECK(map_->Get(addr).IsJust());
30 : }
31 617 : isolate->set_external_reference_map(map_);
32 : }
33 :
34 976799 : uint32_t ExternalReferenceEncoder::Encode(Address address) const {
35 976799 : Maybe<uint32_t> maybe_index = map_->Get(address);
36 976799 : if (maybe_index.IsNothing()) {
37 : void* addr = address;
38 0 : v8::base::OS::PrintError("Unknown external reference %p.\n", addr);
39 0 : v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr));
40 0 : v8::base::OS::Abort();
41 : }
42 : #ifdef DEBUG
43 : table_->increment_count(maybe_index.FromJust());
44 : #endif // DEBUG
45 976799 : return maybe_index.FromJust();
46 : }
47 :
48 0 : const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
49 : Address address) const {
50 0 : Maybe<uint32_t> maybe_index = map_->Get(address);
51 0 : if (maybe_index.IsNothing()) return "<unknown>";
52 : return ExternalReferenceTable::instance(isolate)->name(
53 0 : maybe_index.FromJust());
54 : }
55 :
56 847 : void SerializedData::AllocateData(int size) {
57 : DCHECK(!owns_data_);
58 847 : data_ = NewArray<byte>(size);
59 847 : size_ = size;
60 847 : owns_data_ = true;
61 : DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
62 847 : }
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
70 241434 : void SerializerDeserializer::Iterate(Isolate* isolate, RootVisitor* visitor) {
71 241434 : List<Object*>* cache = isolate->partial_snapshot_cache();
72 412200400 : for (int i = 0;; ++i) {
73 : // Extend the array ready to get a value when deserializing.
74 412441834 : 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 824883364 : visitor->VisitRootPointer(Root::kPartialSnapshotCache, &cache->at(i));
78 824883851 : if (cache->at(i)->IsUndefined(isolate)) break;
79 412200400 : }
80 241434 : }
81 :
82 12437 : bool SerializerDeserializer::CanBeDeferred(HeapObject* o) {
83 24874 : return !o->IsString() && !o->IsScript();
84 : }
85 :
86 60890 : void SerializerDeserializer::RestoreExternalReferenceRedirectors(
87 : List<AccessorInfo*>* accessor_infos) {
88 : // Restore wiped accessor infos.
89 121780 : for (AccessorInfo* info : *accessor_infos) {
90 : Foreign::cast(info->js_getter())
91 0 : ->set_foreign_address(info->redirected_getter());
92 : }
93 60890 : }
94 :
95 : } // namespace internal
96 : } // namespace v8
|