OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 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 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include <limits.h> | 28 #include <limits.h> |
29 | 29 |
30 #include "v8.h" | 30 #include "v8.h" |
31 | 31 |
32 #include "api.h" | 32 #include "api.h" |
33 #include "compilation-cache.h" | 33 #include "compilation-cache.h" |
34 #include "execution.h" | 34 #include "execution.h" |
35 #include "snapshot.h" | 35 #include "snapshot.h" |
36 #include "platform.h" | 36 #include "platform.h" |
37 #include "top.h" | |
38 #include "utils.h" | 37 #include "utils.h" |
39 #include "cctest.h" | 38 #include "cctest.h" |
40 #include "parser.h" | 39 #include "parser.h" |
41 #include "unicode-inl.h" | 40 #include "unicode-inl.h" |
42 | 41 |
43 static const bool kLogThreading = true; | 42 static const bool kLogThreading = true; |
44 | 43 |
45 static bool IsNaN(double x) { | 44 static bool IsNaN(double x) { |
46 #ifdef WIN32 | 45 #ifdef WIN32 |
47 return _isnan(x); | 46 return _isnan(x); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 LocalContext env; | 390 LocalContext env; |
392 TestResource* resource = new TestResource(two_byte_source); | 391 TestResource* resource = new TestResource(two_byte_source); |
393 Local<String> source = String::NewExternal(resource); | 392 Local<String> source = String::NewExternal(resource); |
394 Local<Script> script = Script::Compile(source); | 393 Local<Script> script = Script::Compile(source); |
395 Local<Value> value = script->Run(); | 394 Local<Value> value = script->Run(); |
396 CHECK(value->IsNumber()); | 395 CHECK(value->IsNumber()); |
397 CHECK_EQ(7, value->Int32Value()); | 396 CHECK_EQ(7, value->Int32Value()); |
398 CHECK(source->IsExternal()); | 397 CHECK(source->IsExternal()); |
399 CHECK_EQ(resource, | 398 CHECK_EQ(resource, |
400 static_cast<TestResource*>(source->GetExternalStringResource())); | 399 static_cast<TestResource*>(source->GetExternalStringResource())); |
401 i::Heap::CollectAllGarbage(false); | 400 HEAP->CollectAllGarbage(false); |
402 CHECK_EQ(0, TestResource::dispose_count); | 401 CHECK_EQ(0, TestResource::dispose_count); |
403 } | 402 } |
404 i::CompilationCache::Clear(); | 403 v8::internal::Isolate::Current()->compilation_cache()->Clear(); |
405 i::Heap::CollectAllGarbage(false); | 404 HEAP->CollectAllGarbage(false); |
406 CHECK_EQ(1, TestResource::dispose_count); | 405 CHECK_EQ(1, TestResource::dispose_count); |
407 } | 406 } |
408 | 407 |
409 | 408 |
410 THREADED_TEST(ScriptUsingAsciiStringResource) { | 409 THREADED_TEST(ScriptUsingAsciiStringResource) { |
411 TestAsciiResource::dispose_count = 0; | 410 TestAsciiResource::dispose_count = 0; |
412 const char* c_source = "1 + 2 * 3"; | 411 const char* c_source = "1 + 2 * 3"; |
413 { | 412 { |
414 v8::HandleScope scope; | 413 v8::HandleScope scope; |
415 LocalContext env; | 414 LocalContext env; |
416 Local<String> source = | 415 Local<String> source = |
417 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); | 416 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); |
418 Local<Script> script = Script::Compile(source); | 417 Local<Script> script = Script::Compile(source); |
419 Local<Value> value = script->Run(); | 418 Local<Value> value = script->Run(); |
420 CHECK(value->IsNumber()); | 419 CHECK(value->IsNumber()); |
421 CHECK_EQ(7, value->Int32Value()); | 420 CHECK_EQ(7, value->Int32Value()); |
422 i::Heap::CollectAllGarbage(false); | 421 HEAP->CollectAllGarbage(false); |
423 CHECK_EQ(0, TestAsciiResource::dispose_count); | 422 CHECK_EQ(0, TestAsciiResource::dispose_count); |
424 } | 423 } |
425 i::CompilationCache::Clear(); | 424 i::Isolate::Current()->compilation_cache()->Clear(); |
426 i::Heap::CollectAllGarbage(false); | 425 HEAP->CollectAllGarbage(false); |
427 CHECK_EQ(1, TestAsciiResource::dispose_count); | 426 CHECK_EQ(1, TestAsciiResource::dispose_count); |
428 } | 427 } |
429 | 428 |
430 | 429 |
431 THREADED_TEST(ScriptMakingExternalString) { | 430 THREADED_TEST(ScriptMakingExternalString) { |
432 TestResource::dispose_count = 0; | 431 TestResource::dispose_count = 0; |
433 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 432 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
434 { | 433 { |
435 v8::HandleScope scope; | 434 v8::HandleScope scope; |
436 LocalContext env; | 435 LocalContext env; |
437 Local<String> source = String::New(two_byte_source); | 436 Local<String> source = String::New(two_byte_source); |
438 // Trigger GCs so that the newly allocated string moves to old gen. | 437 // Trigger GCs so that the newly allocated string moves to old gen. |
439 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 438 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
440 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 439 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
441 bool success = source->MakeExternal(new TestResource(two_byte_source)); | 440 bool success = source->MakeExternal(new TestResource(two_byte_source)); |
442 CHECK(success); | 441 CHECK(success); |
443 Local<Script> script = Script::Compile(source); | 442 Local<Script> script = Script::Compile(source); |
444 Local<Value> value = script->Run(); | 443 Local<Value> value = script->Run(); |
445 CHECK(value->IsNumber()); | 444 CHECK(value->IsNumber()); |
446 CHECK_EQ(7, value->Int32Value()); | 445 CHECK_EQ(7, value->Int32Value()); |
447 i::Heap::CollectAllGarbage(false); | 446 HEAP->CollectAllGarbage(false); |
448 CHECK_EQ(0, TestResource::dispose_count); | 447 CHECK_EQ(0, TestResource::dispose_count); |
449 } | 448 } |
450 i::CompilationCache::Clear(); | 449 i::Isolate::Current()->compilation_cache()->Clear(); |
451 i::Heap::CollectAllGarbage(false); | 450 HEAP->CollectAllGarbage(false); |
452 CHECK_EQ(1, TestResource::dispose_count); | 451 CHECK_EQ(1, TestResource::dispose_count); |
453 } | 452 } |
454 | 453 |
455 | 454 |
456 THREADED_TEST(ScriptMakingExternalAsciiString) { | 455 THREADED_TEST(ScriptMakingExternalAsciiString) { |
457 TestAsciiResource::dispose_count = 0; | 456 TestAsciiResource::dispose_count = 0; |
458 const char* c_source = "1 + 2 * 3"; | 457 const char* c_source = "1 + 2 * 3"; |
459 { | 458 { |
460 v8::HandleScope scope; | 459 v8::HandleScope scope; |
461 LocalContext env; | 460 LocalContext env; |
462 Local<String> source = v8_str(c_source); | 461 Local<String> source = v8_str(c_source); |
463 // Trigger GCs so that the newly allocated string moves to old gen. | 462 // Trigger GCs so that the newly allocated string moves to old gen. |
464 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 463 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
465 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 464 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
466 bool success = source->MakeExternal( | 465 bool success = source->MakeExternal( |
467 new TestAsciiResource(i::StrDup(c_source))); | 466 new TestAsciiResource(i::StrDup(c_source))); |
468 CHECK(success); | 467 CHECK(success); |
469 Local<Script> script = Script::Compile(source); | 468 Local<Script> script = Script::Compile(source); |
470 Local<Value> value = script->Run(); | 469 Local<Value> value = script->Run(); |
471 CHECK(value->IsNumber()); | 470 CHECK(value->IsNumber()); |
472 CHECK_EQ(7, value->Int32Value()); | 471 CHECK_EQ(7, value->Int32Value()); |
473 i::Heap::CollectAllGarbage(false); | 472 HEAP->CollectAllGarbage(false); |
474 CHECK_EQ(0, TestAsciiResource::dispose_count); | 473 CHECK_EQ(0, TestAsciiResource::dispose_count); |
475 } | 474 } |
476 i::CompilationCache::Clear(); | 475 i::Isolate::Current()->compilation_cache()->Clear(); |
477 i::Heap::CollectAllGarbage(false); | 476 HEAP->CollectAllGarbage(false); |
478 CHECK_EQ(1, TestAsciiResource::dispose_count); | 477 CHECK_EQ(1, TestAsciiResource::dispose_count); |
479 } | 478 } |
480 | 479 |
481 | 480 |
482 TEST(MakingExternalStringConditions) { | 481 TEST(MakingExternalStringConditions) { |
483 v8::HandleScope scope; | 482 v8::HandleScope scope; |
484 LocalContext env; | 483 LocalContext env; |
485 | 484 |
486 // Free some space in the new space so that we can check freshness. | 485 // Free some space in the new space so that we can check freshness. |
487 i::Heap::CollectGarbage(i::NEW_SPACE); | 486 HEAP->CollectGarbage(i::NEW_SPACE); |
488 i::Heap::CollectGarbage(i::NEW_SPACE); | 487 HEAP->CollectGarbage(i::NEW_SPACE); |
489 | 488 |
490 uint16_t* two_byte_string = AsciiToTwoByteString("small"); | 489 uint16_t* two_byte_string = AsciiToTwoByteString("small"); |
491 Local<String> small_string = String::New(two_byte_string); | 490 Local<String> small_string = String::New(two_byte_string); |
492 i::DeleteArray(two_byte_string); | 491 i::DeleteArray(two_byte_string); |
493 | 492 |
494 // We should refuse to externalize newly created small string. | 493 // We should refuse to externalize newly created small string. |
495 CHECK(!small_string->CanMakeExternal()); | 494 CHECK(!small_string->CanMakeExternal()); |
496 // Trigger GCs so that the newly allocated string moves to old gen. | 495 // Trigger GCs so that the newly allocated string moves to old gen. |
497 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 496 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
498 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 497 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
499 // Old space strings should be accepted. | 498 // Old space strings should be accepted. |
500 CHECK(small_string->CanMakeExternal()); | 499 CHECK(small_string->CanMakeExternal()); |
501 | 500 |
502 two_byte_string = AsciiToTwoByteString("small 2"); | 501 two_byte_string = AsciiToTwoByteString("small 2"); |
503 small_string = String::New(two_byte_string); | 502 small_string = String::New(two_byte_string); |
504 i::DeleteArray(two_byte_string); | 503 i::DeleteArray(two_byte_string); |
505 | 504 |
506 // We should refuse externalizing newly created small string. | 505 // We should refuse externalizing newly created small string. |
507 CHECK(!small_string->CanMakeExternal()); | 506 CHECK(!small_string->CanMakeExternal()); |
508 for (int i = 0; i < 100; i++) { | 507 for (int i = 0; i < 100; i++) { |
(...skipping 14 matching lines...) Expand all Loading... |
523 // Large strings should be immediately accepted. | 522 // Large strings should be immediately accepted. |
524 CHECK(large_string->CanMakeExternal()); | 523 CHECK(large_string->CanMakeExternal()); |
525 } | 524 } |
526 | 525 |
527 | 526 |
528 TEST(MakingExternalAsciiStringConditions) { | 527 TEST(MakingExternalAsciiStringConditions) { |
529 v8::HandleScope scope; | 528 v8::HandleScope scope; |
530 LocalContext env; | 529 LocalContext env; |
531 | 530 |
532 // Free some space in the new space so that we can check freshness. | 531 // Free some space in the new space so that we can check freshness. |
533 i::Heap::CollectGarbage(i::NEW_SPACE); | 532 HEAP->CollectGarbage(i::NEW_SPACE); |
534 i::Heap::CollectGarbage(i::NEW_SPACE); | 533 HEAP->CollectGarbage(i::NEW_SPACE); |
535 | 534 |
536 Local<String> small_string = String::New("small"); | 535 Local<String> small_string = String::New("small"); |
537 // We should refuse to externalize newly created small string. | 536 // We should refuse to externalize newly created small string. |
538 CHECK(!small_string->CanMakeExternal()); | 537 CHECK(!small_string->CanMakeExternal()); |
539 // Trigger GCs so that the newly allocated string moves to old gen. | 538 // Trigger GCs so that the newly allocated string moves to old gen. |
540 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 539 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
541 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 540 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
542 // Old space strings should be accepted. | 541 // Old space strings should be accepted. |
543 CHECK(small_string->CanMakeExternal()); | 542 CHECK(small_string->CanMakeExternal()); |
544 | 543 |
545 small_string = String::New("small 2"); | 544 small_string = String::New("small 2"); |
546 // We should refuse externalizing newly created small string. | 545 // We should refuse externalizing newly created small string. |
547 CHECK(!small_string->CanMakeExternal()); | 546 CHECK(!small_string->CanMakeExternal()); |
548 for (int i = 0; i < 100; i++) { | 547 for (int i = 0; i < 100; i++) { |
549 String::Value value(small_string); | 548 String::Value value(small_string); |
550 } | 549 } |
551 // Frequently used strings should be accepted. | 550 // Frequently used strings should be accepted. |
(...skipping 11 matching lines...) Expand all Loading... |
563 | 562 |
564 | 563 |
565 THREADED_TEST(UsingExternalString) { | 564 THREADED_TEST(UsingExternalString) { |
566 { | 565 { |
567 v8::HandleScope scope; | 566 v8::HandleScope scope; |
568 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 567 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
569 Local<String> string = | 568 Local<String> string = |
570 String::NewExternal(new TestResource(two_byte_string)); | 569 String::NewExternal(new TestResource(two_byte_string)); |
571 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 570 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
572 // Trigger GCs so that the newly allocated string moves to old gen. | 571 // Trigger GCs so that the newly allocated string moves to old gen. |
573 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 572 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
574 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 573 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
575 i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring); | 574 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
576 CHECK(isymbol->IsSymbol()); | 575 CHECK(isymbol->IsSymbol()); |
577 } | 576 } |
578 i::Heap::CollectAllGarbage(false); | 577 HEAP->CollectAllGarbage(false); |
579 i::Heap::CollectAllGarbage(false); | 578 HEAP->CollectAllGarbage(false); |
580 } | 579 } |
581 | 580 |
582 | 581 |
583 THREADED_TEST(UsingExternalAsciiString) { | 582 THREADED_TEST(UsingExternalAsciiString) { |
584 { | 583 { |
585 v8::HandleScope scope; | 584 v8::HandleScope scope; |
586 const char* one_byte_string = "test string"; | 585 const char* one_byte_string = "test string"; |
587 Local<String> string = String::NewExternal( | 586 Local<String> string = String::NewExternal( |
588 new TestAsciiResource(i::StrDup(one_byte_string))); | 587 new TestAsciiResource(i::StrDup(one_byte_string))); |
589 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 588 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
590 // Trigger GCs so that the newly allocated string moves to old gen. | 589 // Trigger GCs so that the newly allocated string moves to old gen. |
591 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 590 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
592 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 591 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
593 i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring); | 592 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
594 CHECK(isymbol->IsSymbol()); | 593 CHECK(isymbol->IsSymbol()); |
595 } | 594 } |
596 i::Heap::CollectAllGarbage(false); | 595 HEAP->CollectAllGarbage(false); |
597 i::Heap::CollectAllGarbage(false); | 596 HEAP->CollectAllGarbage(false); |
598 } | 597 } |
599 | 598 |
600 | 599 |
601 THREADED_TEST(ScavengeExternalString) { | 600 THREADED_TEST(ScavengeExternalString) { |
602 TestResource::dispose_count = 0; | 601 TestResource::dispose_count = 0; |
603 bool in_new_space = false; | 602 bool in_new_space = false; |
604 { | 603 { |
605 v8::HandleScope scope; | 604 v8::HandleScope scope; |
606 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 605 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
607 Local<String> string = | 606 Local<String> string = |
608 String::NewExternal(new TestResource(two_byte_string)); | 607 String::NewExternal(new TestResource(two_byte_string)); |
609 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 608 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
610 i::Heap::CollectGarbage(i::NEW_SPACE); | 609 HEAP->CollectGarbage(i::NEW_SPACE); |
611 in_new_space = i::Heap::InNewSpace(*istring); | 610 in_new_space = HEAP->InNewSpace(*istring); |
612 CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring)); | 611 CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); |
613 CHECK_EQ(0, TestResource::dispose_count); | 612 CHECK_EQ(0, TestResource::dispose_count); |
614 } | 613 } |
615 i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 614 HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
616 CHECK_EQ(1, TestResource::dispose_count); | 615 CHECK_EQ(1, TestResource::dispose_count); |
617 } | 616 } |
618 | 617 |
619 | 618 |
620 THREADED_TEST(ScavengeExternalAsciiString) { | 619 THREADED_TEST(ScavengeExternalAsciiString) { |
621 TestAsciiResource::dispose_count = 0; | 620 TestAsciiResource::dispose_count = 0; |
622 bool in_new_space = false; | 621 bool in_new_space = false; |
623 { | 622 { |
624 v8::HandleScope scope; | 623 v8::HandleScope scope; |
625 const char* one_byte_string = "test string"; | 624 const char* one_byte_string = "test string"; |
626 Local<String> string = String::NewExternal( | 625 Local<String> string = String::NewExternal( |
627 new TestAsciiResource(i::StrDup(one_byte_string))); | 626 new TestAsciiResource(i::StrDup(one_byte_string))); |
628 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 627 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
629 i::Heap::CollectGarbage(i::NEW_SPACE); | 628 HEAP->CollectGarbage(i::NEW_SPACE); |
630 in_new_space = i::Heap::InNewSpace(*istring); | 629 in_new_space = HEAP->InNewSpace(*istring); |
631 CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring)); | 630 CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); |
632 CHECK_EQ(0, TestAsciiResource::dispose_count); | 631 CHECK_EQ(0, TestAsciiResource::dispose_count); |
633 } | 632 } |
634 i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 633 HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
635 CHECK_EQ(1, TestAsciiResource::dispose_count); | 634 CHECK_EQ(1, TestAsciiResource::dispose_count); |
636 } | 635 } |
637 | 636 |
638 | 637 |
639 class TestAsciiResourceWithDisposeControl: public TestAsciiResource { | 638 class TestAsciiResourceWithDisposeControl: public TestAsciiResource { |
640 public: | 639 public: |
641 static int dispose_calls; | 640 static int dispose_calls; |
642 | 641 |
643 TestAsciiResourceWithDisposeControl(const char* data, bool dispose) | 642 TestAsciiResourceWithDisposeControl(const char* data, bool dispose) |
644 : TestAsciiResource(data), | 643 : TestAsciiResource(data), |
(...skipping 19 matching lines...) Expand all Loading... |
664 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 663 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
665 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 664 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
666 { | 665 { |
667 v8::HandleScope scope; | 666 v8::HandleScope scope; |
668 LocalContext env; | 667 LocalContext env; |
669 Local<String> source = String::NewExternal(&res_stack); | 668 Local<String> source = String::NewExternal(&res_stack); |
670 Local<Script> script = Script::Compile(source); | 669 Local<Script> script = Script::Compile(source); |
671 Local<Value> value = script->Run(); | 670 Local<Value> value = script->Run(); |
672 CHECK(value->IsNumber()); | 671 CHECK(value->IsNumber()); |
673 CHECK_EQ(7, value->Int32Value()); | 672 CHECK_EQ(7, value->Int32Value()); |
674 i::Heap::CollectAllGarbage(false); | 673 HEAP->CollectAllGarbage(false); |
675 CHECK_EQ(0, TestAsciiResource::dispose_count); | 674 CHECK_EQ(0, TestAsciiResource::dispose_count); |
676 } | 675 } |
677 i::CompilationCache::Clear(); | 676 i::Isolate::Current()->compilation_cache()->Clear(); |
678 i::Heap::CollectAllGarbage(false); | 677 HEAP->CollectAllGarbage(false); |
679 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 678 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
680 CHECK_EQ(0, TestAsciiResource::dispose_count); | 679 CHECK_EQ(0, TestAsciiResource::dispose_count); |
681 | 680 |
682 // Use a heap allocated external string resource allocated object. | 681 // Use a heap allocated external string resource allocated object. |
683 TestAsciiResource::dispose_count = 0; | 682 TestAsciiResource::dispose_count = 0; |
684 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 683 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
685 TestAsciiResource* res_heap = | 684 TestAsciiResource* res_heap = |
686 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 685 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); |
687 { | 686 { |
688 v8::HandleScope scope; | 687 v8::HandleScope scope; |
689 LocalContext env; | 688 LocalContext env; |
690 Local<String> source = String::NewExternal(res_heap); | 689 Local<String> source = String::NewExternal(res_heap); |
691 Local<Script> script = Script::Compile(source); | 690 Local<Script> script = Script::Compile(source); |
692 Local<Value> value = script->Run(); | 691 Local<Value> value = script->Run(); |
693 CHECK(value->IsNumber()); | 692 CHECK(value->IsNumber()); |
694 CHECK_EQ(7, value->Int32Value()); | 693 CHECK_EQ(7, value->Int32Value()); |
695 i::Heap::CollectAllGarbage(false); | 694 HEAP->CollectAllGarbage(false); |
696 CHECK_EQ(0, TestAsciiResource::dispose_count); | 695 CHECK_EQ(0, TestAsciiResource::dispose_count); |
697 } | 696 } |
698 i::CompilationCache::Clear(); | 697 i::Isolate::Current()->compilation_cache()->Clear(); |
699 i::Heap::CollectAllGarbage(false); | 698 HEAP->CollectAllGarbage(false); |
700 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 699 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
701 CHECK_EQ(1, TestAsciiResource::dispose_count); | 700 CHECK_EQ(1, TestAsciiResource::dispose_count); |
702 } | 701 } |
703 | 702 |
704 | 703 |
705 THREADED_TEST(StringConcat) { | 704 THREADED_TEST(StringConcat) { |
706 { | 705 { |
707 v8::HandleScope scope; | 706 v8::HandleScope scope; |
708 LocalContext env; | 707 LocalContext env; |
709 const char* one_byte_string_1 = "function a_times_t"; | 708 const char* one_byte_string_1 = "function a_times_t"; |
(...skipping 25 matching lines...) Expand all Loading... |
735 | 734 |
736 source = String::Concat(source, right); | 735 source = String::Concat(source, right); |
737 right = String::NewExternal( | 736 right = String::NewExternal( |
738 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); | 737 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); |
739 source = String::Concat(source, right); | 738 source = String::Concat(source, right); |
740 Local<Script> script = Script::Compile(source); | 739 Local<Script> script = Script::Compile(source); |
741 Local<Value> value = script->Run(); | 740 Local<Value> value = script->Run(); |
742 CHECK(value->IsNumber()); | 741 CHECK(value->IsNumber()); |
743 CHECK_EQ(68, value->Int32Value()); | 742 CHECK_EQ(68, value->Int32Value()); |
744 } | 743 } |
745 i::CompilationCache::Clear(); | 744 i::Isolate::Current()->compilation_cache()->Clear(); |
746 i::Heap::CollectAllGarbage(false); | 745 HEAP->CollectAllGarbage(false); |
747 i::Heap::CollectAllGarbage(false); | 746 HEAP->CollectAllGarbage(false); |
748 } | 747 } |
749 | 748 |
750 | 749 |
751 THREADED_TEST(GlobalProperties) { | 750 THREADED_TEST(GlobalProperties) { |
752 v8::HandleScope scope; | 751 v8::HandleScope scope; |
753 LocalContext env; | 752 LocalContext env; |
754 v8::Handle<v8::Object> global = env->Global(); | 753 v8::Handle<v8::Object> global = env->Global(); |
755 global->Set(v8_str("pi"), v8_num(3.1415926)); | 754 global->Set(v8_str("pi"), v8_num(3.1415926)); |
756 Local<Value> pi = global->Get(v8_str("pi")); | 755 Local<Value> pi = global->Get(v8_str("pi")); |
757 CHECK_EQ(3.1415926, pi->NumberValue()); | 756 CHECK_EQ(3.1415926, pi->NumberValue()); |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 | 1571 |
1573 char* data = new char[100]; | 1572 char* data = new char[100]; |
1574 | 1573 |
1575 void* aligned = data; | 1574 void* aligned = data; |
1576 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1575 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
1577 void* unaligned = data + 1; | 1576 void* unaligned = data + 1; |
1578 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1577 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
1579 | 1578 |
1580 // Check reading and writing aligned pointers. | 1579 // Check reading and writing aligned pointers. |
1581 obj->SetPointerInInternalField(0, aligned); | 1580 obj->SetPointerInInternalField(0, aligned); |
1582 i::Heap::CollectAllGarbage(false); | 1581 HEAP->CollectAllGarbage(false); |
1583 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1582 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
1584 | 1583 |
1585 // Check reading and writing unaligned pointers. | 1584 // Check reading and writing unaligned pointers. |
1586 obj->SetPointerInInternalField(0, unaligned); | 1585 obj->SetPointerInInternalField(0, unaligned); |
1587 i::Heap::CollectAllGarbage(false); | 1586 HEAP->CollectAllGarbage(false); |
1588 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1587 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
1589 | 1588 |
1590 delete[] data; | 1589 delete[] data; |
1591 } | 1590 } |
1592 | 1591 |
1593 | 1592 |
1594 THREADED_TEST(InternalFieldsNativePointersAndExternal) { | 1593 THREADED_TEST(InternalFieldsNativePointersAndExternal) { |
1595 v8::HandleScope scope; | 1594 v8::HandleScope scope; |
1596 LocalContext env; | 1595 LocalContext env; |
1597 | 1596 |
1598 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1597 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
1599 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); | 1598 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); |
1600 instance_templ->SetInternalFieldCount(1); | 1599 instance_templ->SetInternalFieldCount(1); |
1601 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); | 1600 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); |
1602 CHECK_EQ(1, obj->InternalFieldCount()); | 1601 CHECK_EQ(1, obj->InternalFieldCount()); |
1603 CHECK(obj->GetPointerFromInternalField(0) == NULL); | 1602 CHECK(obj->GetPointerFromInternalField(0) == NULL); |
1604 | 1603 |
1605 char* data = new char[100]; | 1604 char* data = new char[100]; |
1606 | 1605 |
1607 void* aligned = data; | 1606 void* aligned = data; |
1608 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1607 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
1609 void* unaligned = data + 1; | 1608 void* unaligned = data + 1; |
1610 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1609 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
1611 | 1610 |
1612 obj->SetPointerInInternalField(0, aligned); | 1611 obj->SetPointerInInternalField(0, aligned); |
1613 i::Heap::CollectAllGarbage(false); | 1612 HEAP->CollectAllGarbage(false); |
1614 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1613 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); |
1615 | 1614 |
1616 obj->SetPointerInInternalField(0, unaligned); | 1615 obj->SetPointerInInternalField(0, unaligned); |
1617 i::Heap::CollectAllGarbage(false); | 1616 HEAP->CollectAllGarbage(false); |
1618 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1617 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); |
1619 | 1618 |
1620 obj->SetInternalField(0, v8::External::Wrap(aligned)); | 1619 obj->SetInternalField(0, v8::External::Wrap(aligned)); |
1621 i::Heap::CollectAllGarbage(false); | 1620 HEAP->CollectAllGarbage(false); |
1622 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1621 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
1623 | 1622 |
1624 obj->SetInternalField(0, v8::External::Wrap(unaligned)); | 1623 obj->SetInternalField(0, v8::External::Wrap(unaligned)); |
1625 i::Heap::CollectAllGarbage(false); | 1624 HEAP->CollectAllGarbage(false); |
1626 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1625 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
1627 | 1626 |
1628 delete[] data; | 1627 delete[] data; |
1629 } | 1628 } |
1630 | 1629 |
1631 | 1630 |
1632 THREADED_TEST(IdentityHash) { | 1631 THREADED_TEST(IdentityHash) { |
1633 v8::HandleScope scope; | 1632 v8::HandleScope scope; |
1634 LocalContext env; | 1633 LocalContext env; |
1635 | 1634 |
1636 // Ensure that the test starts with an fresh heap to test whether the hash | 1635 // Ensure that the test starts with an fresh heap to test whether the hash |
1637 // code is based on the address. | 1636 // code is based on the address. |
1638 i::Heap::CollectAllGarbage(false); | 1637 HEAP->CollectAllGarbage(false); |
1639 Local<v8::Object> obj = v8::Object::New(); | 1638 Local<v8::Object> obj = v8::Object::New(); |
1640 int hash = obj->GetIdentityHash(); | 1639 int hash = obj->GetIdentityHash(); |
1641 int hash1 = obj->GetIdentityHash(); | 1640 int hash1 = obj->GetIdentityHash(); |
1642 CHECK_EQ(hash, hash1); | 1641 CHECK_EQ(hash, hash1); |
1643 int hash2 = v8::Object::New()->GetIdentityHash(); | 1642 int hash2 = v8::Object::New()->GetIdentityHash(); |
1644 // Since the identity hash is essentially a random number two consecutive | 1643 // Since the identity hash is essentially a random number two consecutive |
1645 // objects should not be assigned the same hash code. If the test below fails | 1644 // objects should not be assigned the same hash code. If the test below fails |
1646 // the random number generator should be evaluated. | 1645 // the random number generator should be evaluated. |
1647 CHECK_NE(hash, hash2); | 1646 CHECK_NE(hash, hash2); |
1648 i::Heap::CollectAllGarbage(false); | 1647 HEAP->CollectAllGarbage(false); |
1649 int hash3 = v8::Object::New()->GetIdentityHash(); | 1648 int hash3 = v8::Object::New()->GetIdentityHash(); |
1650 // Make sure that the identity hash is not based on the initial address of | 1649 // Make sure that the identity hash is not based on the initial address of |
1651 // the object alone. If the test below fails the random number generator | 1650 // the object alone. If the test below fails the random number generator |
1652 // should be evaluated. | 1651 // should be evaluated. |
1653 CHECK_NE(hash, hash3); | 1652 CHECK_NE(hash, hash3); |
1654 int hash4 = obj->GetIdentityHash(); | 1653 int hash4 = obj->GetIdentityHash(); |
1655 CHECK_EQ(hash, hash4); | 1654 CHECK_EQ(hash, hash4); |
1656 | 1655 |
1657 // Check identity hashes behaviour in the presence of JS accessors. | 1656 // Check identity hashes behaviour in the presence of JS accessors. |
1658 // Put a getter for 'v8::IdentityHash' on the Object's prototype: | 1657 // Put a getter for 'v8::IdentityHash' on the Object's prototype: |
(...skipping 16 matching lines...) Expand all Loading... |
1675 | 1674 |
1676 THREADED_TEST(HiddenProperties) { | 1675 THREADED_TEST(HiddenProperties) { |
1677 v8::HandleScope scope; | 1676 v8::HandleScope scope; |
1678 LocalContext env; | 1677 LocalContext env; |
1679 | 1678 |
1680 v8::Local<v8::Object> obj = v8::Object::New(); | 1679 v8::Local<v8::Object> obj = v8::Object::New(); |
1681 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 1680 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
1682 v8::Local<v8::String> empty = v8_str(""); | 1681 v8::Local<v8::String> empty = v8_str(""); |
1683 v8::Local<v8::String> prop_name = v8_str("prop_name"); | 1682 v8::Local<v8::String> prop_name = v8_str("prop_name"); |
1684 | 1683 |
1685 i::Heap::CollectAllGarbage(false); | 1684 HEAP->CollectAllGarbage(false); |
1686 | 1685 |
1687 // Make sure delete of a non-existent hidden value works | 1686 // Make sure delete of a non-existent hidden value works |
1688 CHECK(obj->DeleteHiddenValue(key)); | 1687 CHECK(obj->DeleteHiddenValue(key)); |
1689 | 1688 |
1690 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); | 1689 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); |
1691 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); | 1690 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); |
1692 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); | 1691 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); |
1693 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1692 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1694 | 1693 |
1695 i::Heap::CollectAllGarbage(false); | 1694 HEAP->CollectAllGarbage(false); |
1696 | 1695 |
1697 // Make sure we do not find the hidden property. | 1696 // Make sure we do not find the hidden property. |
1698 CHECK(!obj->Has(empty)); | 1697 CHECK(!obj->Has(empty)); |
1699 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1698 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1700 CHECK(obj->Get(empty)->IsUndefined()); | 1699 CHECK(obj->Get(empty)->IsUndefined()); |
1701 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1700 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1702 CHECK(obj->Set(empty, v8::Integer::New(2003))); | 1701 CHECK(obj->Set(empty, v8::Integer::New(2003))); |
1703 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1702 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1704 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); | 1703 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); |
1705 | 1704 |
1706 i::Heap::CollectAllGarbage(false); | 1705 HEAP->CollectAllGarbage(false); |
1707 | 1706 |
1708 // Add another property and delete it afterwards to force the object in | 1707 // Add another property and delete it afterwards to force the object in |
1709 // slow case. | 1708 // slow case. |
1710 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); | 1709 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); |
1711 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1710 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1712 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); | 1711 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); |
1713 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1712 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1714 CHECK(obj->Delete(prop_name)); | 1713 CHECK(obj->Delete(prop_name)); |
1715 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1714 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1716 | 1715 |
1717 i::Heap::CollectAllGarbage(false); | 1716 HEAP->CollectAllGarbage(false); |
1718 | 1717 |
1719 CHECK(obj->DeleteHiddenValue(key)); | 1718 CHECK(obj->DeleteHiddenValue(key)); |
1720 CHECK(obj->GetHiddenValue(key).IsEmpty()); | 1719 CHECK(obj->GetHiddenValue(key).IsEmpty()); |
1721 } | 1720 } |
1722 | 1721 |
1723 | 1722 |
1724 static bool interceptor_for_hidden_properties_called; | 1723 static bool interceptor_for_hidden_properties_called; |
1725 static v8::Handle<Value> InterceptorForHiddenProperties( | 1724 static v8::Handle<Value> InterceptorForHiddenProperties( |
1726 Local<String> name, const AccessorInfo& info) { | 1725 Local<String> name, const AccessorInfo& info) { |
1727 interceptor_for_hidden_properties_called = true; | 1726 interceptor_for_hidden_properties_called = true; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1839 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
1841 Persistent<Value> g1_children[] = { g1c1 }; | 1840 Persistent<Value> g1_children[] = { g1c1 }; |
1842 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1841 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
1843 Persistent<Value> g2_children[] = { g2c1 }; | 1842 Persistent<Value> g2_children[] = { g2c1 }; |
1844 V8::AddObjectGroup(g1_objects, 2); | 1843 V8::AddObjectGroup(g1_objects, 2); |
1845 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1844 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1846 V8::AddObjectGroup(g2_objects, 2); | 1845 V8::AddObjectGroup(g2_objects, 2); |
1847 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1846 V8::AddImplicitReferences(g2s2, g2_children, 1); |
1848 } | 1847 } |
1849 // Do a full GC | 1848 // Do a full GC |
1850 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1849 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
1851 | 1850 |
1852 // All object should be alive. | 1851 // All object should be alive. |
1853 CHECK_EQ(0, NumberOfWeakCalls); | 1852 CHECK_EQ(0, NumberOfWeakCalls); |
1854 | 1853 |
1855 // Weaken the root. | 1854 // Weaken the root. |
1856 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1855 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
1857 // But make children strong roots---all the objects (except for children) | 1856 // But make children strong roots---all the objects (except for children) |
1858 // should be collectable now. | 1857 // should be collectable now. |
1859 g1c1.ClearWeak(); | 1858 g1c1.ClearWeak(); |
1860 g2c1.ClearWeak(); | 1859 g2c1.ClearWeak(); |
1861 | 1860 |
1862 // Groups are deleted, rebuild groups. | 1861 // Groups are deleted, rebuild groups. |
1863 { | 1862 { |
1864 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1863 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
1865 Persistent<Value> g1_children[] = { g1c1 }; | 1864 Persistent<Value> g1_children[] = { g1c1 }; |
1866 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1865 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
1867 Persistent<Value> g2_children[] = { g2c1 }; | 1866 Persistent<Value> g2_children[] = { g2c1 }; |
1868 V8::AddObjectGroup(g1_objects, 2); | 1867 V8::AddObjectGroup(g1_objects, 2); |
1869 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1868 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1870 V8::AddObjectGroup(g2_objects, 2); | 1869 V8::AddObjectGroup(g2_objects, 2); |
1871 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1870 V8::AddImplicitReferences(g2s2, g2_children, 1); |
1872 } | 1871 } |
1873 | 1872 |
1874 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1873 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
1875 | 1874 |
1876 // All objects should be gone. 5 global handles in total. | 1875 // All objects should be gone. 5 global handles in total. |
1877 CHECK_EQ(5, NumberOfWeakCalls); | 1876 CHECK_EQ(5, NumberOfWeakCalls); |
1878 | 1877 |
1879 // And now make children weak again and collect them. | 1878 // And now make children weak again and collect them. |
1880 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1879 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
1881 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1880 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
1882 | 1881 |
1883 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1882 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
1884 CHECK_EQ(7, NumberOfWeakCalls); | 1883 CHECK_EQ(7, NumberOfWeakCalls); |
1885 } | 1884 } |
1886 | 1885 |
1887 | 1886 |
1888 THREADED_TEST(ApiObjectGroupsCycle) { | 1887 THREADED_TEST(ApiObjectGroupsCycle) { |
1889 HandleScope scope; | 1888 HandleScope scope; |
1890 LocalContext env; | 1889 LocalContext env; |
1891 | 1890 |
1892 NumberOfWeakCalls = 0; | 1891 NumberOfWeakCalls = 0; |
1893 | 1892 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 1928 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
1930 Persistent<Value> g3_children[] = { g1s1 }; | 1929 Persistent<Value> g3_children[] = { g1s1 }; |
1931 V8::AddObjectGroup(g1_objects, 2); | 1930 V8::AddObjectGroup(g1_objects, 2); |
1932 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1931 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1933 V8::AddObjectGroup(g2_objects, 2); | 1932 V8::AddObjectGroup(g2_objects, 2); |
1934 V8::AddImplicitReferences(g2s1, g2_children, 1); | 1933 V8::AddImplicitReferences(g2s1, g2_children, 1); |
1935 V8::AddObjectGroup(g3_objects, 2); | 1934 V8::AddObjectGroup(g3_objects, 2); |
1936 V8::AddImplicitReferences(g3s1, g3_children, 1); | 1935 V8::AddImplicitReferences(g3s1, g3_children, 1); |
1937 } | 1936 } |
1938 // Do a full GC | 1937 // Do a full GC |
1939 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1938 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
1940 | 1939 |
1941 // All object should be alive. | 1940 // All object should be alive. |
1942 CHECK_EQ(0, NumberOfWeakCalls); | 1941 CHECK_EQ(0, NumberOfWeakCalls); |
1943 | 1942 |
1944 // Weaken the root. | 1943 // Weaken the root. |
1945 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1944 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
1946 | 1945 |
1947 // Groups are deleted, rebuild groups. | 1946 // Groups are deleted, rebuild groups. |
1948 { | 1947 { |
1949 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1948 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
1950 Persistent<Value> g1_children[] = { g2s1 }; | 1949 Persistent<Value> g1_children[] = { g2s1 }; |
1951 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1950 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
1952 Persistent<Value> g2_children[] = { g3s1 }; | 1951 Persistent<Value> g2_children[] = { g3s1 }; |
1953 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 1952 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
1954 Persistent<Value> g3_children[] = { g1s1 }; | 1953 Persistent<Value> g3_children[] = { g1s1 }; |
1955 V8::AddObjectGroup(g1_objects, 2); | 1954 V8::AddObjectGroup(g1_objects, 2); |
1956 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1955 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1957 V8::AddObjectGroup(g2_objects, 2); | 1956 V8::AddObjectGroup(g2_objects, 2); |
1958 V8::AddImplicitReferences(g2s1, g2_children, 1); | 1957 V8::AddImplicitReferences(g2s1, g2_children, 1); |
1959 V8::AddObjectGroup(g3_objects, 2); | 1958 V8::AddObjectGroup(g3_objects, 2); |
1960 V8::AddImplicitReferences(g3s1, g3_children, 1); | 1959 V8::AddImplicitReferences(g3s1, g3_children, 1); |
1961 } | 1960 } |
1962 | 1961 |
1963 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1962 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
1964 | 1963 |
1965 // All objects should be gone. 7 global handles in total. | 1964 // All objects should be gone. 7 global handles in total. |
1966 CHECK_EQ(7, NumberOfWeakCalls); | 1965 CHECK_EQ(7, NumberOfWeakCalls); |
1967 } | 1966 } |
1968 | 1967 |
1969 | 1968 |
1970 THREADED_TEST(ScriptException) { | 1969 THREADED_TEST(ScriptException) { |
1971 v8::HandleScope scope; | 1970 v8::HandleScope scope; |
1972 LocalContext env; | 1971 LocalContext env; |
1973 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 1972 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2257 "}"); | 2256 "}"); |
2258 // Check for out of memory state. | 2257 // Check for out of memory state. |
2259 CHECK(result.IsEmpty()); | 2258 CHECK(result.IsEmpty()); |
2260 CHECK(context->HasOutOfMemoryException()); | 2259 CHECK(context->HasOutOfMemoryException()); |
2261 } | 2260 } |
2262 | 2261 |
2263 | 2262 |
2264 TEST(HugeConsStringOutOfMemory) { | 2263 TEST(HugeConsStringOutOfMemory) { |
2265 // It's not possible to read a snapshot into a heap with different dimensions. | 2264 // It's not possible to read a snapshot into a heap with different dimensions. |
2266 if (i::Snapshot::IsEnabled()) return; | 2265 if (i::Snapshot::IsEnabled()) return; |
2267 v8::HandleScope scope; | |
2268 LocalContext context; | |
2269 // Set heap limits. | 2266 // Set heap limits. |
2270 static const int K = 1024; | 2267 static const int K = 1024; |
2271 v8::ResourceConstraints constraints; | 2268 v8::ResourceConstraints constraints; |
2272 constraints.set_max_young_space_size(256 * K); | 2269 constraints.set_max_young_space_size(256 * K); |
2273 constraints.set_max_old_space_size(2 * K * K); | 2270 constraints.set_max_old_space_size(2 * K * K); |
2274 v8::SetResourceConstraints(&constraints); | 2271 v8::SetResourceConstraints(&constraints); |
2275 | 2272 |
2276 // Execute a script that causes out of memory. | 2273 // Execute a script that causes out of memory. |
2277 v8::V8::IgnoreOutOfMemoryException(); | 2274 v8::V8::IgnoreOutOfMemoryException(); |
2278 | 2275 |
| 2276 v8::HandleScope scope; |
| 2277 LocalContext context; |
| 2278 |
2279 // Build huge string. This should fail with out of memory exception. | 2279 // Build huge string. This should fail with out of memory exception. |
2280 Local<Value> result = CompileRun( | 2280 Local<Value> result = CompileRun( |
2281 "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();" | 2281 "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();" |
2282 "for (var i = 0; i < 22; i++) { str = str + str; }"); | 2282 "for (var i = 0; i < 22; i++) { str = str + str; }"); |
2283 | 2283 |
2284 // Check for out of memory state. | 2284 // Check for out of memory state. |
2285 CHECK(result.IsEmpty()); | 2285 CHECK(result.IsEmpty()); |
2286 CHECK(context->HasOutOfMemoryException()); | 2286 CHECK(context->HasOutOfMemoryException()); |
2287 } | 2287 } |
2288 | 2288 |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2688 args[1], | 2688 args[1], |
2689 args[2], | 2689 args[2], |
2690 args[3] }; | 2690 args[3] }; |
2691 if (count % cInterval == 0) { | 2691 if (count % cInterval == 0) { |
2692 v8::TryCatch try_catch; | 2692 v8::TryCatch try_catch; |
2693 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); | 2693 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); |
2694 int expected = args[3]->Int32Value(); | 2694 int expected = args[3]->Int32Value(); |
2695 if (try_catch.HasCaught()) { | 2695 if (try_catch.HasCaught()) { |
2696 CHECK_EQ(expected, count); | 2696 CHECK_EQ(expected, count); |
2697 CHECK(result.IsEmpty()); | 2697 CHECK(result.IsEmpty()); |
2698 CHECK(!i::Top::has_scheduled_exception()); | 2698 CHECK(!i::Isolate::Current()->has_scheduled_exception()); |
2699 } else { | 2699 } else { |
2700 CHECK_NE(expected, count); | 2700 CHECK_NE(expected, count); |
2701 } | 2701 } |
2702 return result; | 2702 return result; |
2703 } else { | 2703 } else { |
2704 return fun.As<Function>()->Call(global, 4, argv); | 2704 return fun.As<Function>()->Call(global, 4, argv); |
2705 } | 2705 } |
2706 } | 2706 } |
2707 } | 2707 } |
2708 | 2708 |
(...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4380 | 4380 |
4381 static bool in_scavenge = false; | 4381 static bool in_scavenge = false; |
4382 static int last = -1; | 4382 static int last = -1; |
4383 | 4383 |
4384 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { | 4384 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
4385 CHECK_EQ(-1, last); | 4385 CHECK_EQ(-1, last); |
4386 last = 0; | 4386 last = 0; |
4387 obj.Dispose(); | 4387 obj.Dispose(); |
4388 obj.Clear(); | 4388 obj.Clear(); |
4389 in_scavenge = true; | 4389 in_scavenge = true; |
4390 i::Heap::PerformScavenge(); | 4390 HEAP->PerformScavenge(); |
4391 in_scavenge = false; | 4391 in_scavenge = false; |
4392 *(reinterpret_cast<bool*>(data)) = true; | 4392 *(reinterpret_cast<bool*>(data)) = true; |
4393 } | 4393 } |
4394 | 4394 |
4395 static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, | 4395 static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, |
4396 void* data) { | 4396 void* data) { |
4397 CHECK_EQ(0, last); | 4397 CHECK_EQ(0, last); |
4398 last = 1; | 4398 last = 1; |
4399 *(reinterpret_cast<bool*>(data)) = in_scavenge; | 4399 *(reinterpret_cast<bool*>(data)) = in_scavenge; |
4400 obj.Dispose(); | 4400 obj.Dispose(); |
(...skipping 16 matching lines...) Expand all Loading... |
4417 object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); | 4417 object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); |
4418 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); | 4418 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); |
4419 } | 4419 } |
4420 | 4420 |
4421 bool object_a_disposed = false; | 4421 bool object_a_disposed = false; |
4422 object_a.MakeWeak(&object_a_disposed, &ForceScavenge); | 4422 object_a.MakeWeak(&object_a_disposed, &ForceScavenge); |
4423 bool released_in_scavenge = false; | 4423 bool released_in_scavenge = false; |
4424 object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); | 4424 object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); |
4425 | 4425 |
4426 while (!object_a_disposed) { | 4426 while (!object_a_disposed) { |
4427 i::Heap::CollectAllGarbage(false); | 4427 HEAP->CollectAllGarbage(false); |
4428 } | 4428 } |
4429 CHECK(!released_in_scavenge); | 4429 CHECK(!released_in_scavenge); |
4430 } | 4430 } |
4431 | 4431 |
4432 | 4432 |
4433 v8::Handle<Function> args_fun; | 4433 v8::Handle<Function> args_fun; |
4434 | 4434 |
4435 | 4435 |
4436 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { | 4436 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { |
4437 ApiTestFuzzer::Fuzz(); | 4437 ApiTestFuzzer::Fuzz(); |
4438 CHECK_EQ(args_fun, args.Callee()); | 4438 CHECK_EQ(args_fun, args.Callee()); |
4439 CHECK_EQ(3, args.Length()); | 4439 CHECK_EQ(3, args.Length()); |
4440 CHECK_EQ(v8::Integer::New(1), args[0]); | 4440 CHECK_EQ(v8::Integer::New(1), args[0]); |
4441 CHECK_EQ(v8::Integer::New(2), args[1]); | 4441 CHECK_EQ(v8::Integer::New(2), args[1]); |
4442 CHECK_EQ(v8::Integer::New(3), args[2]); | 4442 CHECK_EQ(v8::Integer::New(3), args[2]); |
4443 CHECK_EQ(v8::Undefined(), args[3]); | 4443 CHECK_EQ(v8::Undefined(), args[3]); |
4444 v8::HandleScope scope; | 4444 v8::HandleScope scope; |
4445 i::Heap::CollectAllGarbage(false); | 4445 HEAP->CollectAllGarbage(false); |
4446 return v8::Undefined(); | 4446 return v8::Undefined(); |
4447 } | 4447 } |
4448 | 4448 |
4449 | 4449 |
4450 THREADED_TEST(Arguments) { | 4450 THREADED_TEST(Arguments) { |
4451 v8::HandleScope scope; | 4451 v8::HandleScope scope; |
4452 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); | 4452 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); |
4453 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); | 4453 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); |
4454 LocalContext context(NULL, global); | 4454 LocalContext context(NULL, global); |
4455 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); | 4455 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); |
(...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6676 | 6676 |
6677 Local<v8::Object> o0 = t->GetFunction()->NewInstance(); | 6677 Local<v8::Object> o0 = t->GetFunction()->NewInstance(); |
6678 Local<v8::Object> o1 = t->GetFunction()->NewInstance(); | 6678 Local<v8::Object> o1 = t->GetFunction()->NewInstance(); |
6679 | 6679 |
6680 CHECK(o0->SetPrototype(o1)); | 6680 CHECK(o0->SetPrototype(o1)); |
6681 // If setting the prototype leads to the cycle, SetPrototype should | 6681 // If setting the prototype leads to the cycle, SetPrototype should |
6682 // return false and keep VM in sane state. | 6682 // return false and keep VM in sane state. |
6683 v8::TryCatch try_catch; | 6683 v8::TryCatch try_catch; |
6684 CHECK(!o1->SetPrototype(o0)); | 6684 CHECK(!o1->SetPrototype(o0)); |
6685 CHECK(!try_catch.HasCaught()); | 6685 CHECK(!try_catch.HasCaught()); |
6686 ASSERT(!i::Top::has_pending_exception()); | 6686 ASSERT(!i::Isolate::Current()->has_pending_exception()); |
6687 | 6687 |
6688 CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); | 6688 CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); |
6689 } | 6689 } |
6690 | 6690 |
6691 | 6691 |
6692 THREADED_TEST(GetterSetterExceptions) { | 6692 THREADED_TEST(GetterSetterExceptions) { |
6693 v8::HandleScope handle_scope; | 6693 v8::HandleScope handle_scope; |
6694 LocalContext context; | 6694 LocalContext context; |
6695 CompileRun( | 6695 CompileRun( |
6696 "function Foo() { };" | 6696 "function Foo() { };" |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7058 "var p = new constructor();" | 7058 "var p = new constructor();" |
7059 "p.hasOwnProperty('ostehaps');"); | 7059 "p.hasOwnProperty('ostehaps');"); |
7060 CHECK_EQ(false, value->BooleanValue()); | 7060 CHECK_EQ(false, value->BooleanValue()); |
7061 } | 7061 } |
7062 | 7062 |
7063 | 7063 |
7064 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( | 7064 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( |
7065 Local<String> name, | 7065 Local<String> name, |
7066 const AccessorInfo& info) { | 7066 const AccessorInfo& info) { |
7067 ApiTestFuzzer::Fuzz(); | 7067 ApiTestFuzzer::Fuzz(); |
7068 i::Heap::CollectAllGarbage(false); | 7068 HEAP->CollectAllGarbage(false); |
7069 return v8::Handle<Value>(); | 7069 return v8::Handle<Value>(); |
7070 } | 7070 } |
7071 | 7071 |
7072 | 7072 |
7073 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { | 7073 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { |
7074 v8::HandleScope scope; | 7074 v8::HandleScope scope; |
7075 LocalContext context; | 7075 LocalContext context; |
7076 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 7076 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
7077 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | 7077 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
7078 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); | 7078 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7788 "};"); | 7788 "};"); |
7789 CHECK_EQ(239 * 10, value->Int32Value()); | 7789 CHECK_EQ(239 * 10, value->Int32Value()); |
7790 } | 7790 } |
7791 | 7791 |
7792 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, | 7792 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
7793 const AccessorInfo& info) { | 7793 const AccessorInfo& info) { |
7794 ApiTestFuzzer::Fuzz(); | 7794 ApiTestFuzzer::Fuzz(); |
7795 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); | 7795 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
7796 ++(*call_count); | 7796 ++(*call_count); |
7797 if ((*call_count) % 20 == 0) { | 7797 if ((*call_count) % 20 == 0) { |
7798 i::Heap::CollectAllGarbage(true); | 7798 HEAP->CollectAllGarbage(true); |
7799 } | 7799 } |
7800 return v8::Handle<Value>(); | 7800 return v8::Handle<Value>(); |
7801 } | 7801 } |
7802 | 7802 |
7803 static v8::Handle<Value> FastApiCallback_TrivialSignature( | 7803 static v8::Handle<Value> FastApiCallback_TrivialSignature( |
7804 const v8::Arguments& args) { | 7804 const v8::Arguments& args) { |
7805 ApiTestFuzzer::Fuzz(); | 7805 ApiTestFuzzer::Fuzz(); |
7806 CHECK_EQ(args.This(), args.Holder()); | 7806 CHECK_EQ(args.This(), args.Holder()); |
7807 CHECK(args.Data()->Equals(v8_str("method_data"))); | 7807 CHECK(args.Data()->Equals(v8_str("method_data"))); |
7808 return v8::Integer::New(args[0]->Int32Value() + 1); | 7808 return v8::Integer::New(args[0]->Int32Value() + 1); |
(...skipping 17 matching lines...) Expand all Loading... |
7826 "for (var i = 0; i < 1000; i++) {" | 7826 "for (var i = 0; i < 1000; i++) {" |
7827 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" | 7827 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" |
7828 "}" | 7828 "}" |
7829 "garbage = undefined;"); | 7829 "garbage = undefined;"); |
7830 } | 7830 } |
7831 | 7831 |
7832 | 7832 |
7833 v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) { | 7833 v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) { |
7834 static int count = 0; | 7834 static int count = 0; |
7835 if (count++ % 3 == 0) { | 7835 if (count++ % 3 == 0) { |
7836 i::Heap::CollectAllGarbage(true); // This should move the stub | 7836 HEAP-> CollectAllGarbage(true); // This should move the stub |
7837 GenerateSomeGarbage(); // This should ensure the old stub memory is flushed | 7837 GenerateSomeGarbage(); // This should ensure the old stub memory is flushed |
7838 } | 7838 } |
7839 return v8::Handle<v8::Value>(); | 7839 return v8::Handle<v8::Value>(); |
7840 } | 7840 } |
7841 | 7841 |
7842 | 7842 |
7843 THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { | 7843 THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { |
7844 v8::HandleScope scope; | 7844 v8::HandleScope scope; |
7845 LocalContext context; | 7845 LocalContext context; |
7846 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); | 7846 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7881 " }" | 7881 " }" |
7882 "}" | 7882 "}" |
7883 "f(); result;"); | 7883 "f(); result;"); |
7884 CHECK_EQ(v8_str("ggggg"), result); | 7884 CHECK_EQ(v8_str("ggggg"), result); |
7885 } | 7885 } |
7886 | 7886 |
7887 | 7887 |
7888 v8::Handle<v8::Value> DirectGetterCallback(Local<String> name, | 7888 v8::Handle<v8::Value> DirectGetterCallback(Local<String> name, |
7889 const v8::AccessorInfo& info) { | 7889 const v8::AccessorInfo& info) { |
7890 if (++p_getter_count % 3 == 0) { | 7890 if (++p_getter_count % 3 == 0) { |
7891 i::Heap::CollectAllGarbage(true); | 7891 HEAP->CollectAllGarbage(true); |
7892 GenerateSomeGarbage(); | 7892 GenerateSomeGarbage(); |
7893 } | 7893 } |
7894 return v8::Handle<v8::Value>(); | 7894 return v8::Handle<v8::Value>(); |
7895 } | 7895 } |
7896 | 7896 |
7897 | 7897 |
7898 THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { | 7898 THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { |
7899 v8::HandleScope scope; | 7899 v8::HandleScope scope; |
7900 LocalContext context; | 7900 LocalContext context; |
7901 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); | 7901 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8796 | 8796 |
8797 void ApiTestFuzzer::Setup(PartOfTest part) { | 8797 void ApiTestFuzzer::Setup(PartOfTest part) { |
8798 linear_congruential_generator = i::FLAG_testing_prng_seed; | 8798 linear_congruential_generator = i::FLAG_testing_prng_seed; |
8799 fuzzing_ = true; | 8799 fuzzing_ = true; |
8800 int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1); | 8800 int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1); |
8801 int end = (part == FIRST_PART) | 8801 int end = (part == FIRST_PART) |
8802 ? (RegisterThreadedTest::count() >> 1) | 8802 ? (RegisterThreadedTest::count() >> 1) |
8803 : RegisterThreadedTest::count(); | 8803 : RegisterThreadedTest::count(); |
8804 active_tests_ = tests_being_run_ = end - start; | 8804 active_tests_ = tests_being_run_ = end - start; |
8805 for (int i = 0; i < tests_being_run_; i++) { | 8805 for (int i = 0; i < tests_being_run_; i++) { |
8806 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(i + start); | 8806 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer( |
| 8807 i::Isolate::Current(), i + start); |
8807 } | 8808 } |
8808 for (int i = 0; i < active_tests_; i++) { | 8809 for (int i = 0; i < active_tests_; i++) { |
8809 RegisterThreadedTest::nth(i)->fuzzer_->Start(); | 8810 RegisterThreadedTest::nth(i)->fuzzer_->Start(); |
8810 } | 8811 } |
8811 } | 8812 } |
8812 | 8813 |
8813 | 8814 |
8814 static void CallTestNumber(int test_number) { | 8815 static void CallTestNumber(int test_number) { |
8815 (RegisterThreadedTest::nth(test_number)->callback())(); | 8816 (RegisterThreadedTest::nth(test_number)->callback())(); |
8816 } | 8817 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9018 return count; | 9019 return count; |
9019 } | 9020 } |
9020 | 9021 |
9021 | 9022 |
9022 static void CheckSurvivingGlobalObjectsCount(int expected) { | 9023 static void CheckSurvivingGlobalObjectsCount(int expected) { |
9023 // We need to collect all garbage twice to be sure that everything | 9024 // We need to collect all garbage twice to be sure that everything |
9024 // has been collected. This is because inline caches are cleared in | 9025 // has been collected. This is because inline caches are cleared in |
9025 // the first garbage collection but some of the maps have already | 9026 // the first garbage collection but some of the maps have already |
9026 // been marked at that point. Therefore some of the maps are not | 9027 // been marked at that point. Therefore some of the maps are not |
9027 // collected until the second garbage collection. | 9028 // collected until the second garbage collection. |
9028 i::Heap::CollectAllGarbage(false); | 9029 HEAP->CollectAllGarbage(false); |
9029 i::Heap::CollectAllGarbage(false); | 9030 HEAP->CollectAllGarbage(false); |
9030 int count = GetGlobalObjectsCount(); | 9031 int count = GetGlobalObjectsCount(); |
9031 #ifdef DEBUG | 9032 #ifdef DEBUG |
9032 if (count != expected) i::Heap::TracePathToGlobal(); | 9033 if (count != expected) HEAP->TracePathToGlobal(); |
9033 #endif | 9034 #endif |
9034 CHECK_EQ(expected, count); | 9035 CHECK_EQ(expected, count); |
9035 } | 9036 } |
9036 | 9037 |
9037 | 9038 |
9038 TEST(DontLeakGlobalObjects) { | 9039 TEST(DontLeakGlobalObjects) { |
9039 // Regression test for issues 1139850 and 1174891. | 9040 // Regression test for issues 1139850 and 1174891. |
9040 | 9041 |
9041 v8::V8::Initialize(); | 9042 v8::V8::Initialize(); |
9042 | 9043 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9088 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9089 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9089 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9090 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9090 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9091 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9091 } | 9092 } |
9092 // Note: order is implementation dependent alas: currently | 9093 // Note: order is implementation dependent alas: currently |
9093 // global handle nodes are processed by PostGarbageCollectionProcessing | 9094 // global handle nodes are processed by PostGarbageCollectionProcessing |
9094 // in reverse allocation order, so if second allocated handle is deleted, | 9095 // in reverse allocation order, so if second allocated handle is deleted, |
9095 // weak callback of the first handle would be able to 'reallocate' it. | 9096 // weak callback of the first handle would be able to 'reallocate' it. |
9096 handle1.MakeWeak(NULL, NewPersistentHandleCallback); | 9097 handle1.MakeWeak(NULL, NewPersistentHandleCallback); |
9097 handle2.Dispose(); | 9098 handle2.Dispose(); |
9098 i::Heap::CollectAllGarbage(false); | 9099 HEAP->CollectAllGarbage(false); |
9099 } | 9100 } |
9100 | 9101 |
9101 | 9102 |
9102 v8::Persistent<v8::Object> to_be_disposed; | 9103 v8::Persistent<v8::Object> to_be_disposed; |
9103 | 9104 |
9104 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { | 9105 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { |
9105 to_be_disposed.Dispose(); | 9106 to_be_disposed.Dispose(); |
9106 i::Heap::CollectAllGarbage(false); | 9107 HEAP->CollectAllGarbage(false); |
9107 handle.Dispose(); | 9108 handle.Dispose(); |
9108 } | 9109 } |
9109 | 9110 |
9110 | 9111 |
9111 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 9112 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
9112 LocalContext context; | 9113 LocalContext context; |
9113 | 9114 |
9114 v8::Persistent<v8::Object> handle1, handle2; | 9115 v8::Persistent<v8::Object> handle1, handle2; |
9115 { | 9116 { |
9116 v8::HandleScope scope; | 9117 v8::HandleScope scope; |
9117 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9118 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9118 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9119 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9119 } | 9120 } |
9120 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); | 9121 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); |
9121 to_be_disposed = handle2; | 9122 to_be_disposed = handle2; |
9122 i::Heap::CollectAllGarbage(false); | 9123 HEAP->CollectAllGarbage(false); |
9123 } | 9124 } |
9124 | 9125 |
9125 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { | 9126 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { |
9126 handle.Dispose(); | 9127 handle.Dispose(); |
9127 } | 9128 } |
9128 | 9129 |
9129 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { | 9130 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { |
9130 v8::HandleScope scope; | 9131 v8::HandleScope scope; |
9131 v8::Persistent<v8::Object>::New(v8::Object::New()); | 9132 v8::Persistent<v8::Object>::New(v8::Object::New()); |
9132 handle.Dispose(); | 9133 handle.Dispose(); |
9133 } | 9134 } |
9134 | 9135 |
9135 | 9136 |
9136 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 9137 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
9137 LocalContext context; | 9138 LocalContext context; |
9138 | 9139 |
9139 v8::Persistent<v8::Object> handle1, handle2, handle3; | 9140 v8::Persistent<v8::Object> handle1, handle2, handle3; |
9140 { | 9141 { |
9141 v8::HandleScope scope; | 9142 v8::HandleScope scope; |
9142 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9143 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9143 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9144 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9144 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9145 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
9145 } | 9146 } |
9146 handle2.MakeWeak(NULL, DisposingCallback); | 9147 handle2.MakeWeak(NULL, DisposingCallback); |
9147 handle3.MakeWeak(NULL, HandleCreatingCallback); | 9148 handle3.MakeWeak(NULL, HandleCreatingCallback); |
9148 i::Heap::CollectAllGarbage(false); | 9149 HEAP->CollectAllGarbage(false); |
9149 } | 9150 } |
9150 | 9151 |
9151 | 9152 |
9152 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 9153 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
9153 v8::V8::Initialize(); | 9154 v8::V8::Initialize(); |
9154 | 9155 |
9155 const int nof = 2; | 9156 const int nof = 2; |
9156 const char* sources[nof] = { | 9157 const char* sources[nof] = { |
9157 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 9158 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
9158 "Object()" | 9159 "Object()" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9384 const char* elmv1[] = {"a", "b"}; | 9385 const char* elmv1[] = {"a", "b"}; |
9385 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); | 9386 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); |
9386 int elmc2 = 3; | 9387 int elmc2 = 3; |
9387 const char* elmv2[] = {"0", "1", "2"}; | 9388 const char* elmv2[] = {"0", "1", "2"}; |
9388 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 9389 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
9389 int elmc3 = 4; | 9390 int elmc3 = 4; |
9390 const char* elmv3[] = {"w", "z", "x", "y"}; | 9391 const char* elmv3[] = {"w", "z", "x", "y"}; |
9391 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); | 9392 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); |
9392 } | 9393 } |
9393 | 9394 |
| 9395 THREADED_TEST(PropertyEnumeration2) { |
| 9396 v8::HandleScope scope; |
| 9397 LocalContext context; |
| 9398 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( |
| 9399 "var result = [];" |
| 9400 "result[0] = {};" |
| 9401 "result[1] = {a: 1, b: 2};" |
| 9402 "result[2] = [1, 2, 3];" |
| 9403 "var proto = {x: 1, y: 2, z: 3};" |
| 9404 "var x = { __proto__: proto, w: 0, z: 1 };" |
| 9405 "result[3] = x;" |
| 9406 "result;"))->Run(); |
| 9407 v8::Handle<v8::Array> elms = obj.As<v8::Array>(); |
| 9408 CHECK_EQ(4, elms->Length()); |
| 9409 int elmc0 = 0; |
| 9410 const char** elmv0 = NULL; |
| 9411 CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); |
| 9412 |
| 9413 v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0)); |
| 9414 v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); |
| 9415 CHECK_EQ(0, props->Length()); |
| 9416 for (uint32_t i = 0; i < props->Length(); i++) { |
| 9417 printf("p[%d]\n", i); |
| 9418 } |
| 9419 } |
9394 | 9420 |
9395 static bool NamedSetAccessBlocker(Local<v8::Object> obj, | 9421 static bool NamedSetAccessBlocker(Local<v8::Object> obj, |
9396 Local<Value> name, | 9422 Local<Value> name, |
9397 v8::AccessType type, | 9423 v8::AccessType type, |
9398 Local<Value> data) { | 9424 Local<Value> data) { |
9399 return type != v8::ACCESS_SET; | 9425 return type != v8::ACCESS_SET; |
9400 } | 9426 } |
9401 | 9427 |
9402 | 9428 |
9403 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, | 9429 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9876 class RegExpInterruptTest { | 9902 class RegExpInterruptTest { |
9877 public: | 9903 public: |
9878 RegExpInterruptTest() : block_(NULL) {} | 9904 RegExpInterruptTest() : block_(NULL) {} |
9879 ~RegExpInterruptTest() { delete block_; } | 9905 ~RegExpInterruptTest() { delete block_; } |
9880 void RunTest() { | 9906 void RunTest() { |
9881 block_ = i::OS::CreateSemaphore(0); | 9907 block_ = i::OS::CreateSemaphore(0); |
9882 gc_count_ = 0; | 9908 gc_count_ = 0; |
9883 gc_during_regexp_ = 0; | 9909 gc_during_regexp_ = 0; |
9884 regexp_success_ = false; | 9910 regexp_success_ = false; |
9885 gc_success_ = false; | 9911 gc_success_ = false; |
9886 GCThread gc_thread(this); | 9912 GCThread gc_thread(i::Isolate::Current(), this); |
9887 gc_thread.Start(); | 9913 gc_thread.Start(); |
9888 v8::Locker::StartPreemption(1); | 9914 v8::Locker::StartPreemption(1); |
9889 | 9915 |
9890 LongRunningRegExp(); | 9916 LongRunningRegExp(); |
9891 { | 9917 { |
9892 v8::Unlocker unlock; | 9918 v8::Unlocker unlock; |
9893 gc_thread.Join(); | 9919 gc_thread.Join(); |
9894 } | 9920 } |
9895 v8::Locker::StopPreemption(); | 9921 v8::Locker::StopPreemption(); |
9896 CHECK(regexp_success_); | 9922 CHECK(regexp_success_); |
9897 CHECK(gc_success_); | 9923 CHECK(gc_success_); |
9898 } | 9924 } |
9899 private: | 9925 private: |
9900 // Number of garbage collections required. | 9926 // Number of garbage collections required. |
9901 static const int kRequiredGCs = 5; | 9927 static const int kRequiredGCs = 5; |
9902 | 9928 |
9903 class GCThread : public i::Thread { | 9929 class GCThread : public i::Thread { |
9904 public: | 9930 public: |
9905 explicit GCThread(RegExpInterruptTest* test) | 9931 explicit GCThread(i::Isolate* isolate, RegExpInterruptTest* test) |
9906 : test_(test) {} | 9932 : Thread(isolate), test_(test) {} |
9907 virtual void Run() { | 9933 virtual void Run() { |
9908 test_->CollectGarbage(); | 9934 test_->CollectGarbage(); |
9909 } | 9935 } |
9910 private: | 9936 private: |
9911 RegExpInterruptTest* test_; | 9937 RegExpInterruptTest* test_; |
9912 }; | 9938 }; |
9913 | 9939 |
9914 void CollectGarbage() { | 9940 void CollectGarbage() { |
9915 block_->Wait(); | 9941 block_->Wait(); |
9916 while (gc_during_regexp_ < kRequiredGCs) { | 9942 while (gc_during_regexp_ < kRequiredGCs) { |
9917 { | 9943 { |
9918 v8::Locker lock; | 9944 v8::Locker lock; |
9919 // TODO(lrn): Perhaps create some garbage before collecting. | 9945 // TODO(lrn): Perhaps create some garbage before collecting. |
9920 i::Heap::CollectAllGarbage(false); | 9946 HEAP->CollectAllGarbage(false); |
9921 gc_count_++; | 9947 gc_count_++; |
9922 } | 9948 } |
9923 i::OS::Sleep(1); | 9949 i::OS::Sleep(1); |
9924 } | 9950 } |
9925 gc_success_ = true; | 9951 gc_success_ = true; |
9926 } | 9952 } |
9927 | 9953 |
9928 void LongRunningRegExp() { | 9954 void LongRunningRegExp() { |
9929 block_->Signal(); // Enable garbage collection thread on next preemption. | 9955 block_->Signal(); // Enable garbage collection thread on next preemption. |
9930 int rounds = 0; | 9956 int rounds = 0; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9998 class ApplyInterruptTest { | 10024 class ApplyInterruptTest { |
9999 public: | 10025 public: |
10000 ApplyInterruptTest() : block_(NULL) {} | 10026 ApplyInterruptTest() : block_(NULL) {} |
10001 ~ApplyInterruptTest() { delete block_; } | 10027 ~ApplyInterruptTest() { delete block_; } |
10002 void RunTest() { | 10028 void RunTest() { |
10003 block_ = i::OS::CreateSemaphore(0); | 10029 block_ = i::OS::CreateSemaphore(0); |
10004 gc_count_ = 0; | 10030 gc_count_ = 0; |
10005 gc_during_apply_ = 0; | 10031 gc_during_apply_ = 0; |
10006 apply_success_ = false; | 10032 apply_success_ = false; |
10007 gc_success_ = false; | 10033 gc_success_ = false; |
10008 GCThread gc_thread(this); | 10034 GCThread gc_thread(i::Isolate::Current(), this); |
10009 gc_thread.Start(); | 10035 gc_thread.Start(); |
10010 v8::Locker::StartPreemption(1); | 10036 v8::Locker::StartPreemption(1); |
10011 | 10037 |
10012 LongRunningApply(); | 10038 LongRunningApply(); |
10013 { | 10039 { |
10014 v8::Unlocker unlock; | 10040 v8::Unlocker unlock; |
10015 gc_thread.Join(); | 10041 gc_thread.Join(); |
10016 } | 10042 } |
10017 v8::Locker::StopPreemption(); | 10043 v8::Locker::StopPreemption(); |
10018 CHECK(apply_success_); | 10044 CHECK(apply_success_); |
10019 CHECK(gc_success_); | 10045 CHECK(gc_success_); |
10020 } | 10046 } |
10021 private: | 10047 private: |
10022 // Number of garbage collections required. | 10048 // Number of garbage collections required. |
10023 static const int kRequiredGCs = 2; | 10049 static const int kRequiredGCs = 2; |
10024 | 10050 |
10025 class GCThread : public i::Thread { | 10051 class GCThread : public i::Thread { |
10026 public: | 10052 public: |
10027 explicit GCThread(ApplyInterruptTest* test) | 10053 explicit GCThread(i::Isolate* isolate, ApplyInterruptTest* test) |
10028 : test_(test) {} | 10054 : Thread(isolate), test_(test) {} |
10029 virtual void Run() { | 10055 virtual void Run() { |
10030 test_->CollectGarbage(); | 10056 test_->CollectGarbage(); |
10031 } | 10057 } |
10032 private: | 10058 private: |
10033 ApplyInterruptTest* test_; | 10059 ApplyInterruptTest* test_; |
10034 }; | 10060 }; |
10035 | 10061 |
10036 void CollectGarbage() { | 10062 void CollectGarbage() { |
10037 block_->Wait(); | 10063 block_->Wait(); |
10038 while (gc_during_apply_ < kRequiredGCs) { | 10064 while (gc_during_apply_ < kRequiredGCs) { |
10039 { | 10065 { |
10040 v8::Locker lock; | 10066 v8::Locker lock; |
10041 i::Heap::CollectAllGarbage(false); | 10067 HEAP->CollectAllGarbage(false); |
10042 gc_count_++; | 10068 gc_count_++; |
10043 } | 10069 } |
10044 i::OS::Sleep(1); | 10070 i::OS::Sleep(1); |
10045 } | 10071 } |
10046 gc_success_ = true; | 10072 gc_success_ = true; |
10047 } | 10073 } |
10048 | 10074 |
10049 void LongRunningApply() { | 10075 void LongRunningApply() { |
10050 block_->Signal(); | 10076 block_->Signal(); |
10051 int rounds = 0; | 10077 int rounds = 0; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10160 i::Vector<const i::uc16> data_; | 10186 i::Vector<const i::uc16> data_; |
10161 }; | 10187 }; |
10162 | 10188 |
10163 | 10189 |
10164 static void MorphAString(i::String* string, | 10190 static void MorphAString(i::String* string, |
10165 AsciiVectorResource* ascii_resource, | 10191 AsciiVectorResource* ascii_resource, |
10166 UC16VectorResource* uc16_resource) { | 10192 UC16VectorResource* uc16_resource) { |
10167 CHECK(i::StringShape(string).IsExternal()); | 10193 CHECK(i::StringShape(string).IsExternal()); |
10168 if (string->IsAsciiRepresentation()) { | 10194 if (string->IsAsciiRepresentation()) { |
10169 // Check old map is not symbol or long. | 10195 // Check old map is not symbol or long. |
10170 CHECK(string->map() == i::Heap::external_ascii_string_map()); | 10196 CHECK(string->map() == HEAP->external_ascii_string_map()); |
10171 // Morph external string to be TwoByte string. | 10197 // Morph external string to be TwoByte string. |
10172 string->set_map(i::Heap::external_string_map()); | 10198 string->set_map(HEAP->external_string_map()); |
10173 i::ExternalTwoByteString* morphed = | 10199 i::ExternalTwoByteString* morphed = |
10174 i::ExternalTwoByteString::cast(string); | 10200 i::ExternalTwoByteString::cast(string); |
10175 morphed->set_resource(uc16_resource); | 10201 morphed->set_resource(uc16_resource); |
10176 } else { | 10202 } else { |
10177 // Check old map is not symbol or long. | 10203 // Check old map is not symbol or long. |
10178 CHECK(string->map() == i::Heap::external_string_map()); | 10204 CHECK(string->map() == HEAP->external_string_map()); |
10179 // Morph external string to be ASCII string. | 10205 // Morph external string to be ASCII string. |
10180 string->set_map(i::Heap::external_ascii_string_map()); | 10206 string->set_map(HEAP->external_ascii_string_map()); |
10181 i::ExternalAsciiString* morphed = | 10207 i::ExternalAsciiString* morphed = |
10182 i::ExternalAsciiString::cast(string); | 10208 i::ExternalAsciiString::cast(string); |
10183 morphed->set_resource(ascii_resource); | 10209 morphed->set_resource(ascii_resource); |
10184 } | 10210 } |
10185 } | 10211 } |
10186 | 10212 |
10187 | 10213 |
10188 // Test that we can still flatten a string if the components it is built up | 10214 // Test that we can still flatten a string if the components it is built up |
10189 // from have been turned into 16 bit strings in the mean time. | 10215 // from have been turned into 16 bit strings in the mean time. |
10190 THREADED_TEST(MorphCompositeStringTest) { | 10216 THREADED_TEST(MorphCompositeStringTest) { |
10191 const char* c_string = "Now is the time for all good men" | 10217 const char* c_string = "Now is the time for all good men" |
10192 " to come to the aid of the party"; | 10218 " to come to the aid of the party"; |
10193 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 10219 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); |
10194 { | 10220 { |
10195 v8::HandleScope scope; | 10221 v8::HandleScope scope; |
10196 LocalContext env; | 10222 LocalContext env; |
10197 AsciiVectorResource ascii_resource( | 10223 AsciiVectorResource ascii_resource( |
10198 i::Vector<const char>(c_string, i::StrLength(c_string))); | 10224 i::Vector<const char>(c_string, i::StrLength(c_string))); |
10199 UC16VectorResource uc16_resource( | 10225 UC16VectorResource uc16_resource( |
10200 i::Vector<const uint16_t>(two_byte_string, | 10226 i::Vector<const uint16_t>(two_byte_string, |
10201 i::StrLength(c_string))); | 10227 i::StrLength(c_string))); |
10202 | 10228 |
10203 Local<String> lhs(v8::Utils::ToLocal( | 10229 Local<String> lhs(v8::Utils::ToLocal( |
10204 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10230 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
10205 Local<String> rhs(v8::Utils::ToLocal( | 10231 Local<String> rhs(v8::Utils::ToLocal( |
10206 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10232 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
10207 | 10233 |
10208 env->Global()->Set(v8_str("lhs"), lhs); | 10234 env->Global()->Set(v8_str("lhs"), lhs); |
10209 env->Global()->Set(v8_str("rhs"), rhs); | 10235 env->Global()->Set(v8_str("rhs"), rhs); |
10210 | 10236 |
10211 CompileRun( | 10237 CompileRun( |
10212 "var cons = lhs + rhs;" | 10238 "var cons = lhs + rhs;" |
10213 "var slice = lhs.substring(1, lhs.length - 1);" | 10239 "var slice = lhs.substring(1, lhs.length - 1);" |
10214 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 10240 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); |
10215 | 10241 |
10216 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 10242 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10281 | 10307 |
10282 // Initialize the contents of two_byte_content_ to be a uc16 representation | 10308 // Initialize the contents of two_byte_content_ to be a uc16 representation |
10283 // of "aaaaaaaaaaaaaab". | 10309 // of "aaaaaaaaaaaaaab". |
10284 for (int i = 0; i < 14; i++) { | 10310 for (int i = 0; i < 14; i++) { |
10285 two_byte_content_[i] = 'a'; | 10311 two_byte_content_[i] = 'a'; |
10286 } | 10312 } |
10287 two_byte_content_[14] = 'b'; | 10313 two_byte_content_[14] = 'b'; |
10288 | 10314 |
10289 // Create the input string for the regexp - the one we are going to change | 10315 // Create the input string for the regexp - the one we are going to change |
10290 // properties of. | 10316 // properties of. |
10291 input_ = i::Factory::NewExternalStringFromAscii(&ascii_resource_); | 10317 input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_); |
10292 | 10318 |
10293 // Inject the input as a global variable. | 10319 // Inject the input as a global variable. |
10294 i::Handle<i::String> input_name = | 10320 i::Handle<i::String> input_name = |
10295 i::Factory::NewStringFromAscii(i::Vector<const char>("input", 5)); | 10321 FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5)); |
10296 i::Top::global_context()->global()->SetProperty( | 10322 i::Isolate::Current()->global_context()->global()->SetProperty( |
10297 *input_name, | 10323 *input_name, |
10298 *input_, | 10324 *input_, |
10299 NONE, | 10325 NONE, |
10300 i::kNonStrictMode)->ToObjectChecked(); | 10326 i::kNonStrictMode)->ToObjectChecked(); |
10301 | 10327 |
10302 MorphThread morph_thread(this); | 10328 MorphThread morph_thread(i::Isolate::Current(), this); |
10303 morph_thread.Start(); | 10329 morph_thread.Start(); |
10304 v8::Locker::StartPreemption(1); | 10330 v8::Locker::StartPreemption(1); |
10305 LongRunningRegExp(); | 10331 LongRunningRegExp(); |
10306 { | 10332 { |
10307 v8::Unlocker unlock; | 10333 v8::Unlocker unlock; |
10308 morph_thread.Join(); | 10334 morph_thread.Join(); |
10309 } | 10335 } |
10310 v8::Locker::StopPreemption(); | 10336 v8::Locker::StopPreemption(); |
10311 CHECK(regexp_success_); | 10337 CHECK(regexp_success_); |
10312 CHECK(morph_success_); | 10338 CHECK(morph_success_); |
10313 } | 10339 } |
10314 private: | 10340 private: |
10315 | 10341 |
10316 // Number of string modifications required. | 10342 // Number of string modifications required. |
10317 static const int kRequiredModifications = 5; | 10343 static const int kRequiredModifications = 5; |
10318 static const int kMaxModifications = 100; | 10344 static const int kMaxModifications = 100; |
10319 | 10345 |
10320 class MorphThread : public i::Thread { | 10346 class MorphThread : public i::Thread { |
10321 public: | 10347 public: |
10322 explicit MorphThread(RegExpStringModificationTest* test) | 10348 explicit MorphThread(i::Isolate* isolate, |
10323 : test_(test) {} | 10349 RegExpStringModificationTest* test) |
| 10350 : Thread(isolate), test_(test) {} |
10324 virtual void Run() { | 10351 virtual void Run() { |
10325 test_->MorphString(); | 10352 test_->MorphString(); |
10326 } | 10353 } |
10327 private: | 10354 private: |
10328 RegExpStringModificationTest* test_; | 10355 RegExpStringModificationTest* test_; |
10329 }; | 10356 }; |
10330 | 10357 |
10331 void MorphString() { | 10358 void MorphString() { |
10332 block_->Wait(); | 10359 block_->Wait(); |
10333 while (morphs_during_regexp_ < kRequiredModifications && | 10360 while (morphs_during_regexp_ < kRequiredModifications && |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10746 } | 10773 } |
10747 | 10774 |
10748 | 10775 |
10749 THREADED_TEST(PixelArray) { | 10776 THREADED_TEST(PixelArray) { |
10750 v8::HandleScope scope; | 10777 v8::HandleScope scope; |
10751 LocalContext context; | 10778 LocalContext context; |
10752 const int kElementCount = 260; | 10779 const int kElementCount = 260; |
10753 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 10780 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
10754 i::Handle<i::ExternalPixelArray> pixels = | 10781 i::Handle<i::ExternalPixelArray> pixels = |
10755 i::Handle<i::ExternalPixelArray>::cast( | 10782 i::Handle<i::ExternalPixelArray>::cast( |
10756 i::Factory::NewExternalArray(kElementCount, | 10783 FACTORY->NewExternalArray(kElementCount, |
10757 v8::kExternalPixelArray, | 10784 v8::kExternalPixelArray, |
10758 pixel_data)); | 10785 pixel_data)); |
10759 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 10786 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
10760 for (int i = 0; i < kElementCount; i++) { | 10787 for (int i = 0; i < kElementCount; i++) { |
10761 pixels->set(i, i % 256); | 10788 pixels->set(i, i % 256); |
10762 } | 10789 } |
10763 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 10790 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
10764 for (int i = 0; i < kElementCount; i++) { | 10791 for (int i = 0; i < kElementCount; i++) { |
10765 CHECK_EQ(i % 256, pixels->get(i)); | 10792 CHECK_EQ(i % 256, pixels->get(i)); |
10766 CHECK_EQ(i % 256, pixel_data[i]); | 10793 CHECK_EQ(i % 256, pixel_data[i]); |
10767 } | 10794 } |
10768 | 10795 |
10769 v8::Handle<v8::Object> obj = v8::Object::New(); | 10796 v8::Handle<v8::Object> obj = v8::Object::New(); |
10770 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 10797 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
10771 // Set the elements to be the pixels. | 10798 // Set the elements to be the pixels. |
10772 // jsobj->set_elements(*pixels); | 10799 // jsobj->set_elements(*pixels); |
10773 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 10800 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11155 } | 11182 } |
11156 | 11183 |
11157 | 11184 |
11158 THREADED_TEST(PixelArrayWithInterceptor) { | 11185 THREADED_TEST(PixelArrayWithInterceptor) { |
11159 v8::HandleScope scope; | 11186 v8::HandleScope scope; |
11160 LocalContext context; | 11187 LocalContext context; |
11161 const int kElementCount = 260; | 11188 const int kElementCount = 260; |
11162 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 11189 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
11163 i::Handle<i::ExternalPixelArray> pixels = | 11190 i::Handle<i::ExternalPixelArray> pixels = |
11164 i::Handle<i::ExternalPixelArray>::cast( | 11191 i::Handle<i::ExternalPixelArray>::cast( |
11165 i::Factory::NewExternalArray(kElementCount, | 11192 FACTORY->NewExternalArray(kElementCount, |
11166 v8::kExternalPixelArray, | 11193 v8::kExternalPixelArray, |
11167 pixel_data)); | 11194 pixel_data)); |
11168 for (int i = 0; i < kElementCount; i++) { | 11195 for (int i = 0; i < kElementCount; i++) { |
11169 pixels->set(i, i % 256); | 11196 pixels->set(i, i % 256); |
11170 } | 11197 } |
11171 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); | 11198 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |
11172 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, | 11199 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, |
11173 NotHandledIndexedPropertySetter); | 11200 NotHandledIndexedPropertySetter); |
11174 v8::Handle<v8::Object> obj = templ->NewInstance(); | 11201 v8::Handle<v8::Object> obj = templ->NewInstance(); |
11175 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 11202 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
11176 context->Global()->Set(v8_str("pixels"), obj); | 11203 context->Global()->Set(v8_str("pixels"), obj); |
11177 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); | 11204 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11218 int64_t low, | 11245 int64_t low, |
11219 int64_t high) { | 11246 int64_t high) { |
11220 v8::HandleScope scope; | 11247 v8::HandleScope scope; |
11221 LocalContext context; | 11248 LocalContext context; |
11222 const int kElementCount = 40; | 11249 const int kElementCount = 40; |
11223 int element_size = ExternalArrayElementSize(array_type); | 11250 int element_size = ExternalArrayElementSize(array_type); |
11224 ElementType* array_data = | 11251 ElementType* array_data = |
11225 static_cast<ElementType*>(malloc(kElementCount * element_size)); | 11252 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
11226 i::Handle<ExternalArrayClass> array = | 11253 i::Handle<ExternalArrayClass> array = |
11227 i::Handle<ExternalArrayClass>::cast( | 11254 i::Handle<ExternalArrayClass>::cast( |
11228 i::Factory::NewExternalArray(kElementCount, array_type, array_data)); | 11255 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); |
11229 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11256 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
11230 for (int i = 0; i < kElementCount; i++) { | 11257 for (int i = 0; i < kElementCount; i++) { |
11231 array->set(i, static_cast<ElementType>(i)); | 11258 array->set(i, static_cast<ElementType>(i)); |
11232 } | 11259 } |
11233 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11260 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
11234 for (int i = 0; i < kElementCount; i++) { | 11261 for (int i = 0; i < kElementCount; i++) { |
11235 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); | 11262 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); |
11236 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); | 11263 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
11237 } | 11264 } |
11238 | 11265 |
11239 v8::Handle<v8::Object> obj = v8::Object::New(); | 11266 v8::Handle<v8::Object> obj = v8::Object::New(); |
11240 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 11267 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
11241 // Set the elements to be the external array. | 11268 // Set the elements to be the external array. |
11242 obj->SetIndexedPropertiesToExternalArrayData(array_data, | 11269 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
11243 array_type, | 11270 array_type, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11340 result = CompileRun("var tmp_array = ext_array;" | 11367 result = CompileRun("var tmp_array = ext_array;" |
11341 "var sum = 0;" | 11368 "var sum = 0;" |
11342 "for (var i = 0; i < 8; i++) {" | 11369 "for (var i = 0; i < 8; i++) {" |
11343 " tmp_array[i] = i;" | 11370 " tmp_array[i] = i;" |
11344 " sum += tmp_array[i];" | 11371 " sum += tmp_array[i];" |
11345 " if (i == 4) {" | 11372 " if (i == 4) {" |
11346 " tmp_array = {};" | 11373 " tmp_array = {};" |
11347 " }" | 11374 " }" |
11348 "}" | 11375 "}" |
11349 "sum;"); | 11376 "sum;"); |
11350 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11377 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
11351 CHECK_EQ(28, result->Int32Value()); | 11378 CHECK_EQ(28, result->Int32Value()); |
11352 | 11379 |
11353 // Make sure out-of-range loads do not throw. | 11380 // Make sure out-of-range loads do not throw. |
11354 i::OS::SNPrintF(test_buf, | 11381 i::OS::SNPrintF(test_buf, |
11355 "var caught_exception = false;" | 11382 "var caught_exception = false;" |
11356 "try {" | 11383 "try {" |
11357 " ext_array[%d];" | 11384 " ext_array[%d];" |
11358 "} catch (e) {" | 11385 "} catch (e) {" |
11359 " caught_exception = true;" | 11386 " caught_exception = true;" |
11360 "}" | 11387 "}" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11497 // This catches bugs in the instructions used for the KeyedLoadIC | 11524 // This catches bugs in the instructions used for the KeyedLoadIC |
11498 // for byte and word types. | 11525 // for byte and word types. |
11499 { | 11526 { |
11500 const int kXSize = 300; | 11527 const int kXSize = 300; |
11501 const int kYSize = 300; | 11528 const int kYSize = 300; |
11502 const int kLargeElementCount = kXSize * kYSize * 4; | 11529 const int kLargeElementCount = kXSize * kYSize * 4; |
11503 ElementType* large_array_data = | 11530 ElementType* large_array_data = |
11504 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); | 11531 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); |
11505 i::Handle<ExternalArrayClass> large_array = | 11532 i::Handle<ExternalArrayClass> large_array = |
11506 i::Handle<ExternalArrayClass>::cast( | 11533 i::Handle<ExternalArrayClass>::cast( |
11507 i::Factory::NewExternalArray(kLargeElementCount, | 11534 FACTORY->NewExternalArray(kLargeElementCount, |
11508 array_type, | 11535 array_type, |
11509 array_data)); | 11536 array_data)); |
11510 v8::Handle<v8::Object> large_obj = v8::Object::New(); | 11537 v8::Handle<v8::Object> large_obj = v8::Object::New(); |
11511 // Set the elements to be the external array. | 11538 // Set the elements to be the external array. |
11512 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, | 11539 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, |
11513 array_type, | 11540 array_type, |
11514 kLargeElementCount); | 11541 kLargeElementCount); |
11515 context->Global()->Set(v8_str("large_array"), large_obj); | 11542 context->Global()->Set(v8_str("large_array"), large_obj); |
11516 // Initialize contents of a few rows. | 11543 // Initialize contents of a few rows. |
11517 for (int x = 0; x < 300; x++) { | 11544 for (int x = 0; x < 300; x++) { |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11933 if (rv) | 11960 if (rv) |
11934 break; | 11961 break; |
11935 } | 11962 } |
11936 CHECK(rv == true); | 11963 CHECK(rv == true); |
11937 } | 11964 } |
11938 | 11965 |
11939 | 11966 |
11940 static uint32_t* stack_limit; | 11967 static uint32_t* stack_limit; |
11941 | 11968 |
11942 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { | 11969 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { |
11943 stack_limit = reinterpret_cast<uint32_t*>(i::StackGuard::real_climit()); | 11970 stack_limit = reinterpret_cast<uint32_t*>( |
| 11971 i::Isolate::Current()->stack_guard()->real_climit()); |
11944 return v8::Undefined(); | 11972 return v8::Undefined(); |
11945 } | 11973 } |
11946 | 11974 |
11947 | 11975 |
11948 // Uses the address of a local variable to determine the stack top now. | 11976 // Uses the address of a local variable to determine the stack top now. |
11949 // Given a size, returns an address that is that far from the current | 11977 // Given a size, returns an address that is that far from the current |
11950 // top of stack. | 11978 // top of stack. |
11951 static uint32_t* ComputeStackLimit(uint32_t size) { | 11979 static uint32_t* ComputeStackLimit(uint32_t size) { |
11952 uint32_t* answer = &size - (size / sizeof(size)); | 11980 uint32_t* answer = &size - (size / sizeof(size)); |
11953 // If the size is very large and the stack is very near the bottom of | 11981 // If the size is very large and the stack is very near the bottom of |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12199 Local<v8::String> obj = v8::String::New(""); | 12227 Local<v8::String> obj = v8::String::New(""); |
12200 context->SetData(obj); | 12228 context->SetData(obj); |
12201 CompileRun(source_simple); | 12229 CompileRun(source_simple); |
12202 context->Exit(); | 12230 context->Exit(); |
12203 } | 12231 } |
12204 context.Dispose(); | 12232 context.Dispose(); |
12205 for (gc_count = 1; gc_count < 10; gc_count++) { | 12233 for (gc_count = 1; gc_count < 10; gc_count++) { |
12206 other_context->Enter(); | 12234 other_context->Enter(); |
12207 CompileRun(source_simple); | 12235 CompileRun(source_simple); |
12208 other_context->Exit(); | 12236 other_context->Exit(); |
12209 i::Heap::CollectAllGarbage(false); | 12237 HEAP->CollectAllGarbage(false); |
12210 if (GetGlobalObjectsCount() == 1) break; | 12238 if (GetGlobalObjectsCount() == 1) break; |
12211 } | 12239 } |
12212 CHECK_GE(2, gc_count); | 12240 CHECK_GE(2, gc_count); |
12213 CHECK_EQ(1, GetGlobalObjectsCount()); | 12241 CHECK_EQ(1, GetGlobalObjectsCount()); |
12214 | 12242 |
12215 // Eval in a function creates reference from the compilation cache to the | 12243 // Eval in a function creates reference from the compilation cache to the |
12216 // global object. | 12244 // global object. |
12217 const char* source_eval = "function f(){eval('1')}; f()"; | 12245 const char* source_eval = "function f(){eval('1')}; f()"; |
12218 context = Context::New(); | 12246 context = Context::New(); |
12219 { | 12247 { |
12220 v8::HandleScope scope; | 12248 v8::HandleScope scope; |
12221 | 12249 |
12222 context->Enter(); | 12250 context->Enter(); |
12223 CompileRun(source_eval); | 12251 CompileRun(source_eval); |
12224 context->Exit(); | 12252 context->Exit(); |
12225 } | 12253 } |
12226 context.Dispose(); | 12254 context.Dispose(); |
12227 for (gc_count = 1; gc_count < 10; gc_count++) { | 12255 for (gc_count = 1; gc_count < 10; gc_count++) { |
12228 other_context->Enter(); | 12256 other_context->Enter(); |
12229 CompileRun(source_eval); | 12257 CompileRun(source_eval); |
12230 other_context->Exit(); | 12258 other_context->Exit(); |
12231 i::Heap::CollectAllGarbage(false); | 12259 HEAP->CollectAllGarbage(false); |
12232 if (GetGlobalObjectsCount() == 1) break; | 12260 if (GetGlobalObjectsCount() == 1) break; |
12233 } | 12261 } |
12234 CHECK_GE(2, gc_count); | 12262 CHECK_GE(2, gc_count); |
12235 CHECK_EQ(1, GetGlobalObjectsCount()); | 12263 CHECK_EQ(1, GetGlobalObjectsCount()); |
12236 | 12264 |
12237 // Looking up the line number for an exception creates reference from the | 12265 // Looking up the line number for an exception creates reference from the |
12238 // compilation cache to the global object. | 12266 // compilation cache to the global object. |
12239 const char* source_exception = "function f(){throw 1;} f()"; | 12267 const char* source_exception = "function f(){throw 1;} f()"; |
12240 context = Context::New(); | 12268 context = Context::New(); |
12241 { | 12269 { |
12242 v8::HandleScope scope; | 12270 v8::HandleScope scope; |
12243 | 12271 |
12244 context->Enter(); | 12272 context->Enter(); |
12245 v8::TryCatch try_catch; | 12273 v8::TryCatch try_catch; |
12246 CompileRun(source_exception); | 12274 CompileRun(source_exception); |
12247 CHECK(try_catch.HasCaught()); | 12275 CHECK(try_catch.HasCaught()); |
12248 v8::Handle<v8::Message> message = try_catch.Message(); | 12276 v8::Handle<v8::Message> message = try_catch.Message(); |
12249 CHECK(!message.IsEmpty()); | 12277 CHECK(!message.IsEmpty()); |
12250 CHECK_EQ(1, message->GetLineNumber()); | 12278 CHECK_EQ(1, message->GetLineNumber()); |
12251 context->Exit(); | 12279 context->Exit(); |
12252 } | 12280 } |
12253 context.Dispose(); | 12281 context.Dispose(); |
12254 for (gc_count = 1; gc_count < 10; gc_count++) { | 12282 for (gc_count = 1; gc_count < 10; gc_count++) { |
12255 other_context->Enter(); | 12283 other_context->Enter(); |
12256 CompileRun(source_exception); | 12284 CompileRun(source_exception); |
12257 other_context->Exit(); | 12285 other_context->Exit(); |
12258 i::Heap::CollectAllGarbage(false); | 12286 HEAP->CollectAllGarbage(false); |
12259 if (GetGlobalObjectsCount() == 1) break; | 12287 if (GetGlobalObjectsCount() == 1) break; |
12260 } | 12288 } |
12261 CHECK_GE(2, gc_count); | 12289 CHECK_GE(2, gc_count); |
12262 CHECK_EQ(1, GetGlobalObjectsCount()); | 12290 CHECK_EQ(1, GetGlobalObjectsCount()); |
12263 | 12291 |
12264 other_context.Dispose(); | 12292 other_context.Dispose(); |
12265 } | 12293 } |
12266 | 12294 |
12267 | 12295 |
12268 THREADED_TEST(ScriptOrigin) { | 12296 THREADED_TEST(ScriptOrigin) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12466 ++epilogue_call_count_second; | 12494 ++epilogue_call_count_second; |
12467 } | 12495 } |
12468 | 12496 |
12469 TEST(GCCallbacks) { | 12497 TEST(GCCallbacks) { |
12470 LocalContext context; | 12498 LocalContext context; |
12471 | 12499 |
12472 v8::V8::AddGCPrologueCallback(PrologueCallback); | 12500 v8::V8::AddGCPrologueCallback(PrologueCallback); |
12473 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 12501 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
12474 CHECK_EQ(0, prologue_call_count); | 12502 CHECK_EQ(0, prologue_call_count); |
12475 CHECK_EQ(0, epilogue_call_count); | 12503 CHECK_EQ(0, epilogue_call_count); |
12476 i::Heap::CollectAllGarbage(false); | 12504 HEAP->CollectAllGarbage(false); |
12477 CHECK_EQ(1, prologue_call_count); | 12505 CHECK_EQ(1, prologue_call_count); |
12478 CHECK_EQ(1, epilogue_call_count); | 12506 CHECK_EQ(1, epilogue_call_count); |
12479 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); | 12507 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); |
12480 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); | 12508 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); |
12481 i::Heap::CollectAllGarbage(false); | 12509 HEAP->CollectAllGarbage(false); |
12482 CHECK_EQ(2, prologue_call_count); | 12510 CHECK_EQ(2, prologue_call_count); |
12483 CHECK_EQ(2, epilogue_call_count); | 12511 CHECK_EQ(2, epilogue_call_count); |
12484 CHECK_EQ(1, prologue_call_count_second); | 12512 CHECK_EQ(1, prologue_call_count_second); |
12485 CHECK_EQ(1, epilogue_call_count_second); | 12513 CHECK_EQ(1, epilogue_call_count_second); |
12486 v8::V8::RemoveGCPrologueCallback(PrologueCallback); | 12514 v8::V8::RemoveGCPrologueCallback(PrologueCallback); |
12487 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); | 12515 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); |
12488 i::Heap::CollectAllGarbage(false); | 12516 HEAP->CollectAllGarbage(false); |
12489 CHECK_EQ(2, prologue_call_count); | 12517 CHECK_EQ(2, prologue_call_count); |
12490 CHECK_EQ(2, epilogue_call_count); | 12518 CHECK_EQ(2, epilogue_call_count); |
12491 CHECK_EQ(2, prologue_call_count_second); | 12519 CHECK_EQ(2, prologue_call_count_second); |
12492 CHECK_EQ(2, epilogue_call_count_second); | 12520 CHECK_EQ(2, epilogue_call_count_second); |
12493 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); | 12521 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); |
12494 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); | 12522 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); |
12495 i::Heap::CollectAllGarbage(false); | 12523 HEAP->CollectAllGarbage(false); |
12496 CHECK_EQ(2, prologue_call_count); | 12524 CHECK_EQ(2, prologue_call_count); |
12497 CHECK_EQ(2, epilogue_call_count); | 12525 CHECK_EQ(2, epilogue_call_count); |
12498 CHECK_EQ(2, prologue_call_count_second); | 12526 CHECK_EQ(2, prologue_call_count_second); |
12499 CHECK_EQ(2, epilogue_call_count_second); | 12527 CHECK_EQ(2, epilogue_call_count_second); |
12500 } | 12528 } |
12501 | 12529 |
12502 | 12530 |
12503 THREADED_TEST(AddToJSFunctionResultCache) { | 12531 THREADED_TEST(AddToJSFunctionResultCache) { |
12504 i::FLAG_allow_natives_syntax = true; | 12532 i::FLAG_allow_natives_syntax = true; |
12505 v8::HandleScope scope; | 12533 v8::HandleScope scope; |
12506 | 12534 |
12507 LocalContext context; | 12535 LocalContext context; |
12508 | 12536 |
12509 const char* code = | 12537 const char* code = |
12510 "(function() {" | 12538 "(function() {" |
12511 " var key0 = 'a';" | 12539 " var key0 = 'a';" |
12512 " var key1 = 'b';" | 12540 " var key1 = 'b';" |
12513 " var r0 = %_GetFromCache(0, key0);" | 12541 " var r0 = %_GetFromCache(0, key0);" |
12514 " var r1 = %_GetFromCache(0, key1);" | 12542 " var r1 = %_GetFromCache(0, key1);" |
12515 " var r0_ = %_GetFromCache(0, key0);" | 12543 " var r0_ = %_GetFromCache(0, key0);" |
12516 " if (r0 !== r0_)" | 12544 " if (r0 !== r0_)" |
12517 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" | 12545 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" |
12518 " var r1_ = %_GetFromCache(0, key1);" | 12546 " var r1_ = %_GetFromCache(0, key1);" |
12519 " if (r1 !== r1_)" | 12547 " if (r1 !== r1_)" |
12520 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" | 12548 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" |
12521 " return 'PASSED';" | 12549 " return 'PASSED';" |
12522 "})()"; | 12550 "})()"; |
12523 i::Heap::ClearJSFunctionResultCaches(); | 12551 HEAP->ClearJSFunctionResultCaches(); |
12524 ExpectString(code, "PASSED"); | 12552 ExpectString(code, "PASSED"); |
12525 } | 12553 } |
12526 | 12554 |
12527 | 12555 |
12528 static const int k0CacheSize = 16; | 12556 static const int k0CacheSize = 16; |
12529 | 12557 |
12530 THREADED_TEST(FillJSFunctionResultCache) { | 12558 THREADED_TEST(FillJSFunctionResultCache) { |
12531 i::FLAG_allow_natives_syntax = true; | 12559 i::FLAG_allow_natives_syntax = true; |
12532 v8::HandleScope scope; | 12560 v8::HandleScope scope; |
12533 | 12561 |
12534 LocalContext context; | 12562 LocalContext context; |
12535 | 12563 |
12536 const char* code = | 12564 const char* code = |
12537 "(function() {" | 12565 "(function() {" |
12538 " var k = 'a';" | 12566 " var k = 'a';" |
12539 " var r = %_GetFromCache(0, k);" | 12567 " var r = %_GetFromCache(0, k);" |
12540 " for (var i = 0; i < 16; i++) {" | 12568 " for (var i = 0; i < 16; i++) {" |
12541 " %_GetFromCache(0, 'a' + i);" | 12569 " %_GetFromCache(0, 'a' + i);" |
12542 " };" | 12570 " };" |
12543 " if (r === %_GetFromCache(0, k))" | 12571 " if (r === %_GetFromCache(0, k))" |
12544 " return 'FAILED: k0CacheSize is too small';" | 12572 " return 'FAILED: k0CacheSize is too small';" |
12545 " return 'PASSED';" | 12573 " return 'PASSED';" |
12546 "})()"; | 12574 "})()"; |
12547 i::Heap::ClearJSFunctionResultCaches(); | 12575 HEAP->ClearJSFunctionResultCaches(); |
12548 ExpectString(code, "PASSED"); | 12576 ExpectString(code, "PASSED"); |
12549 } | 12577 } |
12550 | 12578 |
12551 | 12579 |
12552 THREADED_TEST(RoundRobinGetFromCache) { | 12580 THREADED_TEST(RoundRobinGetFromCache) { |
12553 i::FLAG_allow_natives_syntax = true; | 12581 i::FLAG_allow_natives_syntax = true; |
12554 v8::HandleScope scope; | 12582 v8::HandleScope scope; |
12555 | 12583 |
12556 LocalContext context; | 12584 LocalContext context; |
12557 | 12585 |
12558 const char* code = | 12586 const char* code = |
12559 "(function() {" | 12587 "(function() {" |
12560 " var keys = [];" | 12588 " var keys = [];" |
12561 " for (var i = 0; i < 16; i++) keys.push(i);" | 12589 " for (var i = 0; i < 16; i++) keys.push(i);" |
12562 " var values = [];" | 12590 " var values = [];" |
12563 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12591 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
12564 " for (var i = 0; i < 16; i++) {" | 12592 " for (var i = 0; i < 16; i++) {" |
12565 " var v = %_GetFromCache(0, keys[i]);" | 12593 " var v = %_GetFromCache(0, keys[i]);" |
12566 " if (v !== values[i])" | 12594 " if (v !== values[i])" |
12567 " return 'Wrong value for ' + " | 12595 " return 'Wrong value for ' + " |
12568 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12596 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
12569 " };" | 12597 " };" |
12570 " return 'PASSED';" | 12598 " return 'PASSED';" |
12571 "})()"; | 12599 "})()"; |
12572 i::Heap::ClearJSFunctionResultCaches(); | 12600 HEAP->ClearJSFunctionResultCaches(); |
12573 ExpectString(code, "PASSED"); | 12601 ExpectString(code, "PASSED"); |
12574 } | 12602 } |
12575 | 12603 |
12576 | 12604 |
12577 THREADED_TEST(ReverseGetFromCache) { | 12605 THREADED_TEST(ReverseGetFromCache) { |
12578 i::FLAG_allow_natives_syntax = true; | 12606 i::FLAG_allow_natives_syntax = true; |
12579 v8::HandleScope scope; | 12607 v8::HandleScope scope; |
12580 | 12608 |
12581 LocalContext context; | 12609 LocalContext context; |
12582 | 12610 |
12583 const char* code = | 12611 const char* code = |
12584 "(function() {" | 12612 "(function() {" |
12585 " var keys = [];" | 12613 " var keys = [];" |
12586 " for (var i = 0; i < 16; i++) keys.push(i);" | 12614 " for (var i = 0; i < 16; i++) keys.push(i);" |
12587 " var values = [];" | 12615 " var values = [];" |
12588 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12616 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
12589 " for (var i = 15; i >= 16; i--) {" | 12617 " for (var i = 15; i >= 16; i--) {" |
12590 " var v = %_GetFromCache(0, keys[i]);" | 12618 " var v = %_GetFromCache(0, keys[i]);" |
12591 " if (v !== values[i])" | 12619 " if (v !== values[i])" |
12592 " return 'Wrong value for ' + " | 12620 " return 'Wrong value for ' + " |
12593 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12621 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
12594 " };" | 12622 " };" |
12595 " return 'PASSED';" | 12623 " return 'PASSED';" |
12596 "})()"; | 12624 "})()"; |
12597 i::Heap::ClearJSFunctionResultCaches(); | 12625 HEAP->ClearJSFunctionResultCaches(); |
12598 ExpectString(code, "PASSED"); | 12626 ExpectString(code, "PASSED"); |
12599 } | 12627 } |
12600 | 12628 |
12601 | 12629 |
12602 THREADED_TEST(TestEviction) { | 12630 THREADED_TEST(TestEviction) { |
12603 i::FLAG_allow_natives_syntax = true; | 12631 i::FLAG_allow_natives_syntax = true; |
12604 v8::HandleScope scope; | 12632 v8::HandleScope scope; |
12605 | 12633 |
12606 LocalContext context; | 12634 LocalContext context; |
12607 | 12635 |
12608 const char* code = | 12636 const char* code = |
12609 "(function() {" | 12637 "(function() {" |
12610 " for (var i = 0; i < 2*16; i++) {" | 12638 " for (var i = 0; i < 2*16; i++) {" |
12611 " %_GetFromCache(0, 'a' + i);" | 12639 " %_GetFromCache(0, 'a' + i);" |
12612 " };" | 12640 " };" |
12613 " return 'PASSED';" | 12641 " return 'PASSED';" |
12614 "})()"; | 12642 "})()"; |
12615 i::Heap::ClearJSFunctionResultCaches(); | 12643 HEAP->ClearJSFunctionResultCaches(); |
12616 ExpectString(code, "PASSED"); | 12644 ExpectString(code, "PASSED"); |
12617 } | 12645 } |
12618 | 12646 |
12619 | 12647 |
12620 THREADED_TEST(TwoByteStringInAsciiCons) { | 12648 THREADED_TEST(TwoByteStringInAsciiCons) { |
12621 // See Chromium issue 47824. | 12649 // See Chromium issue 47824. |
12622 v8::HandleScope scope; | 12650 v8::HandleScope scope; |
12623 | 12651 |
12624 LocalContext context; | 12652 LocalContext context; |
12625 const char* init_code = | 12653 const char* init_code = |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12695 | 12723 |
12696 reresult = CompileRun("str2.charCodeAt(2);"); | 12724 reresult = CompileRun("str2.charCodeAt(2);"); |
12697 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); | 12725 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
12698 } | 12726 } |
12699 | 12727 |
12700 | 12728 |
12701 // Failed access check callback that performs a GC on each invocation. | 12729 // Failed access check callback that performs a GC on each invocation. |
12702 void FailedAccessCheckCallbackGC(Local<v8::Object> target, | 12730 void FailedAccessCheckCallbackGC(Local<v8::Object> target, |
12703 v8::AccessType type, | 12731 v8::AccessType type, |
12704 Local<v8::Value> data) { | 12732 Local<v8::Value> data) { |
12705 i::Heap::CollectAllGarbage(true); | 12733 HEAP->CollectAllGarbage(true); |
12706 } | 12734 } |
12707 | 12735 |
12708 | 12736 |
12709 TEST(GCInFailedAccessCheckCallback) { | 12737 TEST(GCInFailedAccessCheckCallback) { |
12710 // Install a failed access check callback that performs a GC on each | 12738 // Install a failed access check callback that performs a GC on each |
12711 // invocation. Then force the callback to be called from va | 12739 // invocation. Then force the callback to be called from va |
12712 | 12740 |
12713 v8::V8::Initialize(); | 12741 v8::V8::Initialize(); |
12714 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 12742 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
12715 | 12743 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12776 | 12804 |
12777 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); | 12805 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); |
12778 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); | 12806 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); |
12779 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); | 12807 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); |
12780 | 12808 |
12781 // Reset the failed access check callback so it does not influence | 12809 // Reset the failed access check callback so it does not influence |
12782 // the other tests. | 12810 // the other tests. |
12783 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); | 12811 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); |
12784 } | 12812 } |
12785 | 12813 |
| 12814 TEST(DefaultIsolateGetCurrent) { |
| 12815 CHECK(v8::Isolate::GetCurrent() != NULL); |
| 12816 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12817 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12818 printf("*** %s\n", "DefaultIsolateGetCurrent success"); |
| 12819 } |
| 12820 |
| 12821 TEST(IsolateNewDispose) { |
| 12822 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12823 v8::Isolate* isolate = v8::Isolate::New(); |
| 12824 CHECK(isolate != NULL); |
| 12825 CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12826 CHECK(current_isolate != isolate); |
| 12827 CHECK(current_isolate == v8::Isolate::GetCurrent()); |
| 12828 |
| 12829 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12830 last_location = last_message = NULL; |
| 12831 isolate->Dispose(); |
| 12832 CHECK_EQ(last_location, NULL); |
| 12833 CHECK_EQ(last_message, NULL); |
| 12834 } |
| 12835 |
| 12836 TEST(IsolateEnterExitDefault) { |
| 12837 v8::HandleScope scope; |
| 12838 LocalContext context; |
| 12839 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12840 CHECK(current_isolate != NULL); // Default isolate. |
| 12841 ExpectString("'hello'", "hello"); |
| 12842 current_isolate->Enter(); |
| 12843 ExpectString("'still working'", "still working"); |
| 12844 current_isolate->Exit(); |
| 12845 ExpectString("'still working 2'", "still working 2"); |
| 12846 current_isolate->Exit(); |
| 12847 // Default isolate is always, well, 'default current'. |
| 12848 CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); |
| 12849 // Still working since default isolate is auto-entering any thread |
| 12850 // that has no isolate and attempts to execute V8 APIs. |
| 12851 ExpectString("'still working 3'", "still working 3"); |
| 12852 } |
| 12853 |
| 12854 TEST(DisposeDefaultIsolate) { |
| 12855 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12856 |
| 12857 // Run some V8 code to trigger default isolate to become 'current'. |
| 12858 v8::HandleScope scope; |
| 12859 LocalContext context; |
| 12860 ExpectString("'run some V8'", "run some V8"); |
| 12861 |
| 12862 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12863 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12864 last_location = last_message = NULL; |
| 12865 isolate->Dispose(); |
| 12866 // It is not possible to dispose default isolate via Isolate API. |
| 12867 CHECK_NE(last_location, NULL); |
| 12868 CHECK_NE(last_message, NULL); |
| 12869 } |
| 12870 |
| 12871 TEST(RunDefaultAndAnotherIsolate) { |
| 12872 v8::HandleScope scope; |
| 12873 LocalContext context; |
| 12874 |
| 12875 // Enter new isolate. |
| 12876 v8::Isolate* isolate = v8::Isolate::New(); |
| 12877 CHECK(isolate); |
| 12878 isolate->Enter(); |
| 12879 { // Need this block because subsequent Exit() will deallocate Heap, |
| 12880 // so we need all scope objects to be deconstructed when it happens. |
| 12881 v8::HandleScope scope_new; |
| 12882 LocalContext context_new; |
| 12883 |
| 12884 // Run something in new isolate. |
| 12885 CompileRun("var foo = 153;"); |
| 12886 ExpectTrue("function f() { return foo == 153; }; f()"); |
| 12887 } |
| 12888 isolate->Exit(); |
| 12889 |
| 12890 // This runs automatically in default isolate. |
| 12891 // Variables in another isolate should be not available. |
| 12892 ExpectTrue("function f() {" |
| 12893 " try {" |
| 12894 " foo;" |
| 12895 " return false;" |
| 12896 " } catch(e) {" |
| 12897 " return true;" |
| 12898 " }" |
| 12899 "};" |
| 12900 "var bar = 371;" |
| 12901 "f()"); |
| 12902 |
| 12903 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12904 last_location = last_message = NULL; |
| 12905 isolate->Dispose(); |
| 12906 CHECK_EQ(last_location, NULL); |
| 12907 CHECK_EQ(last_message, NULL); |
| 12908 |
| 12909 // Check that default isolate still runs. |
| 12910 ExpectTrue("function f() { return bar == 371; }; f()"); |
| 12911 } |
| 12912 |
| 12913 TEST(DisposeIsolateWhenInUse) { |
| 12914 v8::Isolate* isolate = v8::Isolate::New(); |
| 12915 CHECK(isolate); |
| 12916 isolate->Enter(); |
| 12917 v8::HandleScope scope; |
| 12918 LocalContext context; |
| 12919 // Run something in this isolate. |
| 12920 ExpectTrue("true"); |
| 12921 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12922 last_location = last_message = NULL; |
| 12923 // Still entered, should fail. |
| 12924 isolate->Dispose(); |
| 12925 CHECK_NE(last_location, NULL); |
| 12926 CHECK_NE(last_message, NULL); |
| 12927 } |
| 12928 |
| 12929 TEST(RunTwoIsolatesOnSingleThread) { |
| 12930 // Run isolate 1. |
| 12931 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 12932 isolate1->Enter(); |
| 12933 v8::Persistent<v8::Context> context1 = v8::Context::New(); |
| 12934 |
| 12935 { |
| 12936 v8::Context::Scope cscope(context1); |
| 12937 v8::HandleScope scope; |
| 12938 // Run something in new isolate. |
| 12939 CompileRun("var foo = 'isolate 1';"); |
| 12940 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12941 } |
| 12942 |
| 12943 // Run isolate 2. |
| 12944 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 12945 v8::Persistent<v8::Context> context2; |
| 12946 |
| 12947 { |
| 12948 v8::Isolate::Scope iscope(isolate2); |
| 12949 context2 = v8::Context::New(); |
| 12950 v8::Context::Scope cscope(context2); |
| 12951 v8::HandleScope scope; |
| 12952 |
| 12953 // Run something in new isolate. |
| 12954 CompileRun("var foo = 'isolate 2';"); |
| 12955 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 12956 } |
| 12957 |
| 12958 { |
| 12959 v8::Context::Scope cscope(context1); |
| 12960 v8::HandleScope scope; |
| 12961 // Now again in isolate 1 |
| 12962 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12963 } |
| 12964 |
| 12965 isolate1->Exit(); |
| 12966 |
| 12967 // Run some stuff in default isolate. |
| 12968 v8::Persistent<v8::Context> context_default = v8::Context::New(); |
| 12969 |
| 12970 { |
| 12971 v8::Context::Scope cscope(context_default); |
| 12972 v8::HandleScope scope; |
| 12973 // Variables in other isolates should be not available, verify there |
| 12974 // is an exception. |
| 12975 ExpectTrue("function f() {" |
| 12976 " try {" |
| 12977 " foo;" |
| 12978 " return false;" |
| 12979 " } catch(e) {" |
| 12980 " return true;" |
| 12981 " }" |
| 12982 "};" |
| 12983 "var isDefaultIsolate = true;" |
| 12984 "f()"); |
| 12985 } |
| 12986 |
| 12987 isolate1->Enter(); |
| 12988 |
| 12989 { |
| 12990 v8::Isolate::Scope iscope(isolate2); |
| 12991 v8::Context::Scope cscope(context2); |
| 12992 v8::HandleScope scope; |
| 12993 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 12994 } |
| 12995 |
| 12996 { |
| 12997 v8::Context::Scope cscope(context1); |
| 12998 v8::HandleScope scope; |
| 12999 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 13000 } |
| 13001 |
| 13002 { |
| 13003 v8::Isolate::Scope iscope(isolate2); |
| 13004 context2.Dispose(); |
| 13005 } |
| 13006 |
| 13007 context1.Dispose(); |
| 13008 isolate1->Exit(); |
| 13009 |
| 13010 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 13011 last_location = last_message = NULL; |
| 13012 |
| 13013 isolate1->Dispose(); |
| 13014 CHECK_EQ(last_location, NULL); |
| 13015 CHECK_EQ(last_message, NULL); |
| 13016 |
| 13017 isolate2->Dispose(); |
| 13018 CHECK_EQ(last_location, NULL); |
| 13019 CHECK_EQ(last_message, NULL); |
| 13020 |
| 13021 // Check that default isolate still runs. |
| 13022 { |
| 13023 v8::Context::Scope cscope(context_default); |
| 13024 v8::HandleScope scope; |
| 13025 ExpectTrue("function f() { return isDefaultIsolate; }; f()"); |
| 13026 } |
| 13027 } |
| 13028 |
| 13029 static int CalcFibonacci(v8::Isolate* isolate, int limit) { |
| 13030 v8::Isolate::Scope isolate_scope(isolate); |
| 13031 v8::HandleScope scope; |
| 13032 LocalContext context; |
| 13033 i::ScopedVector<char> code(1024); |
| 13034 i::OS::SNPrintF(code, "function fib(n) {" |
| 13035 " if (n <= 2) return 1;" |
| 13036 " return fib(n-1) + fib(n-2);" |
| 13037 "}" |
| 13038 "fib(%d)", limit); |
| 13039 Local<Value> value = CompileRun(code.start()); |
| 13040 CHECK(value->IsNumber()); |
| 13041 return static_cast<int>(value->NumberValue()); |
| 13042 } |
| 13043 |
| 13044 class IsolateThread : public v8::internal::Thread { |
| 13045 public: |
| 13046 explicit IsolateThread(v8::Isolate* isolate, int fib_limit) |
| 13047 : Thread(NULL), |
| 13048 isolate_(isolate), |
| 13049 fib_limit_(fib_limit), |
| 13050 result_(0) { } |
| 13051 |
| 13052 void Run() { |
| 13053 result_ = CalcFibonacci(isolate_, fib_limit_); |
| 13054 } |
| 13055 |
| 13056 int result() { return result_; } |
| 13057 |
| 13058 private: |
| 13059 v8::Isolate* isolate_; |
| 13060 int fib_limit_; |
| 13061 int result_; |
| 13062 }; |
| 13063 |
| 13064 TEST(MultipleIsolatesOnIndividualThreads) { |
| 13065 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 13066 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 13067 |
| 13068 IsolateThread thread1(isolate1, 21); |
| 13069 IsolateThread thread2(isolate2, 12); |
| 13070 |
| 13071 // Compute some fibonacci numbers on 3 threads in 3 isolates. |
| 13072 thread1.Start(); |
| 13073 thread2.Start(); |
| 13074 |
| 13075 int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); |
| 13076 int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); |
| 13077 |
| 13078 thread1.Join(); |
| 13079 thread2.Join(); |
| 13080 |
| 13081 // Compare results. The actual fibonacci numbers for 12 and 21 are taken |
| 13082 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number |
| 13083 CHECK_EQ(result1, 10946); |
| 13084 CHECK_EQ(result2, 144); |
| 13085 CHECK_EQ(result1, thread1.result()); |
| 13086 CHECK_EQ(result2, thread2.result()); |
| 13087 |
| 13088 isolate1->Dispose(); |
| 13089 isolate2->Dispose(); |
| 13090 } |
| 13091 |
| 13092 |
| 13093 class InitDefaultIsolateThread : public v8::internal::Thread { |
| 13094 public: |
| 13095 enum TestCase { IgnoreOOM, SetResourceConstraints, SetFatalHandler }; |
| 13096 |
| 13097 explicit InitDefaultIsolateThread(TestCase testCase) |
| 13098 : Thread(NULL), |
| 13099 testCase_(testCase), |
| 13100 result_(false) { } |
| 13101 |
| 13102 void Run() { |
| 13103 switch (testCase_) { |
| 13104 case IgnoreOOM: |
| 13105 v8::V8::IgnoreOutOfMemoryException(); |
| 13106 break; |
| 13107 |
| 13108 case SetResourceConstraints: { |
| 13109 static const int K = 1024; |
| 13110 v8::ResourceConstraints constraints; |
| 13111 constraints.set_max_young_space_size(256 * K); |
| 13112 constraints.set_max_old_space_size(4 * K * K); |
| 13113 v8::SetResourceConstraints(&constraints); |
| 13114 break; |
| 13115 } |
| 13116 |
| 13117 case SetFatalHandler: |
| 13118 v8::V8::SetFatalErrorHandler(NULL); |
| 13119 break; |
| 13120 } |
| 13121 result_ = true; |
| 13122 } |
| 13123 |
| 13124 bool result() { return result_; } |
| 13125 |
| 13126 private: |
| 13127 TestCase testCase_; |
| 13128 bool result_; |
| 13129 }; |
| 13130 |
| 13131 |
| 13132 static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { |
| 13133 InitDefaultIsolateThread thread(testCase); |
| 13134 thread.Start(); |
| 13135 thread.Join(); |
| 13136 CHECK_EQ(thread.result(), true); |
| 13137 } |
| 13138 |
| 13139 TEST(InitializeDefaultIsolateOnSecondaryThread1) { |
| 13140 InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); |
| 13141 } |
| 13142 |
| 13143 TEST(InitializeDefaultIsolateOnSecondaryThread2) { |
| 13144 InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); |
| 13145 } |
| 13146 |
| 13147 TEST(InitializeDefaultIsolateOnSecondaryThread3) { |
| 13148 InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); |
| 13149 } |
| 13150 |
12786 | 13151 |
12787 TEST(StringCheckMultipleContexts) { | 13152 TEST(StringCheckMultipleContexts) { |
12788 const char* code = | 13153 const char* code = |
12789 "(function() { return \"a\".charAt(0); })()"; | 13154 "(function() { return \"a\".charAt(0); })()"; |
12790 | 13155 |
12791 { | 13156 { |
12792 // Run the code twice in the first context to initialize the call IC. | 13157 // Run the code twice in the first context to initialize the call IC. |
12793 v8::HandleScope scope; | 13158 v8::HandleScope scope; |
12794 LocalContext context1; | 13159 LocalContext context1; |
12795 ExpectString(code, "a"); | 13160 ExpectString(code, "a"); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12879 ExpectBoolean("delete cell", true); | 13244 ExpectBoolean("delete cell", true); |
12880 ExpectString("(function() {" | 13245 ExpectString("(function() {" |
12881 " try {" | 13246 " try {" |
12882 " return readCell();" | 13247 " return readCell();" |
12883 " } catch(e) {" | 13248 " } catch(e) {" |
12884 " return e.toString();" | 13249 " return e.toString();" |
12885 " }" | 13250 " }" |
12886 "})()", | 13251 "})()", |
12887 "ReferenceError: cell is not defined"); | 13252 "ReferenceError: cell is not defined"); |
12888 CompileRun("cell = \"new_second\";"); | 13253 CompileRun("cell = \"new_second\";"); |
12889 i::Heap::CollectAllGarbage(true); | 13254 HEAP->CollectAllGarbage(true); |
12890 ExpectString("readCell()", "new_second"); | 13255 ExpectString("readCell()", "new_second"); |
12891 ExpectString("readCell()", "new_second"); | 13256 ExpectString("readCell()", "new_second"); |
12892 } | 13257 } |
12893 } | 13258 } |
12894 | 13259 |
12895 | 13260 |
12896 TEST(DontDeleteCellLoadICForceDelete) { | 13261 TEST(DontDeleteCellLoadICForceDelete) { |
12897 const char* function_code = | 13262 const char* function_code = |
12898 "function readCell() { while (true) { return cell; } }"; | 13263 "function readCell() { while (true) { return cell; } }"; |
12899 | 13264 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13110 v8::Handle<v8::Function> define_property = | 13475 v8::Handle<v8::Function> define_property = |
13111 CompileRun("(function() {" | 13476 CompileRun("(function() {" |
13112 " Object.defineProperty(" | 13477 " Object.defineProperty(" |
13113 " this," | 13478 " this," |
13114 " 1," | 13479 " 1," |
13115 " { configurable: true, enumerable: true, value: 3 });" | 13480 " { configurable: true, enumerable: true, value: 3 });" |
13116 "})").As<Function>(); | 13481 "})").As<Function>(); |
13117 context->DetachGlobal(); | 13482 context->DetachGlobal(); |
13118 define_property->Call(proxy, 0, NULL); | 13483 define_property->Call(proxy, 0, NULL); |
13119 } | 13484 } |
OLD | NEW |