| 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(i::Heap::kNoGCFlags); | 400 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 402 CHECK_EQ(0, TestResource::dispose_count); | 401 CHECK_EQ(0, TestResource::dispose_count); |
| 403 } | 402 } |
| 404 i::CompilationCache::Clear(); | 403 i::Isolate::Current()->compilation_cache()->Clear(); |
| 405 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 404 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 421 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 425 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 446 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 450 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 472 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 476 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 577 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 579 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 578 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 595 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 597 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 596 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 673 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 677 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 694 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 698 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 745 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 747 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 746 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1581 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1586 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1612 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1616 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1620 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1624 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1637 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1647 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1684 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1694 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1705 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 1716 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 4427 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 4445 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kNoGCFlags); | 7068 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 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(i::Heap::kForceCompactionMask); | 7798 HEAP->CollectAllGarbage(i::Heap::kForceCompactionMask); |
| 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9004 Local<Script> script = v8_compile("(function () {" | 9005 Local<Script> script = v8_compile("(function () {" |
| 9005 " unlock_for_a_moment();" | 9006 " unlock_for_a_moment();" |
| 9006 " return 42;" | 9007 " return 42;" |
| 9007 "})();"); | 9008 "})();"); |
| 9008 CHECK_EQ(42, script->Run()->Int32Value()); | 9009 CHECK_EQ(42, script->Run()->Int32Value()); |
| 9009 } | 9010 } |
| 9010 } | 9011 } |
| 9011 | 9012 |
| 9012 | 9013 |
| 9013 static int GetGlobalObjectsCount() { | 9014 static int GetGlobalObjectsCount() { |
| 9014 i::Heap::EnsureHeapIsIterable(); | 9015 i::Isolate::Current()->heap()->EnsureHeapIsIterable(); |
| 9015 int count = 0; | 9016 int count = 0; |
| 9016 i::HeapIterator it; | 9017 i::HeapIterator it; |
| 9017 for (i::HeapObject* object = it.Next(); object != NULL; object = it.Next()) | 9018 for (i::HeapObject* object = it.Next(); object != NULL; object = it.Next()) |
| 9018 if (object->IsJSGlobalObject()) count++; | 9019 if (object->IsJSGlobalObject()) count++; |
| 9019 return count; | 9020 return count; |
| 9020 } | 9021 } |
| 9021 | 9022 |
| 9022 | 9023 |
| 9023 static void CheckSurvivingGlobalObjectsCount(int expected) { | 9024 static void CheckSurvivingGlobalObjectsCount(int expected) { |
| 9024 // We need to collect all garbage twice to be sure that everything | 9025 // We need to collect all garbage twice to be sure that everything |
| 9025 // has been collected. This is because inline caches are cleared in | 9026 // has been collected. This is because inline caches are cleared in |
| 9026 // the first garbage collection but some of the maps have already | 9027 // the first garbage collection but some of the maps have already |
| 9027 // been marked at that point. Therefore some of the maps are not | 9028 // been marked at that point. Therefore some of the maps are not |
| 9028 // collected until the second garbage collection. | 9029 // collected until the second garbage collection. |
| 9029 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9030 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9030 i::Heap::CollectAllGarbage(i::Heap::kMakeHeapIterableMask); | 9031 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 9031 int count = GetGlobalObjectsCount(); | 9032 int count = GetGlobalObjectsCount(); |
| 9032 #ifdef DEBUG | 9033 #ifdef DEBUG |
| 9033 if (count != expected) i::Heap::TracePathToGlobal(); | 9034 if (count != expected) HEAP->TracePathToGlobal(); |
| 9034 #endif | 9035 #endif |
| 9035 CHECK_EQ(expected, count); | 9036 CHECK_EQ(expected, count); |
| 9036 } | 9037 } |
| 9037 | 9038 |
| 9038 | 9039 |
| 9039 TEST(DontLeakGlobalObjects) { | 9040 TEST(DontLeakGlobalObjects) { |
| 9040 // Regression test for issues 1139850 and 1174891. | 9041 // Regression test for issues 1139850 and 1174891. |
| 9041 | 9042 |
| 9042 v8::V8::Initialize(); | 9043 v8::V8::Initialize(); |
| 9043 | 9044 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9089 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9090 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9090 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9091 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9091 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9092 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9092 } | 9093 } |
| 9093 // Note: order is implementation dependent alas: currently | 9094 // Note: order is implementation dependent alas: currently |
| 9094 // global handle nodes are processed by PostGarbageCollectionProcessing | 9095 // global handle nodes are processed by PostGarbageCollectionProcessing |
| 9095 // in reverse allocation order, so if second allocated handle is deleted, | 9096 // in reverse allocation order, so if second allocated handle is deleted, |
| 9096 // weak callback of the first handle would be able to 'reallocate' it. | 9097 // weak callback of the first handle would be able to 'reallocate' it. |
| 9097 handle1.MakeWeak(NULL, NewPersistentHandleCallback); | 9098 handle1.MakeWeak(NULL, NewPersistentHandleCallback); |
| 9098 handle2.Dispose(); | 9099 handle2.Dispose(); |
| 9099 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9100 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9100 } | 9101 } |
| 9101 | 9102 |
| 9102 | 9103 |
| 9103 v8::Persistent<v8::Object> to_be_disposed; | 9104 v8::Persistent<v8::Object> to_be_disposed; |
| 9104 | 9105 |
| 9105 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { | 9106 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9106 to_be_disposed.Dispose(); | 9107 to_be_disposed.Dispose(); |
| 9107 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9108 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9108 handle.Dispose(); | 9109 handle.Dispose(); |
| 9109 } | 9110 } |
| 9110 | 9111 |
| 9111 | 9112 |
| 9112 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 9113 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
| 9113 LocalContext context; | 9114 LocalContext context; |
| 9114 | 9115 |
| 9115 v8::Persistent<v8::Object> handle1, handle2; | 9116 v8::Persistent<v8::Object> handle1, handle2; |
| 9116 { | 9117 { |
| 9117 v8::HandleScope scope; | 9118 v8::HandleScope scope; |
| 9118 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9119 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9119 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9120 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9120 } | 9121 } |
| 9121 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); | 9122 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); |
| 9122 to_be_disposed = handle2; | 9123 to_be_disposed = handle2; |
| 9123 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9124 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9124 } | 9125 } |
| 9125 | 9126 |
| 9126 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { | 9127 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9127 handle.Dispose(); | 9128 handle.Dispose(); |
| 9128 } | 9129 } |
| 9129 | 9130 |
| 9130 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { | 9131 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9131 v8::HandleScope scope; | 9132 v8::HandleScope scope; |
| 9132 v8::Persistent<v8::Object>::New(v8::Object::New()); | 9133 v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9133 handle.Dispose(); | 9134 handle.Dispose(); |
| 9134 } | 9135 } |
| 9135 | 9136 |
| 9136 | 9137 |
| 9137 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 9138 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
| 9138 LocalContext context; | 9139 LocalContext context; |
| 9139 | 9140 |
| 9140 v8::Persistent<v8::Object> handle1, handle2, handle3; | 9141 v8::Persistent<v8::Object> handle1, handle2, handle3; |
| 9141 { | 9142 { |
| 9142 v8::HandleScope scope; | 9143 v8::HandleScope scope; |
| 9143 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9144 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9144 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9145 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9145 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9146 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9146 } | 9147 } |
| 9147 handle2.MakeWeak(NULL, DisposingCallback); | 9148 handle2.MakeWeak(NULL, DisposingCallback); |
| 9148 handle3.MakeWeak(NULL, HandleCreatingCallback); | 9149 handle3.MakeWeak(NULL, HandleCreatingCallback); |
| 9149 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9150 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9150 } | 9151 } |
| 9151 | 9152 |
| 9152 | 9153 |
| 9153 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 9154 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
| 9154 v8::V8::Initialize(); | 9155 v8::V8::Initialize(); |
| 9155 | 9156 |
| 9156 const int nof = 2; | 9157 const int nof = 2; |
| 9157 const char* sources[nof] = { | 9158 const char* sources[nof] = { |
| 9158 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 9159 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
| 9159 "Object()" | 9160 "Object()" |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9385 const char* elmv1[] = {"a", "b"}; | 9386 const char* elmv1[] = {"a", "b"}; |
| 9386 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); | 9387 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); |
| 9387 int elmc2 = 3; | 9388 int elmc2 = 3; |
| 9388 const char* elmv2[] = {"0", "1", "2"}; | 9389 const char* elmv2[] = {"0", "1", "2"}; |
| 9389 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 9390 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
| 9390 int elmc3 = 4; | 9391 int elmc3 = 4; |
| 9391 const char* elmv3[] = {"w", "z", "x", "y"}; | 9392 const char* elmv3[] = {"w", "z", "x", "y"}; |
| 9392 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); | 9393 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); |
| 9393 } | 9394 } |
| 9394 | 9395 |
| 9396 THREADED_TEST(PropertyEnumeration2) { |
| 9397 v8::HandleScope scope; |
| 9398 LocalContext context; |
| 9399 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( |
| 9400 "var result = [];" |
| 9401 "result[0] = {};" |
| 9402 "result[1] = {a: 1, b: 2};" |
| 9403 "result[2] = [1, 2, 3];" |
| 9404 "var proto = {x: 1, y: 2, z: 3};" |
| 9405 "var x = { __proto__: proto, w: 0, z: 1 };" |
| 9406 "result[3] = x;" |
| 9407 "result;"))->Run(); |
| 9408 v8::Handle<v8::Array> elms = obj.As<v8::Array>(); |
| 9409 CHECK_EQ(4, elms->Length()); |
| 9410 int elmc0 = 0; |
| 9411 const char** elmv0 = NULL; |
| 9412 CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); |
| 9413 |
| 9414 v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0)); |
| 9415 v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); |
| 9416 CHECK_EQ(0, props->Length()); |
| 9417 for (uint32_t i = 0; i < props->Length(); i++) { |
| 9418 printf("p[%d]\n", i); |
| 9419 } |
| 9420 } |
| 9395 | 9421 |
| 9396 static bool NamedSetAccessBlocker(Local<v8::Object> obj, | 9422 static bool NamedSetAccessBlocker(Local<v8::Object> obj, |
| 9397 Local<Value> name, | 9423 Local<Value> name, |
| 9398 v8::AccessType type, | 9424 v8::AccessType type, |
| 9399 Local<Value> data) { | 9425 Local<Value> data) { |
| 9400 return type != v8::ACCESS_SET; | 9426 return type != v8::ACCESS_SET; |
| 9401 } | 9427 } |
| 9402 | 9428 |
| 9403 | 9429 |
| 9404 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, | 9430 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9877 class RegExpInterruptTest { | 9903 class RegExpInterruptTest { |
| 9878 public: | 9904 public: |
| 9879 RegExpInterruptTest() : block_(NULL) {} | 9905 RegExpInterruptTest() : block_(NULL) {} |
| 9880 ~RegExpInterruptTest() { delete block_; } | 9906 ~RegExpInterruptTest() { delete block_; } |
| 9881 void RunTest() { | 9907 void RunTest() { |
| 9882 block_ = i::OS::CreateSemaphore(0); | 9908 block_ = i::OS::CreateSemaphore(0); |
| 9883 gc_count_ = 0; | 9909 gc_count_ = 0; |
| 9884 gc_during_regexp_ = 0; | 9910 gc_during_regexp_ = 0; |
| 9885 regexp_success_ = false; | 9911 regexp_success_ = false; |
| 9886 gc_success_ = false; | 9912 gc_success_ = false; |
| 9887 GCThread gc_thread(this); | 9913 GCThread gc_thread(i::Isolate::Current(), this); |
| 9888 gc_thread.Start(); | 9914 gc_thread.Start(); |
| 9889 v8::Locker::StartPreemption(1); | 9915 v8::Locker::StartPreemption(1); |
| 9890 | 9916 |
| 9891 LongRunningRegExp(); | 9917 LongRunningRegExp(); |
| 9892 { | 9918 { |
| 9893 v8::Unlocker unlock; | 9919 v8::Unlocker unlock; |
| 9894 gc_thread.Join(); | 9920 gc_thread.Join(); |
| 9895 } | 9921 } |
| 9896 v8::Locker::StopPreemption(); | 9922 v8::Locker::StopPreemption(); |
| 9897 CHECK(regexp_success_); | 9923 CHECK(regexp_success_); |
| 9898 CHECK(gc_success_); | 9924 CHECK(gc_success_); |
| 9899 } | 9925 } |
| 9900 private: | 9926 private: |
| 9901 // Number of garbage collections required. | 9927 // Number of garbage collections required. |
| 9902 static const int kRequiredGCs = 5; | 9928 static const int kRequiredGCs = 5; |
| 9903 | 9929 |
| 9904 class GCThread : public i::Thread { | 9930 class GCThread : public i::Thread { |
| 9905 public: | 9931 public: |
| 9906 explicit GCThread(RegExpInterruptTest* test) | 9932 explicit GCThread(i::Isolate* isolate, RegExpInterruptTest* test) |
| 9907 : test_(test) {} | 9933 : Thread(isolate), test_(test) {} |
| 9908 virtual void Run() { | 9934 virtual void Run() { |
| 9909 test_->CollectGarbage(); | 9935 test_->CollectGarbage(); |
| 9910 } | 9936 } |
| 9911 private: | 9937 private: |
| 9912 RegExpInterruptTest* test_; | 9938 RegExpInterruptTest* test_; |
| 9913 }; | 9939 }; |
| 9914 | 9940 |
| 9915 void CollectGarbage() { | 9941 void CollectGarbage() { |
| 9916 block_->Wait(); | 9942 block_->Wait(); |
| 9917 while (gc_during_regexp_ < kRequiredGCs) { | 9943 while (gc_during_regexp_ < kRequiredGCs) { |
| 9918 { | 9944 { |
| 9919 v8::Locker lock; | 9945 v8::Locker lock; |
| 9920 // TODO(lrn): Perhaps create some garbage before collecting. | 9946 // TODO(lrn): Perhaps create some garbage before collecting. |
| 9921 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 9947 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9922 gc_count_++; | 9948 gc_count_++; |
| 9923 } | 9949 } |
| 9924 i::OS::Sleep(1); | 9950 i::OS::Sleep(1); |
| 9925 } | 9951 } |
| 9926 gc_success_ = true; | 9952 gc_success_ = true; |
| 9927 } | 9953 } |
| 9928 | 9954 |
| 9929 void LongRunningRegExp() { | 9955 void LongRunningRegExp() { |
| 9930 block_->Signal(); // Enable garbage collection thread on next preemption. | 9956 block_->Signal(); // Enable garbage collection thread on next preemption. |
| 9931 int rounds = 0; | 9957 int rounds = 0; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9999 class ApplyInterruptTest { | 10025 class ApplyInterruptTest { |
| 10000 public: | 10026 public: |
| 10001 ApplyInterruptTest() : block_(NULL) {} | 10027 ApplyInterruptTest() : block_(NULL) {} |
| 10002 ~ApplyInterruptTest() { delete block_; } | 10028 ~ApplyInterruptTest() { delete block_; } |
| 10003 void RunTest() { | 10029 void RunTest() { |
| 10004 block_ = i::OS::CreateSemaphore(0); | 10030 block_ = i::OS::CreateSemaphore(0); |
| 10005 gc_count_ = 0; | 10031 gc_count_ = 0; |
| 10006 gc_during_apply_ = 0; | 10032 gc_during_apply_ = 0; |
| 10007 apply_success_ = false; | 10033 apply_success_ = false; |
| 10008 gc_success_ = false; | 10034 gc_success_ = false; |
| 10009 GCThread gc_thread(this); | 10035 GCThread gc_thread(i::Isolate::Current(), this); |
| 10010 gc_thread.Start(); | 10036 gc_thread.Start(); |
| 10011 v8::Locker::StartPreemption(1); | 10037 v8::Locker::StartPreemption(1); |
| 10012 | 10038 |
| 10013 LongRunningApply(); | 10039 LongRunningApply(); |
| 10014 { | 10040 { |
| 10015 v8::Unlocker unlock; | 10041 v8::Unlocker unlock; |
| 10016 gc_thread.Join(); | 10042 gc_thread.Join(); |
| 10017 } | 10043 } |
| 10018 v8::Locker::StopPreemption(); | 10044 v8::Locker::StopPreemption(); |
| 10019 CHECK(apply_success_); | 10045 CHECK(apply_success_); |
| 10020 CHECK(gc_success_); | 10046 CHECK(gc_success_); |
| 10021 } | 10047 } |
| 10022 private: | 10048 private: |
| 10023 // Number of garbage collections required. | 10049 // Number of garbage collections required. |
| 10024 static const int kRequiredGCs = 2; | 10050 static const int kRequiredGCs = 2; |
| 10025 | 10051 |
| 10026 class GCThread : public i::Thread { | 10052 class GCThread : public i::Thread { |
| 10027 public: | 10053 public: |
| 10028 explicit GCThread(ApplyInterruptTest* test) | 10054 explicit GCThread(i::Isolate* isolate, ApplyInterruptTest* test) |
| 10029 : test_(test) {} | 10055 : Thread(isolate), test_(test) {} |
| 10030 virtual void Run() { | 10056 virtual void Run() { |
| 10031 test_->CollectGarbage(); | 10057 test_->CollectGarbage(); |
| 10032 } | 10058 } |
| 10033 private: | 10059 private: |
| 10034 ApplyInterruptTest* test_; | 10060 ApplyInterruptTest* test_; |
| 10035 }; | 10061 }; |
| 10036 | 10062 |
| 10037 void CollectGarbage() { | 10063 void CollectGarbage() { |
| 10038 block_->Wait(); | 10064 block_->Wait(); |
| 10039 while (gc_during_apply_ < kRequiredGCs) { | 10065 while (gc_during_apply_ < kRequiredGCs) { |
| 10040 { | 10066 { |
| 10041 v8::Locker lock; | 10067 v8::Locker lock; |
| 10042 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 10068 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10043 gc_count_++; | 10069 gc_count_++; |
| 10044 } | 10070 } |
| 10045 i::OS::Sleep(1); | 10071 i::OS::Sleep(1); |
| 10046 } | 10072 } |
| 10047 gc_success_ = true; | 10073 gc_success_ = true; |
| 10048 } | 10074 } |
| 10049 | 10075 |
| 10050 void LongRunningApply() { | 10076 void LongRunningApply() { |
| 10051 block_->Signal(); | 10077 block_->Signal(); |
| 10052 int rounds = 0; | 10078 int rounds = 0; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10161 i::Vector<const i::uc16> data_; | 10187 i::Vector<const i::uc16> data_; |
| 10162 }; | 10188 }; |
| 10163 | 10189 |
| 10164 | 10190 |
| 10165 static void MorphAString(i::String* string, | 10191 static void MorphAString(i::String* string, |
| 10166 AsciiVectorResource* ascii_resource, | 10192 AsciiVectorResource* ascii_resource, |
| 10167 UC16VectorResource* uc16_resource) { | 10193 UC16VectorResource* uc16_resource) { |
| 10168 CHECK(i::StringShape(string).IsExternal()); | 10194 CHECK(i::StringShape(string).IsExternal()); |
| 10169 if (string->IsAsciiRepresentation()) { | 10195 if (string->IsAsciiRepresentation()) { |
| 10170 // Check old map is not symbol or long. | 10196 // Check old map is not symbol or long. |
| 10171 CHECK(string->map() == i::Heap::external_ascii_string_map()); | 10197 CHECK(string->map() == HEAP->external_ascii_string_map()); |
| 10172 // Morph external string to be TwoByte string. | 10198 // Morph external string to be TwoByte string. |
| 10173 string->set_map(i::Heap::external_string_map()); | 10199 string->set_map(HEAP->external_string_map()); |
| 10174 i::ExternalTwoByteString* morphed = | 10200 i::ExternalTwoByteString* morphed = |
| 10175 i::ExternalTwoByteString::cast(string); | 10201 i::ExternalTwoByteString::cast(string); |
| 10176 morphed->set_resource(uc16_resource); | 10202 morphed->set_resource(uc16_resource); |
| 10177 } else { | 10203 } else { |
| 10178 // Check old map is not symbol or long. | 10204 // Check old map is not symbol or long. |
| 10179 CHECK(string->map() == i::Heap::external_string_map()); | 10205 CHECK(string->map() == HEAP->external_string_map()); |
| 10180 // Morph external string to be ASCII string. | 10206 // Morph external string to be ASCII string. |
| 10181 string->set_map(i::Heap::external_ascii_string_map()); | 10207 string->set_map(HEAP->external_ascii_string_map()); |
| 10182 i::ExternalAsciiString* morphed = | 10208 i::ExternalAsciiString* morphed = |
| 10183 i::ExternalAsciiString::cast(string); | 10209 i::ExternalAsciiString::cast(string); |
| 10184 morphed->set_resource(ascii_resource); | 10210 morphed->set_resource(ascii_resource); |
| 10185 } | 10211 } |
| 10186 } | 10212 } |
| 10187 | 10213 |
| 10188 | 10214 |
| 10189 // Test that we can still flatten a string if the components it is built up | 10215 // Test that we can still flatten a string if the components it is built up |
| 10190 // from have been turned into 16 bit strings in the mean time. | 10216 // from have been turned into 16 bit strings in the mean time. |
| 10191 THREADED_TEST(MorphCompositeStringTest) { | 10217 THREADED_TEST(MorphCompositeStringTest) { |
| 10192 const char* c_string = "Now is the time for all good men" | 10218 const char* c_string = "Now is the time for all good men" |
| 10193 " to come to the aid of the party"; | 10219 " to come to the aid of the party"; |
| 10194 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 10220 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); |
| 10195 { | 10221 { |
| 10196 v8::HandleScope scope; | 10222 v8::HandleScope scope; |
| 10197 LocalContext env; | 10223 LocalContext env; |
| 10198 AsciiVectorResource ascii_resource( | 10224 AsciiVectorResource ascii_resource( |
| 10199 i::Vector<const char>(c_string, i::StrLength(c_string))); | 10225 i::Vector<const char>(c_string, i::StrLength(c_string))); |
| 10200 UC16VectorResource uc16_resource( | 10226 UC16VectorResource uc16_resource( |
| 10201 i::Vector<const uint16_t>(two_byte_string, | 10227 i::Vector<const uint16_t>(two_byte_string, |
| 10202 i::StrLength(c_string))); | 10228 i::StrLength(c_string))); |
| 10203 | 10229 |
| 10204 Local<String> lhs(v8::Utils::ToLocal( | 10230 Local<String> lhs(v8::Utils::ToLocal( |
| 10205 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10231 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
| 10206 Local<String> rhs(v8::Utils::ToLocal( | 10232 Local<String> rhs(v8::Utils::ToLocal( |
| 10207 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10233 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
| 10208 | 10234 |
| 10209 env->Global()->Set(v8_str("lhs"), lhs); | 10235 env->Global()->Set(v8_str("lhs"), lhs); |
| 10210 env->Global()->Set(v8_str("rhs"), rhs); | 10236 env->Global()->Set(v8_str("rhs"), rhs); |
| 10211 | 10237 |
| 10212 CompileRun( | 10238 CompileRun( |
| 10213 "var cons = lhs + rhs;" | 10239 "var cons = lhs + rhs;" |
| 10214 "var slice = lhs.substring(1, lhs.length - 1);" | 10240 "var slice = lhs.substring(1, lhs.length - 1);" |
| 10215 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 10241 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); |
| 10216 | 10242 |
| 10217 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 10243 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10282 | 10308 |
| 10283 // Initialize the contents of two_byte_content_ to be a uc16 representation | 10309 // Initialize the contents of two_byte_content_ to be a uc16 representation |
| 10284 // of "aaaaaaaaaaaaaab". | 10310 // of "aaaaaaaaaaaaaab". |
| 10285 for (int i = 0; i < 14; i++) { | 10311 for (int i = 0; i < 14; i++) { |
| 10286 two_byte_content_[i] = 'a'; | 10312 two_byte_content_[i] = 'a'; |
| 10287 } | 10313 } |
| 10288 two_byte_content_[14] = 'b'; | 10314 two_byte_content_[14] = 'b'; |
| 10289 | 10315 |
| 10290 // Create the input string for the regexp - the one we are going to change | 10316 // Create the input string for the regexp - the one we are going to change |
| 10291 // properties of. | 10317 // properties of. |
| 10292 input_ = i::Factory::NewExternalStringFromAscii(&ascii_resource_); | 10318 input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_); |
| 10293 | 10319 |
| 10294 // Inject the input as a global variable. | 10320 // Inject the input as a global variable. |
| 10295 i::Handle<i::String> input_name = | 10321 i::Handle<i::String> input_name = |
| 10296 i::Factory::NewStringFromAscii(i::Vector<const char>("input", 5)); | 10322 FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5)); |
| 10297 i::Top::global_context()->global()->SetProperty( | 10323 i::Isolate::Current()->global_context()->global()->SetProperty( |
| 10298 *input_name, | 10324 *input_name, |
| 10299 *input_, | 10325 *input_, |
| 10300 NONE, | 10326 NONE, |
| 10301 i::kNonStrictMode)->ToObjectChecked(); | 10327 i::kNonStrictMode)->ToObjectChecked(); |
| 10302 | 10328 |
| 10303 MorphThread morph_thread(this); | 10329 MorphThread morph_thread(i::Isolate::Current(), this); |
| 10304 morph_thread.Start(); | 10330 morph_thread.Start(); |
| 10305 v8::Locker::StartPreemption(1); | 10331 v8::Locker::StartPreemption(1); |
| 10306 LongRunningRegExp(); | 10332 LongRunningRegExp(); |
| 10307 { | 10333 { |
| 10308 v8::Unlocker unlock; | 10334 v8::Unlocker unlock; |
| 10309 morph_thread.Join(); | 10335 morph_thread.Join(); |
| 10310 } | 10336 } |
| 10311 v8::Locker::StopPreemption(); | 10337 v8::Locker::StopPreemption(); |
| 10312 CHECK(regexp_success_); | 10338 CHECK(regexp_success_); |
| 10313 CHECK(morph_success_); | 10339 CHECK(morph_success_); |
| 10314 } | 10340 } |
| 10315 private: | 10341 private: |
| 10316 | 10342 |
| 10317 // Number of string modifications required. | 10343 // Number of string modifications required. |
| 10318 static const int kRequiredModifications = 5; | 10344 static const int kRequiredModifications = 5; |
| 10319 static const int kMaxModifications = 100; | 10345 static const int kMaxModifications = 100; |
| 10320 | 10346 |
| 10321 class MorphThread : public i::Thread { | 10347 class MorphThread : public i::Thread { |
| 10322 public: | 10348 public: |
| 10323 explicit MorphThread(RegExpStringModificationTest* test) | 10349 explicit MorphThread(i::Isolate* isolate, |
| 10324 : test_(test) {} | 10350 RegExpStringModificationTest* test) |
| 10351 : Thread(isolate), test_(test) {} |
| 10325 virtual void Run() { | 10352 virtual void Run() { |
| 10326 test_->MorphString(); | 10353 test_->MorphString(); |
| 10327 } | 10354 } |
| 10328 private: | 10355 private: |
| 10329 RegExpStringModificationTest* test_; | 10356 RegExpStringModificationTest* test_; |
| 10330 }; | 10357 }; |
| 10331 | 10358 |
| 10332 void MorphString() { | 10359 void MorphString() { |
| 10333 block_->Wait(); | 10360 block_->Wait(); |
| 10334 while (morphs_during_regexp_ < kRequiredModifications && | 10361 while (morphs_during_regexp_ < kRequiredModifications && |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10747 } | 10774 } |
| 10748 | 10775 |
| 10749 | 10776 |
| 10750 THREADED_TEST(PixelArray) { | 10777 THREADED_TEST(PixelArray) { |
| 10751 v8::HandleScope scope; | 10778 v8::HandleScope scope; |
| 10752 LocalContext context; | 10779 LocalContext context; |
| 10753 const int kElementCount = 260; | 10780 const int kElementCount = 260; |
| 10754 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 10781 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 10755 i::Handle<i::ExternalPixelArray> pixels = | 10782 i::Handle<i::ExternalPixelArray> pixels = |
| 10756 i::Handle<i::ExternalPixelArray>::cast( | 10783 i::Handle<i::ExternalPixelArray>::cast( |
| 10757 i::Factory::NewExternalArray(kElementCount, | 10784 FACTORY->NewExternalArray(kElementCount, |
| 10758 v8::kExternalPixelArray, | 10785 v8::kExternalPixelArray, |
| 10759 pixel_data)); | 10786 pixel_data)); |
| 10760 // Force GC to trigger verification. | 10787 // Force GC to trigger verification. |
| 10761 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 10788 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10762 for (int i = 0; i < kElementCount; i++) { | 10789 for (int i = 0; i < kElementCount; i++) { |
| 10763 pixels->set(i, i % 256); | 10790 pixels->set(i, i % 256); |
| 10764 } | 10791 } |
| 10765 // Force GC to trigger verification. | 10792 // Force GC to trigger verification. |
| 10766 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 10793 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10767 for (int i = 0; i < kElementCount; i++) { | 10794 for (int i = 0; i < kElementCount; i++) { |
| 10768 CHECK_EQ(i % 256, pixels->get(i)); | 10795 CHECK_EQ(i % 256, pixels->get(i)); |
| 10769 CHECK_EQ(i % 256, pixel_data[i]); | 10796 CHECK_EQ(i % 256, pixel_data[i]); |
| 10770 } | 10797 } |
| 10771 | 10798 |
| 10772 v8::Handle<v8::Object> obj = v8::Object::New(); | 10799 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 10773 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 10800 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 10774 // Set the elements to be the pixels. | 10801 // Set the elements to be the pixels. |
| 10775 // jsobj->set_elements(*pixels); | 10802 // jsobj->set_elements(*pixels); |
| 10776 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 10803 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11158 } | 11185 } |
| 11159 | 11186 |
| 11160 | 11187 |
| 11161 THREADED_TEST(PixelArrayWithInterceptor) { | 11188 THREADED_TEST(PixelArrayWithInterceptor) { |
| 11162 v8::HandleScope scope; | 11189 v8::HandleScope scope; |
| 11163 LocalContext context; | 11190 LocalContext context; |
| 11164 const int kElementCount = 260; | 11191 const int kElementCount = 260; |
| 11165 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 11192 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 11166 i::Handle<i::ExternalPixelArray> pixels = | 11193 i::Handle<i::ExternalPixelArray> pixels = |
| 11167 i::Handle<i::ExternalPixelArray>::cast( | 11194 i::Handle<i::ExternalPixelArray>::cast( |
| 11168 i::Factory::NewExternalArray(kElementCount, | 11195 FACTORY->NewExternalArray(kElementCount, |
| 11169 v8::kExternalPixelArray, | 11196 v8::kExternalPixelArray, |
| 11170 pixel_data)); | 11197 pixel_data)); |
| 11171 for (int i = 0; i < kElementCount; i++) { | 11198 for (int i = 0; i < kElementCount; i++) { |
| 11172 pixels->set(i, i % 256); | 11199 pixels->set(i, i % 256); |
| 11173 } | 11200 } |
| 11174 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); | 11201 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |
| 11175 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, | 11202 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, |
| 11176 NotHandledIndexedPropertySetter); | 11203 NotHandledIndexedPropertySetter); |
| 11177 v8::Handle<v8::Object> obj = templ->NewInstance(); | 11204 v8::Handle<v8::Object> obj = templ->NewInstance(); |
| 11178 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 11205 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| 11179 context->Global()->Set(v8_str("pixels"), obj); | 11206 context->Global()->Set(v8_str("pixels"), obj); |
| 11180 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); | 11207 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11221 int64_t low, | 11248 int64_t low, |
| 11222 int64_t high) { | 11249 int64_t high) { |
| 11223 v8::HandleScope scope; | 11250 v8::HandleScope scope; |
| 11224 LocalContext context; | 11251 LocalContext context; |
| 11225 const int kElementCount = 40; | 11252 const int kElementCount = 40; |
| 11226 int element_size = ExternalArrayElementSize(array_type); | 11253 int element_size = ExternalArrayElementSize(array_type); |
| 11227 ElementType* array_data = | 11254 ElementType* array_data = |
| 11228 static_cast<ElementType*>(malloc(kElementCount * element_size)); | 11255 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
| 11229 i::Handle<ExternalArrayClass> array = | 11256 i::Handle<ExternalArrayClass> array = |
| 11230 i::Handle<ExternalArrayClass>::cast( | 11257 i::Handle<ExternalArrayClass>::cast( |
| 11231 i::Factory::NewExternalArray(kElementCount, array_type, array_data)); | 11258 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); |
| 11232 // Force GC to trigger verification. | 11259 // Force GC to trigger verification. |
| 11233 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 11260 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11234 for (int i = 0; i < kElementCount; i++) { | 11261 for (int i = 0; i < kElementCount; i++) { |
| 11235 array->set(i, static_cast<ElementType>(i)); | 11262 array->set(i, static_cast<ElementType>(i)); |
| 11236 } | 11263 } |
| 11237 // Force GC to trigger verification. | 11264 // Force GC to trigger verification. |
| 11238 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 11265 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11239 for (int i = 0; i < kElementCount; i++) { | 11266 for (int i = 0; i < kElementCount; i++) { |
| 11240 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); | 11267 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); |
| 11241 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); | 11268 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
| 11242 } | 11269 } |
| 11243 | 11270 |
| 11244 v8::Handle<v8::Object> obj = v8::Object::New(); | 11271 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 11245 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 11272 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 11246 // Set the elements to be the external array. | 11273 // Set the elements to be the external array. |
| 11247 obj->SetIndexedPropertiesToExternalArrayData(array_data, | 11274 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
| 11248 array_type, | 11275 array_type, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11346 "var sum = 0;" | 11373 "var sum = 0;" |
| 11347 "for (var i = 0; i < 8; i++) {" | 11374 "for (var i = 0; i < 8; i++) {" |
| 11348 " tmp_array[i] = i;" | 11375 " tmp_array[i] = i;" |
| 11349 " sum += tmp_array[i];" | 11376 " sum += tmp_array[i];" |
| 11350 " if (i == 4) {" | 11377 " if (i == 4) {" |
| 11351 " tmp_array = {};" | 11378 " tmp_array = {};" |
| 11352 " }" | 11379 " }" |
| 11353 "}" | 11380 "}" |
| 11354 "sum;"); | 11381 "sum;"); |
| 11355 // Force GC to trigger verification. | 11382 // Force GC to trigger verification. |
| 11356 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 11383 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11357 CHECK_EQ(28, result->Int32Value()); | 11384 CHECK_EQ(28, result->Int32Value()); |
| 11358 | 11385 |
| 11359 // Make sure out-of-range loads do not throw. | 11386 // Make sure out-of-range loads do not throw. |
| 11360 i::OS::SNPrintF(test_buf, | 11387 i::OS::SNPrintF(test_buf, |
| 11361 "var caught_exception = false;" | 11388 "var caught_exception = false;" |
| 11362 "try {" | 11389 "try {" |
| 11363 " ext_array[%d];" | 11390 " ext_array[%d];" |
| 11364 "} catch (e) {" | 11391 "} catch (e) {" |
| 11365 " caught_exception = true;" | 11392 " caught_exception = true;" |
| 11366 "}" | 11393 "}" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11503 // This catches bugs in the instructions used for the KeyedLoadIC | 11530 // This catches bugs in the instructions used for the KeyedLoadIC |
| 11504 // for byte and word types. | 11531 // for byte and word types. |
| 11505 { | 11532 { |
| 11506 const int kXSize = 300; | 11533 const int kXSize = 300; |
| 11507 const int kYSize = 300; | 11534 const int kYSize = 300; |
| 11508 const int kLargeElementCount = kXSize * kYSize * 4; | 11535 const int kLargeElementCount = kXSize * kYSize * 4; |
| 11509 ElementType* large_array_data = | 11536 ElementType* large_array_data = |
| 11510 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); | 11537 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); |
| 11511 i::Handle<ExternalArrayClass> large_array = | 11538 i::Handle<ExternalArrayClass> large_array = |
| 11512 i::Handle<ExternalArrayClass>::cast( | 11539 i::Handle<ExternalArrayClass>::cast( |
| 11513 i::Factory::NewExternalArray(kLargeElementCount, | 11540 FACTORY->NewExternalArray(kLargeElementCount, |
| 11514 array_type, | 11541 array_type, |
| 11515 array_data)); | 11542 array_data)); |
| 11516 v8::Handle<v8::Object> large_obj = v8::Object::New(); | 11543 v8::Handle<v8::Object> large_obj = v8::Object::New(); |
| 11517 // Set the elements to be the external array. | 11544 // Set the elements to be the external array. |
| 11518 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, | 11545 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, |
| 11519 array_type, | 11546 array_type, |
| 11520 kLargeElementCount); | 11547 kLargeElementCount); |
| 11521 context->Global()->Set(v8_str("large_array"), large_obj); | 11548 context->Global()->Set(v8_str("large_array"), large_obj); |
| 11522 // Initialize contents of a few rows. | 11549 // Initialize contents of a few rows. |
| 11523 for (int x = 0; x < 300; x++) { | 11550 for (int x = 0; x < 300; x++) { |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11939 if (rv) | 11966 if (rv) |
| 11940 break; | 11967 break; |
| 11941 } | 11968 } |
| 11942 CHECK(rv == true); | 11969 CHECK(rv == true); |
| 11943 } | 11970 } |
| 11944 | 11971 |
| 11945 | 11972 |
| 11946 static uint32_t* stack_limit; | 11973 static uint32_t* stack_limit; |
| 11947 | 11974 |
| 11948 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { | 11975 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { |
| 11949 stack_limit = reinterpret_cast<uint32_t*>(i::StackGuard::real_climit()); | 11976 stack_limit = reinterpret_cast<uint32_t*>( |
| 11977 i::Isolate::Current()->stack_guard()->real_climit()); |
| 11950 return v8::Undefined(); | 11978 return v8::Undefined(); |
| 11951 } | 11979 } |
| 11952 | 11980 |
| 11953 | 11981 |
| 11954 // Uses the address of a local variable to determine the stack top now. | 11982 // Uses the address of a local variable to determine the stack top now. |
| 11955 // Given a size, returns an address that is that far from the current | 11983 // Given a size, returns an address that is that far from the current |
| 11956 // top of stack. | 11984 // top of stack. |
| 11957 static uint32_t* ComputeStackLimit(uint32_t size) { | 11985 static uint32_t* ComputeStackLimit(uint32_t size) { |
| 11958 uint32_t* answer = &size - (size / sizeof(size)); | 11986 uint32_t* answer = &size - (size / sizeof(size)); |
| 11959 // If the size is very large and the stack is very near the bottom of | 11987 // 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... |
| 12205 Local<v8::String> obj = v8::String::New(""); | 12233 Local<v8::String> obj = v8::String::New(""); |
| 12206 context->SetData(obj); | 12234 context->SetData(obj); |
| 12207 CompileRun(source_simple); | 12235 CompileRun(source_simple); |
| 12208 context->Exit(); | 12236 context->Exit(); |
| 12209 } | 12237 } |
| 12210 context.Dispose(); | 12238 context.Dispose(); |
| 12211 for (gc_count = 1; gc_count < 10; gc_count++) { | 12239 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12212 other_context->Enter(); | 12240 other_context->Enter(); |
| 12213 CompileRun(source_simple); | 12241 CompileRun(source_simple); |
| 12214 other_context->Exit(); | 12242 other_context->Exit(); |
| 12215 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12243 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12216 if (GetGlobalObjectsCount() == 1) break; | 12244 if (GetGlobalObjectsCount() == 1) break; |
| 12217 } | 12245 } |
| 12218 CHECK_GE(2, gc_count); | 12246 CHECK_GE(2, gc_count); |
| 12219 CHECK_EQ(1, GetGlobalObjectsCount()); | 12247 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12220 | 12248 |
| 12221 // Eval in a function creates reference from the compilation cache to the | 12249 // Eval in a function creates reference from the compilation cache to the |
| 12222 // global object. | 12250 // global object. |
| 12223 const char* source_eval = "function f(){eval('1')}; f()"; | 12251 const char* source_eval = "function f(){eval('1')}; f()"; |
| 12224 context = Context::New(); | 12252 context = Context::New(); |
| 12225 { | 12253 { |
| 12226 v8::HandleScope scope; | 12254 v8::HandleScope scope; |
| 12227 | 12255 |
| 12228 context->Enter(); | 12256 context->Enter(); |
| 12229 CompileRun(source_eval); | 12257 CompileRun(source_eval); |
| 12230 context->Exit(); | 12258 context->Exit(); |
| 12231 } | 12259 } |
| 12232 context.Dispose(); | 12260 context.Dispose(); |
| 12233 for (gc_count = 1; gc_count < 10; gc_count++) { | 12261 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12234 other_context->Enter(); | 12262 other_context->Enter(); |
| 12235 CompileRun(source_eval); | 12263 CompileRun(source_eval); |
| 12236 other_context->Exit(); | 12264 other_context->Exit(); |
| 12237 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12265 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12238 if (GetGlobalObjectsCount() == 1) break; | 12266 if (GetGlobalObjectsCount() == 1) break; |
| 12239 } | 12267 } |
| 12240 CHECK_GE(2, gc_count); | 12268 CHECK_GE(2, gc_count); |
| 12241 CHECK_EQ(1, GetGlobalObjectsCount()); | 12269 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12242 | 12270 |
| 12243 // Looking up the line number for an exception creates reference from the | 12271 // Looking up the line number for an exception creates reference from the |
| 12244 // compilation cache to the global object. | 12272 // compilation cache to the global object. |
| 12245 const char* source_exception = "function f(){throw 1;} f()"; | 12273 const char* source_exception = "function f(){throw 1;} f()"; |
| 12246 context = Context::New(); | 12274 context = Context::New(); |
| 12247 { | 12275 { |
| 12248 v8::HandleScope scope; | 12276 v8::HandleScope scope; |
| 12249 | 12277 |
| 12250 context->Enter(); | 12278 context->Enter(); |
| 12251 v8::TryCatch try_catch; | 12279 v8::TryCatch try_catch; |
| 12252 CompileRun(source_exception); | 12280 CompileRun(source_exception); |
| 12253 CHECK(try_catch.HasCaught()); | 12281 CHECK(try_catch.HasCaught()); |
| 12254 v8::Handle<v8::Message> message = try_catch.Message(); | 12282 v8::Handle<v8::Message> message = try_catch.Message(); |
| 12255 CHECK(!message.IsEmpty()); | 12283 CHECK(!message.IsEmpty()); |
| 12256 CHECK_EQ(1, message->GetLineNumber()); | 12284 CHECK_EQ(1, message->GetLineNumber()); |
| 12257 context->Exit(); | 12285 context->Exit(); |
| 12258 } | 12286 } |
| 12259 context.Dispose(); | 12287 context.Dispose(); |
| 12260 for (gc_count = 1; gc_count < 10; gc_count++) { | 12288 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12261 other_context->Enter(); | 12289 other_context->Enter(); |
| 12262 CompileRun(source_exception); | 12290 CompileRun(source_exception); |
| 12263 other_context->Exit(); | 12291 other_context->Exit(); |
| 12264 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12292 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12265 if (GetGlobalObjectsCount() == 1) break; | 12293 if (GetGlobalObjectsCount() == 1) break; |
| 12266 } | 12294 } |
| 12267 CHECK_GE(2, gc_count); | 12295 CHECK_GE(2, gc_count); |
| 12268 CHECK_EQ(1, GetGlobalObjectsCount()); | 12296 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12269 | 12297 |
| 12270 other_context.Dispose(); | 12298 other_context.Dispose(); |
| 12271 } | 12299 } |
| 12272 | 12300 |
| 12273 | 12301 |
| 12274 THREADED_TEST(ScriptOrigin) { | 12302 THREADED_TEST(ScriptOrigin) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12472 ++epilogue_call_count_second; | 12500 ++epilogue_call_count_second; |
| 12473 } | 12501 } |
| 12474 | 12502 |
| 12475 TEST(GCCallbacks) { | 12503 TEST(GCCallbacks) { |
| 12476 LocalContext context; | 12504 LocalContext context; |
| 12477 | 12505 |
| 12478 v8::V8::AddGCPrologueCallback(PrologueCallback); | 12506 v8::V8::AddGCPrologueCallback(PrologueCallback); |
| 12479 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 12507 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
| 12480 CHECK_EQ(0, prologue_call_count); | 12508 CHECK_EQ(0, prologue_call_count); |
| 12481 CHECK_EQ(0, epilogue_call_count); | 12509 CHECK_EQ(0, epilogue_call_count); |
| 12482 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12510 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12483 CHECK_EQ(1, prologue_call_count); | 12511 CHECK_EQ(1, prologue_call_count); |
| 12484 CHECK_EQ(1, epilogue_call_count); | 12512 CHECK_EQ(1, epilogue_call_count); |
| 12485 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); | 12513 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); |
| 12486 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); | 12514 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); |
| 12487 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12515 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12488 CHECK_EQ(2, prologue_call_count); | 12516 CHECK_EQ(2, prologue_call_count); |
| 12489 CHECK_EQ(2, epilogue_call_count); | 12517 CHECK_EQ(2, epilogue_call_count); |
| 12490 CHECK_EQ(1, prologue_call_count_second); | 12518 CHECK_EQ(1, prologue_call_count_second); |
| 12491 CHECK_EQ(1, epilogue_call_count_second); | 12519 CHECK_EQ(1, epilogue_call_count_second); |
| 12492 v8::V8::RemoveGCPrologueCallback(PrologueCallback); | 12520 v8::V8::RemoveGCPrologueCallback(PrologueCallback); |
| 12493 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); | 12521 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); |
| 12494 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12522 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12495 CHECK_EQ(2, prologue_call_count); | 12523 CHECK_EQ(2, prologue_call_count); |
| 12496 CHECK_EQ(2, epilogue_call_count); | 12524 CHECK_EQ(2, epilogue_call_count); |
| 12497 CHECK_EQ(2, prologue_call_count_second); | 12525 CHECK_EQ(2, prologue_call_count_second); |
| 12498 CHECK_EQ(2, epilogue_call_count_second); | 12526 CHECK_EQ(2, epilogue_call_count_second); |
| 12499 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); | 12527 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); |
| 12500 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); | 12528 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); |
| 12501 i::Heap::CollectAllGarbage(i::Heap::kNoGCFlags); | 12529 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12502 CHECK_EQ(2, prologue_call_count); | 12530 CHECK_EQ(2, prologue_call_count); |
| 12503 CHECK_EQ(2, epilogue_call_count); | 12531 CHECK_EQ(2, epilogue_call_count); |
| 12504 CHECK_EQ(2, prologue_call_count_second); | 12532 CHECK_EQ(2, prologue_call_count_second); |
| 12505 CHECK_EQ(2, epilogue_call_count_second); | 12533 CHECK_EQ(2, epilogue_call_count_second); |
| 12506 } | 12534 } |
| 12507 | 12535 |
| 12508 | 12536 |
| 12509 THREADED_TEST(AddToJSFunctionResultCache) { | 12537 THREADED_TEST(AddToJSFunctionResultCache) { |
| 12510 i::FLAG_allow_natives_syntax = true; | 12538 i::FLAG_allow_natives_syntax = true; |
| 12511 v8::HandleScope scope; | 12539 v8::HandleScope scope; |
| 12512 | 12540 |
| 12513 LocalContext context; | 12541 LocalContext context; |
| 12514 | 12542 |
| 12515 const char* code = | 12543 const char* code = |
| 12516 "(function() {" | 12544 "(function() {" |
| 12517 " var key0 = 'a';" | 12545 " var key0 = 'a';" |
| 12518 " var key1 = 'b';" | 12546 " var key1 = 'b';" |
| 12519 " var r0 = %_GetFromCache(0, key0);" | 12547 " var r0 = %_GetFromCache(0, key0);" |
| 12520 " var r1 = %_GetFromCache(0, key1);" | 12548 " var r1 = %_GetFromCache(0, key1);" |
| 12521 " var r0_ = %_GetFromCache(0, key0);" | 12549 " var r0_ = %_GetFromCache(0, key0);" |
| 12522 " if (r0 !== r0_)" | 12550 " if (r0 !== r0_)" |
| 12523 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" | 12551 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" |
| 12524 " var r1_ = %_GetFromCache(0, key1);" | 12552 " var r1_ = %_GetFromCache(0, key1);" |
| 12525 " if (r1 !== r1_)" | 12553 " if (r1 !== r1_)" |
| 12526 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" | 12554 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" |
| 12527 " return 'PASSED';" | 12555 " return 'PASSED';" |
| 12528 "})()"; | 12556 "})()"; |
| 12529 i::Heap::ClearJSFunctionResultCaches(); | 12557 HEAP->ClearJSFunctionResultCaches(); |
| 12530 ExpectString(code, "PASSED"); | 12558 ExpectString(code, "PASSED"); |
| 12531 } | 12559 } |
| 12532 | 12560 |
| 12533 | 12561 |
| 12534 static const int k0CacheSize = 16; | 12562 static const int k0CacheSize = 16; |
| 12535 | 12563 |
| 12536 THREADED_TEST(FillJSFunctionResultCache) { | 12564 THREADED_TEST(FillJSFunctionResultCache) { |
| 12537 i::FLAG_allow_natives_syntax = true; | 12565 i::FLAG_allow_natives_syntax = true; |
| 12538 v8::HandleScope scope; | 12566 v8::HandleScope scope; |
| 12539 | 12567 |
| 12540 LocalContext context; | 12568 LocalContext context; |
| 12541 | 12569 |
| 12542 const char* code = | 12570 const char* code = |
| 12543 "(function() {" | 12571 "(function() {" |
| 12544 " var k = 'a';" | 12572 " var k = 'a';" |
| 12545 " var r = %_GetFromCache(0, k);" | 12573 " var r = %_GetFromCache(0, k);" |
| 12546 " for (var i = 0; i < 16; i++) {" | 12574 " for (var i = 0; i < 16; i++) {" |
| 12547 " %_GetFromCache(0, 'a' + i);" | 12575 " %_GetFromCache(0, 'a' + i);" |
| 12548 " };" | 12576 " };" |
| 12549 " if (r === %_GetFromCache(0, k))" | 12577 " if (r === %_GetFromCache(0, k))" |
| 12550 " return 'FAILED: k0CacheSize is too small';" | 12578 " return 'FAILED: k0CacheSize is too small';" |
| 12551 " return 'PASSED';" | 12579 " return 'PASSED';" |
| 12552 "})()"; | 12580 "})()"; |
| 12553 i::Heap::ClearJSFunctionResultCaches(); | 12581 HEAP->ClearJSFunctionResultCaches(); |
| 12554 ExpectString(code, "PASSED"); | 12582 ExpectString(code, "PASSED"); |
| 12555 } | 12583 } |
| 12556 | 12584 |
| 12557 | 12585 |
| 12558 THREADED_TEST(RoundRobinGetFromCache) { | 12586 THREADED_TEST(RoundRobinGetFromCache) { |
| 12559 i::FLAG_allow_natives_syntax = true; | 12587 i::FLAG_allow_natives_syntax = true; |
| 12560 v8::HandleScope scope; | 12588 v8::HandleScope scope; |
| 12561 | 12589 |
| 12562 LocalContext context; | 12590 LocalContext context; |
| 12563 | 12591 |
| 12564 const char* code = | 12592 const char* code = |
| 12565 "(function() {" | 12593 "(function() {" |
| 12566 " var keys = [];" | 12594 " var keys = [];" |
| 12567 " for (var i = 0; i < 16; i++) keys.push(i);" | 12595 " for (var i = 0; i < 16; i++) keys.push(i);" |
| 12568 " var values = [];" | 12596 " var values = [];" |
| 12569 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12597 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
| 12570 " for (var i = 0; i < 16; i++) {" | 12598 " for (var i = 0; i < 16; i++) {" |
| 12571 " var v = %_GetFromCache(0, keys[i]);" | 12599 " var v = %_GetFromCache(0, keys[i]);" |
| 12572 " if (v !== values[i])" | 12600 " if (v !== values[i])" |
| 12573 " return 'Wrong value for ' + " | 12601 " return 'Wrong value for ' + " |
| 12574 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12602 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
| 12575 " };" | 12603 " };" |
| 12576 " return 'PASSED';" | 12604 " return 'PASSED';" |
| 12577 "})()"; | 12605 "})()"; |
| 12578 i::Heap::ClearJSFunctionResultCaches(); | 12606 HEAP->ClearJSFunctionResultCaches(); |
| 12579 ExpectString(code, "PASSED"); | 12607 ExpectString(code, "PASSED"); |
| 12580 } | 12608 } |
| 12581 | 12609 |
| 12582 | 12610 |
| 12583 THREADED_TEST(ReverseGetFromCache) { | 12611 THREADED_TEST(ReverseGetFromCache) { |
| 12584 i::FLAG_allow_natives_syntax = true; | 12612 i::FLAG_allow_natives_syntax = true; |
| 12585 v8::HandleScope scope; | 12613 v8::HandleScope scope; |
| 12586 | 12614 |
| 12587 LocalContext context; | 12615 LocalContext context; |
| 12588 | 12616 |
| 12589 const char* code = | 12617 const char* code = |
| 12590 "(function() {" | 12618 "(function() {" |
| 12591 " var keys = [];" | 12619 " var keys = [];" |
| 12592 " for (var i = 0; i < 16; i++) keys.push(i);" | 12620 " for (var i = 0; i < 16; i++) keys.push(i);" |
| 12593 " var values = [];" | 12621 " var values = [];" |
| 12594 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12622 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
| 12595 " for (var i = 15; i >= 16; i--) {" | 12623 " for (var i = 15; i >= 16; i--) {" |
| 12596 " var v = %_GetFromCache(0, keys[i]);" | 12624 " var v = %_GetFromCache(0, keys[i]);" |
| 12597 " if (v !== values[i])" | 12625 " if (v !== values[i])" |
| 12598 " return 'Wrong value for ' + " | 12626 " return 'Wrong value for ' + " |
| 12599 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12627 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
| 12600 " };" | 12628 " };" |
| 12601 " return 'PASSED';" | 12629 " return 'PASSED';" |
| 12602 "})()"; | 12630 "})()"; |
| 12603 i::Heap::ClearJSFunctionResultCaches(); | 12631 HEAP->ClearJSFunctionResultCaches(); |
| 12604 ExpectString(code, "PASSED"); | 12632 ExpectString(code, "PASSED"); |
| 12605 } | 12633 } |
| 12606 | 12634 |
| 12607 | 12635 |
| 12608 THREADED_TEST(TestEviction) { | 12636 THREADED_TEST(TestEviction) { |
| 12609 i::FLAG_allow_natives_syntax = true; | 12637 i::FLAG_allow_natives_syntax = true; |
| 12610 v8::HandleScope scope; | 12638 v8::HandleScope scope; |
| 12611 | 12639 |
| 12612 LocalContext context; | 12640 LocalContext context; |
| 12613 | 12641 |
| 12614 const char* code = | 12642 const char* code = |
| 12615 "(function() {" | 12643 "(function() {" |
| 12616 " for (var i = 0; i < 2*16; i++) {" | 12644 " for (var i = 0; i < 2*16; i++) {" |
| 12617 " %_GetFromCache(0, 'a' + i);" | 12645 " %_GetFromCache(0, 'a' + i);" |
| 12618 " };" | 12646 " };" |
| 12619 " return 'PASSED';" | 12647 " return 'PASSED';" |
| 12620 "})()"; | 12648 "})()"; |
| 12621 i::Heap::ClearJSFunctionResultCaches(); | 12649 HEAP->ClearJSFunctionResultCaches(); |
| 12622 ExpectString(code, "PASSED"); | 12650 ExpectString(code, "PASSED"); |
| 12623 } | 12651 } |
| 12624 | 12652 |
| 12625 | 12653 |
| 12626 THREADED_TEST(TwoByteStringInAsciiCons) { | 12654 THREADED_TEST(TwoByteStringInAsciiCons) { |
| 12627 // See Chromium issue 47824. | 12655 // See Chromium issue 47824. |
| 12628 v8::HandleScope scope; | 12656 v8::HandleScope scope; |
| 12629 | 12657 |
| 12630 LocalContext context; | 12658 LocalContext context; |
| 12631 const char* init_code = | 12659 const char* init_code = |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12701 | 12729 |
| 12702 reresult = CompileRun("str2.charCodeAt(2);"); | 12730 reresult = CompileRun("str2.charCodeAt(2);"); |
| 12703 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); | 12731 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
| 12704 } | 12732 } |
| 12705 | 12733 |
| 12706 | 12734 |
| 12707 // Failed access check callback that performs a GC on each invocation. | 12735 // Failed access check callback that performs a GC on each invocation. |
| 12708 void FailedAccessCheckCallbackGC(Local<v8::Object> target, | 12736 void FailedAccessCheckCallbackGC(Local<v8::Object> target, |
| 12709 v8::AccessType type, | 12737 v8::AccessType type, |
| 12710 Local<v8::Value> data) { | 12738 Local<v8::Value> data) { |
| 12711 i::Heap::CollectAllGarbage(i::Heap::kForceCompactionMask); | 12739 HEAP->CollectAllGarbage(i::Heap::kForceCompactionMask); |
| 12712 } | 12740 } |
| 12713 | 12741 |
| 12714 | 12742 |
| 12715 TEST(GCInFailedAccessCheckCallback) { | 12743 TEST(GCInFailedAccessCheckCallback) { |
| 12716 // Install a failed access check callback that performs a GC on each | 12744 // Install a failed access check callback that performs a GC on each |
| 12717 // invocation. Then force the callback to be called from va | 12745 // invocation. Then force the callback to be called from va |
| 12718 | 12746 |
| 12719 v8::V8::Initialize(); | 12747 v8::V8::Initialize(); |
| 12720 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 12748 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
| 12721 | 12749 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12782 | 12810 |
| 12783 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); | 12811 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); |
| 12784 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); | 12812 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); |
| 12785 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); | 12813 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); |
| 12786 | 12814 |
| 12787 // Reset the failed access check callback so it does not influence | 12815 // Reset the failed access check callback so it does not influence |
| 12788 // the other tests. | 12816 // the other tests. |
| 12789 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); | 12817 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); |
| 12790 } | 12818 } |
| 12791 | 12819 |
| 12820 TEST(DefaultIsolateGetCurrent) { |
| 12821 CHECK(v8::Isolate::GetCurrent() != NULL); |
| 12822 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12823 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12824 printf("*** %s\n", "DefaultIsolateGetCurrent success"); |
| 12825 } |
| 12826 |
| 12827 TEST(IsolateNewDispose) { |
| 12828 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12829 v8::Isolate* isolate = v8::Isolate::New(); |
| 12830 CHECK(isolate != NULL); |
| 12831 CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12832 CHECK(current_isolate != isolate); |
| 12833 CHECK(current_isolate == v8::Isolate::GetCurrent()); |
| 12834 |
| 12835 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12836 last_location = last_message = NULL; |
| 12837 isolate->Dispose(); |
| 12838 CHECK_EQ(last_location, NULL); |
| 12839 CHECK_EQ(last_message, NULL); |
| 12840 } |
| 12841 |
| 12842 TEST(IsolateEnterExitDefault) { |
| 12843 v8::HandleScope scope; |
| 12844 LocalContext context; |
| 12845 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12846 CHECK(current_isolate != NULL); // Default isolate. |
| 12847 ExpectString("'hello'", "hello"); |
| 12848 current_isolate->Enter(); |
| 12849 ExpectString("'still working'", "still working"); |
| 12850 current_isolate->Exit(); |
| 12851 ExpectString("'still working 2'", "still working 2"); |
| 12852 current_isolate->Exit(); |
| 12853 // Default isolate is always, well, 'default current'. |
| 12854 CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); |
| 12855 // Still working since default isolate is auto-entering any thread |
| 12856 // that has no isolate and attempts to execute V8 APIs. |
| 12857 ExpectString("'still working 3'", "still working 3"); |
| 12858 } |
| 12859 |
| 12860 TEST(DisposeDefaultIsolate) { |
| 12861 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12862 |
| 12863 // Run some V8 code to trigger default isolate to become 'current'. |
| 12864 v8::HandleScope scope; |
| 12865 LocalContext context; |
| 12866 ExpectString("'run some V8'", "run some V8"); |
| 12867 |
| 12868 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12869 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12870 last_location = last_message = NULL; |
| 12871 isolate->Dispose(); |
| 12872 // It is not possible to dispose default isolate via Isolate API. |
| 12873 CHECK_NE(last_location, NULL); |
| 12874 CHECK_NE(last_message, NULL); |
| 12875 } |
| 12876 |
| 12877 TEST(RunDefaultAndAnotherIsolate) { |
| 12878 v8::HandleScope scope; |
| 12879 LocalContext context; |
| 12880 |
| 12881 // Enter new isolate. |
| 12882 v8::Isolate* isolate = v8::Isolate::New(); |
| 12883 CHECK(isolate); |
| 12884 isolate->Enter(); |
| 12885 { // Need this block because subsequent Exit() will deallocate Heap, |
| 12886 // so we need all scope objects to be deconstructed when it happens. |
| 12887 v8::HandleScope scope_new; |
| 12888 LocalContext context_new; |
| 12889 |
| 12890 // Run something in new isolate. |
| 12891 CompileRun("var foo = 153;"); |
| 12892 ExpectTrue("function f() { return foo == 153; }; f()"); |
| 12893 } |
| 12894 isolate->Exit(); |
| 12895 |
| 12896 // This runs automatically in default isolate. |
| 12897 // Variables in another isolate should be not available. |
| 12898 ExpectTrue("function f() {" |
| 12899 " try {" |
| 12900 " foo;" |
| 12901 " return false;" |
| 12902 " } catch(e) {" |
| 12903 " return true;" |
| 12904 " }" |
| 12905 "};" |
| 12906 "var bar = 371;" |
| 12907 "f()"); |
| 12908 |
| 12909 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12910 last_location = last_message = NULL; |
| 12911 isolate->Dispose(); |
| 12912 CHECK_EQ(last_location, NULL); |
| 12913 CHECK_EQ(last_message, NULL); |
| 12914 |
| 12915 // Check that default isolate still runs. |
| 12916 ExpectTrue("function f() { return bar == 371; }; f()"); |
| 12917 } |
| 12918 |
| 12919 TEST(DisposeIsolateWhenInUse) { |
| 12920 v8::Isolate* isolate = v8::Isolate::New(); |
| 12921 CHECK(isolate); |
| 12922 isolate->Enter(); |
| 12923 v8::HandleScope scope; |
| 12924 LocalContext context; |
| 12925 // Run something in this isolate. |
| 12926 ExpectTrue("true"); |
| 12927 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12928 last_location = last_message = NULL; |
| 12929 // Still entered, should fail. |
| 12930 isolate->Dispose(); |
| 12931 CHECK_NE(last_location, NULL); |
| 12932 CHECK_NE(last_message, NULL); |
| 12933 } |
| 12934 |
| 12935 TEST(RunTwoIsolatesOnSingleThread) { |
| 12936 // Run isolate 1. |
| 12937 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 12938 isolate1->Enter(); |
| 12939 v8::Persistent<v8::Context> context1 = v8::Context::New(); |
| 12940 |
| 12941 { |
| 12942 v8::Context::Scope cscope(context1); |
| 12943 v8::HandleScope scope; |
| 12944 // Run something in new isolate. |
| 12945 CompileRun("var foo = 'isolate 1';"); |
| 12946 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12947 } |
| 12948 |
| 12949 // Run isolate 2. |
| 12950 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 12951 v8::Persistent<v8::Context> context2; |
| 12952 |
| 12953 { |
| 12954 v8::Isolate::Scope iscope(isolate2); |
| 12955 context2 = v8::Context::New(); |
| 12956 v8::Context::Scope cscope(context2); |
| 12957 v8::HandleScope scope; |
| 12958 |
| 12959 // Run something in new isolate. |
| 12960 CompileRun("var foo = 'isolate 2';"); |
| 12961 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 12962 } |
| 12963 |
| 12964 { |
| 12965 v8::Context::Scope cscope(context1); |
| 12966 v8::HandleScope scope; |
| 12967 // Now again in isolate 1 |
| 12968 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12969 } |
| 12970 |
| 12971 isolate1->Exit(); |
| 12972 |
| 12973 // Run some stuff in default isolate. |
| 12974 v8::Persistent<v8::Context> context_default = v8::Context::New(); |
| 12975 |
| 12976 { |
| 12977 v8::Context::Scope cscope(context_default); |
| 12978 v8::HandleScope scope; |
| 12979 // Variables in other isolates should be not available, verify there |
| 12980 // is an exception. |
| 12981 ExpectTrue("function f() {" |
| 12982 " try {" |
| 12983 " foo;" |
| 12984 " return false;" |
| 12985 " } catch(e) {" |
| 12986 " return true;" |
| 12987 " }" |
| 12988 "};" |
| 12989 "var isDefaultIsolate = true;" |
| 12990 "f()"); |
| 12991 } |
| 12992 |
| 12993 isolate1->Enter(); |
| 12994 |
| 12995 { |
| 12996 v8::Isolate::Scope iscope(isolate2); |
| 12997 v8::Context::Scope cscope(context2); |
| 12998 v8::HandleScope scope; |
| 12999 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 13000 } |
| 13001 |
| 13002 { |
| 13003 v8::Context::Scope cscope(context1); |
| 13004 v8::HandleScope scope; |
| 13005 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 13006 } |
| 13007 |
| 13008 { |
| 13009 v8::Isolate::Scope iscope(isolate2); |
| 13010 context2.Dispose(); |
| 13011 } |
| 13012 |
| 13013 context1.Dispose(); |
| 13014 isolate1->Exit(); |
| 13015 |
| 13016 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 13017 last_location = last_message = NULL; |
| 13018 |
| 13019 isolate1->Dispose(); |
| 13020 CHECK_EQ(last_location, NULL); |
| 13021 CHECK_EQ(last_message, NULL); |
| 13022 |
| 13023 isolate2->Dispose(); |
| 13024 CHECK_EQ(last_location, NULL); |
| 13025 CHECK_EQ(last_message, NULL); |
| 13026 |
| 13027 // Check that default isolate still runs. |
| 13028 { |
| 13029 v8::Context::Scope cscope(context_default); |
| 13030 v8::HandleScope scope; |
| 13031 ExpectTrue("function f() { return isDefaultIsolate; }; f()"); |
| 13032 } |
| 13033 } |
| 13034 |
| 13035 static int CalcFibonacci(v8::Isolate* isolate, int limit) { |
| 13036 v8::Isolate::Scope isolate_scope(isolate); |
| 13037 v8::HandleScope scope; |
| 13038 LocalContext context; |
| 13039 i::ScopedVector<char> code(1024); |
| 13040 i::OS::SNPrintF(code, "function fib(n) {" |
| 13041 " if (n <= 2) return 1;" |
| 13042 " return fib(n-1) + fib(n-2);" |
| 13043 "}" |
| 13044 "fib(%d)", limit); |
| 13045 Local<Value> value = CompileRun(code.start()); |
| 13046 CHECK(value->IsNumber()); |
| 13047 return static_cast<int>(value->NumberValue()); |
| 13048 } |
| 13049 |
| 13050 class IsolateThread : public v8::internal::Thread { |
| 13051 public: |
| 13052 explicit IsolateThread(v8::Isolate* isolate, int fib_limit) |
| 13053 : Thread(NULL), |
| 13054 isolate_(isolate), |
| 13055 fib_limit_(fib_limit), |
| 13056 result_(0) { } |
| 13057 |
| 13058 void Run() { |
| 13059 result_ = CalcFibonacci(isolate_, fib_limit_); |
| 13060 } |
| 13061 |
| 13062 int result() { return result_; } |
| 13063 |
| 13064 private: |
| 13065 v8::Isolate* isolate_; |
| 13066 int fib_limit_; |
| 13067 int result_; |
| 13068 }; |
| 13069 |
| 13070 TEST(MultipleIsolatesOnIndividualThreads) { |
| 13071 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 13072 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 13073 |
| 13074 IsolateThread thread1(isolate1, 21); |
| 13075 IsolateThread thread2(isolate2, 12); |
| 13076 |
| 13077 // Compute some fibonacci numbers on 3 threads in 3 isolates. |
| 13078 thread1.Start(); |
| 13079 thread2.Start(); |
| 13080 |
| 13081 int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); |
| 13082 int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); |
| 13083 |
| 13084 thread1.Join(); |
| 13085 thread2.Join(); |
| 13086 |
| 13087 // Compare results. The actual fibonacci numbers for 12 and 21 are taken |
| 13088 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number |
| 13089 CHECK_EQ(result1, 10946); |
| 13090 CHECK_EQ(result2, 144); |
| 13091 CHECK_EQ(result1, thread1.result()); |
| 13092 CHECK_EQ(result2, thread2.result()); |
| 13093 |
| 13094 isolate1->Dispose(); |
| 13095 isolate2->Dispose(); |
| 13096 } |
| 13097 |
| 13098 |
| 13099 class InitDefaultIsolateThread : public v8::internal::Thread { |
| 13100 public: |
| 13101 enum TestCase { IgnoreOOM, SetResourceConstraints, SetFatalHandler }; |
| 13102 |
| 13103 explicit InitDefaultIsolateThread(TestCase testCase) |
| 13104 : Thread(NULL), |
| 13105 testCase_(testCase), |
| 13106 result_(false) { } |
| 13107 |
| 13108 void Run() { |
| 13109 switch (testCase_) { |
| 13110 case IgnoreOOM: |
| 13111 v8::V8::IgnoreOutOfMemoryException(); |
| 13112 break; |
| 13113 |
| 13114 case SetResourceConstraints: { |
| 13115 static const int K = 1024; |
| 13116 v8::ResourceConstraints constraints; |
| 13117 constraints.set_max_young_space_size(256 * K); |
| 13118 constraints.set_max_old_space_size(4 * K * K); |
| 13119 v8::SetResourceConstraints(&constraints); |
| 13120 break; |
| 13121 } |
| 13122 |
| 13123 case SetFatalHandler: |
| 13124 v8::V8::SetFatalErrorHandler(NULL); |
| 13125 break; |
| 13126 } |
| 13127 result_ = true; |
| 13128 } |
| 13129 |
| 13130 bool result() { return result_; } |
| 13131 |
| 13132 private: |
| 13133 TestCase testCase_; |
| 13134 bool result_; |
| 13135 }; |
| 13136 |
| 13137 |
| 13138 static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { |
| 13139 InitDefaultIsolateThread thread(testCase); |
| 13140 thread.Start(); |
| 13141 thread.Join(); |
| 13142 CHECK_EQ(thread.result(), true); |
| 13143 } |
| 13144 |
| 13145 TEST(InitializeDefaultIsolateOnSecondaryThread1) { |
| 13146 InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); |
| 13147 } |
| 13148 |
| 13149 TEST(InitializeDefaultIsolateOnSecondaryThread2) { |
| 13150 InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); |
| 13151 } |
| 13152 |
| 13153 TEST(InitializeDefaultIsolateOnSecondaryThread3) { |
| 13154 InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); |
| 13155 } |
| 13156 |
| 12792 | 13157 |
| 12793 TEST(StringCheckMultipleContexts) { | 13158 TEST(StringCheckMultipleContexts) { |
| 12794 const char* code = | 13159 const char* code = |
| 12795 "(function() { return \"a\".charAt(0); })()"; | 13160 "(function() { return \"a\".charAt(0); })()"; |
| 12796 | 13161 |
| 12797 { | 13162 { |
| 12798 // Run the code twice in the first context to initialize the call IC. | 13163 // Run the code twice in the first context to initialize the call IC. |
| 12799 v8::HandleScope scope; | 13164 v8::HandleScope scope; |
| 12800 LocalContext context1; | 13165 LocalContext context1; |
| 12801 ExpectString(code, "a"); | 13166 ExpectString(code, "a"); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12885 ExpectBoolean("delete cell", true); | 13250 ExpectBoolean("delete cell", true); |
| 12886 ExpectString("(function() {" | 13251 ExpectString("(function() {" |
| 12887 " try {" | 13252 " try {" |
| 12888 " return readCell();" | 13253 " return readCell();" |
| 12889 " } catch(e) {" | 13254 " } catch(e) {" |
| 12890 " return e.toString();" | 13255 " return e.toString();" |
| 12891 " }" | 13256 " }" |
| 12892 "})()", | 13257 "})()", |
| 12893 "ReferenceError: cell is not defined"); | 13258 "ReferenceError: cell is not defined"); |
| 12894 CompileRun("cell = \"new_second\";"); | 13259 CompileRun("cell = \"new_second\";"); |
| 12895 i::Heap::CollectAllGarbage(i::Heap::kForceCompactionMask); | 13260 HEAP->CollectAllGarbage(i::Heap::kForceCompactionMask); |
| 12896 ExpectString("readCell()", "new_second"); | 13261 ExpectString("readCell()", "new_second"); |
| 12897 ExpectString("readCell()", "new_second"); | 13262 ExpectString("readCell()", "new_second"); |
| 12898 } | 13263 } |
| 12899 } | 13264 } |
| 12900 | 13265 |
| 12901 | 13266 |
| 12902 TEST(DontDeleteCellLoadICForceDelete) { | 13267 TEST(DontDeleteCellLoadICForceDelete) { |
| 12903 const char* function_code = | 13268 const char* function_code = |
| 12904 "function readCell() { while (true) { return cell; } }"; | 13269 "function readCell() { while (true) { return cell; } }"; |
| 12905 | 13270 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13116 v8::Handle<v8::Function> define_property = | 13481 v8::Handle<v8::Function> define_property = |
| 13117 CompileRun("(function() {" | 13482 CompileRun("(function() {" |
| 13118 " Object.defineProperty(" | 13483 " Object.defineProperty(" |
| 13119 " this," | 13484 " this," |
| 13120 " 1," | 13485 " 1," |
| 13121 " { configurable: true, enumerable: true, value: 3 });" | 13486 " { configurable: true, enumerable: true, value: 3 });" |
| 13122 "})").As<Function>(); | 13487 "})").As<Function>(); |
| 13123 context->DetachGlobal(); | 13488 context->DetachGlobal(); |
| 13124 define_property->Call(proxy, 0, NULL); | 13489 define_property->Call(proxy, 0, NULL); |
| 13125 } | 13490 } |
| OLD | NEW |