OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 using ::v8::Value; | 73 using ::v8::Value; |
74 | 74 |
75 | 75 |
76 static void ExpectString(const char* code, const char* expected) { | 76 static void ExpectString(const char* code, const char* expected) { |
77 Local<Value> result = CompileRun(code); | 77 Local<Value> result = CompileRun(code); |
78 CHECK(result->IsString()); | 78 CHECK(result->IsString()); |
79 String::AsciiValue ascii(result); | 79 String::AsciiValue ascii(result); |
80 CHECK_EQ(expected, *ascii); | 80 CHECK_EQ(expected, *ascii); |
81 } | 81 } |
82 | 82 |
| 83 static void ExpectInt32(const char* code, int expected) { |
| 84 Local<Value> result = CompileRun(code); |
| 85 CHECK(result->IsInt32()); |
| 86 CHECK_EQ(expected, result->Int32Value()); |
| 87 } |
83 | 88 |
84 static void ExpectBoolean(const char* code, bool expected) { | 89 static void ExpectBoolean(const char* code, bool expected) { |
85 Local<Value> result = CompileRun(code); | 90 Local<Value> result = CompileRun(code); |
86 CHECK(result->IsBoolean()); | 91 CHECK(result->IsBoolean()); |
87 CHECK_EQ(expected, result->BooleanValue()); | 92 CHECK_EQ(expected, result->BooleanValue()); |
88 } | 93 } |
89 | 94 |
90 | 95 |
91 static void ExpectTrue(const char* code) { | 96 static void ExpectTrue(const char* code) { |
92 ExpectBoolean(code, true); | 97 ExpectBoolean(code, true); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 LocalContext env; | 391 LocalContext env; |
387 TestResource* resource = new TestResource(two_byte_source, &dispose_count); | 392 TestResource* resource = new TestResource(two_byte_source, &dispose_count); |
388 Local<String> source = String::NewExternal(resource); | 393 Local<String> source = String::NewExternal(resource); |
389 Local<Script> script = Script::Compile(source); | 394 Local<Script> script = Script::Compile(source); |
390 Local<Value> value = script->Run(); | 395 Local<Value> value = script->Run(); |
391 CHECK(value->IsNumber()); | 396 CHECK(value->IsNumber()); |
392 CHECK_EQ(7, value->Int32Value()); | 397 CHECK_EQ(7, value->Int32Value()); |
393 CHECK(source->IsExternal()); | 398 CHECK(source->IsExternal()); |
394 CHECK_EQ(resource, | 399 CHECK_EQ(resource, |
395 static_cast<TestResource*>(source->GetExternalStringResource())); | 400 static_cast<TestResource*>(source->GetExternalStringResource())); |
396 HEAP->CollectAllGarbage(false); | 401 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
397 CHECK_EQ(0, dispose_count); | 402 CHECK_EQ(0, dispose_count); |
398 } | 403 } |
399 v8::internal::Isolate::Current()->compilation_cache()->Clear(); | 404 v8::internal::Isolate::Current()->compilation_cache()->Clear(); |
400 HEAP->CollectAllGarbage(false); | 405 HEAP->CollectAllAvailableGarbage(); |
401 CHECK_EQ(1, dispose_count); | 406 CHECK_EQ(1, dispose_count); |
402 } | 407 } |
403 | 408 |
404 | 409 |
405 THREADED_TEST(ScriptUsingAsciiStringResource) { | 410 THREADED_TEST(ScriptUsingAsciiStringResource) { |
406 int dispose_count = 0; | 411 int dispose_count = 0; |
407 const char* c_source = "1 + 2 * 3"; | 412 const char* c_source = "1 + 2 * 3"; |
408 { | 413 { |
409 v8::HandleScope scope; | 414 v8::HandleScope scope; |
410 LocalContext env; | 415 LocalContext env; |
411 Local<String> source = | 416 Local<String> source = |
412 String::NewExternal(new TestAsciiResource(i::StrDup(c_source), | 417 String::NewExternal(new TestAsciiResource(i::StrDup(c_source), |
413 &dispose_count)); | 418 &dispose_count)); |
414 Local<Script> script = Script::Compile(source); | 419 Local<Script> script = Script::Compile(source); |
415 Local<Value> value = script->Run(); | 420 Local<Value> value = script->Run(); |
416 CHECK(value->IsNumber()); | 421 CHECK(value->IsNumber()); |
417 CHECK_EQ(7, value->Int32Value()); | 422 CHECK_EQ(7, value->Int32Value()); |
418 HEAP->CollectAllGarbage(false); | 423 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
419 CHECK_EQ(0, dispose_count); | 424 CHECK_EQ(0, dispose_count); |
420 } | 425 } |
421 i::Isolate::Current()->compilation_cache()->Clear(); | 426 i::Isolate::Current()->compilation_cache()->Clear(); |
422 HEAP->CollectAllGarbage(false); | 427 HEAP->CollectAllAvailableGarbage(); |
423 CHECK_EQ(1, dispose_count); | 428 CHECK_EQ(1, dispose_count); |
424 } | 429 } |
425 | 430 |
426 | 431 |
427 THREADED_TEST(ScriptMakingExternalString) { | 432 THREADED_TEST(ScriptMakingExternalString) { |
428 int dispose_count = 0; | 433 int dispose_count = 0; |
429 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 434 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
430 { | 435 { |
431 v8::HandleScope scope; | 436 v8::HandleScope scope; |
432 LocalContext env; | 437 LocalContext env; |
433 Local<String> source = String::New(two_byte_source); | 438 Local<String> source = String::New(two_byte_source); |
434 // Trigger GCs so that the newly allocated string moves to old gen. | 439 // Trigger GCs so that the newly allocated string moves to old gen. |
435 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 440 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
436 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 441 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
437 bool success = source->MakeExternal(new TestResource(two_byte_source, | 442 bool success = source->MakeExternal(new TestResource(two_byte_source, |
438 &dispose_count)); | 443 &dispose_count)); |
439 CHECK(success); | 444 CHECK(success); |
440 Local<Script> script = Script::Compile(source); | 445 Local<Script> script = Script::Compile(source); |
441 Local<Value> value = script->Run(); | 446 Local<Value> value = script->Run(); |
442 CHECK(value->IsNumber()); | 447 CHECK(value->IsNumber()); |
443 CHECK_EQ(7, value->Int32Value()); | 448 CHECK_EQ(7, value->Int32Value()); |
444 HEAP->CollectAllGarbage(false); | 449 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
445 CHECK_EQ(0, dispose_count); | 450 CHECK_EQ(0, dispose_count); |
446 } | 451 } |
447 i::Isolate::Current()->compilation_cache()->Clear(); | 452 i::Isolate::Current()->compilation_cache()->Clear(); |
448 HEAP->CollectAllGarbage(false); | 453 // TODO(1608): This should use kAbortIncrementalMarking. |
| 454 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
449 CHECK_EQ(1, dispose_count); | 455 CHECK_EQ(1, dispose_count); |
450 } | 456 } |
451 | 457 |
452 | 458 |
453 THREADED_TEST(ScriptMakingExternalAsciiString) { | 459 THREADED_TEST(ScriptMakingExternalAsciiString) { |
454 int dispose_count = 0; | 460 int dispose_count = 0; |
455 const char* c_source = "1 + 2 * 3"; | 461 const char* c_source = "1 + 2 * 3"; |
456 { | 462 { |
457 v8::HandleScope scope; | 463 v8::HandleScope scope; |
458 LocalContext env; | 464 LocalContext env; |
459 Local<String> source = v8_str(c_source); | 465 Local<String> source = v8_str(c_source); |
460 // Trigger GCs so that the newly allocated string moves to old gen. | 466 // Trigger GCs so that the newly allocated string moves to old gen. |
461 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 467 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
462 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 468 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
463 bool success = source->MakeExternal( | 469 bool success = source->MakeExternal( |
464 new TestAsciiResource(i::StrDup(c_source), &dispose_count)); | 470 new TestAsciiResource(i::StrDup(c_source), &dispose_count)); |
465 CHECK(success); | 471 CHECK(success); |
466 Local<Script> script = Script::Compile(source); | 472 Local<Script> script = Script::Compile(source); |
467 Local<Value> value = script->Run(); | 473 Local<Value> value = script->Run(); |
468 CHECK(value->IsNumber()); | 474 CHECK(value->IsNumber()); |
469 CHECK_EQ(7, value->Int32Value()); | 475 CHECK_EQ(7, value->Int32Value()); |
470 HEAP->CollectAllGarbage(false); | 476 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
471 CHECK_EQ(0, dispose_count); | 477 CHECK_EQ(0, dispose_count); |
472 } | 478 } |
473 i::Isolate::Current()->compilation_cache()->Clear(); | 479 i::Isolate::Current()->compilation_cache()->Clear(); |
474 HEAP->CollectAllGarbage(false); | 480 // TODO(1608): This should use kAbortIncrementalMarking. |
| 481 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
475 CHECK_EQ(1, dispose_count); | 482 CHECK_EQ(1, dispose_count); |
476 } | 483 } |
477 | 484 |
478 | 485 |
479 TEST(MakingExternalStringConditions) { | 486 TEST(MakingExternalStringConditions) { |
480 v8::HandleScope scope; | 487 v8::HandleScope scope; |
481 LocalContext env; | 488 LocalContext env; |
482 | 489 |
483 // Free some space in the new space so that we can check freshness. | 490 // Free some space in the new space so that we can check freshness. |
484 HEAP->CollectGarbage(i::NEW_SPACE); | 491 HEAP->CollectGarbage(i::NEW_SPACE); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 572 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
566 Local<String> string = | 573 Local<String> string = |
567 String::NewExternal(new TestResource(two_byte_string)); | 574 String::NewExternal(new TestResource(two_byte_string)); |
568 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 575 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
569 // Trigger GCs so that the newly allocated string moves to old gen. | 576 // Trigger GCs so that the newly allocated string moves to old gen. |
570 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 577 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
571 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 578 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
572 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); | 579 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
573 CHECK(isymbol->IsSymbol()); | 580 CHECK(isymbol->IsSymbol()); |
574 } | 581 } |
575 HEAP->CollectAllGarbage(false); | 582 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
576 HEAP->CollectAllGarbage(false); | 583 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
577 } | 584 } |
578 | 585 |
579 | 586 |
580 THREADED_TEST(UsingExternalAsciiString) { | 587 THREADED_TEST(UsingExternalAsciiString) { |
581 { | 588 { |
582 v8::HandleScope scope; | 589 v8::HandleScope scope; |
583 const char* one_byte_string = "test string"; | 590 const char* one_byte_string = "test string"; |
584 Local<String> string = String::NewExternal( | 591 Local<String> string = String::NewExternal( |
585 new TestAsciiResource(i::StrDup(one_byte_string))); | 592 new TestAsciiResource(i::StrDup(one_byte_string))); |
586 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 593 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
587 // Trigger GCs so that the newly allocated string moves to old gen. | 594 // Trigger GCs so that the newly allocated string moves to old gen. |
588 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 595 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
589 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 596 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
590 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); | 597 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
591 CHECK(isymbol->IsSymbol()); | 598 CHECK(isymbol->IsSymbol()); |
592 } | 599 } |
593 HEAP->CollectAllGarbage(false); | 600 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
594 HEAP->CollectAllGarbage(false); | 601 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
595 } | 602 } |
596 | 603 |
597 | 604 |
598 THREADED_TEST(ScavengeExternalString) { | 605 THREADED_TEST(ScavengeExternalString) { |
599 int dispose_count = 0; | 606 int dispose_count = 0; |
600 bool in_new_space = false; | 607 bool in_new_space = false; |
601 { | 608 { |
602 v8::HandleScope scope; | 609 v8::HandleScope scope; |
603 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 610 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
604 Local<String> string = | 611 Local<String> string = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 672 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
666 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 673 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
667 { | 674 { |
668 v8::HandleScope scope; | 675 v8::HandleScope scope; |
669 LocalContext env; | 676 LocalContext env; |
670 Local<String> source = String::NewExternal(&res_stack); | 677 Local<String> source = String::NewExternal(&res_stack); |
671 Local<Script> script = Script::Compile(source); | 678 Local<Script> script = Script::Compile(source); |
672 Local<Value> value = script->Run(); | 679 Local<Value> value = script->Run(); |
673 CHECK(value->IsNumber()); | 680 CHECK(value->IsNumber()); |
674 CHECK_EQ(7, value->Int32Value()); | 681 CHECK_EQ(7, value->Int32Value()); |
675 HEAP->CollectAllGarbage(false); | 682 HEAP->CollectAllAvailableGarbage(); |
676 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 683 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
677 } | 684 } |
678 i::Isolate::Current()->compilation_cache()->Clear(); | 685 i::Isolate::Current()->compilation_cache()->Clear(); |
679 HEAP->CollectAllGarbage(false); | 686 HEAP->CollectAllAvailableGarbage(); |
680 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 687 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
681 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 688 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
682 | 689 |
683 // Use a heap allocated external string resource allocated object. | 690 // Use a heap allocated external string resource allocated object. |
684 TestAsciiResourceWithDisposeControl::dispose_count = 0; | 691 TestAsciiResourceWithDisposeControl::dispose_count = 0; |
685 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 692 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
686 TestAsciiResource* res_heap = | 693 TestAsciiResource* res_heap = |
687 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 694 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); |
688 { | 695 { |
689 v8::HandleScope scope; | 696 v8::HandleScope scope; |
690 LocalContext env; | 697 LocalContext env; |
691 Local<String> source = String::NewExternal(res_heap); | 698 Local<String> source = String::NewExternal(res_heap); |
692 Local<Script> script = Script::Compile(source); | 699 Local<Script> script = Script::Compile(source); |
693 Local<Value> value = script->Run(); | 700 Local<Value> value = script->Run(); |
694 CHECK(value->IsNumber()); | 701 CHECK(value->IsNumber()); |
695 CHECK_EQ(7, value->Int32Value()); | 702 CHECK_EQ(7, value->Int32Value()); |
696 HEAP->CollectAllGarbage(false); | 703 HEAP->CollectAllAvailableGarbage(); |
697 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 704 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
698 } | 705 } |
699 i::Isolate::Current()->compilation_cache()->Clear(); | 706 i::Isolate::Current()->compilation_cache()->Clear(); |
700 HEAP->CollectAllGarbage(false); | 707 HEAP->CollectAllAvailableGarbage(); |
701 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 708 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
702 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); | 709 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); |
703 } | 710 } |
704 | 711 |
705 | 712 |
706 THREADED_TEST(StringConcat) { | 713 THREADED_TEST(StringConcat) { |
707 { | 714 { |
708 v8::HandleScope scope; | 715 v8::HandleScope scope; |
709 LocalContext env; | 716 LocalContext env; |
710 const char* one_byte_string_1 = "function a_times_t"; | 717 const char* one_byte_string_1 = "function a_times_t"; |
(...skipping 26 matching lines...) Expand all Loading... |
737 source = String::Concat(source, right); | 744 source = String::Concat(source, right); |
738 right = String::NewExternal( | 745 right = String::NewExternal( |
739 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); | 746 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); |
740 source = String::Concat(source, right); | 747 source = String::Concat(source, right); |
741 Local<Script> script = Script::Compile(source); | 748 Local<Script> script = Script::Compile(source); |
742 Local<Value> value = script->Run(); | 749 Local<Value> value = script->Run(); |
743 CHECK(value->IsNumber()); | 750 CHECK(value->IsNumber()); |
744 CHECK_EQ(68, value->Int32Value()); | 751 CHECK_EQ(68, value->Int32Value()); |
745 } | 752 } |
746 i::Isolate::Current()->compilation_cache()->Clear(); | 753 i::Isolate::Current()->compilation_cache()->Clear(); |
747 HEAP->CollectAllGarbage(false); | 754 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
748 HEAP->CollectAllGarbage(false); | 755 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
749 } | 756 } |
750 | 757 |
751 | 758 |
752 THREADED_TEST(GlobalProperties) { | 759 THREADED_TEST(GlobalProperties) { |
753 v8::HandleScope scope; | 760 v8::HandleScope scope; |
754 LocalContext env; | 761 LocalContext env; |
755 v8::Handle<v8::Object> global = env->Global(); | 762 v8::Handle<v8::Object> global = env->Global(); |
756 global->Set(v8_str("pi"), v8_num(3.1415926)); | 763 global->Set(v8_str("pi"), v8_num(3.1415926)); |
757 Local<Value> pi = global->Get(v8_str("pi")); | 764 Local<Value> pi = global->Get(v8_str("pi")); |
758 CHECK_EQ(3.1415926, pi->NumberValue()); | 765 CHECK_EQ(3.1415926, pi->NumberValue()); |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 | 1294 |
1288 | 1295 |
1289 static v8::Handle<Value> EchoNamedProperty(Local<String> name, | 1296 static v8::Handle<Value> EchoNamedProperty(Local<String> name, |
1290 const AccessorInfo& info) { | 1297 const AccessorInfo& info) { |
1291 ApiTestFuzzer::Fuzz(); | 1298 ApiTestFuzzer::Fuzz(); |
1292 CHECK_EQ(v8_str("data"), info.Data()); | 1299 CHECK_EQ(v8_str("data"), info.Data()); |
1293 echo_named_call_count++; | 1300 echo_named_call_count++; |
1294 return name; | 1301 return name; |
1295 } | 1302 } |
1296 | 1303 |
| 1304 // Helper functions for Interceptor/Accessor interaction tests |
| 1305 |
| 1306 Handle<Value> SimpleAccessorGetter(Local<String> name, |
| 1307 const AccessorInfo& info) { |
| 1308 Handle<Object> self = info.This(); |
| 1309 return self->Get(String::Concat(v8_str("accessor_"), name)); |
| 1310 } |
| 1311 |
| 1312 void SimpleAccessorSetter(Local<String> name, Local<Value> value, |
| 1313 const AccessorInfo& info) { |
| 1314 Handle<Object> self = info.This(); |
| 1315 self->Set(String::Concat(v8_str("accessor_"), name), value); |
| 1316 } |
| 1317 |
| 1318 Handle<Value> EmptyInterceptorGetter(Local<String> name, |
| 1319 const AccessorInfo& info) { |
| 1320 return Handle<Value>(); |
| 1321 } |
| 1322 |
| 1323 Handle<Value> EmptyInterceptorSetter(Local<String> name, |
| 1324 Local<Value> value, |
| 1325 const AccessorInfo& info) { |
| 1326 return Handle<Value>(); |
| 1327 } |
| 1328 |
| 1329 Handle<Value> InterceptorGetter(Local<String> name, |
| 1330 const AccessorInfo& info) { |
| 1331 // Intercept names that start with 'interceptor_'. |
| 1332 String::AsciiValue ascii(name); |
| 1333 char* name_str = *ascii; |
| 1334 char prefix[] = "interceptor_"; |
| 1335 int i; |
| 1336 for (i = 0; name_str[i] && prefix[i]; ++i) { |
| 1337 if (name_str[i] != prefix[i]) return Handle<Value>(); |
| 1338 } |
| 1339 Handle<Object> self = info.This(); |
| 1340 return self->GetHiddenValue(v8_str(name_str + i)); |
| 1341 } |
| 1342 |
| 1343 Handle<Value> InterceptorSetter(Local<String> name, |
| 1344 Local<Value> value, |
| 1345 const AccessorInfo& info) { |
| 1346 // Intercept accesses that set certain integer values. |
| 1347 if (value->IsInt32() && value->Int32Value() < 10000) { |
| 1348 Handle<Object> self = info.This(); |
| 1349 self->SetHiddenValue(name, value); |
| 1350 return value; |
| 1351 } |
| 1352 return Handle<Value>(); |
| 1353 } |
| 1354 |
| 1355 void AddAccessor(Handle<FunctionTemplate> templ, |
| 1356 Handle<String> name, |
| 1357 v8::AccessorGetter getter, |
| 1358 v8::AccessorSetter setter) { |
| 1359 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
| 1360 } |
| 1361 |
| 1362 void AddInterceptor(Handle<FunctionTemplate> templ, |
| 1363 v8::NamedPropertyGetter getter, |
| 1364 v8::NamedPropertySetter setter) { |
| 1365 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); |
| 1366 } |
| 1367 |
| 1368 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { |
| 1369 v8::HandleScope scope; |
| 1370 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1371 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1372 child->Inherit(parent); |
| 1373 AddAccessor(parent, v8_str("age"), |
| 1374 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1375 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1376 LocalContext env; |
| 1377 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1378 CompileRun("var child = new Child;" |
| 1379 "child.age = 10;"); |
| 1380 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 1381 ExpectInt32("child.age", 10); |
| 1382 ExpectInt32("child.accessor_age", 10); |
| 1383 } |
| 1384 |
| 1385 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { |
| 1386 v8::HandleScope scope; |
| 1387 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1388 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1389 child->Inherit(parent); |
| 1390 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1391 LocalContext env; |
| 1392 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1393 CompileRun("var child = new Child;" |
| 1394 "var parent = child.__proto__;" |
| 1395 "Object.defineProperty(parent, 'age', " |
| 1396 " {get: function(){ return this.accessor_age; }, " |
| 1397 " set: function(v){ this.accessor_age = v; }, " |
| 1398 " enumerable: true, configurable: true});" |
| 1399 "child.age = 10;"); |
| 1400 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 1401 ExpectInt32("child.age", 10); |
| 1402 ExpectInt32("child.accessor_age", 10); |
| 1403 } |
| 1404 |
| 1405 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { |
| 1406 v8::HandleScope scope; |
| 1407 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1408 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1409 child->Inherit(parent); |
| 1410 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1411 LocalContext env; |
| 1412 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1413 CompileRun("var child = new Child;" |
| 1414 "var parent = child.__proto__;" |
| 1415 "parent.name = 'Alice';"); |
| 1416 ExpectBoolean("child.hasOwnProperty('name')", false); |
| 1417 ExpectString("child.name", "Alice"); |
| 1418 CompileRun("child.name = 'Bob';"); |
| 1419 ExpectString("child.name", "Bob"); |
| 1420 ExpectBoolean("child.hasOwnProperty('name')", true); |
| 1421 ExpectString("parent.name", "Alice"); |
| 1422 } |
| 1423 |
| 1424 THREADED_TEST(SwitchFromInterceptorToAccessor) { |
| 1425 v8::HandleScope scope; |
| 1426 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1427 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1428 child->Inherit(parent); |
| 1429 AddAccessor(parent, v8_str("age"), |
| 1430 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1431 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1432 LocalContext env; |
| 1433 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1434 CompileRun("var child = new Child;" |
| 1435 "function setAge(i){ child.age = i; };" |
| 1436 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
| 1437 // All i < 10000 go to the interceptor. |
| 1438 ExpectInt32("child.interceptor_age", 9999); |
| 1439 // The last i goes to the accessor. |
| 1440 ExpectInt32("child.accessor_age", 10000); |
| 1441 } |
| 1442 |
| 1443 THREADED_TEST(SwitchFromAccessorToInterceptor) { |
| 1444 v8::HandleScope scope; |
| 1445 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1446 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1447 child->Inherit(parent); |
| 1448 AddAccessor(parent, v8_str("age"), |
| 1449 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1450 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1451 LocalContext env; |
| 1452 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1453 CompileRun("var child = new Child;" |
| 1454 "function setAge(i){ child.age = i; };" |
| 1455 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
| 1456 // All i >= 10000 go to the accessor. |
| 1457 ExpectInt32("child.accessor_age", 10000); |
| 1458 // The last i goes to the interceptor. |
| 1459 ExpectInt32("child.interceptor_age", 9999); |
| 1460 } |
| 1461 |
| 1462 THREADED_TEST(SwitchFromInterceptorToProperty) { |
| 1463 v8::HandleScope scope; |
| 1464 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1465 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1466 child->Inherit(parent); |
| 1467 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1468 LocalContext env; |
| 1469 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1470 CompileRun("var child = new Child;" |
| 1471 "function setAge(i){ child.age = i; };" |
| 1472 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
| 1473 // All i < 10000 go to the interceptor. |
| 1474 ExpectInt32("child.interceptor_age", 9999); |
| 1475 // The last i goes to child's own property. |
| 1476 ExpectInt32("child.age", 10000); |
| 1477 } |
| 1478 |
| 1479 THREADED_TEST(SwitchFromPropertyToInterceptor) { |
| 1480 v8::HandleScope scope; |
| 1481 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1482 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1483 child->Inherit(parent); |
| 1484 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1485 LocalContext env; |
| 1486 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1487 CompileRun("var child = new Child;" |
| 1488 "function setAge(i){ child.age = i; };" |
| 1489 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
| 1490 // All i >= 10000 go to child's own property. |
| 1491 ExpectInt32("child.age", 10000); |
| 1492 // The last i goes to the interceptor. |
| 1493 ExpectInt32("child.interceptor_age", 9999); |
| 1494 } |
1297 | 1495 |
1298 THREADED_TEST(NamedPropertyHandlerGetter) { | 1496 THREADED_TEST(NamedPropertyHandlerGetter) { |
1299 echo_named_call_count = 0; | 1497 echo_named_call_count = 0; |
1300 v8::HandleScope scope; | 1498 v8::HandleScope scope; |
1301 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1499 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
1302 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, | 1500 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, |
1303 0, 0, 0, 0, | 1501 0, 0, 0, 0, |
1304 v8_str("data")); | 1502 v8_str("data")); |
1305 LocalContext env; | 1503 LocalContext env; |
1306 env->Global()->Set(v8_str("obj"), | 1504 env->Global()->Set(v8_str("obj"), |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 | 1857 |
1660 char* data = new char[100]; | 1858 char* data = new char[100]; |
1661 | 1859 |
1662 void* aligned = data; | 1860 void* aligned = data; |
1663 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1861 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
1664 void* unaligned = data + 1; | 1862 void* unaligned = data + 1; |
1665 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1863 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
1666 | 1864 |
1667 // Check reading and writing aligned pointers. | 1865 // Check reading and writing aligned pointers. |
1668 obj->SetPointerInInternalField(0, aligned); | 1866 obj->SetPointerInInternalField(0, aligned); |
1669 HEAP->CollectAllGarbage(false); | 1867 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1670 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1868 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
1671 | 1869 |
1672 // Check reading and writing unaligned pointers. | 1870 // Check reading and writing unaligned pointers. |
1673 obj->SetPointerInInternalField(0, unaligned); | 1871 obj->SetPointerInInternalField(0, unaligned); |
1674 HEAP->CollectAllGarbage(false); | 1872 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1675 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1873 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
1676 | 1874 |
1677 delete[] data; | 1875 delete[] data; |
1678 } | 1876 } |
1679 | 1877 |
1680 | 1878 |
1681 THREADED_TEST(InternalFieldsNativePointersAndExternal) { | 1879 THREADED_TEST(InternalFieldsNativePointersAndExternal) { |
1682 v8::HandleScope scope; | 1880 v8::HandleScope scope; |
1683 LocalContext env; | 1881 LocalContext env; |
1684 | 1882 |
1685 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1883 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
1686 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); | 1884 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); |
1687 instance_templ->SetInternalFieldCount(1); | 1885 instance_templ->SetInternalFieldCount(1); |
1688 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); | 1886 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); |
1689 CHECK_EQ(1, obj->InternalFieldCount()); | 1887 CHECK_EQ(1, obj->InternalFieldCount()); |
1690 CHECK(obj->GetPointerFromInternalField(0) == NULL); | 1888 CHECK(obj->GetPointerFromInternalField(0) == NULL); |
1691 | 1889 |
1692 char* data = new char[100]; | 1890 char* data = new char[100]; |
1693 | 1891 |
1694 void* aligned = data; | 1892 void* aligned = data; |
1695 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1893 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
1696 void* unaligned = data + 1; | 1894 void* unaligned = data + 1; |
1697 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1895 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
1698 | 1896 |
1699 obj->SetPointerInInternalField(0, aligned); | 1897 obj->SetPointerInInternalField(0, aligned); |
1700 HEAP->CollectAllGarbage(false); | 1898 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1701 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1899 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); |
1702 | 1900 |
1703 obj->SetPointerInInternalField(0, unaligned); | 1901 obj->SetPointerInInternalField(0, unaligned); |
1704 HEAP->CollectAllGarbage(false); | 1902 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1705 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1903 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); |
1706 | 1904 |
1707 obj->SetInternalField(0, v8::External::Wrap(aligned)); | 1905 obj->SetInternalField(0, v8::External::Wrap(aligned)); |
1708 HEAP->CollectAllGarbage(false); | 1906 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1709 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1907 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
1710 | 1908 |
1711 obj->SetInternalField(0, v8::External::Wrap(unaligned)); | 1909 obj->SetInternalField(0, v8::External::Wrap(unaligned)); |
1712 HEAP->CollectAllGarbage(false); | 1910 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1713 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1911 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
1714 | 1912 |
1715 delete[] data; | 1913 delete[] data; |
1716 } | 1914 } |
1717 | 1915 |
1718 | 1916 |
1719 THREADED_TEST(IdentityHash) { | 1917 THREADED_TEST(IdentityHash) { |
1720 v8::HandleScope scope; | 1918 v8::HandleScope scope; |
1721 LocalContext env; | 1919 LocalContext env; |
1722 | 1920 |
1723 // Ensure that the test starts with an fresh heap to test whether the hash | 1921 // Ensure that the test starts with an fresh heap to test whether the hash |
1724 // code is based on the address. | 1922 // code is based on the address. |
1725 HEAP->CollectAllGarbage(false); | 1923 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1726 Local<v8::Object> obj = v8::Object::New(); | 1924 Local<v8::Object> obj = v8::Object::New(); |
1727 int hash = obj->GetIdentityHash(); | 1925 int hash = obj->GetIdentityHash(); |
1728 int hash1 = obj->GetIdentityHash(); | 1926 int hash1 = obj->GetIdentityHash(); |
1729 CHECK_EQ(hash, hash1); | 1927 CHECK_EQ(hash, hash1); |
1730 int hash2 = v8::Object::New()->GetIdentityHash(); | 1928 int hash2 = v8::Object::New()->GetIdentityHash(); |
1731 // Since the identity hash is essentially a random number two consecutive | 1929 // Since the identity hash is essentially a random number two consecutive |
1732 // objects should not be assigned the same hash code. If the test below fails | 1930 // objects should not be assigned the same hash code. If the test below fails |
1733 // the random number generator should be evaluated. | 1931 // the random number generator should be evaluated. |
1734 CHECK_NE(hash, hash2); | 1932 CHECK_NE(hash, hash2); |
1735 HEAP->CollectAllGarbage(false); | 1933 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1736 int hash3 = v8::Object::New()->GetIdentityHash(); | 1934 int hash3 = v8::Object::New()->GetIdentityHash(); |
1737 // Make sure that the identity hash is not based on the initial address of | 1935 // Make sure that the identity hash is not based on the initial address of |
1738 // the object alone. If the test below fails the random number generator | 1936 // the object alone. If the test below fails the random number generator |
1739 // should be evaluated. | 1937 // should be evaluated. |
1740 CHECK_NE(hash, hash3); | 1938 CHECK_NE(hash, hash3); |
1741 int hash4 = obj->GetIdentityHash(); | 1939 int hash4 = obj->GetIdentityHash(); |
1742 CHECK_EQ(hash, hash4); | 1940 CHECK_EQ(hash, hash4); |
1743 | 1941 |
1744 // Check identity hashes behaviour in the presence of JS accessors. | 1942 // Check identity hashes behaviour in the presence of JS accessors. |
1745 // Put a getter for 'v8::IdentityHash' on the Object's prototype: | 1943 // Put a getter for 'v8::IdentityHash' on the Object's prototype: |
(...skipping 16 matching lines...) Expand all Loading... |
1762 | 1960 |
1763 THREADED_TEST(HiddenProperties) { | 1961 THREADED_TEST(HiddenProperties) { |
1764 v8::HandleScope scope; | 1962 v8::HandleScope scope; |
1765 LocalContext env; | 1963 LocalContext env; |
1766 | 1964 |
1767 v8::Local<v8::Object> obj = v8::Object::New(); | 1965 v8::Local<v8::Object> obj = v8::Object::New(); |
1768 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 1966 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
1769 v8::Local<v8::String> empty = v8_str(""); | 1967 v8::Local<v8::String> empty = v8_str(""); |
1770 v8::Local<v8::String> prop_name = v8_str("prop_name"); | 1968 v8::Local<v8::String> prop_name = v8_str("prop_name"); |
1771 | 1969 |
1772 HEAP->CollectAllGarbage(false); | 1970 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1773 | 1971 |
1774 // Make sure delete of a non-existent hidden value works | 1972 // Make sure delete of a non-existent hidden value works |
1775 CHECK(obj->DeleteHiddenValue(key)); | 1973 CHECK(obj->DeleteHiddenValue(key)); |
1776 | 1974 |
1777 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); | 1975 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); |
1778 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); | 1976 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); |
1779 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); | 1977 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); |
1780 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1978 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1781 | 1979 |
1782 HEAP->CollectAllGarbage(false); | 1980 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1783 | 1981 |
1784 // Make sure we do not find the hidden property. | 1982 // Make sure we do not find the hidden property. |
1785 CHECK(!obj->Has(empty)); | 1983 CHECK(!obj->Has(empty)); |
1786 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1984 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1787 CHECK(obj->Get(empty)->IsUndefined()); | 1985 CHECK(obj->Get(empty)->IsUndefined()); |
1788 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1986 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1789 CHECK(obj->Set(empty, v8::Integer::New(2003))); | 1987 CHECK(obj->Set(empty, v8::Integer::New(2003))); |
1790 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1988 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1791 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); | 1989 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); |
1792 | 1990 |
1793 HEAP->CollectAllGarbage(false); | 1991 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1794 | 1992 |
1795 // Add another property and delete it afterwards to force the object in | 1993 // Add another property and delete it afterwards to force the object in |
1796 // slow case. | 1994 // slow case. |
1797 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); | 1995 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); |
1798 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1996 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1799 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); | 1997 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); |
1800 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1998 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1801 CHECK(obj->Delete(prop_name)); | 1999 CHECK(obj->Delete(prop_name)); |
1802 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 2000 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
1803 | 2001 |
1804 HEAP->CollectAllGarbage(false); | 2002 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
1805 | 2003 |
1806 CHECK(obj->DeleteHiddenValue(key)); | 2004 CHECK(obj->DeleteHiddenValue(key)); |
1807 CHECK(obj->GetHiddenValue(key).IsEmpty()); | 2005 CHECK(obj->GetHiddenValue(key).IsEmpty()); |
1808 } | 2006 } |
1809 | 2007 |
1810 | 2008 |
1811 THREADED_TEST(Regress97784) { | 2009 THREADED_TEST(Regress97784) { |
1812 // Regression test for crbug.com/97784 | 2010 // Regression test for crbug.com/97784 |
1813 // Messing with the Object.prototype should not have effect on | 2011 // Messing with the Object.prototype should not have effect on |
1814 // hidden properties. | 2012 // hidden properties. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 { | 2099 { |
1902 v8::HandleScope scope; | 2100 v8::HandleScope scope; |
1903 Local<String> str = v8_str("str"); | 2101 Local<String> str = v8_str("str"); |
1904 global = v8::Persistent<String>::New(str); | 2102 global = v8::Persistent<String>::New(str); |
1905 } | 2103 } |
1906 CHECK_EQ(global->Length(), 3); | 2104 CHECK_EQ(global->Length(), 3); |
1907 global.Dispose(); | 2105 global.Dispose(); |
1908 } | 2106 } |
1909 | 2107 |
1910 | 2108 |
1911 static int NumberOfWeakCalls = 0; | 2109 class WeakCallCounter { |
| 2110 public: |
| 2111 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } |
| 2112 int id() { return id_; } |
| 2113 void increment() { number_of_weak_calls_++; } |
| 2114 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
| 2115 private: |
| 2116 int id_; |
| 2117 int number_of_weak_calls_; |
| 2118 }; |
| 2119 |
| 2120 |
1912 static void WeakPointerCallback(Persistent<Value> handle, void* id) { | 2121 static void WeakPointerCallback(Persistent<Value> handle, void* id) { |
1913 CHECK_EQ(reinterpret_cast<void*>(1234), id); | 2122 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); |
1914 NumberOfWeakCalls++; | 2123 CHECK_EQ(1234, counter->id()); |
| 2124 counter->increment(); |
1915 handle.Dispose(); | 2125 handle.Dispose(); |
1916 } | 2126 } |
1917 | 2127 |
| 2128 |
1918 THREADED_TEST(ApiObjectGroups) { | 2129 THREADED_TEST(ApiObjectGroups) { |
1919 HandleScope scope; | 2130 HandleScope scope; |
1920 LocalContext env; | 2131 LocalContext env; |
1921 | 2132 |
1922 NumberOfWeakCalls = 0; | |
1923 | |
1924 Persistent<Object> g1s1; | 2133 Persistent<Object> g1s1; |
1925 Persistent<Object> g1s2; | 2134 Persistent<Object> g1s2; |
1926 Persistent<Object> g1c1; | 2135 Persistent<Object> g1c1; |
1927 Persistent<Object> g2s1; | 2136 Persistent<Object> g2s1; |
1928 Persistent<Object> g2s2; | 2137 Persistent<Object> g2s2; |
1929 Persistent<Object> g2c1; | 2138 Persistent<Object> g2c1; |
1930 | 2139 |
| 2140 WeakCallCounter counter(1234); |
| 2141 |
1931 { | 2142 { |
1932 HandleScope scope; | 2143 HandleScope scope; |
1933 g1s1 = Persistent<Object>::New(Object::New()); | 2144 g1s1 = Persistent<Object>::New(Object::New()); |
1934 g1s2 = Persistent<Object>::New(Object::New()); | 2145 g1s2 = Persistent<Object>::New(Object::New()); |
1935 g1c1 = Persistent<Object>::New(Object::New()); | 2146 g1c1 = Persistent<Object>::New(Object::New()); |
1936 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2147 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1937 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2148 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1938 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2149 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1939 | 2150 |
1940 g2s1 = Persistent<Object>::New(Object::New()); | 2151 g2s1 = Persistent<Object>::New(Object::New()); |
1941 g2s2 = Persistent<Object>::New(Object::New()); | 2152 g2s2 = Persistent<Object>::New(Object::New()); |
1942 g2c1 = Persistent<Object>::New(Object::New()); | 2153 g2c1 = Persistent<Object>::New(Object::New()); |
1943 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2154 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1944 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2155 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1945 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2156 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1946 } | 2157 } |
1947 | 2158 |
1948 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 2159 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
1949 | 2160 |
1950 // Connect group 1 and 2, make a cycle. | 2161 // Connect group 1 and 2, make a cycle. |
1951 CHECK(g1s2->Set(0, g2s2)); | 2162 CHECK(g1s2->Set(0, g2s2)); |
1952 CHECK(g2s1->Set(0, g1s1)); | 2163 CHECK(g2s1->Set(0, g1s1)); |
1953 | 2164 |
1954 { | 2165 { |
1955 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2166 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
1956 Persistent<Value> g1_children[] = { g1c1 }; | 2167 Persistent<Value> g1_children[] = { g1c1 }; |
1957 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2168 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
1958 Persistent<Value> g2_children[] = { g2c1 }; | 2169 Persistent<Value> g2_children[] = { g2c1 }; |
1959 V8::AddObjectGroup(g1_objects, 2); | 2170 V8::AddObjectGroup(g1_objects, 2); |
1960 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2171 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1961 V8::AddObjectGroup(g2_objects, 2); | 2172 V8::AddObjectGroup(g2_objects, 2); |
1962 V8::AddImplicitReferences(g2s2, g2_children, 1); | 2173 V8::AddImplicitReferences(g2s2, g2_children, 1); |
1963 } | 2174 } |
1964 // Do a full GC | 2175 // Do a single full GC. Use kMakeHeapIterableMask to ensure that |
1965 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2176 // incremental garbage collection is stopped. |
| 2177 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
1966 | 2178 |
1967 // All object should be alive. | 2179 // All object should be alive. |
1968 CHECK_EQ(0, NumberOfWeakCalls); | 2180 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
1969 | 2181 |
1970 // Weaken the root. | 2182 // Weaken the root. |
1971 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2183 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1972 // But make children strong roots---all the objects (except for children) | 2184 // But make children strong roots---all the objects (except for children) |
1973 // should be collectable now. | 2185 // should be collectable now. |
1974 g1c1.ClearWeak(); | 2186 g1c1.ClearWeak(); |
1975 g2c1.ClearWeak(); | 2187 g2c1.ClearWeak(); |
1976 | 2188 |
1977 // Groups are deleted, rebuild groups. | 2189 // Groups are deleted, rebuild groups. |
1978 { | 2190 { |
1979 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2191 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
1980 Persistent<Value> g1_children[] = { g1c1 }; | 2192 Persistent<Value> g1_children[] = { g1c1 }; |
1981 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2193 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
1982 Persistent<Value> g2_children[] = { g2c1 }; | 2194 Persistent<Value> g2_children[] = { g2c1 }; |
1983 V8::AddObjectGroup(g1_objects, 2); | 2195 V8::AddObjectGroup(g1_objects, 2); |
1984 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2196 V8::AddImplicitReferences(g1s1, g1_children, 1); |
1985 V8::AddObjectGroup(g2_objects, 2); | 2197 V8::AddObjectGroup(g2_objects, 2); |
1986 V8::AddImplicitReferences(g2s2, g2_children, 1); | 2198 V8::AddImplicitReferences(g2s2, g2_children, 1); |
1987 } | 2199 } |
1988 | 2200 |
1989 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2201 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
1990 | 2202 |
1991 // All objects should be gone. 5 global handles in total. | 2203 // All objects should be gone. 5 global handles in total. |
1992 CHECK_EQ(5, NumberOfWeakCalls); | 2204 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
1993 | 2205 |
1994 // And now make children weak again and collect them. | 2206 // And now make children weak again and collect them. |
1995 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2207 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1996 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2208 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
1997 | 2209 |
1998 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2210 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
1999 CHECK_EQ(7, NumberOfWeakCalls); | 2211 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2000 } | 2212 } |
2001 | 2213 |
2002 | 2214 |
2003 THREADED_TEST(ApiObjectGroupsCycle) { | 2215 THREADED_TEST(ApiObjectGroupsCycle) { |
2004 HandleScope scope; | 2216 HandleScope scope; |
2005 LocalContext env; | 2217 LocalContext env; |
2006 | 2218 |
2007 NumberOfWeakCalls = 0; | 2219 WeakCallCounter counter(1234); |
2008 | 2220 |
2009 Persistent<Object> g1s1; | 2221 Persistent<Object> g1s1; |
2010 Persistent<Object> g1s2; | 2222 Persistent<Object> g1s2; |
2011 Persistent<Object> g2s1; | 2223 Persistent<Object> g2s1; |
2012 Persistent<Object> g2s2; | 2224 Persistent<Object> g2s2; |
2013 Persistent<Object> g3s1; | 2225 Persistent<Object> g3s1; |
2014 Persistent<Object> g3s2; | 2226 Persistent<Object> g3s2; |
2015 | 2227 |
2016 { | 2228 { |
2017 HandleScope scope; | 2229 HandleScope scope; |
2018 g1s1 = Persistent<Object>::New(Object::New()); | 2230 g1s1 = Persistent<Object>::New(Object::New()); |
2019 g1s2 = Persistent<Object>::New(Object::New()); | 2231 g1s2 = Persistent<Object>::New(Object::New()); |
2020 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2232 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2021 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2233 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2022 | 2234 |
2023 g2s1 = Persistent<Object>::New(Object::New()); | 2235 g2s1 = Persistent<Object>::New(Object::New()); |
2024 g2s2 = Persistent<Object>::New(Object::New()); | 2236 g2s2 = Persistent<Object>::New(Object::New()); |
2025 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2237 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2026 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2238 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2027 | 2239 |
2028 g3s1 = Persistent<Object>::New(Object::New()); | 2240 g3s1 = Persistent<Object>::New(Object::New()); |
2029 g3s2 = Persistent<Object>::New(Object::New()); | 2241 g3s2 = Persistent<Object>::New(Object::New()); |
2030 g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2242 g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2031 g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2243 g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2032 } | 2244 } |
2033 | 2245 |
2034 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 2246 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
2035 | 2247 |
2036 // Connect groups. We're building the following cycle: | 2248 // Connect groups. We're building the following cycle: |
2037 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2249 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
2038 // groups. | 2250 // groups. |
2039 { | 2251 { |
2040 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2252 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2041 Persistent<Value> g1_children[] = { g2s1 }; | 2253 Persistent<Value> g1_children[] = { g2s1 }; |
2042 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2254 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2043 Persistent<Value> g2_children[] = { g3s1 }; | 2255 Persistent<Value> g2_children[] = { g3s1 }; |
2044 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2256 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
2045 Persistent<Value> g3_children[] = { g1s1 }; | 2257 Persistent<Value> g3_children[] = { g1s1 }; |
2046 V8::AddObjectGroup(g1_objects, 2); | 2258 V8::AddObjectGroup(g1_objects, 2); |
2047 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2259 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2048 V8::AddObjectGroup(g2_objects, 2); | 2260 V8::AddObjectGroup(g2_objects, 2); |
2049 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2261 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2050 V8::AddObjectGroup(g3_objects, 2); | 2262 V8::AddObjectGroup(g3_objects, 2); |
2051 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2263 V8::AddImplicitReferences(g3s1, g3_children, 1); |
2052 } | 2264 } |
2053 // Do a full GC | 2265 // Do a single full GC |
2054 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2266 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
2055 | 2267 |
2056 // All object should be alive. | 2268 // All object should be alive. |
2057 CHECK_EQ(0, NumberOfWeakCalls); | 2269 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2058 | 2270 |
2059 // Weaken the root. | 2271 // Weaken the root. |
2060 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2272 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2061 | 2273 |
2062 // Groups are deleted, rebuild groups. | 2274 // Groups are deleted, rebuild groups. |
2063 { | 2275 { |
2064 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2276 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2065 Persistent<Value> g1_children[] = { g2s1 }; | 2277 Persistent<Value> g1_children[] = { g2s1 }; |
2066 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2278 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2067 Persistent<Value> g2_children[] = { g3s1 }; | 2279 Persistent<Value> g2_children[] = { g3s1 }; |
2068 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2280 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
2069 Persistent<Value> g3_children[] = { g1s1 }; | 2281 Persistent<Value> g3_children[] = { g1s1 }; |
2070 V8::AddObjectGroup(g1_objects, 2); | 2282 V8::AddObjectGroup(g1_objects, 2); |
2071 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2283 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2072 V8::AddObjectGroup(g2_objects, 2); | 2284 V8::AddObjectGroup(g2_objects, 2); |
2073 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2285 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2074 V8::AddObjectGroup(g3_objects, 2); | 2286 V8::AddObjectGroup(g3_objects, 2); |
2075 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2287 V8::AddImplicitReferences(g3s1, g3_children, 1); |
2076 } | 2288 } |
2077 | 2289 |
2078 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2290 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
2079 | 2291 |
2080 // All objects should be gone. 7 global handles in total. | 2292 // All objects should be gone. 7 global handles in total. |
2081 CHECK_EQ(7, NumberOfWeakCalls); | 2293 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2082 } | 2294 } |
2083 | 2295 |
2084 | 2296 |
2085 THREADED_TEST(ScriptException) { | 2297 THREADED_TEST(ScriptException) { |
2086 v8::HandleScope scope; | 2298 v8::HandleScope scope; |
2087 LocalContext env; | 2299 LocalContext env; |
2088 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 2300 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
2089 v8::TryCatch try_catch; | 2301 v8::TryCatch try_catch; |
2090 Local<Value> result = script->Run(); | 2302 Local<Value> result = script->Run(); |
2091 CHECK(result.IsEmpty()); | 2303 CHECK(result.IsEmpty()); |
(...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4298 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); | 4510 v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); |
4299 const char* extension_names[] = { "simpletest" }; | 4511 const char* extension_names[] = { "simpletest" }; |
4300 v8::ExtensionConfiguration extensions(1, extension_names); | 4512 v8::ExtensionConfiguration extensions(1, extension_names); |
4301 v8::Handle<Context> context = Context::New(&extensions); | 4513 v8::Handle<Context> context = Context::New(&extensions); |
4302 Context::Scope lock(context); | 4514 Context::Scope lock(context); |
4303 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); | 4515 v8::Handle<Value> result = Script::Compile(v8_str("Foo()"))->Run(); |
4304 CHECK_EQ(result, v8::Integer::New(4)); | 4516 CHECK_EQ(result, v8::Integer::New(4)); |
4305 } | 4517 } |
4306 | 4518 |
4307 | 4519 |
| 4520 static const char* kEmbeddedExtensionSource = |
| 4521 "function Ret54321(){return 54321;}~~@@$" |
| 4522 "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; |
| 4523 static const int kEmbeddedExtensionSourceValidLen = 34; |
| 4524 |
| 4525 |
| 4526 THREADED_TEST(ExtensionMissingSourceLength) { |
| 4527 v8::HandleScope handle_scope; |
| 4528 v8::RegisterExtension(new Extension("srclentest_fail", |
| 4529 kEmbeddedExtensionSource)); |
| 4530 const char* extension_names[] = { "srclentest_fail" }; |
| 4531 v8::ExtensionConfiguration extensions(1, extension_names); |
| 4532 v8::Handle<Context> context = Context::New(&extensions); |
| 4533 CHECK_EQ(0, *context); |
| 4534 } |
| 4535 |
| 4536 |
| 4537 THREADED_TEST(ExtensionWithSourceLength) { |
| 4538 for (int source_len = kEmbeddedExtensionSourceValidLen - 1; |
| 4539 source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { |
| 4540 v8::HandleScope handle_scope; |
| 4541 i::ScopedVector<char> extension_name(32); |
| 4542 i::OS::SNPrintF(extension_name, "ext #%d", source_len); |
| 4543 v8::RegisterExtension(new Extension(extension_name.start(), |
| 4544 kEmbeddedExtensionSource, 0, 0, |
| 4545 source_len)); |
| 4546 const char* extension_names[1] = { extension_name.start() }; |
| 4547 v8::ExtensionConfiguration extensions(1, extension_names); |
| 4548 v8::Handle<Context> context = Context::New(&extensions); |
| 4549 if (source_len == kEmbeddedExtensionSourceValidLen) { |
| 4550 Context::Scope lock(context); |
| 4551 v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run(); |
| 4552 CHECK_EQ(v8::Integer::New(54321), result); |
| 4553 } else { |
| 4554 // Anything but exactly the right length should fail to compile. |
| 4555 CHECK_EQ(0, *context); |
| 4556 } |
| 4557 } |
| 4558 } |
| 4559 |
| 4560 |
4308 static const char* kEvalExtensionSource1 = | 4561 static const char* kEvalExtensionSource1 = |
4309 "function UseEval1() {" | 4562 "function UseEval1() {" |
4310 " var x = 42;" | 4563 " var x = 42;" |
4311 " return eval('x');" | 4564 " return eval('x');" |
4312 "}"; | 4565 "}"; |
4313 | 4566 |
4314 | 4567 |
4315 static const char* kEvalExtensionSource2 = | 4568 static const char* kEvalExtensionSource2 = |
4316 "(function() {" | 4569 "(function() {" |
4317 " var x = 42;" | 4570 " var x = 42;" |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4798 CHECK(object_a_disposed); | 5051 CHECK(object_a_disposed); |
4799 } | 5052 } |
4800 | 5053 |
4801 | 5054 |
4802 static void InvokeScavenge() { | 5055 static void InvokeScavenge() { |
4803 HEAP->PerformScavenge(); | 5056 HEAP->PerformScavenge(); |
4804 } | 5057 } |
4805 | 5058 |
4806 | 5059 |
4807 static void InvokeMarkSweep() { | 5060 static void InvokeMarkSweep() { |
4808 HEAP->CollectAllGarbage(false); | 5061 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
4809 } | 5062 } |
4810 | 5063 |
4811 | 5064 |
4812 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { | 5065 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
4813 obj.Dispose(); | 5066 obj.Dispose(); |
4814 obj.Clear(); | 5067 obj.Clear(); |
4815 *(reinterpret_cast<bool*>(data)) = true; | 5068 *(reinterpret_cast<bool*>(data)) = true; |
4816 InvokeScavenge(); | 5069 InvokeScavenge(); |
4817 } | 5070 } |
4818 | 5071 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 | 5144 |
4892 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { | 5145 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { |
4893 ApiTestFuzzer::Fuzz(); | 5146 ApiTestFuzzer::Fuzz(); |
4894 CHECK_EQ(args_fun, args.Callee()); | 5147 CHECK_EQ(args_fun, args.Callee()); |
4895 CHECK_EQ(3, args.Length()); | 5148 CHECK_EQ(3, args.Length()); |
4896 CHECK_EQ(v8::Integer::New(1), args[0]); | 5149 CHECK_EQ(v8::Integer::New(1), args[0]); |
4897 CHECK_EQ(v8::Integer::New(2), args[1]); | 5150 CHECK_EQ(v8::Integer::New(2), args[1]); |
4898 CHECK_EQ(v8::Integer::New(3), args[2]); | 5151 CHECK_EQ(v8::Integer::New(3), args[2]); |
4899 CHECK_EQ(v8::Undefined(), args[3]); | 5152 CHECK_EQ(v8::Undefined(), args[3]); |
4900 v8::HandleScope scope; | 5153 v8::HandleScope scope; |
4901 HEAP->CollectAllGarbage(false); | 5154 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
4902 return v8::Undefined(); | 5155 return v8::Undefined(); |
4903 } | 5156 } |
4904 | 5157 |
4905 | 5158 |
4906 THREADED_TEST(Arguments) { | 5159 THREADED_TEST(Arguments) { |
4907 v8::HandleScope scope; | 5160 v8::HandleScope scope; |
4908 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); | 5161 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); |
4909 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); | 5162 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); |
4910 LocalContext context(NULL, global); | 5163 LocalContext context(NULL, global); |
4911 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); | 5164 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); |
(...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7876 "var p = new constructor();" | 8129 "var p = new constructor();" |
7877 "p.hasOwnProperty('ostehaps');"); | 8130 "p.hasOwnProperty('ostehaps');"); |
7878 CHECK_EQ(false, value->BooleanValue()); | 8131 CHECK_EQ(false, value->BooleanValue()); |
7879 } | 8132 } |
7880 | 8133 |
7881 | 8134 |
7882 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( | 8135 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( |
7883 Local<String> name, | 8136 Local<String> name, |
7884 const AccessorInfo& info) { | 8137 const AccessorInfo& info) { |
7885 ApiTestFuzzer::Fuzz(); | 8138 ApiTestFuzzer::Fuzz(); |
7886 HEAP->CollectAllGarbage(false); | 8139 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
7887 return v8::Handle<Value>(); | 8140 return v8::Handle<Value>(); |
7888 } | 8141 } |
7889 | 8142 |
7890 | 8143 |
7891 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { | 8144 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { |
7892 v8::HandleScope scope; | 8145 v8::HandleScope scope; |
7893 LocalContext context; | 8146 LocalContext context; |
7894 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 8147 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
7895 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | 8148 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
7896 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); | 8149 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8606 "};"); | 8859 "};"); |
8607 CHECK_EQ(239 * 10, value->Int32Value()); | 8860 CHECK_EQ(239 * 10, value->Int32Value()); |
8608 } | 8861 } |
8609 | 8862 |
8610 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, | 8863 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
8611 const AccessorInfo& info) { | 8864 const AccessorInfo& info) { |
8612 ApiTestFuzzer::Fuzz(); | 8865 ApiTestFuzzer::Fuzz(); |
8613 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); | 8866 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
8614 ++(*call_count); | 8867 ++(*call_count); |
8615 if ((*call_count) % 20 == 0) { | 8868 if ((*call_count) % 20 == 0) { |
8616 HEAP->CollectAllGarbage(true); | 8869 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
8617 } | 8870 } |
8618 return v8::Handle<Value>(); | 8871 return v8::Handle<Value>(); |
8619 } | 8872 } |
8620 | 8873 |
8621 static v8::Handle<Value> FastApiCallback_TrivialSignature( | 8874 static v8::Handle<Value> FastApiCallback_TrivialSignature( |
8622 const v8::Arguments& args) { | 8875 const v8::Arguments& args) { |
8623 ApiTestFuzzer::Fuzz(); | 8876 ApiTestFuzzer::Fuzz(); |
8624 CHECK_EQ(args.This(), args.Holder()); | 8877 CHECK_EQ(args.This(), args.Holder()); |
8625 CHECK(args.Data()->Equals(v8_str("method_data"))); | 8878 CHECK(args.Data()->Equals(v8_str("method_data"))); |
8626 return v8::Integer::New(args[0]->Int32Value() + 1); | 8879 return v8::Integer::New(args[0]->Int32Value() + 1); |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9957 Local<Script> script = v8_compile("(function () {" | 10210 Local<Script> script = v8_compile("(function () {" |
9958 " unlock_for_a_moment();" | 10211 " unlock_for_a_moment();" |
9959 " return 42;" | 10212 " return 42;" |
9960 "})();"); | 10213 "})();"); |
9961 CHECK_EQ(42, script->Run()->Int32Value()); | 10214 CHECK_EQ(42, script->Run()->Int32Value()); |
9962 } | 10215 } |
9963 } | 10216 } |
9964 | 10217 |
9965 | 10218 |
9966 static int GetGlobalObjectsCount() { | 10219 static int GetGlobalObjectsCount() { |
| 10220 i::Isolate::Current()->heap()->EnsureHeapIsIterable(); |
9967 int count = 0; | 10221 int count = 0; |
9968 i::HeapIterator it; | 10222 i::HeapIterator it; |
9969 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) | 10223 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) |
9970 if (object->IsJSGlobalObject()) count++; | 10224 if (object->IsJSGlobalObject()) count++; |
9971 return count; | 10225 return count; |
9972 } | 10226 } |
9973 | 10227 |
9974 | 10228 |
9975 static void CheckSurvivingGlobalObjectsCount(int expected) { | 10229 static void CheckSurvivingGlobalObjectsCount(int expected) { |
9976 // We need to collect all garbage twice to be sure that everything | 10230 // We need to collect all garbage twice to be sure that everything |
9977 // has been collected. This is because inline caches are cleared in | 10231 // has been collected. This is because inline caches are cleared in |
9978 // the first garbage collection but some of the maps have already | 10232 // the first garbage collection but some of the maps have already |
9979 // been marked at that point. Therefore some of the maps are not | 10233 // been marked at that point. Therefore some of the maps are not |
9980 // collected until the second garbage collection. | 10234 // collected until the second garbage collection. |
9981 HEAP->global_context_map(); | 10235 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
9982 HEAP->CollectAllGarbage(false); | 10236 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
9983 HEAP->CollectAllGarbage(false); | |
9984 int count = GetGlobalObjectsCount(); | 10237 int count = GetGlobalObjectsCount(); |
9985 #ifdef DEBUG | 10238 #ifdef DEBUG |
9986 if (count != expected) HEAP->TracePathToGlobal(); | 10239 if (count != expected) HEAP->TracePathToGlobal(); |
9987 #endif | 10240 #endif |
9988 CHECK_EQ(expected, count); | 10241 CHECK_EQ(expected, count); |
9989 } | 10242 } |
9990 | 10243 |
9991 | 10244 |
9992 TEST(DontLeakGlobalObjects) { | 10245 TEST(DontLeakGlobalObjects) { |
9993 // Regression test for issues 1139850 and 1174891. | 10246 // Regression test for issues 1139850 and 1174891. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10042 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10295 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10043 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10296 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10044 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10297 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10045 } | 10298 } |
10046 // Note: order is implementation dependent alas: currently | 10299 // Note: order is implementation dependent alas: currently |
10047 // global handle nodes are processed by PostGarbageCollectionProcessing | 10300 // global handle nodes are processed by PostGarbageCollectionProcessing |
10048 // in reverse allocation order, so if second allocated handle is deleted, | 10301 // in reverse allocation order, so if second allocated handle is deleted, |
10049 // weak callback of the first handle would be able to 'reallocate' it. | 10302 // weak callback of the first handle would be able to 'reallocate' it. |
10050 handle1.MakeWeak(NULL, NewPersistentHandleCallback); | 10303 handle1.MakeWeak(NULL, NewPersistentHandleCallback); |
10051 handle2.Dispose(); | 10304 handle2.Dispose(); |
10052 HEAP->CollectAllGarbage(false); | 10305 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
10053 } | 10306 } |
10054 | 10307 |
10055 | 10308 |
10056 v8::Persistent<v8::Object> to_be_disposed; | 10309 v8::Persistent<v8::Object> to_be_disposed; |
10057 | 10310 |
10058 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { | 10311 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { |
10059 to_be_disposed.Dispose(); | 10312 to_be_disposed.Dispose(); |
10060 HEAP->CollectAllGarbage(false); | 10313 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
10061 handle.Dispose(); | 10314 handle.Dispose(); |
10062 } | 10315 } |
10063 | 10316 |
10064 | 10317 |
10065 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 10318 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
10066 LocalContext context; | 10319 LocalContext context; |
10067 | 10320 |
10068 v8::Persistent<v8::Object> handle1, handle2; | 10321 v8::Persistent<v8::Object> handle1, handle2; |
10069 { | 10322 { |
10070 v8::HandleScope scope; | 10323 v8::HandleScope scope; |
10071 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10324 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10072 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10325 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10073 } | 10326 } |
10074 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); | 10327 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); |
10075 to_be_disposed = handle2; | 10328 to_be_disposed = handle2; |
10076 HEAP->CollectAllGarbage(false); | 10329 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
10077 } | 10330 } |
10078 | 10331 |
10079 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { | 10332 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { |
10080 handle.Dispose(); | 10333 handle.Dispose(); |
10081 } | 10334 } |
10082 | 10335 |
10083 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { | 10336 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { |
10084 v8::HandleScope scope; | 10337 v8::HandleScope scope; |
10085 v8::Persistent<v8::Object>::New(v8::Object::New()); | 10338 v8::Persistent<v8::Object>::New(v8::Object::New()); |
10086 handle.Dispose(); | 10339 handle.Dispose(); |
10087 } | 10340 } |
10088 | 10341 |
10089 | 10342 |
10090 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 10343 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
10091 LocalContext context; | 10344 LocalContext context; |
10092 | 10345 |
10093 v8::Persistent<v8::Object> handle1, handle2, handle3; | 10346 v8::Persistent<v8::Object> handle1, handle2, handle3; |
10094 { | 10347 { |
10095 v8::HandleScope scope; | 10348 v8::HandleScope scope; |
10096 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10349 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10097 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10350 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10098 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10351 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
10099 } | 10352 } |
10100 handle2.MakeWeak(NULL, DisposingCallback); | 10353 handle2.MakeWeak(NULL, DisposingCallback); |
10101 handle3.MakeWeak(NULL, HandleCreatingCallback); | 10354 handle3.MakeWeak(NULL, HandleCreatingCallback); |
10102 HEAP->CollectAllGarbage(false); | 10355 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
10103 } | 10356 } |
10104 | 10357 |
10105 | 10358 |
10106 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 10359 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
10107 v8::V8::Initialize(); | 10360 v8::V8::Initialize(); |
10108 | 10361 |
10109 const int nof = 2; | 10362 const int nof = 2; |
10110 const char* sources[nof] = { | 10363 const char* sources[nof] = { |
10111 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 10364 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
10112 "Object()" | 10365 "Object()" |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10908 private: | 11161 private: |
10909 RegExpInterruptTest* test_; | 11162 RegExpInterruptTest* test_; |
10910 }; | 11163 }; |
10911 | 11164 |
10912 void CollectGarbage() { | 11165 void CollectGarbage() { |
10913 block_->Wait(); | 11166 block_->Wait(); |
10914 while (gc_during_regexp_ < kRequiredGCs) { | 11167 while (gc_during_regexp_ < kRequiredGCs) { |
10915 { | 11168 { |
10916 v8::Locker lock; | 11169 v8::Locker lock; |
10917 // TODO(lrn): Perhaps create some garbage before collecting. | 11170 // TODO(lrn): Perhaps create some garbage before collecting. |
10918 HEAP->CollectAllGarbage(false); | 11171 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
10919 gc_count_++; | 11172 gc_count_++; |
10920 } | 11173 } |
10921 i::OS::Sleep(1); | 11174 i::OS::Sleep(1); |
10922 } | 11175 } |
10923 gc_success_ = true; | 11176 gc_success_ = true; |
10924 } | 11177 } |
10925 | 11178 |
10926 void LongRunningRegExp() { | 11179 void LongRunningRegExp() { |
10927 block_->Signal(); // Enable garbage collection thread on next preemption. | 11180 block_->Signal(); // Enable garbage collection thread on next preemption. |
10928 int rounds = 0; | 11181 int rounds = 0; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11030 } | 11283 } |
11031 private: | 11284 private: |
11032 ApplyInterruptTest* test_; | 11285 ApplyInterruptTest* test_; |
11033 }; | 11286 }; |
11034 | 11287 |
11035 void CollectGarbage() { | 11288 void CollectGarbage() { |
11036 block_->Wait(); | 11289 block_->Wait(); |
11037 while (gc_during_apply_ < kRequiredGCs) { | 11290 while (gc_during_apply_ < kRequiredGCs) { |
11038 { | 11291 { |
11039 v8::Locker lock; | 11292 v8::Locker lock; |
11040 HEAP->CollectAllGarbage(false); | 11293 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11041 gc_count_++; | 11294 gc_count_++; |
11042 } | 11295 } |
11043 i::OS::Sleep(1); | 11296 i::OS::Sleep(1); |
11044 } | 11297 } |
11045 gc_success_ = true; | 11298 gc_success_ = true; |
11046 } | 11299 } |
11047 | 11300 |
11048 void LongRunningApply() { | 11301 void LongRunningApply() { |
11049 block_->Signal(); | 11302 block_->Signal(); |
11050 int rounds = 0; | 11303 int rounds = 0; |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11746 | 11999 |
11747 | 12000 |
11748 THREADED_TEST(PixelArray) { | 12001 THREADED_TEST(PixelArray) { |
11749 v8::HandleScope scope; | 12002 v8::HandleScope scope; |
11750 LocalContext context; | 12003 LocalContext context; |
11751 const int kElementCount = 260; | 12004 const int kElementCount = 260; |
11752 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 12005 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
11753 i::Handle<i::ExternalPixelArray> pixels = | 12006 i::Handle<i::ExternalPixelArray> pixels = |
11754 i::Handle<i::ExternalPixelArray>::cast( | 12007 i::Handle<i::ExternalPixelArray>::cast( |
11755 FACTORY->NewExternalArray(kElementCount, | 12008 FACTORY->NewExternalArray(kElementCount, |
11756 v8::kExternalPixelArray, | 12009 v8::kExternalPixelArray, |
11757 pixel_data)); | 12010 pixel_data)); |
11758 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12011 // Force GC to trigger verification. |
| 12012 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11759 for (int i = 0; i < kElementCount; i++) { | 12013 for (int i = 0; i < kElementCount; i++) { |
11760 pixels->set(i, i % 256); | 12014 pixels->set(i, i % 256); |
11761 } | 12015 } |
11762 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12016 // Force GC to trigger verification. |
| 12017 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11763 for (int i = 0; i < kElementCount; i++) { | 12018 for (int i = 0; i < kElementCount; i++) { |
11764 CHECK_EQ(i % 256, pixels->get_scalar(i)); | 12019 CHECK_EQ(i % 256, pixels->get_scalar(i)); |
11765 CHECK_EQ(i % 256, pixel_data[i]); | 12020 CHECK_EQ(i % 256, pixel_data[i]); |
11766 } | 12021 } |
11767 | 12022 |
11768 v8::Handle<v8::Object> obj = v8::Object::New(); | 12023 v8::Handle<v8::Object> obj = v8::Object::New(); |
11769 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 12024 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
11770 // Set the elements to be the pixels. | 12025 // Set the elements to be the pixels. |
11771 // jsobj->set_elements(*pixels); | 12026 // jsobj->set_elements(*pixels); |
11772 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 12027 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12228 int64_t high) { | 12483 int64_t high) { |
12229 v8::HandleScope scope; | 12484 v8::HandleScope scope; |
12230 LocalContext context; | 12485 LocalContext context; |
12231 const int kElementCount = 40; | 12486 const int kElementCount = 40; |
12232 int element_size = ExternalArrayElementSize(array_type); | 12487 int element_size = ExternalArrayElementSize(array_type); |
12233 ElementType* array_data = | 12488 ElementType* array_data = |
12234 static_cast<ElementType*>(malloc(kElementCount * element_size)); | 12489 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
12235 i::Handle<ExternalArrayClass> array = | 12490 i::Handle<ExternalArrayClass> array = |
12236 i::Handle<ExternalArrayClass>::cast( | 12491 i::Handle<ExternalArrayClass>::cast( |
12237 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); | 12492 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); |
12238 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12493 // Force GC to trigger verification. |
| 12494 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
12239 for (int i = 0; i < kElementCount; i++) { | 12495 for (int i = 0; i < kElementCount; i++) { |
12240 array->set(i, static_cast<ElementType>(i)); | 12496 array->set(i, static_cast<ElementType>(i)); |
12241 } | 12497 } |
12242 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12498 // Force GC to trigger verification. |
| 12499 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
12243 for (int i = 0; i < kElementCount; i++) { | 12500 for (int i = 0; i < kElementCount; i++) { |
12244 CHECK_EQ(static_cast<int64_t>(i), | 12501 CHECK_EQ(static_cast<int64_t>(i), |
12245 static_cast<int64_t>(array->get_scalar(i))); | 12502 static_cast<int64_t>(array->get_scalar(i))); |
12246 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); | 12503 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
12247 } | 12504 } |
12248 | 12505 |
12249 v8::Handle<v8::Object> obj = v8::Object::New(); | 12506 v8::Handle<v8::Object> obj = v8::Object::New(); |
12250 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 12507 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
12251 // Set the elements to be the external array. | 12508 // Set the elements to be the external array. |
12252 obj->SetIndexedPropertiesToExternalArrayData(array_data, | 12509 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12350 result = CompileRun("var tmp_array = ext_array;" | 12607 result = CompileRun("var tmp_array = ext_array;" |
12351 "var sum = 0;" | 12608 "var sum = 0;" |
12352 "for (var i = 0; i < 8; i++) {" | 12609 "for (var i = 0; i < 8; i++) {" |
12353 " tmp_array[i] = i;" | 12610 " tmp_array[i] = i;" |
12354 " sum += tmp_array[i];" | 12611 " sum += tmp_array[i];" |
12355 " if (i == 4) {" | 12612 " if (i == 4) {" |
12356 " tmp_array = {};" | 12613 " tmp_array = {};" |
12357 " }" | 12614 " }" |
12358 "}" | 12615 "}" |
12359 "sum;"); | 12616 "sum;"); |
12360 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12617 // Force GC to trigger verification. |
| 12618 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
12361 CHECK_EQ(28, result->Int32Value()); | 12619 CHECK_EQ(28, result->Int32Value()); |
12362 | 12620 |
12363 // Make sure out-of-range loads do not throw. | 12621 // Make sure out-of-range loads do not throw. |
12364 i::OS::SNPrintF(test_buf, | 12622 i::OS::SNPrintF(test_buf, |
12365 "var caught_exception = false;" | 12623 "var caught_exception = false;" |
12366 "try {" | 12624 "try {" |
12367 " ext_array[%d];" | 12625 " ext_array[%d];" |
12368 "} catch (e) {" | 12626 "} catch (e) {" |
12369 " caught_exception = true;" | 12627 " caught_exception = true;" |
12370 "}" | 12628 "}" |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13330 Local<v8::String> obj = v8::String::New(""); | 13588 Local<v8::String> obj = v8::String::New(""); |
13331 context->SetData(obj); | 13589 context->SetData(obj); |
13332 CompileRun(source_simple); | 13590 CompileRun(source_simple); |
13333 context->Exit(); | 13591 context->Exit(); |
13334 } | 13592 } |
13335 context.Dispose(); | 13593 context.Dispose(); |
13336 for (gc_count = 1; gc_count < 10; gc_count++) { | 13594 for (gc_count = 1; gc_count < 10; gc_count++) { |
13337 other_context->Enter(); | 13595 other_context->Enter(); |
13338 CompileRun(source_simple); | 13596 CompileRun(source_simple); |
13339 other_context->Exit(); | 13597 other_context->Exit(); |
13340 HEAP->CollectAllGarbage(false); | 13598 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13341 if (GetGlobalObjectsCount() == 1) break; | 13599 if (GetGlobalObjectsCount() == 1) break; |
13342 } | 13600 } |
13343 CHECK_GE(2, gc_count); | 13601 CHECK_GE(2, gc_count); |
13344 CHECK_EQ(1, GetGlobalObjectsCount()); | 13602 CHECK_EQ(1, GetGlobalObjectsCount()); |
13345 | 13603 |
13346 // Eval in a function creates reference from the compilation cache to the | 13604 // Eval in a function creates reference from the compilation cache to the |
13347 // global object. | 13605 // global object. |
13348 const char* source_eval = "function f(){eval('1')}; f()"; | 13606 const char* source_eval = "function f(){eval('1')}; f()"; |
13349 context = Context::New(); | 13607 context = Context::New(); |
13350 { | 13608 { |
13351 v8::HandleScope scope; | 13609 v8::HandleScope scope; |
13352 | 13610 |
13353 context->Enter(); | 13611 context->Enter(); |
13354 CompileRun(source_eval); | 13612 CompileRun(source_eval); |
13355 context->Exit(); | 13613 context->Exit(); |
13356 } | 13614 } |
13357 context.Dispose(); | 13615 context.Dispose(); |
13358 for (gc_count = 1; gc_count < 10; gc_count++) { | 13616 for (gc_count = 1; gc_count < 10; gc_count++) { |
13359 other_context->Enter(); | 13617 other_context->Enter(); |
13360 CompileRun(source_eval); | 13618 CompileRun(source_eval); |
13361 other_context->Exit(); | 13619 other_context->Exit(); |
13362 HEAP->CollectAllGarbage(false); | 13620 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13363 if (GetGlobalObjectsCount() == 1) break; | 13621 if (GetGlobalObjectsCount() == 1) break; |
13364 } | 13622 } |
13365 CHECK_GE(2, gc_count); | 13623 CHECK_GE(2, gc_count); |
13366 CHECK_EQ(1, GetGlobalObjectsCount()); | 13624 CHECK_EQ(1, GetGlobalObjectsCount()); |
13367 | 13625 |
13368 // Looking up the line number for an exception creates reference from the | 13626 // Looking up the line number for an exception creates reference from the |
13369 // compilation cache to the global object. | 13627 // compilation cache to the global object. |
13370 const char* source_exception = "function f(){throw 1;} f()"; | 13628 const char* source_exception = "function f(){throw 1;} f()"; |
13371 context = Context::New(); | 13629 context = Context::New(); |
13372 { | 13630 { |
13373 v8::HandleScope scope; | 13631 v8::HandleScope scope; |
13374 | 13632 |
13375 context->Enter(); | 13633 context->Enter(); |
13376 v8::TryCatch try_catch; | 13634 v8::TryCatch try_catch; |
13377 CompileRun(source_exception); | 13635 CompileRun(source_exception); |
13378 CHECK(try_catch.HasCaught()); | 13636 CHECK(try_catch.HasCaught()); |
13379 v8::Handle<v8::Message> message = try_catch.Message(); | 13637 v8::Handle<v8::Message> message = try_catch.Message(); |
13380 CHECK(!message.IsEmpty()); | 13638 CHECK(!message.IsEmpty()); |
13381 CHECK_EQ(1, message->GetLineNumber()); | 13639 CHECK_EQ(1, message->GetLineNumber()); |
13382 context->Exit(); | 13640 context->Exit(); |
13383 } | 13641 } |
13384 context.Dispose(); | 13642 context.Dispose(); |
13385 for (gc_count = 1; gc_count < 10; gc_count++) { | 13643 for (gc_count = 1; gc_count < 10; gc_count++) { |
13386 other_context->Enter(); | 13644 other_context->Enter(); |
13387 CompileRun(source_exception); | 13645 CompileRun(source_exception); |
13388 other_context->Exit(); | 13646 other_context->Exit(); |
13389 HEAP->CollectAllGarbage(false); | 13647 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13390 if (GetGlobalObjectsCount() == 1) break; | 13648 if (GetGlobalObjectsCount() == 1) break; |
13391 } | 13649 } |
13392 CHECK_GE(2, gc_count); | 13650 CHECK_GE(2, gc_count); |
13393 CHECK_EQ(1, GetGlobalObjectsCount()); | 13651 CHECK_EQ(1, GetGlobalObjectsCount()); |
13394 | 13652 |
13395 other_context.Dispose(); | 13653 other_context.Dispose(); |
13396 } | 13654 } |
13397 | 13655 |
13398 | 13656 |
13399 THREADED_TEST(ScriptOrigin) { | 13657 THREADED_TEST(ScriptOrigin) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13597 ++epilogue_call_count_second; | 13855 ++epilogue_call_count_second; |
13598 } | 13856 } |
13599 | 13857 |
13600 TEST(GCCallbacks) { | 13858 TEST(GCCallbacks) { |
13601 LocalContext context; | 13859 LocalContext context; |
13602 | 13860 |
13603 v8::V8::AddGCPrologueCallback(PrologueCallback); | 13861 v8::V8::AddGCPrologueCallback(PrologueCallback); |
13604 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 13862 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
13605 CHECK_EQ(0, prologue_call_count); | 13863 CHECK_EQ(0, prologue_call_count); |
13606 CHECK_EQ(0, epilogue_call_count); | 13864 CHECK_EQ(0, epilogue_call_count); |
13607 HEAP->CollectAllGarbage(false); | 13865 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13608 CHECK_EQ(1, prologue_call_count); | 13866 CHECK_EQ(1, prologue_call_count); |
13609 CHECK_EQ(1, epilogue_call_count); | 13867 CHECK_EQ(1, epilogue_call_count); |
13610 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); | 13868 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); |
13611 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); | 13869 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); |
13612 HEAP->CollectAllGarbage(false); | 13870 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13613 CHECK_EQ(2, prologue_call_count); | 13871 CHECK_EQ(2, prologue_call_count); |
13614 CHECK_EQ(2, epilogue_call_count); | 13872 CHECK_EQ(2, epilogue_call_count); |
13615 CHECK_EQ(1, prologue_call_count_second); | 13873 CHECK_EQ(1, prologue_call_count_second); |
13616 CHECK_EQ(1, epilogue_call_count_second); | 13874 CHECK_EQ(1, epilogue_call_count_second); |
13617 v8::V8::RemoveGCPrologueCallback(PrologueCallback); | 13875 v8::V8::RemoveGCPrologueCallback(PrologueCallback); |
13618 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); | 13876 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); |
13619 HEAP->CollectAllGarbage(false); | 13877 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13620 CHECK_EQ(2, prologue_call_count); | 13878 CHECK_EQ(2, prologue_call_count); |
13621 CHECK_EQ(2, epilogue_call_count); | 13879 CHECK_EQ(2, epilogue_call_count); |
13622 CHECK_EQ(2, prologue_call_count_second); | 13880 CHECK_EQ(2, prologue_call_count_second); |
13623 CHECK_EQ(2, epilogue_call_count_second); | 13881 CHECK_EQ(2, epilogue_call_count_second); |
13624 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); | 13882 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); |
13625 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); | 13883 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); |
13626 HEAP->CollectAllGarbage(false); | 13884 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13627 CHECK_EQ(2, prologue_call_count); | 13885 CHECK_EQ(2, prologue_call_count); |
13628 CHECK_EQ(2, epilogue_call_count); | 13886 CHECK_EQ(2, epilogue_call_count); |
13629 CHECK_EQ(2, prologue_call_count_second); | 13887 CHECK_EQ(2, prologue_call_count_second); |
13630 CHECK_EQ(2, epilogue_call_count_second); | 13888 CHECK_EQ(2, epilogue_call_count_second); |
13631 } | 13889 } |
13632 | 13890 |
13633 | 13891 |
13634 THREADED_TEST(AddToJSFunctionResultCache) { | 13892 THREADED_TEST(AddToJSFunctionResultCache) { |
13635 i::FLAG_allow_natives_syntax = true; | 13893 i::FLAG_allow_natives_syntax = true; |
13636 v8::HandleScope scope; | 13894 v8::HandleScope scope; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13833 | 14091 |
13834 reresult = CompileRun("str2.charCodeAt(2);"); | 14092 reresult = CompileRun("str2.charCodeAt(2);"); |
13835 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); | 14093 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
13836 } | 14094 } |
13837 | 14095 |
13838 | 14096 |
13839 // Failed access check callback that performs a GC on each invocation. | 14097 // Failed access check callback that performs a GC on each invocation. |
13840 void FailedAccessCheckCallbackGC(Local<v8::Object> target, | 14098 void FailedAccessCheckCallbackGC(Local<v8::Object> target, |
13841 v8::AccessType type, | 14099 v8::AccessType type, |
13842 Local<v8::Value> data) { | 14100 Local<v8::Value> data) { |
13843 HEAP->CollectAllGarbage(true); | 14101 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
13844 } | 14102 } |
13845 | 14103 |
13846 | 14104 |
13847 TEST(GCInFailedAccessCheckCallback) { | 14105 TEST(GCInFailedAccessCheckCallback) { |
13848 // Install a failed access check callback that performs a GC on each | 14106 // Install a failed access check callback that performs a GC on each |
13849 // invocation. Then force the callback to be called from va | 14107 // invocation. Then force the callback to be called from va |
13850 | 14108 |
13851 v8::V8::Initialize(); | 14109 v8::V8::Initialize(); |
13852 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 14110 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
13853 | 14111 |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14407 ExpectBoolean("delete cell", true); | 14665 ExpectBoolean("delete cell", true); |
14408 ExpectString("(function() {" | 14666 ExpectString("(function() {" |
14409 " try {" | 14667 " try {" |
14410 " return readCell();" | 14668 " return readCell();" |
14411 " } catch(e) {" | 14669 " } catch(e) {" |
14412 " return e.toString();" | 14670 " return e.toString();" |
14413 " }" | 14671 " }" |
14414 "})()", | 14672 "})()", |
14415 "ReferenceError: cell is not defined"); | 14673 "ReferenceError: cell is not defined"); |
14416 CompileRun("cell = \"new_second\";"); | 14674 CompileRun("cell = \"new_second\";"); |
14417 HEAP->CollectAllGarbage(true); | 14675 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
14418 ExpectString("readCell()", "new_second"); | 14676 ExpectString("readCell()", "new_second"); |
14419 ExpectString("readCell()", "new_second"); | 14677 ExpectString("readCell()", "new_second"); |
14420 } | 14678 } |
14421 } | 14679 } |
14422 | 14680 |
14423 | 14681 |
14424 TEST(DontDeleteCellLoadICForceDelete) { | 14682 TEST(DontDeleteCellLoadICForceDelete) { |
14425 const char* function_code = | 14683 const char* function_code = |
14426 "function readCell() { while (true) { return cell; } }"; | 14684 "function readCell() { while (true) { return cell; } }"; |
14427 | 14685 |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15175 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); | 15433 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
15176 | 15434 |
15177 // TODO(1547): Make the following also return "i". | 15435 // TODO(1547): Make the following also return "i". |
15178 // Calling with environment record as base. | 15436 // Calling with environment record as base. |
15179 TestReceiver(o, context->Global(), "func()"); | 15437 TestReceiver(o, context->Global(), "func()"); |
15180 // Calling with no base. | 15438 // Calling with no base. |
15181 TestReceiver(o, context->Global(), "(1,func)()"); | 15439 TestReceiver(o, context->Global(), "(1,func)()"); |
15182 | 15440 |
15183 foreign_context.Dispose(); | 15441 foreign_context.Dispose(); |
15184 } | 15442 } |
OLD | NEW |