blob: eeb7eb73fa429573ecedf7a918e4eba47abd1b2c [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// 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
11namespace v8 {
12namespace internal {
13
14ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
15 map_ = isolate->external_reference_map();
16 if (map_ != NULL) return;
17 map_ = new HashMap(HashMap::PointersMatch);
18 ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
19 for (int i = 0; i < table->size(); ++i) {
20 Address addr = table->address(i);
21 if (addr == ExternalReferenceTable::NotAvailable()) continue;
22 // We expect no duplicate external references entries in the table.
23 DCHECK_NULL(map_->Lookup(addr, Hash(addr)));
24 map_->LookupOrInsert(addr, Hash(addr))->value = reinterpret_cast<void*>(i);
25 }
26 isolate->set_external_reference_map(map_);
27}
28
29uint32_t ExternalReferenceEncoder::Encode(Address address) const {
30 DCHECK_NOT_NULL(address);
31 HashMap::Entry* entry =
32 const_cast<HashMap*>(map_)->Lookup(address, Hash(address));
33 DCHECK_NOT_NULL(entry);
34 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
35}
36
37const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate,
38 Address address) const {
39 HashMap::Entry* entry =
40 const_cast<HashMap*>(map_)->Lookup(address, Hash(address));
41 if (entry == NULL) return "<unknown>";
42 uint32_t i = static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
43 return ExternalReferenceTable::instance(isolate)->name(i);
44}
45
46void SerializedData::AllocateData(int size) {
47 DCHECK(!owns_data_);
48 data_ = NewArray<byte>(size);
49 size_ = size;
50 owns_data_ = true;
51 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
52}
53
54// The partial snapshot cache is terminated by undefined. We visit the
55// partial snapshot...
56// - during deserialization to populate it.
57// - during normal GC to keep its content alive.
58// - not during serialization. The partial serializer adds to it explicitly.
59void SerializerDeserializer::Iterate(Isolate* isolate, ObjectVisitor* visitor) {
60 List<Object*>* cache = isolate->partial_snapshot_cache();
61 for (int i = 0;; ++i) {
62 // Extend the array ready to get a value when deserializing.
63 if (cache->length() <= i) cache->Add(Smi::FromInt(0));
64 // During deserialization, the visitor populates the partial snapshot cache
65 // and eventually terminates the cache with undefined.
66 visitor->VisitPointer(&cache->at(i));
67 if (cache->at(i)->IsUndefined()) break;
68 }
69}
70
71bool SerializerDeserializer::CanBeDeferred(HeapObject* o) {
72 return !o->IsString() && !o->IsScript();
73}
74
75} // namespace internal
76} // namespace v8