Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/snapshot/startup-serializer.cc

Issue 1811913002: [serializer] ensure that immortal immovable roots are correctly deserialized. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/snapshot/startup-serializer.h" 5 #include "src/snapshot/startup-serializer.h"
6 6
7 #include "src/objects-inl.h" 7 #include "src/objects-inl.h"
8 #include "src/v8threads.h" 8 #include "src/v8threads.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 StartupSerializer::StartupSerializer( 13 StartupSerializer::StartupSerializer(
14 Isolate* isolate, SnapshotByteSink* sink, 14 Isolate* isolate, SnapshotByteSink* sink,
15 FunctionCodeHandling function_code_handling) 15 FunctionCodeHandling function_code_handling)
16 : Serializer(isolate, sink), 16 : Serializer(isolate, sink),
17 root_index_wave_front_(0), 17 function_code_handling_(function_code_handling),
18 serializing_builtins_(false), 18 serializing_builtins_(false) {
19 function_code_handling_(function_code_handling) {
20 InitializeCodeAddressMap(); 19 InitializeCodeAddressMap();
21 } 20 }
22 21
23 StartupSerializer::~StartupSerializer() { 22 StartupSerializer::~StartupSerializer() {
24 OutputStatistics("StartupSerializer"); 23 OutputStatistics("StartupSerializer");
25 } 24 }
26 25
27 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, 26 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
28 WhereToPoint where_to_point, int skip) { 27 WhereToPoint where_to_point, int skip) {
29 DCHECK(!obj->IsJSFunction()); 28 DCHECK(!obj->IsJSFunction());
30 29
31 if (obj->IsCode()) { 30 if (obj->IsCode()) {
32 Code* code = Code::cast(obj); 31 Code* code = Code::cast(obj);
33 // If the function code is compiled (either as native code or bytecode), 32 // If the function code is compiled (either as native code or bytecode),
34 // replace it with lazy-compile builtin. Only exception is when we are 33 // replace it with lazy-compile builtin. Only exception is when we are
35 // serializing the canonical interpreter-entry-trampoline builtin. 34 // serializing the canonical interpreter-entry-trampoline builtin.
36 if (function_code_handling_ == CLEAR_FUNCTION_CODE && 35 if (function_code_handling_ == CLEAR_FUNCTION_CODE &&
37 (code->kind() == Code::FUNCTION || 36 (code->kind() == Code::FUNCTION ||
38 (!serializing_builtins_ && code->is_interpreter_entry_trampoline()))) { 37 (!serializing_builtins_ && code->is_interpreter_entry_trampoline()))) {
39 obj = isolate()->builtins()->builtin(Builtins::kCompileLazy); 38 obj = isolate()->builtins()->builtin(Builtins::kCompileLazy);
40 } 39 }
41 } else if (obj->IsBytecodeArray()) { 40 } else if (obj->IsBytecodeArray()) {
42 obj = isolate()->heap()->undefined_value(); 41 obj = isolate()->heap()->undefined_value();
43 } 42 }
44 43
45 int root_index = root_index_map_.Lookup(obj); 44 int root_index = root_index_map_.Lookup(obj);
46 bool is_immortal_immovable_root = false;
47 // We can only encode roots as such if it has already been serialized. 45 // We can only encode roots as such if it has already been serialized.
48 // That applies to root indices below the wave front. 46 // That applies to root indices below the wave front.
49 if (root_index != RootIndexMap::kInvalidRootIndex) { 47 if (root_index != RootIndexMap::kInvalidRootIndex) {
50 if (root_index < root_index_wave_front_) { 48 if (root_has_been_serialized_.test(root_index)) {
51 PutRoot(root_index, obj, how_to_code, where_to_point, skip); 49 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
52 return; 50 return;
53 } else {
54 is_immortal_immovable_root = Heap::RootIsImmortalImmovable(root_index);
55 } 51 }
56 } 52 }
57 53
58 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return; 54 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
59 55
60 FlushSkip(skip); 56 FlushSkip(skip);
61 57
62 // Object has not yet been serialized. Serialize it here. 58 // Object has not yet been serialized. Serialize it here.
63 ObjectSerializer object_serializer(this, obj, sink_, how_to_code, 59 ObjectSerializer object_serializer(this, obj, sink_, how_to_code,
64 where_to_point); 60 where_to_point);
65 object_serializer.Serialize(); 61 object_serializer.Serialize();
66 62
67 if (is_immortal_immovable_root) { 63 if (serializing_immortal_immovables_roots_ &&
64 root_index != RootIndexMap::kInvalidRootIndex) {
68 // Make sure that the immortal immovable root has been included in the first 65 // Make sure that the immortal immovable root has been included in the first
69 // chunk of its reserved space , so that it is deserialized onto the first 66 // chunk of its reserved space , so that it is deserialized onto the first
70 // page of its space and stays immortal immovable. 67 // page of its space and stays immortal immovable.
71 BackReference ref = back_reference_map_.Lookup(obj); 68 BackReference ref = back_reference_map_.Lookup(obj);
72 CHECK(ref.is_valid() && ref.chunk_index() == 0); 69 CHECK(ref.is_valid() && ref.chunk_index() == 0);
73 } 70 }
74 } 71 }
75 72
76 void StartupSerializer::SerializeWeakReferencesAndDeferred() { 73 void StartupSerializer::SerializeWeakReferencesAndDeferred() {
77 // This comes right after serialization of the partial snapshot, where we 74 // This comes right after serialization of the partial snapshot, where we
(...skipping 16 matching lines...) Expand all
94 void StartupSerializer::SerializeStrongReferences() { 91 void StartupSerializer::SerializeStrongReferences() {
95 Isolate* isolate = this->isolate(); 92 Isolate* isolate = this->isolate();
96 // No active threads. 93 // No active threads.
97 CHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse()); 94 CHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse());
98 // No active or weak handles. 95 // No active or weak handles.
99 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty()); 96 CHECK(isolate->handle_scope_implementer()->blocks()->is_empty());
100 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); 97 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles());
101 CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles()); 98 CHECK_EQ(0, isolate->eternal_handles()->NumberOfHandles());
102 // We don't support serializing installed extensions. 99 // We don't support serializing installed extensions.
103 CHECK(!isolate->has_installed_extensions()); 100 CHECK(!isolate->has_installed_extensions());
101 // First visit immortal immovables to make sure they end up in the first page.
102 serializing_immortal_immovables_roots_ = true;
103 isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG_ROOT_LIST);
104 // Check that immortal immovable roots are allocated on the first page.
105 CHECK(HasNotExceededFirstPageOfEachSpace());
106 serializing_immortal_immovables_roots_ = false;
107 // Visit the rest of the strong roots.
104 isolate->heap()->IterateSmiRoots(this); 108 isolate->heap()->IterateSmiRoots(this);
105 isolate->heap()->IterateStrongRoots(this, 109 isolate->heap()->IterateStrongRoots(this,
106 VISIT_ONLY_STRONG_FOR_SERIALIZATION); 110 VISIT_ONLY_STRONG_FOR_SERIALIZATION);
107 } 111 }
108 112
109 void StartupSerializer::VisitPointers(Object** start, Object** end) { 113 void StartupSerializer::VisitPointers(Object** start, Object** end) {
110 for (Object** current = start; current < end; current++) { 114 if (start == isolate()->heap()->roots_array_start()) {
111 if (start == isolate()->heap()->roots_array_start()) { 115 // Serializing the root list needs special handling:
112 root_index_wave_front_ = 116 // - The first pass over the root list only serializes immortal immovables.
113 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); 117 // - The second pass over the root list serializes the rest.
118 // - Only root list elements that have been fully serialized can be
119 // referenced via as root by using kRootArray bytecodes.
120 int skip = 0;
121 for (Object** current = start; current < end; current++) {
122 int root_index = static_cast<int>(current - start);
123 if (RootShouldBeSkipped(root_index)) {
124 skip += kPointerSize;
125 continue;
126 } else {
127 if ((*current)->IsSmi()) {
128 FlushSkip(skip);
129 PutSmi(Smi::cast(*current));
130 } else {
131 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject,
132 skip);
133 }
134 root_has_been_serialized_.set(root_index);
135 skip = 0;
136 }
114 } 137 }
115 if (ShouldBeSkipped(current)) { 138 FlushSkip(skip);
116 sink_->Put(kSkip, "Skip"); 139 } else {
117 sink_->PutInt(kPointerSize, "SkipOneWord"); 140 Serializer::VisitPointers(start, end);
118 } else if ((*current)->IsSmi()) {
119 sink_->Put(kOnePointerRawData, "Smi");
120 for (int i = 0; i < kPointerSize; i++) {
121 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
122 }
123 } else {
124 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
125 }
126 } 141 }
127 } 142 }
128 143
144 bool StartupSerializer::RootShouldBeSkipped(int root_index) {
145 if (root_index == Heap::kStoreBufferTopRootIndex ||
146 root_index == Heap::kStackLimitRootIndex ||
147 root_index == Heap::kRealStackLimitRootIndex) {
148 return true;
149 }
150 return Heap::RootIsImmortalImmovable(root_index) !=
151 serializing_immortal_immovables_roots_;
152 }
153
129 } // namespace internal 154 } // namespace internal
130 } // namespace v8 155 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698