Line data Source code
1 : // Copyright 2017 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/builtin-serializer.h"
6 :
7 : #include "src/objects-inl.h"
8 : #include "src/snapshot/startup-serializer.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 161 : BuiltinSerializer::BuiltinSerializer(Isolate* isolate,
14 : StartupSerializer* startup_serializer)
15 161 : : Serializer(isolate), startup_serializer_(startup_serializer) {}
16 :
17 322 : BuiltinSerializer::~BuiltinSerializer() {
18 161 : OutputStatistics("BuiltinSerializer");
19 161 : }
20 :
21 161 : void BuiltinSerializer::SerializeBuiltins() {
22 113022 : for (int i = 0; i < Builtins::builtin_count; i++) {
23 112861 : builtin_offsets_[i] = sink_.Position();
24 225722 : SerializeBuiltin(isolate()->builtins()->builtin(i));
25 : }
26 161 : Pad(); // Pad with kNop since GetInt() might read too far.
27 :
28 : // Append the offset table. During deserialization, the offset table is
29 : // extracted by BuiltinSnapshotData.
30 161 : const byte* data = reinterpret_cast<const byte*>(&builtin_offsets_[0]);
31 : int data_length = static_cast<int>(sizeof(builtin_offsets_));
32 161 : sink_.PutRaw(data, data_length, "BuiltinOffsets");
33 161 : }
34 :
35 0 : void BuiltinSerializer::VisitRootPointers(Root root, Object** start,
36 : Object** end) {
37 0 : UNREACHABLE(); // We iterate manually in SerializeBuiltins.
38 : }
39 :
40 112861 : void BuiltinSerializer::SerializeBuiltin(Code* code) {
41 : DCHECK_GE(code->builtin_index(), 0);
42 :
43 : // All builtins are serialized unconditionally when the respective builtin is
44 : // reached while iterating the builtins list. A builtin seen at any other
45 : // time (e.g. startup snapshot creation, or while iterating a builtin code
46 : // object during builtin serialization) is serialized by reference - see
47 : // BuiltinSerializer::SerializeObject below.
48 : ObjectSerializer object_serializer(this, code, &sink_, kPlain,
49 112861 : kStartOfObject);
50 112861 : object_serializer.Serialize();
51 112861 : }
52 :
53 1231006 : void BuiltinSerializer::SerializeObject(HeapObject* o, HowToCode how_to_code,
54 : WhereToPoint where_to_point, int skip) {
55 : DCHECK(!o->IsSmi());
56 :
57 : // Roots can simply be serialized as root references.
58 1231006 : int root_index = root_index_map()->Lookup(o);
59 1231006 : if (root_index != RootIndexMap::kInvalidRootIndex) {
60 : DCHECK(startup_serializer_->root_has_been_serialized(root_index));
61 451444 : PutRoot(root_index, o, how_to_code, where_to_point, skip);
62 451444 : return;
63 : }
64 :
65 : // Builtins are serialized using a dedicated bytecode. We only reach this
66 : // point if encountering a Builtin e.g. while iterating the body of another
67 : // builtin.
68 779562 : if (SerializeBuiltinReference(o, how_to_code, where_to_point, skip)) return;
69 :
70 : // Embedded objects are serialized as part of the partial snapshot cache.
71 : // Currently we expect to see:
72 : // * Code: Jump targets.
73 : // * ByteArrays: Relocation infos.
74 : // * FixedArrays: Handler tables.
75 : // * Strings: CSA_ASSERTs in debug builds, various other string constants.
76 : // * HeapNumbers: Embedded constants.
77 : // TODO(6624): Jump targets should never trigger content serialization, it
78 : // should always result in a reference instead. Reloc infos and handler
79 : // tables should not end up in the partial snapshot cache.
80 :
81 503286 : FlushSkip(skip);
82 :
83 503286 : int cache_index = startup_serializer_->PartialSnapshotCacheIndex(o);
84 : sink_.Put(kPartialSnapshotCache + how_to_code + where_to_point,
85 503286 : "PartialSnapshotCache");
86 503286 : sink_.PutInt(cache_index, "partial_snapshot_cache_index");
87 : }
88 :
89 : } // namespace internal
90 : } // namespace v8
|