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

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

Issue 2205973003: [wasm] Serialization/Deserialization of compiled module (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: disable dchecks Created 4 years, 4 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
« no previous file with comments | « src/snapshot/code-serializer.h ('k') | src/snapshot/deserializer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/code-serializer.h" 5 #include "src/snapshot/code-serializer.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/log.h" 10 #include "src/log.h"
11 #include "src/macro-assembler.h" 11 #include "src/macro-assembler.h"
12 #include "src/snapshot/deserializer.h" 12 #include "src/snapshot/deserializer.h"
13 #include "src/snapshot/snapshot.h"
13 #include "src/version.h" 14 #include "src/version.h"
14 15
15 namespace v8 { 16 namespace v8 {
16 namespace internal { 17 namespace internal {
17 18
18 ScriptData* CodeSerializer::Serialize(Isolate* isolate, 19 ScriptData* CodeSerializer::Serialize(Isolate* isolate,
19 Handle<SharedFunctionInfo> info, 20 Handle<SharedFunctionInfo> info,
20 Handle<String> source) { 21 Handle<String> source) {
21 base::ElapsedTimer timer; 22 base::ElapsedTimer timer;
22 if (FLAG_profile_deserialization) timer.Start(); 23 if (FLAG_profile_deserialization) timer.Start();
23 if (FLAG_trace_serializer) { 24 if (FLAG_trace_serializer) {
24 PrintF("[Serializing from"); 25 PrintF("[Serializing from");
25 Object* script = info->script(); 26 Object* script = info->script();
26 if (script->IsScript()) Script::cast(script)->name()->ShortPrint(); 27 if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
27 PrintF("]\n"); 28 PrintF("]\n");
28 } 29 }
29 30
30 // Serialize code object. 31 // Serialize code object.
31 CodeSerializer cs(isolate, *source); 32 CodeSerializer cs(isolate, SerializedCodeData::SourceHash(source));
32 DisallowHeapAllocation no_gc; 33 DisallowHeapAllocation no_gc;
33 Object** location = Handle<Object>::cast(info).location(); 34 cs.reference_map()->AddAttachedReference(*source);
34 cs.VisitPointer(location); 35 ScriptData* ret = cs.Serialize(info);
35 cs.SerializeDeferredObjects();
36 cs.Pad();
37
38 SerializedCodeData data(cs.sink()->data(), &cs);
39 ScriptData* script_data = data.GetScriptData();
40 36
41 if (FLAG_profile_deserialization) { 37 if (FLAG_profile_deserialization) {
42 double ms = timer.Elapsed().InMillisecondsF(); 38 double ms = timer.Elapsed().InMillisecondsF();
43 int length = script_data->length(); 39 int length = ret->length();
44 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); 40 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms);
45 } 41 }
46 42
47 return script_data; 43 return ret;
44 }
45
46 ScriptData* CodeSerializer::Serialize(Handle<HeapObject> obj) {
47 DisallowHeapAllocation no_gc;
48
49 VisitPointer(Handle<Object>::cast(obj).location());
50 SerializeDeferredObjects();
51 Pad();
52
53 SerializedCodeData data(sink()->data(), this);
54
55 return data.GetScriptData();
48 } 56 }
49 57
50 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, 58 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
51 WhereToPoint where_to_point, int skip) { 59 WhereToPoint where_to_point, int skip) {
52 if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return; 60 if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return;
53 61
54 int root_index = root_index_map_.Lookup(obj); 62 int root_index = root_index_map_.Lookup(obj);
55 if (root_index != RootIndexMap::kInvalidRootIndex) { 63 if (root_index != RootIndexMap::kInvalidRootIndex) {
56 PutRoot(root_index, obj, how_to_code, where_to_point, skip); 64 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
57 return; 65 return;
(...skipping 19 matching lines...) Expand all
77 case Code::STUB: 85 case Code::STUB:
78 #define IC_KIND_CASE(KIND) case Code::KIND: 86 #define IC_KIND_CASE(KIND) case Code::KIND:
79 IC_KIND_LIST(IC_KIND_CASE) 87 IC_KIND_LIST(IC_KIND_CASE)
80 #undef IC_KIND_CASE 88 #undef IC_KIND_CASE
81 SerializeCodeStub(code_object, how_to_code, where_to_point); 89 SerializeCodeStub(code_object, how_to_code, where_to_point);
82 return; 90 return;
83 case Code::FUNCTION: 91 case Code::FUNCTION:
84 DCHECK(code_object->has_reloc_info_for_serialization()); 92 DCHECK(code_object->has_reloc_info_for_serialization());
85 SerializeGeneric(code_object, how_to_code, where_to_point); 93 SerializeGeneric(code_object, how_to_code, where_to_point);
86 return; 94 return;
87 case Code::WASM_FUNCTION: 95 default:
88 case Code::WASM_TO_JS_FUNCTION: 96 return SerializeCodeObject(code_object, how_to_code, where_to_point);
89 case Code::JS_TO_WASM_FUNCTION:
90 UNREACHABLE();
91 } 97 }
92 UNREACHABLE(); 98 UNREACHABLE();
93 } 99 }
94 100
95 // Past this point we should not see any (context-specific) maps anymore. 101 // Past this point we should not see any (context-specific) maps anymore.
96 CHECK(!obj->IsMap()); 102 CHECK(!obj->IsMap());
97 // There should be no references to the global object embedded. 103 // There should be no references to the global object embedded.
98 CHECK(!obj->IsJSGlobalProxy() && !obj->IsJSGlobalObject()); 104 CHECK(!obj->IsJSGlobalProxy() && !obj->IsJSGlobalObject());
99 // There should be no hash table embedded. They would require rehashing. 105 // There should be no hash table embedded. They would require rehashing.
100 CHECK(!obj->IsHashTable()); 106 CHECK(!obj->IsHashTable());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 PutAttachedReference(reference, how_to_code, where_to_point); 155 PutAttachedReference(reference, how_to_code, where_to_point);
150 } 156 }
151 157
152 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( 158 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
153 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { 159 Isolate* isolate, ScriptData* cached_data, Handle<String> source) {
154 base::ElapsedTimer timer; 160 base::ElapsedTimer timer;
155 if (FLAG_profile_deserialization) timer.Start(); 161 if (FLAG_profile_deserialization) timer.Start();
156 162
157 HandleScope scope(isolate); 163 HandleScope scope(isolate);
158 164
159 std::unique_ptr<SerializedCodeData> scd( 165 SerializedCodeData::SanityCheckResult sanity_check_result =
160 SerializedCodeData::FromCachedData(isolate, cached_data, *source)); 166 SerializedCodeData::CHECK_SUCCESS;
161 if (!scd) { 167 const SerializedCodeData scd = SerializedCodeData::FromCachedData(
168 isolate, cached_data, SerializedCodeData::SourceHash(source),
169 &sanity_check_result);
170 if (sanity_check_result != SerializedCodeData::CHECK_SUCCESS) {
162 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); 171 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n");
163 DCHECK(cached_data->rejected()); 172 DCHECK(cached_data->rejected());
173 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(
174 sanity_check_result);
164 return MaybeHandle<SharedFunctionInfo>(); 175 return MaybeHandle<SharedFunctionInfo>();
165 } 176 }
166 177
167 Deserializer deserializer(scd.get()); 178 Deserializer deserializer(&scd);
168 deserializer.AddAttachedObject(source); 179 deserializer.AddAttachedObject(source);
169 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); 180 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
170 for (int i = 0; i < code_stub_keys.length(); i++) { 181 for (int i = 0; i < code_stub_keys.length(); i++) {
171 deserializer.AddAttachedObject( 182 deserializer.AddAttachedObject(
172 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); 183 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked());
173 } 184 }
174 185
175 // Deserialize. 186 // Deserialize.
176 Handle<SharedFunctionInfo> result; 187 Handle<HeapObject> as_heap_object;
177 if (!deserializer.DeserializeCode(isolate).ToHandle(&result)) { 188 if (!deserializer.DeserializeObject(isolate).ToHandle(&as_heap_object)) {
178 // Deserializing may fail if the reservations cannot be fulfilled. 189 // Deserializing may fail if the reservations cannot be fulfilled.
179 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); 190 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
180 return MaybeHandle<SharedFunctionInfo>(); 191 return MaybeHandle<SharedFunctionInfo>();
181 } 192 }
182 193
194 Handle<SharedFunctionInfo> result =
195 Handle<SharedFunctionInfo>::cast(as_heap_object);
183 if (FLAG_profile_deserialization) { 196 if (FLAG_profile_deserialization) {
184 double ms = timer.Elapsed().InMillisecondsF(); 197 double ms = timer.Elapsed().InMillisecondsF();
185 int length = cached_data->length(); 198 int length = cached_data->length();
186 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); 199 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms);
187 } 200 }
188 result->set_deserialized(true); 201 result->set_deserialized(true);
189 202
190 if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) { 203 if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
191 String* name = isolate->heap()->empty_string(); 204 String* name = isolate->heap()->empty_string();
192 if (result->script()->IsScript()) { 205 if (result->script()->IsScript()) {
193 Script* script = Script::cast(result->script()); 206 Script* script = Script::cast(result->script());
194 if (script->name()->IsString()) name = String::cast(script->name()); 207 if (script->name()->IsString()) name = String::cast(script->name());
195 } 208 }
196 PROFILE(isolate, CodeCreateEvent(CodeEventListener::SCRIPT_TAG, 209 PROFILE(isolate, CodeCreateEvent(CodeEventListener::SCRIPT_TAG,
197 result->abstract_code(), *result, name)); 210 result->abstract_code(), *result, name));
198 } 211 }
199 return scope.CloseAndEscape(result); 212 return scope.CloseAndEscape(result);
200 } 213 }
201 214
215 std::unique_ptr<ScriptData> WasmCompiledModuleSerializer::SerializeWasmModule(
216 Isolate* isolate, Handle<FixedArray> compiled_module) {
217 WasmCompiledModuleSerializer wasm_cs(isolate, 0);
218 wasm_cs.reference_map()->AddAttachedReference(*isolate->native_context());
219 ScriptData* data = wasm_cs.Serialize(compiled_module);
220 return std::unique_ptr<ScriptData>(data);
221 }
222
223 MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule(
224 Isolate* isolate, ScriptData* data) {
225 SerializedCodeData::SanityCheckResult sanity_check_result =
226 SerializedCodeData::CHECK_SUCCESS;
227 MaybeHandle<FixedArray> nothing;
228 const SerializedCodeData scd = SerializedCodeData::FromCachedData(
229 isolate, data, 0, &sanity_check_result);
230
231 if (sanity_check_result != SerializedCodeData::CHECK_SUCCESS) {
232 return nothing;
233 }
234
235 Deserializer deserializer(&scd, true);
236 deserializer.AddAttachedObject(isolate->native_context());
237
238 Vector<const uint32_t> stub_keys = scd.CodeStubKeys();
239 for (int i = 0; i < stub_keys.length(); ++i) {
240 deserializer.AddAttachedObject(
241 CodeStub::GetCode(isolate, stub_keys[i]).ToHandleChecked());
242 }
243
244 MaybeHandle<HeapObject> obj = deserializer.DeserializeObject(isolate);
245 if (obj.is_null() || !obj.ToHandleChecked()->IsFixedArray()) return nothing;
246 return Handle<FixedArray>::cast(obj.ToHandleChecked());
247 }
248
202 class Checksum { 249 class Checksum {
203 public: 250 public:
204 explicit Checksum(Vector<const byte> payload) { 251 explicit Checksum(Vector<const byte> payload) {
205 #ifdef MEMORY_SANITIZER 252 #ifdef MEMORY_SANITIZER
206 // Computing the checksum includes padding bytes for objects like strings. 253 // Computing the checksum includes padding bytes for objects like strings.
207 // Mark every object as initialized in the code serializer. 254 // Mark every object as initialized in the code serializer.
208 MSAN_MEMORY_IS_INITIALIZED(payload.start(), payload.length()); 255 MSAN_MEMORY_IS_INITIALIZED(payload.start(), payload.length());
209 #endif // MEMORY_SANITIZER 256 #endif // MEMORY_SANITIZER
210 // Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit. 257 // Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit.
211 uintptr_t a = 1; 258 uintptr_t a = 1;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 int payload_offset = kHeaderSize + reservation_size + stub_keys_size; 300 int payload_offset = kHeaderSize + reservation_size + stub_keys_size;
254 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset); 301 int padded_payload_offset = POINTER_SIZE_ALIGN(payload_offset);
255 int size = padded_payload_offset + payload->length(); 302 int size = padded_payload_offset + payload->length();
256 303
257 // Allocate backing store and create result data. 304 // Allocate backing store and create result data.
258 AllocateData(size); 305 AllocateData(size);
259 306
260 // Set header values. 307 // Set header values.
261 SetMagicNumber(cs->isolate()); 308 SetMagicNumber(cs->isolate());
262 SetHeaderValue(kVersionHashOffset, Version::Hash()); 309 SetHeaderValue(kVersionHashOffset, Version::Hash());
263 SetHeaderValue(kSourceHashOffset, SourceHash(cs->source())); 310 SetHeaderValue(kSourceHashOffset, cs->source_hash());
264 SetHeaderValue(kCpuFeaturesOffset, 311 SetHeaderValue(kCpuFeaturesOffset,
265 static_cast<uint32_t>(CpuFeatures::SupportedFeatures())); 312 static_cast<uint32_t>(CpuFeatures::SupportedFeatures()));
266 SetHeaderValue(kFlagHashOffset, FlagList::Hash()); 313 SetHeaderValue(kFlagHashOffset, FlagList::Hash());
267 SetHeaderValue(kNumReservationsOffset, reservations.length()); 314 SetHeaderValue(kNumReservationsOffset, reservations.length());
268 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); 315 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
269 SetHeaderValue(kPayloadLengthOffset, payload->length()); 316 SetHeaderValue(kPayloadLengthOffset, payload->length());
270 317
271 Checksum checksum(payload->ToConstVector()); 318 Checksum checksum(payload->ToConstVector());
272 SetHeaderValue(kChecksum1Offset, checksum.a()); 319 SetHeaderValue(kChecksum1Offset, checksum.a());
273 SetHeaderValue(kChecksum2Offset, checksum.b()); 320 SetHeaderValue(kChecksum2Offset, checksum.b());
274 321
275 // Copy reservation chunk sizes. 322 // Copy reservation chunk sizes.
276 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), 323 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
277 reservation_size); 324 reservation_size);
278 325
279 // Copy code stub keys. 326 // Copy code stub keys.
280 CopyBytes(data_ + kHeaderSize + reservation_size, 327 CopyBytes(data_ + kHeaderSize + reservation_size,
281 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); 328 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size);
282 329
283 memset(data_ + payload_offset, 0, padded_payload_offset - payload_offset); 330 memset(data_ + payload_offset, 0, padded_payload_offset - payload_offset);
284 331
285 // Copy serialized data. 332 // Copy serialized data.
286 CopyBytes(data_ + padded_payload_offset, payload->begin(), 333 CopyBytes(data_ + padded_payload_offset, payload->begin(),
287 static_cast<size_t>(payload->length())); 334 static_cast<size_t>(payload->length()));
288 } 335 }
289 336
290 SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( 337 SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck(
291 Isolate* isolate, String* source) const { 338 Isolate* isolate, uint32_t expected_source_hash) const {
292 uint32_t magic_number = GetMagicNumber(); 339 uint32_t magic_number = GetMagicNumber();
293 if (magic_number != ComputeMagicNumber(isolate)) return MAGIC_NUMBER_MISMATCH; 340 if (magic_number != ComputeMagicNumber(isolate)) return MAGIC_NUMBER_MISMATCH;
294 uint32_t version_hash = GetHeaderValue(kVersionHashOffset); 341 uint32_t version_hash = GetHeaderValue(kVersionHashOffset);
295 uint32_t source_hash = GetHeaderValue(kSourceHashOffset); 342 uint32_t source_hash = GetHeaderValue(kSourceHashOffset);
296 uint32_t cpu_features = GetHeaderValue(kCpuFeaturesOffset); 343 uint32_t cpu_features = GetHeaderValue(kCpuFeaturesOffset);
297 uint32_t flags_hash = GetHeaderValue(kFlagHashOffset); 344 uint32_t flags_hash = GetHeaderValue(kFlagHashOffset);
298 uint32_t c1 = GetHeaderValue(kChecksum1Offset); 345 uint32_t c1 = GetHeaderValue(kChecksum1Offset);
299 uint32_t c2 = GetHeaderValue(kChecksum2Offset); 346 uint32_t c2 = GetHeaderValue(kChecksum2Offset);
300 if (version_hash != Version::Hash()) return VERSION_MISMATCH; 347 if (version_hash != Version::Hash()) return VERSION_MISMATCH;
301 if (source_hash != SourceHash(source)) return SOURCE_MISMATCH; 348 if (source_hash != expected_source_hash) return SOURCE_MISMATCH;
302 if (cpu_features != static_cast<uint32_t>(CpuFeatures::SupportedFeatures())) { 349 if (cpu_features != static_cast<uint32_t>(CpuFeatures::SupportedFeatures())) {
303 return CPU_FEATURES_MISMATCH; 350 return CPU_FEATURES_MISMATCH;
304 } 351 }
305 if (flags_hash != FlagList::Hash()) return FLAGS_MISMATCH; 352 if (flags_hash != FlagList::Hash()) return FLAGS_MISMATCH;
306 if (!Checksum(Payload()).Check(c1, c2)) return CHECKSUM_MISMATCH; 353 if (!Checksum(Payload()).Check(c1, c2)) return CHECKSUM_MISMATCH;
307 return CHECK_SUCCESS; 354 return CHECK_SUCCESS;
308 } 355 }
309 356
310 uint32_t SerializedCodeData::SourceHash(String* source) const { 357 uint32_t SerializedCodeData::SourceHash(Handle<String> source) {
311 return source->length(); 358 return source->length();
312 } 359 }
313 360
314 // Return ScriptData object and relinquish ownership over it to the caller. 361 // Return ScriptData object and relinquish ownership over it to the caller.
315 ScriptData* SerializedCodeData::GetScriptData() { 362 ScriptData* SerializedCodeData::GetScriptData() {
316 DCHECK(owns_data_); 363 DCHECK(owns_data_);
317 ScriptData* result = new ScriptData(data_, size_); 364 ScriptData* result = new ScriptData(data_, size_);
318 result->AcquireDataOwnership(); 365 result->AcquireDataOwnership();
319 owns_data_ = false; 366 owns_data_ = false;
320 data_ = NULL; 367 data_ = NULL;
(...skipping 22 matching lines...) Expand all
343 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { 390 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
344 int reservations_size = GetHeaderValue(kNumReservationsOffset) * kInt32Size; 391 int reservations_size = GetHeaderValue(kNumReservationsOffset) * kInt32Size;
345 const byte* start = data_ + kHeaderSize + reservations_size; 392 const byte* start = data_ + kHeaderSize + reservations_size;
346 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), 393 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
347 GetHeaderValue(kNumCodeStubKeysOffset)); 394 GetHeaderValue(kNumCodeStubKeysOffset));
348 } 395 }
349 396
350 SerializedCodeData::SerializedCodeData(ScriptData* data) 397 SerializedCodeData::SerializedCodeData(ScriptData* data)
351 : SerializedData(const_cast<byte*>(data->data()), data->length()) {} 398 : SerializedData(const_cast<byte*>(data->data()), data->length()) {}
352 399
353 SerializedCodeData* SerializedCodeData::FromCachedData(Isolate* isolate, 400 const SerializedCodeData SerializedCodeData::FromCachedData(
354 ScriptData* cached_data, 401 Isolate* isolate, ScriptData* cached_data, uint32_t expected_source_hash,
355 String* source) { 402 SanityCheckResult* rejection_result) {
356 DisallowHeapAllocation no_gc; 403 DisallowHeapAllocation no_gc;
357 SerializedCodeData* scd = new SerializedCodeData(cached_data); 404 SerializedCodeData scd(cached_data);
358 SanityCheckResult r = scd->SanityCheck(isolate, source); 405 *rejection_result = scd.SanityCheck(isolate, expected_source_hash);
359 if (r == CHECK_SUCCESS) return scd; 406 if (*rejection_result != CHECK_SUCCESS) {
360 cached_data->Reject(); 407 cached_data->Reject();
361 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); 408 return SerializedCodeData(nullptr, 0);
362 delete scd; 409 }
363 return NULL; 410 return scd;
364 } 411 }
365 412
366 } // namespace internal 413 } // namespace internal
367 } // namespace v8 414 } // namespace v8
OLDNEW
« no previous file with comments | « src/snapshot/code-serializer.h ('k') | src/snapshot/deserializer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698