OLD | NEW |
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/code-serializer.h" | 5 #include "src/snapshot/code-serializer.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/log.h" | 8 #include "src/log.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/profiler/cpu-profiler.h" | 10 #include "src/profiler/cpu-profiler.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 case Code::BYTECODE_HANDLER: // No direct references to handlers. | 69 case Code::BYTECODE_HANDLER: // No direct references to handlers. |
70 CHECK(false); | 70 CHECK(false); |
71 case Code::BUILTIN: | 71 case Code::BUILTIN: |
72 SerializeBuiltin(code_object->builtin_index(), how_to_code, | 72 SerializeBuiltin(code_object->builtin_index(), how_to_code, |
73 where_to_point); | 73 where_to_point); |
74 return; | 74 return; |
75 case Code::STUB: | 75 case Code::STUB: |
76 #define IC_KIND_CASE(KIND) case Code::KIND: | 76 #define IC_KIND_CASE(KIND) case Code::KIND: |
77 IC_KIND_LIST(IC_KIND_CASE) | 77 IC_KIND_LIST(IC_KIND_CASE) |
78 #undef IC_KIND_CASE | 78 #undef IC_KIND_CASE |
79 SerializeCodeStub(code_object->stub_key(), how_to_code, where_to_point); | 79 SerializeCodeStub(code_object, how_to_code, where_to_point); |
80 return; | 80 return; |
81 case Code::FUNCTION: | 81 case Code::FUNCTION: |
82 DCHECK(code_object->has_reloc_info_for_serialization()); | 82 DCHECK(code_object->has_reloc_info_for_serialization()); |
83 SerializeGeneric(code_object, how_to_code, where_to_point); | 83 SerializeGeneric(code_object, how_to_code, where_to_point); |
84 return; | 84 return; |
85 case Code::WASM_FUNCTION: | 85 case Code::WASM_FUNCTION: |
86 case Code::WASM_TO_JS_FUNCTION: | 86 case Code::WASM_TO_JS_FUNCTION: |
87 case Code::JS_TO_WASM_FUNCTION: | 87 case Code::JS_TO_WASM_FUNCTION: |
88 UNREACHABLE(); | 88 UNREACHABLE(); |
89 } | 89 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 121 |
122 if (FLAG_trace_serializer) { | 122 if (FLAG_trace_serializer) { |
123 PrintF(" Encoding builtin: %s\n", | 123 PrintF(" Encoding builtin: %s\n", |
124 isolate()->builtins()->name(builtin_index)); | 124 isolate()->builtins()->name(builtin_index)); |
125 } | 125 } |
126 | 126 |
127 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); | 127 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); |
128 sink_->PutInt(builtin_index, "builtin_index"); | 128 sink_->PutInt(builtin_index, "builtin_index"); |
129 } | 129 } |
130 | 130 |
131 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, | 131 void CodeSerializer::SerializeCodeStub(Code* code_stub, HowToCode how_to_code, |
132 WhereToPoint where_to_point) { | 132 WhereToPoint where_to_point) { |
133 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || | 133 // We only arrive here if we have not encountered this code stub before. |
134 (how_to_code == kPlain && where_to_point == kInnerPointer) || | 134 DCHECK(!reference_map()->Lookup(code_stub).is_valid()); |
135 (how_to_code == kFromCode && where_to_point == kInnerPointer)); | 135 uint32_t stub_key = code_stub->stub_key(); |
136 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); | 136 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); |
137 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); | 137 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); |
| 138 stub_keys_.Add(stub_key); |
138 | 139 |
139 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; | 140 SerializerReference reference = |
140 | 141 reference_map()->AddAttachedReference(code_stub); |
141 if (FLAG_trace_serializer) { | 142 if (FLAG_trace_serializer) { |
142 PrintF(" Encoding code stub %s as %d\n", | 143 PrintF(" Encoding code stub %s as attached reference %d\n", |
143 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key)), index); | 144 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key)), |
| 145 reference.attached_reference_index()); |
144 } | 146 } |
145 | 147 PutAttachedReference(reference, how_to_code, where_to_point); |
146 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub"); | |
147 sink_->PutInt(index, "CodeStub key"); | |
148 } | |
149 | |
150 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { | |
151 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). | |
152 int index = 0; | |
153 while (index < stub_keys_.length()) { | |
154 if (stub_keys_[index] == stub_key) return index; | |
155 index++; | |
156 } | |
157 stub_keys_.Add(stub_key); | |
158 return index; | |
159 } | 148 } |
160 | 149 |
161 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( | 150 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( |
162 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { | 151 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { |
163 base::ElapsedTimer timer; | 152 base::ElapsedTimer timer; |
164 if (FLAG_profile_deserialization) timer.Start(); | 153 if (FLAG_profile_deserialization) timer.Start(); |
165 | 154 |
166 HandleScope scope(isolate); | 155 HandleScope scope(isolate); |
167 | 156 |
168 base::SmartPointer<SerializedCodeData> scd( | 157 base::SmartPointer<SerializedCodeData> scd( |
169 SerializedCodeData::FromCachedData(isolate, cached_data, *source)); | 158 SerializedCodeData::FromCachedData(isolate, cached_data, *source)); |
170 if (scd.is_empty()) { | 159 if (scd.is_empty()) { |
171 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); | 160 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); |
172 DCHECK(cached_data->rejected()); | 161 DCHECK(cached_data->rejected()); |
173 return MaybeHandle<SharedFunctionInfo>(); | 162 return MaybeHandle<SharedFunctionInfo>(); |
174 } | 163 } |
175 | 164 |
176 // Prepare and register list of attached objects. | 165 Deserializer deserializer(scd.get()); |
| 166 deserializer.AddAttachedObject(source); |
177 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); | 167 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); |
178 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | |
179 code_stub_keys.length() + kCodeStubsBaseIndex); | |
180 attached_objects[kSourceObjectIndex] = source; | |
181 for (int i = 0; i < code_stub_keys.length(); i++) { | 168 for (int i = 0; i < code_stub_keys.length(); i++) { |
182 attached_objects[i + kCodeStubsBaseIndex] = | 169 deserializer.AddAttachedObject( |
183 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); | 170 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); |
184 } | 171 } |
185 | 172 |
186 Deserializer deserializer(scd.get()); | |
187 deserializer.SetAttachedObjects(attached_objects); | |
188 | |
189 // Deserialize. | 173 // Deserialize. |
190 Handle<SharedFunctionInfo> result; | 174 Handle<SharedFunctionInfo> result; |
191 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { | 175 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { |
192 // Deserializing may fail if the reservations cannot be fulfilled. | 176 // Deserializing may fail if the reservations cannot be fulfilled. |
193 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); | 177 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); |
194 return MaybeHandle<SharedFunctionInfo>(); | 178 return MaybeHandle<SharedFunctionInfo>(); |
195 } | 179 } |
196 | 180 |
197 if (FLAG_profile_deserialization) { | 181 if (FLAG_profile_deserialization) { |
198 double ms = timer.Elapsed().InMillisecondsF(); | 182 double ms = timer.Elapsed().InMillisecondsF(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 SanityCheckResult r = scd->SanityCheck(isolate, source); | 357 SanityCheckResult r = scd->SanityCheck(isolate, source); |
374 if (r == CHECK_SUCCESS) return scd; | 358 if (r == CHECK_SUCCESS) return scd; |
375 cached_data->Reject(); | 359 cached_data->Reject(); |
376 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 360 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
377 delete scd; | 361 delete scd; |
378 return NULL; | 362 return NULL; |
379 } | 363 } |
380 | 364 |
381 } // namespace internal | 365 } // namespace internal |
382 } // namespace v8 | 366 } // namespace v8 |
OLD | NEW |