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

Side by Side Diff: test/cctest/test-serialize.cc

Issue 949623006: Attach snapshot data blob to the isolate. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« no previous file with comments | « test/cctest/test-heap.cc ('k') | test/cctest/test-spaces.cc » ('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 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 28 matching lines...) Expand all
39 #include "src/objects.h" 39 #include "src/objects.h"
40 #include "src/runtime/runtime.h" 40 #include "src/runtime/runtime.h"
41 #include "src/scopeinfo.h" 41 #include "src/scopeinfo.h"
42 #include "src/serialize.h" 42 #include "src/serialize.h"
43 #include "src/snapshot.h" 43 #include "src/snapshot.h"
44 #include "test/cctest/cctest.h" 44 #include "test/cctest/cctest.h"
45 45
46 using namespace v8::internal; 46 using namespace v8::internal;
47 47
48 48
49 bool DefaultSnapshotAvailable() {
50 return i::Snapshot::DefaultSnapshotBlob() != NULL;
51 }
52
53
54 // TestIsolate is used for testing isolate serialization.
55 class TestIsolate : public Isolate {
56 public:
57 static v8::Isolate* NewInitialized(bool enable_serializer) {
58 i::Isolate* isolate = new TestIsolate(enable_serializer);
59 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
60 v8::Isolate::Scope isolate_scope(v8_isolate);
61 isolate->Init(NULL);
62 return v8_isolate;
63 }
64 explicit TestIsolate(bool enable_serializer) : Isolate(enable_serializer) {}
65 };
66
67
49 template <class T> 68 template <class T>
50 static Address AddressOf(T id) { 69 static Address AddressOf(T id) {
51 return ExternalReference(id, CcTest::i_isolate()).address(); 70 return ExternalReference(id, CcTest::i_isolate()).address();
52 } 71 }
53 72
54 73
55 template <class T> 74 template <class T>
56 static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) { 75 static uint32_t Encode(const ExternalReferenceEncoder& encoder, T id) {
57 return encoder.Encode(AddressOf(id)); 76 return encoder.Encode(AddressOf(id));
58 } 77 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 187 }
169 CopyChars(source + head.length() + repeats * body.length(), tail.start(), 188 CopyChars(source + head.length() + repeats * body.length(), tail.start(),
170 tail.length()); 189 tail.length());
171 return Vector<const uint8_t>(const_cast<const uint8_t*>(source), 190 return Vector<const uint8_t>(const_cast<const uint8_t*>(source),
172 source_length); 191 source_length);
173 } 192 }
174 193
175 194
176 // Test that the whole heap can be serialized. 195 // Test that the whole heap can be serialized.
177 UNINITIALIZED_TEST(Serialize) { 196 UNINITIALIZED_TEST(Serialize) {
178 if (!Snapshot::HaveASnapshotToStartFrom()) { 197 if (DefaultSnapshotAvailable()) return;
179 v8::Isolate::CreateParams params; 198 v8::Isolate* isolate = TestIsolate::NewInitialized(true);
180 params.enable_serializer = true; 199 Serialize(isolate);
181 v8::Isolate* isolate = v8::Isolate::New(params);
182 Serialize(isolate);
183 }
184 } 200 }
185 201
186 202
187 // Test that heap serialization is non-destructive. 203 // Test that heap serialization is non-destructive.
188 UNINITIALIZED_TEST(SerializeTwice) { 204 UNINITIALIZED_TEST(SerializeTwice) {
189 if (!Snapshot::HaveASnapshotToStartFrom()) { 205 if (DefaultSnapshotAvailable()) return;
190 v8::Isolate::CreateParams params; 206 v8::Isolate* isolate = TestIsolate::NewInitialized(true);
191 params.enable_serializer = true; 207 Serialize(isolate);
192 v8::Isolate* isolate = v8::Isolate::New(params); 208 Serialize(isolate);
193 Serialize(isolate);
194 Serialize(isolate);
195 }
196 } 209 }
197 210
198 211
199 //---------------------------------------------------------------------------- 212 //----------------------------------------------------------------------------
200 // Tests that the heap can be deserialized. 213 // Tests that the heap can be deserialized.
201 214
202 v8::Isolate* InitializeFromFile(const char* snapshot_file) { 215 v8::Isolate* InitializeFromFile(const char* snapshot_file) {
203 int len; 216 int len;
204 byte* str = ReadBytes(snapshot_file, &len); 217 byte* str = ReadBytes(snapshot_file, &len);
205 if (!str) return NULL; 218 if (!str) return NULL;
206 v8::Isolate* v8_isolate = NULL; 219 v8::Isolate* v8_isolate = NULL;
207 { 220 {
208 SnapshotData snapshot_data(Vector<const byte>(str, len)); 221 SnapshotData snapshot_data(Vector<const byte>(str, len));
209 Deserializer deserializer(&snapshot_data); 222 Deserializer deserializer(&snapshot_data);
210 Isolate* isolate = Isolate::NewForTesting(); 223 Isolate* isolate = new TestIsolate(false);
211 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); 224 v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
212 v8::Isolate::Scope isolate_scope(v8_isolate); 225 v8::Isolate::Scope isolate_scope(v8_isolate);
213 isolate->Init(&deserializer); 226 isolate->Init(&deserializer);
214 } 227 }
215 DeleteArray(str); 228 DeleteArray(str);
216 return v8_isolate; 229 return v8_isolate;
217 } 230 }
218 231
219 232
220 static v8::Isolate* Deserialize() { 233 static v8::Isolate* Deserialize() {
(...skipping 13 matching lines...) Expand all
234 CHECK(isolate->native_context()->IsContext()); 247 CHECK(isolate->native_context()->IsContext());
235 CHECK(isolate->heap()->string_table()->IsStringTable()); 248 CHECK(isolate->heap()->string_table()->IsStringTable());
236 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Empty")); 249 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("Empty"));
237 } 250 }
238 251
239 252
240 UNINITIALIZED_DEPENDENT_TEST(Deserialize, Serialize) { 253 UNINITIALIZED_DEPENDENT_TEST(Deserialize, Serialize) {
241 // The serialize-deserialize tests only work if the VM is built without 254 // The serialize-deserialize tests only work if the VM is built without
242 // serialization. That doesn't matter. We don't need to be able to 255 // serialization. That doesn't matter. We don't need to be able to
243 // serialize a snapshot in a VM that is booted from a snapshot. 256 // serialize a snapshot in a VM that is booted from a snapshot.
244 if (!Snapshot::HaveASnapshotToStartFrom()) { 257 if (DefaultSnapshotAvailable()) return;
245 v8::Isolate* isolate = Deserialize(); 258 v8::Isolate* isolate = Deserialize();
246 { 259 {
247 v8::HandleScope handle_scope(isolate); 260 v8::HandleScope handle_scope(isolate);
248 v8::Isolate::Scope isolate_scope(isolate); 261 v8::Isolate::Scope isolate_scope(isolate);
249 262
250 v8::Local<v8::Context> env = v8::Context::New(isolate); 263 v8::Local<v8::Context> env = v8::Context::New(isolate);
251 env->Enter(); 264 env->Enter();
252 265
253 SanityCheck(isolate); 266 SanityCheck(isolate);
254 } 267 }
255 isolate->Dispose(); 268 isolate->Dispose();
256 }
257 } 269 }
258 270
259 271
260 UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerialization, 272 UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerialization,
261 SerializeTwice) { 273 SerializeTwice) {
262 if (!Snapshot::HaveASnapshotToStartFrom()) { 274 if (DefaultSnapshotAvailable()) return;
263 v8::Isolate* isolate = Deserialize(); 275 v8::Isolate* isolate = Deserialize();
264 { 276 {
265 v8::Isolate::Scope isolate_scope(isolate); 277 v8::Isolate::Scope isolate_scope(isolate);
266 v8::HandleScope handle_scope(isolate); 278 v8::HandleScope handle_scope(isolate);
267 279
268 v8::Local<v8::Context> env = v8::Context::New(isolate); 280 v8::Local<v8::Context> env = v8::Context::New(isolate);
269 env->Enter(); 281 env->Enter();
270 282
271 SanityCheck(isolate); 283 SanityCheck(isolate);
272 } 284 }
273 isolate->Dispose(); 285 isolate->Dispose();
274 }
275 } 286 }
276 287
277 288
278 UNINITIALIZED_DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) { 289 UNINITIALIZED_DEPENDENT_TEST(DeserializeAndRunScript2, Serialize) {
279 if (!Snapshot::HaveASnapshotToStartFrom()) { 290 if (DefaultSnapshotAvailable()) return;
280 v8::Isolate* isolate = Deserialize(); 291 v8::Isolate* isolate = Deserialize();
281 { 292 {
282 v8::Isolate::Scope isolate_scope(isolate); 293 v8::Isolate::Scope isolate_scope(isolate);
283 v8::HandleScope handle_scope(isolate); 294 v8::HandleScope handle_scope(isolate);
284 295
285 296
286 v8::Local<v8::Context> env = v8::Context::New(isolate); 297 v8::Local<v8::Context> env = v8::Context::New(isolate);
287 env->Enter(); 298 env->Enter();
288 299
289 const char* c_source = "\"1234\".length"; 300 const char* c_source = "\"1234\".length";
290 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source); 301 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
291 v8::Local<v8::Script> script = v8::Script::Compile(source); 302 v8::Local<v8::Script> script = v8::Script::Compile(source);
292 CHECK_EQ(4, script->Run()->Int32Value()); 303 CHECK_EQ(4, script->Run()->Int32Value());
293 } 304 }
294 isolate->Dispose(); 305 isolate->Dispose();
295 }
296 } 306 }
297 307
298 308
299 UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2, 309 UNINITIALIZED_DEPENDENT_TEST(DeserializeFromSecondSerializationAndRunScript2,
300 SerializeTwice) { 310 SerializeTwice) {
301 if (!Snapshot::HaveASnapshotToStartFrom()) { 311 if (DefaultSnapshotAvailable()) return;
302 v8::Isolate* isolate = Deserialize(); 312 v8::Isolate* isolate = Deserialize();
303 { 313 {
304 v8::Isolate::Scope isolate_scope(isolate); 314 v8::Isolate::Scope isolate_scope(isolate);
305 v8::HandleScope handle_scope(isolate); 315 v8::HandleScope handle_scope(isolate);
306 316
307 v8::Local<v8::Context> env = v8::Context::New(isolate); 317 v8::Local<v8::Context> env = v8::Context::New(isolate);
308 env->Enter(); 318 env->Enter();
309 319
310 const char* c_source = "\"1234\".length"; 320 const char* c_source = "\"1234\".length";
311 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source); 321 v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, c_source);
312 v8::Local<v8::Script> script = v8::Script::Compile(source); 322 v8::Local<v8::Script> script = v8::Script::Compile(source);
313 CHECK_EQ(4, script->Run()->Int32Value()); 323 CHECK_EQ(4, script->Run()->Int32Value());
314 } 324 }
315 isolate->Dispose(); 325 isolate->Dispose();
316 }
317 } 326 }
318 327
319 328
320 UNINITIALIZED_TEST(PartialSerialization) { 329 UNINITIALIZED_TEST(PartialSerialization) {
321 if (!Snapshot::HaveASnapshotToStartFrom()) { 330 if (DefaultSnapshotAvailable()) return;
322 v8::Isolate::CreateParams params; 331 v8::Isolate* v8_isolate = TestIsolate::NewInitialized(true);
323 params.enable_serializer = true; 332 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
324 v8::Isolate* v8_isolate = v8::Isolate::New(params); 333 v8_isolate->Enter();
325 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); 334 {
326 v8_isolate->Enter(); 335 Heap* heap = isolate->heap();
327 { 336
328 Heap* heap = isolate->heap(); 337 v8::Persistent<v8::Context> env;
329 338 {
330 v8::Persistent<v8::Context> env; 339 HandleScope scope(isolate);
331 { 340 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
332 HandleScope scope(isolate); 341 }
333 env.Reset(v8_isolate, v8::Context::New(v8_isolate)); 342 DCHECK(!env.IsEmpty());
343 {
344 v8::HandleScope handle_scope(v8_isolate);
345 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
346 }
347 // Make sure all builtin scripts are cached.
348 {
349 HandleScope scope(isolate);
350 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
351 isolate->bootstrapper()->NativesSourceLookup(i);
334 } 352 }
335 DCHECK(!env.IsEmpty()); 353 }
336 { 354 heap->CollectAllGarbage(Heap::kNoGCFlags);
337 v8::HandleScope handle_scope(v8_isolate); 355 heap->CollectAllGarbage(Heap::kNoGCFlags);
338 v8::Local<v8::Context>::New(v8_isolate, env)->Enter(); 356
339 } 357 Object* raw_foo;
340 // Make sure all builtin scripts are cached. 358 {
341 { 359 v8::HandleScope handle_scope(v8_isolate);
342 HandleScope scope(isolate); 360 v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
343 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { 361 DCHECK(!foo.IsEmpty());
344 isolate->bootstrapper()->NativesSourceLookup(i); 362 raw_foo = *(v8::Utils::OpenHandle(*foo));
345 } 363 }
346 } 364
347 heap->CollectAllGarbage(Heap::kNoGCFlags);
348 heap->CollectAllGarbage(Heap::kNoGCFlags);
349
350 Object* raw_foo;
351 {
352 v8::HandleScope handle_scope(v8_isolate);
353 v8::Local<v8::String> foo = v8::String::NewFromUtf8(v8_isolate, "foo");
354 DCHECK(!foo.IsEmpty());
355 raw_foo = *(v8::Utils::OpenHandle(*foo));
356 }
357
358 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
359 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
360 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
361
362 {
363 v8::HandleScope handle_scope(v8_isolate);
364 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
365 }
366 env.Reset();
367
368 SnapshotByteSink startup_sink;
369 StartupSerializer startup_serializer(isolate, &startup_sink);
370 startup_serializer.SerializeStrongReferences();
371
372 SnapshotByteSink partial_sink;
373 PartialSerializer partial_serializer(isolate, &startup_serializer,
374 &partial_sink);
375 partial_serializer.Serialize(&raw_foo);
376
377 startup_serializer.SerializeWeakReferences();
378
379 SnapshotData startup_snapshot(startup_serializer);
380 SnapshotData partial_snapshot(partial_serializer);
381
382 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
383 WritePayload(startup_snapshot.RawData(), startup_name.start());
384
385 startup_name.Dispose();
386 }
387 v8_isolate->Exit();
388 v8_isolate->Dispose();
389 }
390 }
391
392
393 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
394 if (!Snapshot::HaveASnapshotToStartFrom()) {
395 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 365 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
396 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 366 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
397 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 367 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
398 368
399 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); 369 {
400 CHECK(v8_isolate); 370 v8::HandleScope handle_scope(v8_isolate);
371 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
372 }
373 env.Reset();
374
375 SnapshotByteSink startup_sink;
376 StartupSerializer startup_serializer(isolate, &startup_sink);
377 startup_serializer.SerializeStrongReferences();
378
379 SnapshotByteSink partial_sink;
380 PartialSerializer partial_serializer(isolate, &startup_serializer,
381 &partial_sink);
382 partial_serializer.Serialize(&raw_foo);
383
384 startup_serializer.SerializeWeakReferences();
385
386 SnapshotData startup_snapshot(startup_serializer);
387 SnapshotData partial_snapshot(partial_serializer);
388
389 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
390 WritePayload(startup_snapshot.RawData(), startup_name.start());
391
401 startup_name.Dispose(); 392 startup_name.Dispose();
402 { 393 }
403 v8::Isolate::Scope isolate_scope(v8_isolate); 394 v8_isolate->Exit();
404 395 v8_isolate->Dispose();
405 const char* file_name = FLAG_testing_serialization_file; 396 }
406 397
407 int snapshot_size = 0; 398
408 byte* snapshot = ReadBytes(file_name, &snapshot_size); 399 UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
409 400 if (DefaultSnapshotAvailable()) return;
410 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); 401 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
411 HandleScope handle_scope(isolate); 402 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
412 Handle<Object> root; 403 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
413 Handle<FixedArray> outdated_contexts; 404
414 // Intentionally empty handle. The deserializer should not come across 405 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start());
415 // any references to the global proxy in this test. 406 CHECK(v8_isolate);
416 Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null(); 407 startup_name.Dispose();
417 { 408 {
418 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); 409 v8::Isolate::Scope isolate_scope(v8_isolate);
419 Deserializer deserializer(&snapshot_data); 410
420 root = deserializer.DeserializePartial(isolate, global_proxy, 411 const char* file_name = FLAG_testing_serialization_file;
421 &outdated_contexts) 412
422 .ToHandleChecked(); 413 int snapshot_size = 0;
423 CHECK_EQ(0, outdated_contexts->length()); 414 byte* snapshot = ReadBytes(file_name, &snapshot_size);
424 CHECK(root->IsString()); 415
416 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
417 HandleScope handle_scope(isolate);
418 Handle<Object> root;
419 Handle<FixedArray> outdated_contexts;
420 // Intentionally empty handle. The deserializer should not come across
421 // any references to the global proxy in this test.
422 Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null();
423 {
424 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
425 Deserializer deserializer(&snapshot_data);
426 root =
427 deserializer.DeserializePartial(isolate, global_proxy,
428 &outdated_contexts).ToHandleChecked();
429 CHECK_EQ(0, outdated_contexts->length());
430 CHECK(root->IsString());
431 }
432
433 Handle<Object> root2;
434 {
435 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
436 Deserializer deserializer(&snapshot_data);
437 root2 =
438 deserializer.DeserializePartial(isolate, global_proxy,
439 &outdated_contexts).ToHandleChecked();
440 CHECK(root2->IsString());
441 CHECK(root.is_identical_to(root2));
442 }
443
444 DeleteArray(snapshot);
445 }
446 v8_isolate->Dispose();
447 }
448
449
450 UNINITIALIZED_TEST(ContextSerialization) {
451 if (DefaultSnapshotAvailable()) return;
452 v8::Isolate* v8_isolate = TestIsolate::NewInitialized(true);
453 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
454 Heap* heap = isolate->heap();
455 {
456 v8::Isolate::Scope isolate_scope(v8_isolate);
457
458 v8::Persistent<v8::Context> env;
459 {
460 HandleScope scope(isolate);
461 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
462 }
463 DCHECK(!env.IsEmpty());
464 {
465 v8::HandleScope handle_scope(v8_isolate);
466 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
467 }
468 // Make sure all builtin scripts are cached.
469 {
470 HandleScope scope(isolate);
471 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
472 isolate->bootstrapper()->NativesSourceLookup(i);
425 } 473 }
426 474 }
427 Handle<Object> root2; 475 // If we don't do this then we end up with a stray root pointing at the
428 { 476 // context even after we have disposed of env.
429 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); 477 heap->CollectAllGarbage(Heap::kNoGCFlags);
430 Deserializer deserializer(&snapshot_data); 478
431 root2 = deserializer.DeserializePartial(isolate, global_proxy,
432 &outdated_contexts)
433 .ToHandleChecked();
434 CHECK(root2->IsString());
435 CHECK(root.is_identical_to(root2));
436 }
437 }
438 v8_isolate->Dispose();
439 }
440 }
441
442
443 UNINITIALIZED_TEST(ContextSerialization) {
444 if (!Snapshot::HaveASnapshotToStartFrom()) {
445 v8::Isolate::CreateParams params;
446 params.enable_serializer = true;
447 v8::Isolate* v8_isolate = v8::Isolate::New(params);
448 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
449 Heap* heap = isolate->heap();
450 {
451 v8::Isolate::Scope isolate_scope(v8_isolate);
452
453 v8::Persistent<v8::Context> env;
454 {
455 HandleScope scope(isolate);
456 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
457 }
458 DCHECK(!env.IsEmpty());
459 {
460 v8::HandleScope handle_scope(v8_isolate);
461 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
462 }
463 // Make sure all builtin scripts are cached.
464 {
465 HandleScope scope(isolate);
466 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
467 isolate->bootstrapper()->NativesSourceLookup(i);
468 }
469 }
470 // If we don't do this then we end up with a stray root pointing at the
471 // context even after we have disposed of env.
472 heap->CollectAllGarbage(Heap::kNoGCFlags);
473
474 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
475 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
476 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
477
478 {
479 v8::HandleScope handle_scope(v8_isolate);
480 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
481 }
482
483 i::Object* raw_context = *v8::Utils::OpenPersistent(env);
484
485 env.Reset();
486
487 SnapshotByteSink startup_sink;
488 StartupSerializer startup_serializer(isolate, &startup_sink);
489 startup_serializer.SerializeStrongReferences();
490
491 SnapshotByteSink partial_sink;
492 PartialSerializer partial_serializer(isolate, &startup_serializer,
493 &partial_sink);
494 partial_serializer.Serialize(&raw_context);
495 startup_serializer.SerializeWeakReferences();
496
497 SnapshotData startup_snapshot(startup_serializer);
498 SnapshotData partial_snapshot(partial_serializer);
499
500 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
501 WritePayload(startup_snapshot.RawData(), startup_name.start());
502
503 startup_name.Dispose();
504 }
505 v8_isolate->Dispose();
506 }
507 }
508
509
510 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
511 if (!Snapshot::HaveASnapshotToStartFrom()) {
512 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 479 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
513 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 480 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
514 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 481 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
515 482
516 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); 483 {
517 CHECK(v8_isolate); 484 v8::HandleScope handle_scope(v8_isolate);
485 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
486 }
487
488 i::Object* raw_context = *v8::Utils::OpenPersistent(env);
489
490 env.Reset();
491
492 SnapshotByteSink startup_sink;
493 StartupSerializer startup_serializer(isolate, &startup_sink);
494 startup_serializer.SerializeStrongReferences();
495
496 SnapshotByteSink partial_sink;
497 PartialSerializer partial_serializer(isolate, &startup_serializer,
498 &partial_sink);
499 partial_serializer.Serialize(&raw_context);
500 startup_serializer.SerializeWeakReferences();
501
502 SnapshotData startup_snapshot(startup_serializer);
503 SnapshotData partial_snapshot(partial_serializer);
504
505 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
506 WritePayload(startup_snapshot.RawData(), startup_name.start());
507
518 startup_name.Dispose(); 508 startup_name.Dispose();
519 { 509 }
520 v8::Isolate::Scope isolate_scope(v8_isolate); 510 v8_isolate->Dispose();
521 511 }
522 const char* file_name = FLAG_testing_serialization_file; 512
523 513
524 int snapshot_size = 0; 514 UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
525 byte* snapshot = ReadBytes(file_name, &snapshot_size); 515 if (DefaultSnapshotAvailable()) return;
526 516 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
527 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); 517 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
528 HandleScope handle_scope(isolate); 518 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
529 Handle<Object> root; 519
530 Handle<FixedArray> outdated_contexts; 520 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start());
531 Handle<JSGlobalProxy> global_proxy = 521 CHECK(v8_isolate);
532 isolate->factory()->NewUninitializedJSGlobalProxy(); 522 startup_name.Dispose();
533 { 523 {
534 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); 524 v8::Isolate::Scope isolate_scope(v8_isolate);
535 Deserializer deserializer(&snapshot_data); 525
536 root = deserializer.DeserializePartial(isolate, global_proxy, 526 const char* file_name = FLAG_testing_serialization_file;
537 &outdated_contexts) 527
538 .ToHandleChecked(); 528 int snapshot_size = 0;
539 CHECK(root->IsContext()); 529 byte* snapshot = ReadBytes(file_name, &snapshot_size);
540 CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy); 530
541 CHECK_EQ(1, outdated_contexts->length()); 531 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
532 HandleScope handle_scope(isolate);
533 Handle<Object> root;
534 Handle<FixedArray> outdated_contexts;
535 Handle<JSGlobalProxy> global_proxy =
536 isolate->factory()->NewUninitializedJSGlobalProxy();
537 {
538 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
539 Deserializer deserializer(&snapshot_data);
540 root =
541 deserializer.DeserializePartial(isolate, global_proxy,
542 &outdated_contexts).ToHandleChecked();
543 CHECK(root->IsContext());
544 CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
545 CHECK_EQ(1, outdated_contexts->length());
546 }
547
548 Handle<Object> root2;
549 {
550 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
551 Deserializer deserializer(&snapshot_data);
552 root2 =
553 deserializer.DeserializePartial(isolate, global_proxy,
554 &outdated_contexts).ToHandleChecked();
555 CHECK(root2->IsContext());
556 CHECK(!root.is_identical_to(root2));
557 }
558 DeleteArray(snapshot);
559 }
560 v8_isolate->Dispose();
561 }
562
563
564 UNINITIALIZED_TEST(CustomContextSerialization) {
565 if (DefaultSnapshotAvailable()) return;
566 v8::Isolate* v8_isolate = TestIsolate::NewInitialized(true);
567 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
568 {
569 v8::Isolate::Scope isolate_scope(v8_isolate);
570
571 v8::Persistent<v8::Context> env;
572 {
573 HandleScope scope(isolate);
574 env.Reset(v8_isolate, v8::Context::New(v8_isolate));
575 }
576 DCHECK(!env.IsEmpty());
577 {
578 v8::HandleScope handle_scope(v8_isolate);
579 v8::Local<v8::Context>::New(v8_isolate, env)->Enter();
580 // After execution, e's function context refers to the global object.
581 CompileRun(
582 "var e;"
583 "(function() {"
584 " e = function(s) { return eval (s); }"
585 "})();"
586 "var o = this;"
587 "var r = Math.random() + Math.cos(0);"
588 "var f = (function(a, b) { return a + b; }).bind(1, 2, 3);"
589 "var s = parseInt('12345');");
590
591 Vector<const uint8_t> source = ConstructSource(
592 STATIC_CHAR_VECTOR("function g() { return [,"),
593 STATIC_CHAR_VECTOR("1,"),
594 STATIC_CHAR_VECTOR("];} a = g(); b = g(); b.push(1);"), 100000);
595 v8::Handle<v8::String> source_str = v8::String::NewFromOneByte(
596 v8_isolate, source.start(), v8::String::kNormalString,
597 source.length());
598 CompileRun(source_str);
599 source.Dispose();
600 }
601 // Make sure all builtin scripts are cached.
602 {
603 HandleScope scope(isolate);
604 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
605 isolate->bootstrapper()->NativesSourceLookup(i);
542 } 606 }
543 607 }
544 Handle<Object> root2; 608 // If we don't do this then we end up with a stray root pointing at the
545 { 609 // context even after we have disposed of env.
546 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); 610 isolate->heap()->CollectAllAvailableGarbage("snapshotting");
547 Deserializer deserializer(&snapshot_data); 611
548 root2 = deserializer.DeserializePartial(isolate, global_proxy, 612 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
549 &outdated_contexts) 613 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
550 .ToHandleChecked(); 614 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
551 CHECK(root2->IsContext()); 615
552 CHECK(!root.is_identical_to(root2)); 616 {
553 } 617 v8::HandleScope handle_scope(v8_isolate);
554 } 618 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
555 v8_isolate->Dispose(); 619 }
556 } 620
557 } 621 i::Object* raw_context = *v8::Utils::OpenPersistent(env);
558 622
559 623 env.Reset();
560 UNINITIALIZED_TEST(CustomContextSerialization) { 624
561 if (!Snapshot::HaveASnapshotToStartFrom()) { 625 SnapshotByteSink startup_sink;
562 v8::Isolate::CreateParams params; 626 StartupSerializer startup_serializer(isolate, &startup_sink);
563 params.enable_serializer = true; 627 startup_serializer.SerializeStrongReferences();
564 v8::Isolate* v8_isolate = v8::Isolate::New(params); 628
565 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); 629 SnapshotByteSink partial_sink;
566 { 630 PartialSerializer partial_serializer(isolate, &startup_serializer,
567 v8::Isolate::Scope isolate_scope(v8_isolate); 631 &partial_sink);
568 632 partial_serializer.Serialize(&raw_context);
569 v8::Persistent<v8::Context> env; 633 startup_serializer.SerializeWeakReferences();
570 { 634
571 HandleScope scope(isolate); 635 SnapshotData startup_snapshot(startup_serializer);
572 env.Reset(v8_isolate, v8::Context::New(v8_isolate)); 636 SnapshotData partial_snapshot(partial_serializer);
573 } 637
574 DCHECK(!env.IsEmpty()); 638 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
575 { 639 WritePayload(startup_snapshot.RawData(), startup_name.start());
576 v8::HandleScope handle_scope(v8_isolate); 640
577 v8::Local<v8::Context>::New(v8_isolate, env)->Enter(); 641 startup_name.Dispose();
578 // After execution, e's function context refers to the global object. 642 }
579 CompileRun( 643 v8_isolate->Dispose();
580 "var e;"
581 "(function() {"
582 " e = function(s) { return eval (s); }"
583 "})();"
584 "var o = this;"
585 "var r = Math.random() + Math.cos(0);"
586 "var f = (function(a, b) { return a + b; }).bind(1, 2, 3);"
587 "var s = parseInt('12345');");
588
589 Vector<const uint8_t> source = ConstructSource(
590 STATIC_CHAR_VECTOR("function g() { return [,"),
591 STATIC_CHAR_VECTOR("1,"),
592 STATIC_CHAR_VECTOR("];} a = g(); b = g(); b.push(1);"), 100000);
593 v8::Handle<v8::String> source_str = v8::String::NewFromOneByte(
594 v8_isolate, source.start(), v8::String::kNormalString,
595 source.length());
596 CompileRun(source_str);
597 source.Dispose();
598 }
599 // Make sure all builtin scripts are cached.
600 {
601 HandleScope scope(isolate);
602 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
603 isolate->bootstrapper()->NativesSourceLookup(i);
604 }
605 }
606 // If we don't do this then we end up with a stray root pointing at the
607 // context even after we have disposed of env.
608 isolate->heap()->CollectAllAvailableGarbage("snapshotting");
609
610 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
611 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
612 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
613
614 {
615 v8::HandleScope handle_scope(v8_isolate);
616 v8::Local<v8::Context>::New(v8_isolate, env)->Exit();
617 }
618
619 i::Object* raw_context = *v8::Utils::OpenPersistent(env);
620
621 env.Reset();
622
623 SnapshotByteSink startup_sink;
624 StartupSerializer startup_serializer(isolate, &startup_sink);
625 startup_serializer.SerializeStrongReferences();
626
627 SnapshotByteSink partial_sink;
628 PartialSerializer partial_serializer(isolate, &startup_serializer,
629 &partial_sink);
630 partial_serializer.Serialize(&raw_context);
631 startup_serializer.SerializeWeakReferences();
632
633 SnapshotData startup_snapshot(startup_serializer);
634 SnapshotData partial_snapshot(partial_serializer);
635
636 WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
637 WritePayload(startup_snapshot.RawData(), startup_name.start());
638
639 startup_name.Dispose();
640 }
641 v8_isolate->Dispose();
642 }
643 } 644 }
644 645
645 646
646 UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization, 647 UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
647 CustomContextSerialization) { 648 CustomContextSerialization) {
648 FLAG_crankshaft = false; 649 FLAG_crankshaft = false;
649 if (!Snapshot::HaveASnapshotToStartFrom()) { 650 if (DefaultSnapshotAvailable()) return;
650 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10; 651 int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
651 Vector<char> startup_name = Vector<char>::New(file_name_length + 1); 652 Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
652 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file); 653 SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
653 654
654 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start()); 655 v8::Isolate* v8_isolate = InitializeFromFile(startup_name.start());
655 CHECK(v8_isolate); 656 CHECK(v8_isolate);
656 startup_name.Dispose(); 657 startup_name.Dispose();
657 { 658 {
658 v8::Isolate::Scope isolate_scope(v8_isolate); 659 v8::Isolate::Scope isolate_scope(v8_isolate);
659 660
660 const char* file_name = FLAG_testing_serialization_file; 661 const char* file_name = FLAG_testing_serialization_file;
661 662
662 int snapshot_size = 0; 663 int snapshot_size = 0;
663 byte* snapshot = ReadBytes(file_name, &snapshot_size); 664 byte* snapshot = ReadBytes(file_name, &snapshot_size);
664 665
665 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); 666 Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
666 HandleScope handle_scope(isolate); 667 HandleScope handle_scope(isolate);
667 Handle<Object> root; 668 Handle<Object> root;
668 Handle<FixedArray> outdated_contexts; 669 Handle<FixedArray> outdated_contexts;
669 Handle<JSGlobalProxy> global_proxy = 670 Handle<JSGlobalProxy> global_proxy =
670 isolate->factory()->NewUninitializedJSGlobalProxy(); 671 isolate->factory()->NewUninitializedJSGlobalProxy();
671 { 672 {
672 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); 673 SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
673 Deserializer deserializer(&snapshot_data); 674 Deserializer deserializer(&snapshot_data);
674 root = deserializer.DeserializePartial(isolate, global_proxy, 675 root =
675 &outdated_contexts) 676 deserializer.DeserializePartial(isolate, global_proxy,
676 .ToHandleChecked(); 677 &outdated_contexts).ToHandleChecked();
677 CHECK_EQ(2, outdated_contexts->length()); 678 CHECK_EQ(2, outdated_contexts->length());
678 CHECK(root->IsContext()); 679 CHECK(root->IsContext());
679 Handle<Context> context = Handle<Context>::cast(root); 680 Handle<Context> context = Handle<Context>::cast(root);
680 CHECK(context->global_proxy() == *global_proxy); 681 CHECK(context->global_proxy() == *global_proxy);
681 Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o"); 682 Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o");
682 Handle<JSObject> global_object(context->global_object(), isolate); 683 Handle<JSObject> global_object(context->global_object(), isolate);
683 Handle<Object> property = JSObject::GetDataProperty(global_object, o); 684 Handle<Object> property = JSObject::GetDataProperty(global_object, o);
684 CHECK(property.is_identical_to(global_proxy)); 685 CHECK(property.is_identical_to(global_proxy));
685 686
686 v8::Handle<v8::Context> v8_context = v8::Utils::ToLocal(context); 687 v8::Handle<v8::Context> v8_context = v8::Utils::ToLocal(context);
687 v8::Context::Scope context_scope(v8_context); 688 v8::Context::Scope context_scope(v8_context);
688 double r = CompileRun("r")->ToNumber(v8_isolate)->Value(); 689 double r = CompileRun("r")->ToNumber(v8_isolate)->Value();
689 CHECK(r >= 1 && r <= 2); 690 CHECK(r >= 1 && r <= 2);
690 int f = CompileRun("f()")->ToNumber(v8_isolate)->Int32Value(); 691 int f = CompileRun("f()")->ToNumber(v8_isolate)->Int32Value();
691 CHECK_EQ(5, f); 692 CHECK_EQ(5, f);
692 f = CompileRun("e('f()')")->ToNumber(v8_isolate)->Int32Value(); 693 f = CompileRun("e('f()')")->ToNumber(v8_isolate)->Int32Value();
693 CHECK_EQ(5, f); 694 CHECK_EQ(5, f);
694 v8::Handle<v8::String> s = CompileRun("s")->ToString(v8_isolate); 695 v8::Handle<v8::String> s = CompileRun("s")->ToString(v8_isolate);
695 CHECK(s->Equals(v8_str("12345"))); 696 CHECK(s->Equals(v8_str("12345")));
696 int a = CompileRun("a.length")->ToNumber(v8_isolate)->Int32Value(); 697 int a = CompileRun("a.length")->ToNumber(v8_isolate)->Int32Value();
697 CHECK_EQ(100001, a); 698 CHECK_EQ(100001, a);
698 int b = CompileRun("b.length")->ToNumber(v8_isolate)->Int32Value(); 699 int b = CompileRun("b.length")->ToNumber(v8_isolate)->Int32Value();
699 CHECK_EQ(100002, b); 700 CHECK_EQ(100002, b);
700 } 701 }
701 } 702 DeleteArray(snapshot);
702 v8_isolate->Dispose(); 703 }
703 } 704 v8_isolate->Dispose();
704 } 705 }
705 706
706 707
708 TEST(PerIsolateSnapshotBlobs) {
709 // Disable experimental natives that are loaded after deserialization.
710 FLAG_harmony_shipping = false;
711 FlagList::EnforceFlagImplications();
712
713 const char* source1 = "function f() { return 42; }";
714 const char* source2 =
715 "function f() { return g() * 2; }"
716 "function g() { return 43; }";
717
718 v8::StartupData data1 = v8::V8::CreateSnapshotDataBlob(source1);
719 v8::StartupData data2 = v8::V8::CreateSnapshotDataBlob(source2);
720
721 v8::Isolate::CreateParams params1;
722 params1.snapshot_blob = &data1;
723 v8::Isolate* isolate1 = v8::Isolate::New(params1);
724 {
725 v8::Isolate::Scope i_scope(isolate1);
726 v8::HandleScope h_scope(isolate1);
727 v8::Local<v8::Context> context = v8::Context::New(isolate1);
728 delete[] data1.data; // We can dispose of the snapshot blob now.
729 v8::Context::Scope c_scope(context);
730 CHECK_EQ(42, CompileRun("f()")->ToInt32(isolate1)->Int32Value());
731 CHECK(CompileRun("this.g")->IsUndefined());
732 }
733 isolate1->Dispose();
734
735 v8::Isolate::CreateParams params2;
736 params2.snapshot_blob = &data2;
737 v8::Isolate* isolate2 = v8::Isolate::New(params2);
738 {
739 v8::Isolate::Scope i_scope(isolate2);
740 v8::HandleScope h_scope(isolate2);
741 v8::Local<v8::Context> context = v8::Context::New(isolate2);
742 delete[] data2.data; // We can dispose of the snapshot blob now.
743 v8::Context::Scope c_scope(context);
744 CHECK_EQ(86, CompileRun("f()")->ToInt32(isolate2)->Int32Value());
745 CHECK_EQ(43, CompileRun("g()")->ToInt32(isolate2)->Int32Value());
746 }
747 isolate2->Dispose();
748 }
749
750
707 TEST(TestThatAlwaysSucceeds) { 751 TEST(TestThatAlwaysSucceeds) {
708 } 752 }
709 753
710 754
711 TEST(TestThatAlwaysFails) { 755 TEST(TestThatAlwaysFails) {
712 bool ArtificialFailure = false; 756 bool ArtificialFailure = false;
713 CHECK(ArtificialFailure); 757 CHECK(ArtificialFailure);
714 } 758 }
715 759
716 760
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 { 1460 {
1417 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2)); 1461 DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
1418 script = v8::ScriptCompiler::CompileUnbound( 1462 script = v8::ScriptCompiler::CompileUnbound(
1419 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache); 1463 isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache);
1420 } 1464 }
1421 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run(); 1465 v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
1422 CHECK(result->ToString(isolate2)->Equals(v8_str("XY"))); 1466 CHECK(result->ToString(isolate2)->Equals(v8_str("XY")));
1423 } 1467 }
1424 isolate2->Dispose(); 1468 isolate2->Dispose();
1425 } 1469 }
OLDNEW
« no previous file with comments | « test/cctest/test-heap.cc ('k') | test/cctest/test-spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698