OLD | NEW |
1 // Copyright 2007-2010 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 decoder.Decode(make_code(UNCLASSIFIED, 2))); | 107 decoder.Decode(make_code(UNCLASSIFIED, 2))); |
108 CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), | 108 CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(), |
109 decoder.Decode(make_code(UNCLASSIFIED, 3))); | 109 decoder.Decode(make_code(UNCLASSIFIED, 3))); |
110 CHECK_EQ(ExternalReference::debug_break(isolate).address(), | 110 CHECK_EQ(ExternalReference::debug_break(isolate).address(), |
111 decoder.Decode(make_code(UNCLASSIFIED, 8))); | 111 decoder.Decode(make_code(UNCLASSIFIED, 8))); |
112 CHECK_EQ(ExternalReference::new_space_start(isolate).address(), | 112 CHECK_EQ(ExternalReference::new_space_start(isolate).address(), |
113 decoder.Decode(make_code(UNCLASSIFIED, 4))); | 113 decoder.Decode(make_code(UNCLASSIFIED, 4))); |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 void WritePayload(const List<byte>& payload, const char* file_name) { | 117 void WritePayload(const Vector<const byte>& payload, const char* file_name) { |
118 FILE* file = v8::base::OS::FOpen(file_name, "wb"); | 118 FILE* file = v8::base::OS::FOpen(file_name, "wb"); |
119 if (file == NULL) { | 119 if (file == NULL) { |
120 PrintF("Unable to write to snapshot file \"%s\"\n", file_name); | 120 PrintF("Unable to write to snapshot file \"%s\"\n", file_name); |
121 exit(1); | 121 exit(1); |
122 } | 122 } |
123 size_t written = fwrite(payload.begin(), 1, payload.length(), file); | 123 size_t written = fwrite(payload.begin(), 1, payload.length(), file); |
124 if (written != static_cast<size_t>(payload.length())) { | 124 if (written != static_cast<size_t>(payload.length())) { |
125 i::PrintF("Writing snapshot file failed.. Aborting.\n"); | 125 i::PrintF("Writing snapshot file failed.. Aborting.\n"); |
126 exit(1); | 126 exit(1); |
127 } | 127 } |
128 fclose(file); | 128 fclose(file); |
129 } | 129 } |
130 | 130 |
131 | 131 |
132 void WriteSpaceUsed(Serializer* ser, const char* file_name) { | |
133 int file_name_length = StrLength(file_name) + 10; | |
134 Vector<char> name = Vector<char>::New(file_name_length + 1); | |
135 SNPrintF(name, "%s.size", file_name); | |
136 FILE* fp = v8::base::OS::FOpen(name.start(), "w"); | |
137 name.Dispose(); | |
138 | |
139 Vector<const uint32_t> chunks = ser->FinalAllocationChunks(NEW_SPACE); | |
140 CHECK_EQ(1, chunks.length()); | |
141 fprintf(fp, "new %d\n", chunks[0]); | |
142 chunks = ser->FinalAllocationChunks(OLD_POINTER_SPACE); | |
143 CHECK_EQ(1, chunks.length()); | |
144 fprintf(fp, "pointer %d\n", chunks[0]); | |
145 chunks = ser->FinalAllocationChunks(OLD_DATA_SPACE); | |
146 CHECK_EQ(1, chunks.length()); | |
147 fprintf(fp, "data %d\n", chunks[0]); | |
148 chunks = ser->FinalAllocationChunks(CODE_SPACE); | |
149 CHECK_EQ(1, chunks.length()); | |
150 fprintf(fp, "code %d\n", chunks[0]); | |
151 chunks = ser->FinalAllocationChunks(MAP_SPACE); | |
152 CHECK_EQ(1, chunks.length()); | |
153 fprintf(fp, "map %d\n", chunks[0]); | |
154 chunks = ser->FinalAllocationChunks(CELL_SPACE); | |
155 CHECK_EQ(1, chunks.length()); | |
156 fprintf(fp, "cell %d\n", chunks[0]); | |
157 chunks = ser->FinalAllocationChunks(PROPERTY_CELL_SPACE); | |
158 CHECK_EQ(1, chunks.length()); | |
159 fprintf(fp, "property cell %d\n", chunks[0]); | |
160 chunks = ser->FinalAllocationChunks(LO_SPACE); | |
161 CHECK_EQ(1, chunks.length()); | |
162 fprintf(fp, "lo %d\n", chunks[0]); | |
163 fclose(fp); | |
164 } | |
165 | |
166 | |
167 static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { | 132 static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { |
168 SnapshotByteSink sink; | 133 SnapshotByteSink sink; |
169 StartupSerializer ser(isolate, &sink); | 134 StartupSerializer ser(isolate, &sink); |
170 ser.Serialize(); | 135 ser.Serialize(); |
171 ser.FinalizeAllocation(); | 136 SnapshotData snapshot_data(sink, ser); |
172 | 137 WritePayload(snapshot_data.RawData(), snapshot_file); |
173 WritePayload(sink.data(), snapshot_file); | |
174 WriteSpaceUsed(&ser, snapshot_file); | |
175 | |
176 return true; | 138 return true; |
177 } | 139 } |
178 | 140 |
179 | 141 |
180 static void Serialize(v8::Isolate* isolate) { | 142 static void Serialize(v8::Isolate* isolate) { |
181 // We have to create one context. One reason for this is so that the builtins | 143 // We have to create one context. One reason for this is so that the builtins |
182 // can be loaded from v8natives.js and their addresses can be processed. This | 144 // can be loaded from v8natives.js and their addresses can be processed. This |
183 // will clear the pending fixups array, which would otherwise contain GC roots | 145 // will clear the pending fixups array, which would otherwise contain GC roots |
184 // that would confuse the serialization/deserialization process. | 146 // that would confuse the serialization/deserialization process. |
185 v8::Isolate::Scope isolate_scope(isolate); | 147 v8::Isolate::Scope isolate_scope(isolate); |
(...skipping 27 matching lines...) Expand all Loading... |
213 v8::Isolate* isolate = v8::Isolate::New(params); | 175 v8::Isolate* isolate = v8::Isolate::New(params); |
214 Serialize(isolate); | 176 Serialize(isolate); |
215 Serialize(isolate); | 177 Serialize(isolate); |
216 } | 178 } |
217 } | 179 } |
218 | 180 |
219 | 181 |
220 //---------------------------------------------------------------------------- | 182 //---------------------------------------------------------------------------- |
221 // Tests that the heap can be deserialized. | 183 // Tests that the heap can be deserialized. |
222 | 184 |
223 | |
224 static void ReserveSpaceForSnapshot(Deserializer* deserializer, | |
225 const char* file_name) { | |
226 int file_name_length = StrLength(file_name) + 10; | |
227 Vector<char> name = Vector<char>::New(file_name_length + 1); | |
228 SNPrintF(name, "%s.size", file_name); | |
229 FILE* fp = v8::base::OS::FOpen(name.start(), "r"); | |
230 name.Dispose(); | |
231 int new_size, pointer_size, data_size, code_size, map_size, cell_size, | |
232 property_cell_size, lo_size; | |
233 #if V8_CC_MSVC | |
234 // Avoid warning about unsafe fscanf from MSVC. | |
235 // Please note that this is only fine if %c and %s are not being used. | |
236 #define fscanf fscanf_s | |
237 #endif | |
238 CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size)); | |
239 CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size)); | |
240 CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size)); | |
241 CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size)); | |
242 CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size)); | |
243 CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size)); | |
244 CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size)); | |
245 CHECK_EQ(1, fscanf(fp, "lo %d\n", &lo_size)); | |
246 #if V8_CC_MSVC | |
247 #undef fscanf | |
248 #endif | |
249 fclose(fp); | |
250 deserializer->AddReservation(NEW_SPACE, new_size); | |
251 deserializer->AddReservation(OLD_POINTER_SPACE, pointer_size); | |
252 deserializer->AddReservation(OLD_DATA_SPACE, data_size); | |
253 deserializer->AddReservation(CODE_SPACE, code_size); | |
254 deserializer->AddReservation(MAP_SPACE, map_size); | |
255 deserializer->AddReservation(CELL_SPACE, cell_size); | |
256 deserializer->AddReservation(PROPERTY_CELL_SPACE, property_cell_size); | |
257 deserializer->AddReservation(LO_SPACE, lo_size); | |
258 } | |
259 | |
260 | |
261 v8::Isolate* InitializeFromFile(const char* snapshot_file) { | 185 v8::Isolate* InitializeFromFile(const char* snapshot_file) { |
262 int len; | 186 int len; |
263 byte* str = ReadBytes(snapshot_file, &len); | 187 byte* str = ReadBytes(snapshot_file, &len); |
264 if (!str) return NULL; | 188 if (!str) return NULL; |
265 v8::Isolate* v8_isolate = NULL; | 189 v8::Isolate* v8_isolate = NULL; |
266 { | 190 { |
267 SnapshotByteSource source(str, len); | 191 SnapshotData snapshot_data(str, len); |
268 Deserializer deserializer(&source); | 192 Deserializer deserializer(&snapshot_data); |
269 ReserveSpaceForSnapshot(&deserializer, snapshot_file); | |
270 Isolate* isolate = Isolate::NewForTesting(); | 193 Isolate* isolate = Isolate::NewForTesting(); |
271 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 194 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
272 v8::Isolate::Scope isolate_scope(v8_isolate); | 195 v8::Isolate::Scope isolate_scope(v8_isolate); |
273 isolate->Init(&deserializer); | 196 isolate->Init(&deserializer); |
274 } | 197 } |
275 DeleteArray(str); | 198 DeleteArray(str); |
276 return v8_isolate; | 199 return v8_isolate; |
277 } | 200 } |
278 | 201 |
279 | 202 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 StartupSerializer startup_serializer(isolate, &startup_sink); | 352 StartupSerializer startup_serializer(isolate, &startup_sink); |
430 startup_serializer.SerializeStrongReferences(); | 353 startup_serializer.SerializeStrongReferences(); |
431 | 354 |
432 SnapshotByteSink partial_sink; | 355 SnapshotByteSink partial_sink; |
433 PartialSerializer partial_serializer(isolate, &startup_serializer, | 356 PartialSerializer partial_serializer(isolate, &startup_serializer, |
434 &partial_sink); | 357 &partial_sink); |
435 partial_serializer.Serialize(&raw_foo); | 358 partial_serializer.Serialize(&raw_foo); |
436 | 359 |
437 startup_serializer.SerializeWeakReferences(); | 360 startup_serializer.SerializeWeakReferences(); |
438 | 361 |
439 partial_serializer.FinalizeAllocation(); | 362 SnapshotData startup_snapshot(startup_sink, startup_serializer); |
440 startup_serializer.FinalizeAllocation(); | 363 SnapshotData partial_snapshot(partial_sink, partial_serializer); |
441 | 364 |
442 WritePayload(partial_sink.data(), FLAG_testing_serialization_file); | 365 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file); |
443 WritePayload(startup_sink.data(), startup_name.start()); | 366 WritePayload(startup_snapshot.RawData(), startup_name.start()); |
444 | |
445 WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file); | |
446 WriteSpaceUsed(&startup_serializer, startup_name.start()); | |
447 | 367 |
448 startup_name.Dispose(); | 368 startup_name.Dispose(); |
449 } | 369 } |
450 v8_isolate->Exit(); | 370 v8_isolate->Exit(); |
451 v8_isolate->Dispose(); | 371 v8_isolate->Dispose(); |
452 } | 372 } |
453 } | 373 } |
454 | 374 |
455 | 375 |
456 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { | 376 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { |
457 if (!Snapshot::HaveASnapshotToStartFrom()) { | 377 if (!Snapshot::HaveASnapshotToStartFrom()) { |
458 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; | 378 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; |
459 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); | 379 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); |
460 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); | 380 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); |
461 | 381 |
462 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); | 382 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); |
463 CHECK(v8_isolate); | 383 CHECK(v8_isolate); |
464 startup_name.Dispose(); | 384 startup_name.Dispose(); |
465 { | 385 { |
466 v8::Isolate::Scope isolate_scope(v8_isolate); | 386 v8::Isolate::Scope isolate_scope(v8_isolate); |
467 | 387 |
468 const char* file_name = FLAG_testing_serialization_file; | 388 const char* file_name = FLAG_testing_serialization_file; |
469 | 389 |
470 int snapshot_size = 0; | 390 int snapshot_size = 0; |
471 byte* snapshot = ReadBytes(file_name, &snapshot_size); | 391 byte* snapshot = ReadBytes(file_name, &snapshot_size); |
472 | 392 |
473 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); | 393 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); |
474 Object* root; | 394 Object* root; |
475 { | 395 { |
476 SnapshotByteSource source(snapshot, snapshot_size); | 396 SnapshotData snapshot_data(snapshot, snapshot_size); |
477 Deserializer deserializer(&source); | 397 Deserializer deserializer(&snapshot_data); |
478 ReserveSpaceForSnapshot(&deserializer, file_name); | |
479 deserializer.DeserializePartial(isolate, &root); | 398 deserializer.DeserializePartial(isolate, &root); |
480 CHECK(root->IsString()); | 399 CHECK(root->IsString()); |
481 } | 400 } |
482 HandleScope handle_scope(isolate); | 401 HandleScope handle_scope(isolate); |
483 Handle<Object> root_handle(root, isolate); | 402 Handle<Object> root_handle(root, isolate); |
484 | 403 |
485 | 404 |
486 Object* root2; | 405 Object* root2; |
487 { | 406 { |
488 SnapshotByteSource source(snapshot, snapshot_size); | 407 SnapshotData snapshot_data(snapshot, snapshot_size); |
489 Deserializer deserializer(&source); | 408 Deserializer deserializer(&snapshot_data); |
490 ReserveSpaceForSnapshot(&deserializer, file_name); | |
491 deserializer.DeserializePartial(isolate, &root2); | 409 deserializer.DeserializePartial(isolate, &root2); |
492 CHECK(root2->IsString()); | 410 CHECK(root2->IsString()); |
493 CHECK(*root_handle == root2); | 411 CHECK(*root_handle == root2); |
494 } | 412 } |
495 } | 413 } |
496 v8_isolate->Dispose(); | 414 v8_isolate->Dispose(); |
497 } | 415 } |
498 } | 416 } |
499 | 417 |
500 | 418 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 SnapshotByteSink startup_sink; | 463 SnapshotByteSink startup_sink; |
546 StartupSerializer startup_serializer(isolate, &startup_sink); | 464 StartupSerializer startup_serializer(isolate, &startup_sink); |
547 startup_serializer.SerializeStrongReferences(); | 465 startup_serializer.SerializeStrongReferences(); |
548 | 466 |
549 SnapshotByteSink partial_sink; | 467 SnapshotByteSink partial_sink; |
550 PartialSerializer partial_serializer(isolate, &startup_serializer, | 468 PartialSerializer partial_serializer(isolate, &startup_serializer, |
551 &partial_sink); | 469 &partial_sink); |
552 partial_serializer.Serialize(&raw_context); | 470 partial_serializer.Serialize(&raw_context); |
553 startup_serializer.SerializeWeakReferences(); | 471 startup_serializer.SerializeWeakReferences(); |
554 | 472 |
555 partial_serializer.FinalizeAllocation(); | 473 SnapshotData startup_snapshot(startup_sink, startup_serializer); |
556 startup_serializer.FinalizeAllocation(); | 474 SnapshotData partial_snapshot(partial_sink, partial_serializer); |
557 | 475 |
558 WritePayload(partial_sink.data(), FLAG_testing_serialization_file); | 476 WritePayload(startup_snapshot.RawData(), FLAG_testing_serialization_file); |
559 WritePayload(startup_sink.data(), startup_name.start()); | 477 WritePayload(startup_snapshot.RawData(), startup_name.start()); |
560 | |
561 WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file); | |
562 WriteSpaceUsed(&startup_serializer, startup_name.start()); | |
563 | 478 |
564 startup_name.Dispose(); | 479 startup_name.Dispose(); |
565 } | 480 } |
566 v8_isolate->Dispose(); | 481 v8_isolate->Dispose(); |
567 } | 482 } |
568 } | 483 } |
569 | 484 |
570 | 485 |
571 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { | 486 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { |
572 if (!Snapshot::HaveASnapshotToStartFrom()) { | 487 if (!Snapshot::HaveASnapshotToStartFrom()) { |
573 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; | 488 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; |
574 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); | 489 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); |
575 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); | 490 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); |
576 | 491 |
577 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); | 492 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); |
578 CHECK(v8_isolate); | 493 CHECK(v8_isolate); |
579 startup_name.Dispose(); | 494 startup_name.Dispose(); |
580 { | 495 { |
581 v8::Isolate::Scope isolate_scope(v8_isolate); | 496 v8::Isolate::Scope isolate_scope(v8_isolate); |
582 | 497 |
583 const char* file_name = FLAG_testing_serialization_file; | 498 const char* file_name = FLAG_testing_serialization_file; |
584 | 499 |
585 int snapshot_size = 0; | 500 int snapshot_size = 0; |
586 byte* snapshot = ReadBytes(file_name, &snapshot_size); | 501 byte* snapshot = ReadBytes(file_name, &snapshot_size); |
587 | 502 |
588 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); | 503 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); |
589 Object* root; | 504 Object* root; |
590 { | 505 { |
591 SnapshotByteSource source(snapshot, snapshot_size); | 506 SnapshotData snapshot_data(snapshot, snapshot_size); |
592 Deserializer deserializer(&source); | 507 Deserializer deserializer(&snapshot_data); |
593 ReserveSpaceForSnapshot(&deserializer, file_name); | |
594 deserializer.DeserializePartial(isolate, &root); | 508 deserializer.DeserializePartial(isolate, &root); |
595 CHECK(root->IsContext()); | 509 CHECK(root->IsContext()); |
596 } | 510 } |
597 HandleScope handle_scope(isolate); | 511 HandleScope handle_scope(isolate); |
598 Handle<Object> root_handle(root, isolate); | 512 Handle<Object> root_handle(root, isolate); |
599 | 513 |
600 | 514 |
601 Object* root2; | 515 Object* root2; |
602 { | 516 { |
603 SnapshotByteSource source(snapshot, snapshot_size); | 517 SnapshotData snapshot_data(snapshot, snapshot_size); |
604 Deserializer deserializer(&source); | 518 Deserializer deserializer(&snapshot_data); |
605 ReserveSpaceForSnapshot(&deserializer, file_name); | |
606 deserializer.DeserializePartial(isolate, &root2); | 519 deserializer.DeserializePartial(isolate, &root2); |
607 CHECK(root2->IsContext()); | 520 CHECK(root2->IsContext()); |
608 CHECK(*root_handle != root2); | 521 CHECK(*root_handle != root2); |
609 } | 522 } |
610 } | 523 } |
611 v8_isolate->Dispose(); | 524 v8_isolate->Dispose(); |
612 } | 525 } |
613 } | 526 } |
614 | 527 |
615 | 528 |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 { | 1212 { |
1300 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2)); | 1213 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2)); |
1301 script = v8::ScriptCompiler::CompileUnbound( | 1214 script = v8::ScriptCompiler::CompileUnbound( |
1302 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache); | 1215 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache); |
1303 } | 1216 } |
1304 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run(); | 1217 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run(); |
1305 CHECK(result->ToString(isolate2)->Equals(v8_str("XY"))); | 1218 CHECK(result->ToString(isolate2)->Equals(v8_str("XY"))); |
1306 } | 1219 } |
1307 isolate2->Dispose(); | 1220 isolate2->Dispose(); |
1308 } | 1221 } |
OLD | NEW |