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 Vector<const byte>& payload, const char* file_name) { | 117 void WritePayload(const List<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 |
132 static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { | 167 static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { |
133 SnapshotByteSink sink; | 168 SnapshotByteSink sink; |
134 StartupSerializer ser(isolate, &sink); | 169 StartupSerializer ser(isolate, &sink); |
135 ser.Serialize(); | 170 ser.Serialize(); |
136 SnapshotData snapshot_data(sink, ser); | 171 ser.FinalizeAllocation(); |
137 WritePayload(snapshot_data.RawData(), snapshot_file); | 172 |
| 173 WritePayload(sink.data(), snapshot_file); |
| 174 WriteSpaceUsed(&ser, snapshot_file); |
| 175 |
138 return true; | 176 return true; |
139 } | 177 } |
140 | 178 |
141 | 179 |
142 static void Serialize(v8::Isolate* isolate) { | 180 static void Serialize(v8::Isolate* isolate) { |
143 // We have to create one context. One reason for this is so that the builtins | 181 // We have to create one context. One reason for this is so that the builtins |
144 // can be loaded from v8natives.js and their addresses can be processed. This | 182 // can be loaded from v8natives.js and their addresses can be processed. This |
145 // will clear the pending fixups array, which would otherwise contain GC roots | 183 // will clear the pending fixups array, which would otherwise contain GC roots |
146 // that would confuse the serialization/deserialization process. | 184 // that would confuse the serialization/deserialization process. |
147 v8::Isolate::Scope isolate_scope(isolate); | 185 v8::Isolate::Scope isolate_scope(isolate); |
(...skipping 27 matching lines...) Expand all Loading... |
175 v8::Isolate* isolate = v8::Isolate::New(params); | 213 v8::Isolate* isolate = v8::Isolate::New(params); |
176 Serialize(isolate); | 214 Serialize(isolate); |
177 Serialize(isolate); | 215 Serialize(isolate); |
178 } | 216 } |
179 } | 217 } |
180 | 218 |
181 | 219 |
182 //---------------------------------------------------------------------------- | 220 //---------------------------------------------------------------------------- |
183 // Tests that the heap can be deserialized. | 221 // Tests that the heap can be deserialized. |
184 | 222 |
| 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 |
185 v8::Isolate* InitializeFromFile(const char* snapshot_file) { | 261 v8::Isolate* InitializeFromFile(const char* snapshot_file) { |
186 int len; | 262 int len; |
187 byte* str = ReadBytes(snapshot_file, &len); | 263 byte* str = ReadBytes(snapshot_file, &len); |
188 if (!str) return NULL; | 264 if (!str) return NULL; |
189 v8::Isolate* v8_isolate = NULL; | 265 v8::Isolate* v8_isolate = NULL; |
190 { | 266 { |
191 SnapshotData snapshot_data(str, len); | 267 SnapshotByteSource source(str, len); |
192 Deserializer deserializer(&snapshot_data); | 268 Deserializer deserializer(&source); |
| 269 ReserveSpaceForSnapshot(&deserializer, snapshot_file); |
193 Isolate* isolate = Isolate::NewForTesting(); | 270 Isolate* isolate = Isolate::NewForTesting(); |
194 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 271 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
195 v8::Isolate::Scope isolate_scope(v8_isolate); | 272 v8::Isolate::Scope isolate_scope(v8_isolate); |
196 isolate->Init(&deserializer); | 273 isolate->Init(&deserializer); |
197 } | 274 } |
198 DeleteArray(str); | 275 DeleteArray(str); |
199 return v8_isolate; | 276 return v8_isolate; |
200 } | 277 } |
201 | 278 |
202 | 279 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 StartupSerializer startup_serializer(isolate, &startup_sink); | 429 StartupSerializer startup_serializer(isolate, &startup_sink); |
353 startup_serializer.SerializeStrongReferences(); | 430 startup_serializer.SerializeStrongReferences(); |
354 | 431 |
355 SnapshotByteSink partial_sink; | 432 SnapshotByteSink partial_sink; |
356 PartialSerializer partial_serializer(isolate, &startup_serializer, | 433 PartialSerializer partial_serializer(isolate, &startup_serializer, |
357 &partial_sink); | 434 &partial_sink); |
358 partial_serializer.Serialize(&raw_foo); | 435 partial_serializer.Serialize(&raw_foo); |
359 | 436 |
360 startup_serializer.SerializeWeakReferences(); | 437 startup_serializer.SerializeWeakReferences(); |
361 | 438 |
362 SnapshotData startup_snapshot(startup_sink, startup_serializer); | 439 partial_serializer.FinalizeAllocation(); |
363 SnapshotData partial_snapshot(partial_sink, partial_serializer); | 440 startup_serializer.FinalizeAllocation(); |
364 | 441 |
365 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file); | 442 WritePayload(partial_sink.data(), FLAG_testing_serialization_file); |
366 WritePayload(startup_snapshot.RawData(), startup_name.start()); | 443 WritePayload(startup_sink.data(), startup_name.start()); |
| 444 |
| 445 WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file); |
| 446 WriteSpaceUsed(&startup_serializer, startup_name.start()); |
367 | 447 |
368 startup_name.Dispose(); | 448 startup_name.Dispose(); |
369 } | 449 } |
370 v8_isolate->Exit(); | 450 v8_isolate->Exit(); |
371 v8_isolate->Dispose(); | 451 v8_isolate->Dispose(); |
372 } | 452 } |
373 } | 453 } |
374 | 454 |
375 | 455 |
376 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { | 456 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { |
377 if (!Snapshot::HaveASnapshotToStartFrom()) { | 457 if (!Snapshot::HaveASnapshotToStartFrom()) { |
378 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; | 458 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; |
379 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); | 459 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); |
380 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); | 460 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); |
381 | 461 |
382 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); | 462 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); |
383 CHECK(v8_isolate); | 463 CHECK(v8_isolate); |
384 startup_name.Dispose(); | 464 startup_name.Dispose(); |
385 { | 465 { |
386 v8::Isolate::Scope isolate_scope(v8_isolate); | 466 v8::Isolate::Scope isolate_scope(v8_isolate); |
387 | 467 |
388 const char* file_name = FLAG_testing_serialization_file; | 468 const char* file_name = FLAG_testing_serialization_file; |
389 | 469 |
390 int snapshot_size = 0; | 470 int snapshot_size = 0; |
391 byte* snapshot = ReadBytes(file_name, &snapshot_size); | 471 byte* snapshot = ReadBytes(file_name, &snapshot_size); |
392 | 472 |
393 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); | 473 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); |
394 Object* root; | 474 Object* root; |
395 { | 475 { |
396 SnapshotData snapshot_data(snapshot, snapshot_size); | 476 SnapshotByteSource source(snapshot, snapshot_size); |
397 Deserializer deserializer(&snapshot_data); | 477 Deserializer deserializer(&source); |
| 478 ReserveSpaceForSnapshot(&deserializer, file_name); |
398 deserializer.DeserializePartial(isolate, &root); | 479 deserializer.DeserializePartial(isolate, &root); |
399 CHECK(root->IsString()); | 480 CHECK(root->IsString()); |
400 } | 481 } |
401 HandleScope handle_scope(isolate); | 482 HandleScope handle_scope(isolate); |
402 Handle<Object> root_handle(root, isolate); | 483 Handle<Object> root_handle(root, isolate); |
403 | 484 |
404 | 485 |
405 Object* root2; | 486 Object* root2; |
406 { | 487 { |
407 SnapshotData snapshot_data(snapshot, snapshot_size); | 488 SnapshotByteSource source(snapshot, snapshot_size); |
408 Deserializer deserializer(&snapshot_data); | 489 Deserializer deserializer(&source); |
| 490 ReserveSpaceForSnapshot(&deserializer, file_name); |
409 deserializer.DeserializePartial(isolate, &root2); | 491 deserializer.DeserializePartial(isolate, &root2); |
410 CHECK(root2->IsString()); | 492 CHECK(root2->IsString()); |
411 CHECK(*root_handle == root2); | 493 CHECK(*root_handle == root2); |
412 } | 494 } |
413 } | 495 } |
414 v8_isolate->Dispose(); | 496 v8_isolate->Dispose(); |
415 } | 497 } |
416 } | 498 } |
417 | 499 |
418 | 500 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 SnapshotByteSink startup_sink; | 545 SnapshotByteSink startup_sink; |
464 StartupSerializer startup_serializer(isolate, &startup_sink); | 546 StartupSerializer startup_serializer(isolate, &startup_sink); |
465 startup_serializer.SerializeStrongReferences(); | 547 startup_serializer.SerializeStrongReferences(); |
466 | 548 |
467 SnapshotByteSink partial_sink; | 549 SnapshotByteSink partial_sink; |
468 PartialSerializer partial_serializer(isolate, &startup_serializer, | 550 PartialSerializer partial_serializer(isolate, &startup_serializer, |
469 &partial_sink); | 551 &partial_sink); |
470 partial_serializer.Serialize(&raw_context); | 552 partial_serializer.Serialize(&raw_context); |
471 startup_serializer.SerializeWeakReferences(); | 553 startup_serializer.SerializeWeakReferences(); |
472 | 554 |
473 SnapshotData startup_snapshot(startup_sink, startup_serializer); | 555 partial_serializer.FinalizeAllocation(); |
474 SnapshotData partial_snapshot(partial_sink, partial_serializer); | 556 startup_serializer.FinalizeAllocation(); |
475 | 557 |
476 WritePayload(startup_snapshot.RawData(), FLAG_testing_serialization_file); | 558 WritePayload(partial_sink.data(), FLAG_testing_serialization_file); |
477 WritePayload(startup_snapshot.RawData(), startup_name.start()); | 559 WritePayload(startup_sink.data(), startup_name.start()); |
| 560 |
| 561 WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file); |
| 562 WriteSpaceUsed(&startup_serializer, startup_name.start()); |
478 | 563 |
479 startup_name.Dispose(); | 564 startup_name.Dispose(); |
480 } | 565 } |
481 v8_isolate->Dispose(); | 566 v8_isolate->Dispose(); |
482 } | 567 } |
483 } | 568 } |
484 | 569 |
485 | 570 |
486 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { | 571 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { |
487 if (!Snapshot::HaveASnapshotToStartFrom()) { | 572 if (!Snapshot::HaveASnapshotToStartFrom()) { |
488 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; | 573 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; |
489 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); | 574 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); |
490 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); | 575 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); |
491 | 576 |
492 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); | 577 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); |
493 CHECK(v8_isolate); | 578 CHECK(v8_isolate); |
494 startup_name.Dispose(); | 579 startup_name.Dispose(); |
495 { | 580 { |
496 v8::Isolate::Scope isolate_scope(v8_isolate); | 581 v8::Isolate::Scope isolate_scope(v8_isolate); |
497 | 582 |
498 const char* file_name = FLAG_testing_serialization_file; | 583 const char* file_name = FLAG_testing_serialization_file; |
499 | 584 |
500 int snapshot_size = 0; | 585 int snapshot_size = 0; |
501 byte* snapshot = ReadBytes(file_name, &snapshot_size); | 586 byte* snapshot = ReadBytes(file_name, &snapshot_size); |
502 | 587 |
503 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); | 588 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); |
504 Object* root; | 589 Object* root; |
505 { | 590 { |
506 SnapshotData snapshot_data(snapshot, snapshot_size); | 591 SnapshotByteSource source(snapshot, snapshot_size); |
507 Deserializer deserializer(&snapshot_data); | 592 Deserializer deserializer(&source); |
| 593 ReserveSpaceForSnapshot(&deserializer, file_name); |
508 deserializer.DeserializePartial(isolate, &root); | 594 deserializer.DeserializePartial(isolate, &root); |
509 CHECK(root->IsContext()); | 595 CHECK(root->IsContext()); |
510 } | 596 } |
511 HandleScope handle_scope(isolate); | 597 HandleScope handle_scope(isolate); |
512 Handle<Object> root_handle(root, isolate); | 598 Handle<Object> root_handle(root, isolate); |
513 | 599 |
514 | 600 |
515 Object* root2; | 601 Object* root2; |
516 { | 602 { |
517 SnapshotData snapshot_data(snapshot, snapshot_size); | 603 SnapshotByteSource source(snapshot, snapshot_size); |
518 Deserializer deserializer(&snapshot_data); | 604 Deserializer deserializer(&source); |
| 605 ReserveSpaceForSnapshot(&deserializer, file_name); |
519 deserializer.DeserializePartial(isolate, &root2); | 606 deserializer.DeserializePartial(isolate, &root2); |
520 CHECK(root2->IsContext()); | 607 CHECK(root2->IsContext()); |
521 CHECK(*root_handle != root2); | 608 CHECK(*root_handle != root2); |
522 } | 609 } |
523 } | 610 } |
524 v8_isolate->Dispose(); | 611 v8_isolate->Dispose(); |
525 } | 612 } |
526 } | 613 } |
527 | 614 |
528 | 615 |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 { | 1299 { |
1213 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2)); | 1300 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2)); |
1214 script = v8::ScriptCompiler::CompileUnbound( | 1301 script = v8::ScriptCompiler::CompileUnbound( |
1215 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache); | 1302 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache); |
1216 } | 1303 } |
1217 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run(); | 1304 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run(); |
1218 CHECK(result->ToString(isolate2)->Equals(v8_str("XY"))); | 1305 CHECK(result->ToString(isolate2)->Equals(v8_str("XY"))); |
1219 } | 1306 } |
1220 isolate2->Dispose(); | 1307 isolate2->Dispose(); |
1221 } | 1308 } |
OLD | NEW |