OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2502 int id() { return id_; } | 2502 int id() { return id_; } |
2503 void increment() { number_of_weak_calls_++; } | 2503 void increment() { number_of_weak_calls_++; } |
2504 int NumberOfWeakCalls() { return number_of_weak_calls_; } | 2504 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
2505 private: | 2505 private: |
2506 int id_; | 2506 int id_; |
2507 int number_of_weak_calls_; | 2507 int number_of_weak_calls_; |
2508 }; | 2508 }; |
2509 | 2509 |
2510 | 2510 |
2511 static void WeakPointerCallback(v8::Isolate* isolate, | 2511 static void WeakPointerCallback(v8::Isolate* isolate, |
2512 Persistent<Value> handle, | 2512 Persistent<Object>* handle, |
2513 void* id) { | 2513 WeakCallCounter* counter) { |
2514 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); | |
2515 CHECK_EQ(1234, counter->id()); | 2514 CHECK_EQ(1234, counter->id()); |
2516 counter->increment(); | 2515 counter->increment(); |
2517 handle.Dispose(isolate); | 2516 handle->Dispose(isolate); |
2518 } | 2517 } |
2519 | 2518 |
2520 | 2519 |
2521 THREADED_TEST(OldApiObjectGroups) { | 2520 THREADED_TEST(OldApiObjectGroups) { |
2522 LocalContext env; | 2521 LocalContext env; |
2523 v8::Isolate* iso = env->GetIsolate(); | 2522 v8::Isolate* iso = env->GetIsolate(); |
2524 HandleScope scope(iso); | 2523 HandleScope scope(iso); |
2525 | 2524 |
2526 Persistent<Object> g1s1; | 2525 Persistent<Object> g1s1; |
2527 Persistent<Object> g1s2; | 2526 Persistent<Object> g1s2; |
2528 Persistent<Object> g1c1; | 2527 Persistent<Object> g1c1; |
2529 Persistent<Object> g2s1; | 2528 Persistent<Object> g2s1; |
2530 Persistent<Object> g2s2; | 2529 Persistent<Object> g2s2; |
2531 Persistent<Object> g2c1; | 2530 Persistent<Object> g2c1; |
2532 | 2531 |
2533 WeakCallCounter counter(1234); | 2532 WeakCallCounter counter(1234); |
2534 | 2533 |
2535 { | 2534 { |
2536 HandleScope scope(iso); | 2535 HandleScope scope(iso); |
2537 g1s1 = Persistent<Object>::New(iso, Object::New()); | 2536 g1s1 = Persistent<Object>::New(iso, Object::New()); |
2538 g1s2 = Persistent<Object>::New(iso, Object::New()); | 2537 g1s2 = Persistent<Object>::New(iso, Object::New()); |
2539 g1c1 = Persistent<Object>::New(iso, Object::New()); | 2538 g1c1 = Persistent<Object>::New(iso, Object::New()); |
2540 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2539 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2541 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2540 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2542 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2541 g1c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2543 | 2542 |
2544 g2s1 = Persistent<Object>::New(iso, Object::New()); | 2543 g2s1 = Persistent<Object>::New(iso, Object::New()); |
2545 g2s2 = Persistent<Object>::New(iso, Object::New()); | 2544 g2s2 = Persistent<Object>::New(iso, Object::New()); |
2546 g2c1 = Persistent<Object>::New(iso, Object::New()); | 2545 g2c1 = Persistent<Object>::New(iso, Object::New()); |
2547 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2546 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2548 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2547 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2549 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2548 g2c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2550 } | 2549 } |
2551 | 2550 |
2552 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. | 2551 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
2553 | 2552 |
2554 // Connect group 1 and 2, make a cycle. | 2553 // Connect group 1 and 2, make a cycle. |
2555 CHECK(g1s2->Set(0, Handle<Object>(*g2s2))); | 2554 CHECK(g1s2->Set(0, Handle<Object>(*g2s2))); |
2556 CHECK(g2s1->Set(0, Handle<Object>(*g1s1))); | 2555 CHECK(g2s1->Set(0, Handle<Object>(*g1s1))); |
2557 | 2556 |
2558 { | 2557 { |
2559 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2558 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2560 Persistent<Value> g1_children[] = { g1c1 }; | 2559 Persistent<Value> g1_children[] = { g1c1 }; |
2561 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2560 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2562 Persistent<Value> g2_children[] = { g2c1 }; | 2561 Persistent<Value> g2_children[] = { g2c1 }; |
2563 V8::AddObjectGroup(g1_objects, 2); | 2562 V8::AddObjectGroup(g1_objects, 2); |
2564 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2563 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2565 V8::AddObjectGroup(g2_objects, 2); | 2564 V8::AddObjectGroup(g2_objects, 2); |
2566 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2565 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2567 } | 2566 } |
2568 // Do a single full GC, ensure incremental marking is stopped. | 2567 // Do a single full GC, ensure incremental marking is stopped. |
2569 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2568 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2570 | 2569 |
2571 // All object should be alive. | 2570 // All object should be alive. |
2572 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2571 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2573 | 2572 |
2574 // Weaken the root. | 2573 // Weaken the root. |
2575 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2574 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
2576 // But make children strong roots---all the objects (except for children) | 2575 // But make children strong roots---all the objects (except for children) |
2577 // should be collectable now. | 2576 // should be collectable now. |
2578 g1c1.ClearWeak(iso); | 2577 g1c1.ClearWeak(iso); |
2579 g2c1.ClearWeak(iso); | 2578 g2c1.ClearWeak(iso); |
2580 | 2579 |
2581 // Groups are deleted, rebuild groups. | 2580 // Groups are deleted, rebuild groups. |
2582 { | 2581 { |
2583 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2582 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2584 Persistent<Value> g1_children[] = { g1c1 }; | 2583 Persistent<Value> g1_children[] = { g1c1 }; |
2585 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2584 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2586 Persistent<Value> g2_children[] = { g2c1 }; | 2585 Persistent<Value> g2_children[] = { g2c1 }; |
2587 V8::AddObjectGroup(g1_objects, 2); | 2586 V8::AddObjectGroup(g1_objects, 2); |
2588 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2587 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2589 V8::AddObjectGroup(g2_objects, 2); | 2588 V8::AddObjectGroup(g2_objects, 2); |
2590 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2589 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2591 } | 2590 } |
2592 | 2591 |
2593 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2592 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2594 | 2593 |
2595 // All objects should be gone. 5 global handles in total. | 2594 // All objects should be gone. 5 global handles in total. |
2596 CHECK_EQ(5, counter.NumberOfWeakCalls()); | 2595 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
2597 | 2596 |
2598 // And now make children weak again and collect them. | 2597 // And now make children weak again and collect them. |
2599 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2598 g1c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2600 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2599 g2c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2601 | 2600 |
2602 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2601 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2603 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 2602 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2604 } | 2603 } |
2605 | 2604 |
2606 | 2605 |
2607 THREADED_TEST(ApiObjectGroups) { | 2606 THREADED_TEST(ApiObjectGroups) { |
2608 LocalContext env; | 2607 LocalContext env; |
2609 v8::Isolate* iso = env->GetIsolate(); | 2608 v8::Isolate* iso = env->GetIsolate(); |
2610 HandleScope scope(iso); | 2609 HandleScope scope(iso); |
2611 | 2610 |
2612 Persistent<Object> g1s1; | 2611 Persistent<Object> g1s1; |
2613 Persistent<Object> g1s2; | 2612 Persistent<Object> g1s2; |
2614 Persistent<Object> g1c1; | 2613 Persistent<Object> g1c1; |
2615 Persistent<Object> g2s1; | 2614 Persistent<Object> g2s1; |
2616 Persistent<Object> g2s2; | 2615 Persistent<Object> g2s2; |
2617 Persistent<Object> g2c1; | 2616 Persistent<Object> g2c1; |
2618 | 2617 |
2619 WeakCallCounter counter(1234); | 2618 WeakCallCounter counter(1234); |
2620 | 2619 |
2621 { | 2620 { |
2622 HandleScope scope(iso); | 2621 HandleScope scope(iso); |
2623 g1s1 = Persistent<Object>::New(iso, Object::New()); | 2622 g1s1 = Persistent<Object>::New(iso, Object::New()); |
2624 g1s2 = Persistent<Object>::New(iso, Object::New()); | 2623 g1s2 = Persistent<Object>::New(iso, Object::New()); |
2625 g1c1 = Persistent<Object>::New(iso, Object::New()); | 2624 g1c1 = Persistent<Object>::New(iso, Object::New()); |
2626 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2625 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2627 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2626 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2628 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2627 g1c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2629 | 2628 |
2630 g2s1 = Persistent<Object>::New(iso, Object::New()); | 2629 g2s1 = Persistent<Object>::New(iso, Object::New()); |
2631 g2s2 = Persistent<Object>::New(iso, Object::New()); | 2630 g2s2 = Persistent<Object>::New(iso, Object::New()); |
2632 g2c1 = Persistent<Object>::New(iso, Object::New()); | 2631 g2c1 = Persistent<Object>::New(iso, Object::New()); |
2633 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2632 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2634 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2633 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2635 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2634 g2c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2636 } | 2635 } |
2637 | 2636 |
2638 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. | 2637 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
2639 | 2638 |
2640 // Connect group 1 and 2, make a cycle. | 2639 // Connect group 1 and 2, make a cycle. |
2641 CHECK(g1s2->Set(0, Local<Value>(*g2s2))); | 2640 CHECK(g1s2->Set(0, Local<Value>(*g2s2))); |
2642 CHECK(g2s1->Set(0, Local<Value>(*g1s1))); | 2641 CHECK(g2s1->Set(0, Local<Value>(*g1s1))); |
2643 | 2642 |
2644 { | 2643 { |
2645 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); | 2644 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
2646 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); | 2645 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); |
2647 iso->SetObjectGroupId(g1s1, id1); | 2646 iso->SetObjectGroupId(g1s1, id1); |
2648 iso->SetObjectGroupId(g1s2, id1); | 2647 iso->SetObjectGroupId(g1s2, id1); |
2649 iso->SetReferenceFromGroup(id1, g1c1); | 2648 iso->SetReferenceFromGroup(id1, g1c1); |
2650 iso->SetObjectGroupId(g2s1, id2); | 2649 iso->SetObjectGroupId(g2s1, id2); |
2651 iso->SetObjectGroupId(g2s2, id2); | 2650 iso->SetObjectGroupId(g2s2, id2); |
2652 iso->SetReferenceFromGroup(id2, g2c1); | 2651 iso->SetReferenceFromGroup(id2, g2c1); |
2653 } | 2652 } |
2654 // Do a single full GC, ensure incremental marking is stopped. | 2653 // Do a single full GC, ensure incremental marking is stopped. |
2655 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 2654 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
2656 iso)->heap(); | 2655 iso)->heap(); |
2657 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2656 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2658 | 2657 |
2659 // All object should be alive. | 2658 // All object should be alive. |
2660 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2659 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2661 | 2660 |
2662 // Weaken the root. | 2661 // Weaken the root. |
2663 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2662 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
2664 // But make children strong roots---all the objects (except for children) | 2663 // But make children strong roots---all the objects (except for children) |
2665 // should be collectable now. | 2664 // should be collectable now. |
2666 g1c1.ClearWeak(iso); | 2665 g1c1.ClearWeak(iso); |
2667 g2c1.ClearWeak(iso); | 2666 g2c1.ClearWeak(iso); |
2668 | 2667 |
2669 // Groups are deleted, rebuild groups. | 2668 // Groups are deleted, rebuild groups. |
2670 { | 2669 { |
2671 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); | 2670 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
2672 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); | 2671 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); |
2673 iso->SetObjectGroupId(g1s1, id1); | 2672 iso->SetObjectGroupId(g1s1, id1); |
2674 iso->SetObjectGroupId(g1s2, id1); | 2673 iso->SetObjectGroupId(g1s2, id1); |
2675 iso->SetReferenceFromGroup(id1, g1c1); | 2674 iso->SetReferenceFromGroup(id1, g1c1); |
2676 iso->SetObjectGroupId(g2s1, id2); | 2675 iso->SetObjectGroupId(g2s1, id2); |
2677 iso->SetObjectGroupId(g2s2, id2); | 2676 iso->SetObjectGroupId(g2s2, id2); |
2678 iso->SetReferenceFromGroup(id2, g2c1); | 2677 iso->SetReferenceFromGroup(id2, g2c1); |
2679 } | 2678 } |
2680 | 2679 |
2681 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2680 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2682 | 2681 |
2683 // All objects should be gone. 5 global handles in total. | 2682 // All objects should be gone. 5 global handles in total. |
2684 CHECK_EQ(5, counter.NumberOfWeakCalls()); | 2683 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
2685 | 2684 |
2686 // And now make children weak again and collect them. | 2685 // And now make children weak again and collect them. |
2687 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2686 g1c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2688 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2687 g2c1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2689 | 2688 |
2690 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2689 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2691 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 2690 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2692 } | 2691 } |
2693 | 2692 |
2694 | 2693 |
2695 THREADED_TEST(OldApiObjectGroupsCycle) { | 2694 THREADED_TEST(OldApiObjectGroupsCycle) { |
2696 LocalContext env; | 2695 LocalContext env; |
2697 v8::Isolate* iso = env->GetIsolate(); | 2696 v8::Isolate* iso = env->GetIsolate(); |
2698 HandleScope scope(iso); | 2697 HandleScope scope(iso); |
2699 | 2698 |
2700 WeakCallCounter counter(1234); | 2699 WeakCallCounter counter(1234); |
2701 | 2700 |
2702 Persistent<Object> g1s1; | 2701 Persistent<Object> g1s1; |
2703 Persistent<Object> g1s2; | 2702 Persistent<Object> g1s2; |
2704 Persistent<Object> g2s1; | 2703 Persistent<Object> g2s1; |
2705 Persistent<Object> g2s2; | 2704 Persistent<Object> g2s2; |
2706 Persistent<Object> g3s1; | 2705 Persistent<Object> g3s1; |
2707 Persistent<Object> g3s2; | 2706 Persistent<Object> g3s2; |
2708 Persistent<Object> g4s1; | 2707 Persistent<Object> g4s1; |
2709 Persistent<Object> g4s2; | 2708 Persistent<Object> g4s2; |
2710 | 2709 |
2711 { | 2710 { |
2712 HandleScope scope(iso); | 2711 HandleScope scope(iso); |
2713 g1s1 = Persistent<Object>::New(iso, Object::New()); | 2712 g1s1 = Persistent<Object>::New(iso, Object::New()); |
2714 g1s2 = Persistent<Object>::New(iso, Object::New()); | 2713 g1s2 = Persistent<Object>::New(iso, Object::New()); |
2715 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2714 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2716 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2715 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2717 CHECK(g1s1.IsWeak(iso)); | 2716 CHECK(g1s1.IsWeak(iso)); |
2718 CHECK(g1s2.IsWeak(iso)); | 2717 CHECK(g1s2.IsWeak(iso)); |
2719 | 2718 |
2720 g2s1 = Persistent<Object>::New(iso, Object::New()); | 2719 g2s1 = Persistent<Object>::New(iso, Object::New()); |
2721 g2s2 = Persistent<Object>::New(iso, Object::New()); | 2720 g2s2 = Persistent<Object>::New(iso, Object::New()); |
2722 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2721 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2723 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2722 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2724 CHECK(g2s1.IsWeak(iso)); | 2723 CHECK(g2s1.IsWeak(iso)); |
2725 CHECK(g2s2.IsWeak(iso)); | 2724 CHECK(g2s2.IsWeak(iso)); |
2726 | 2725 |
2727 g3s1 = Persistent<Object>::New(iso, Object::New()); | 2726 g3s1 = Persistent<Object>::New(iso, Object::New()); |
2728 g3s2 = Persistent<Object>::New(iso, Object::New()); | 2727 g3s2 = Persistent<Object>::New(iso, Object::New()); |
2729 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2728 g3s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2730 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2729 g3s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2731 CHECK(g3s1.IsWeak(iso)); | 2730 CHECK(g3s1.IsWeak(iso)); |
2732 CHECK(g3s2.IsWeak(iso)); | 2731 CHECK(g3s2.IsWeak(iso)); |
2733 | 2732 |
2734 g4s1 = Persistent<Object>::New(iso, Object::New()); | 2733 g4s1 = Persistent<Object>::New(iso, Object::New()); |
2735 g4s2 = Persistent<Object>::New(iso, Object::New()); | 2734 g4s2 = Persistent<Object>::New(iso, Object::New()); |
2736 g4s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2735 g4s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2737 g4s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2736 g4s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2738 CHECK(g4s1.IsWeak(iso)); | 2737 CHECK(g4s1.IsWeak(iso)); |
2739 CHECK(g4s2.IsWeak(iso)); | 2738 CHECK(g4s2.IsWeak(iso)); |
2740 } | 2739 } |
2741 | 2740 |
2742 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. | 2741 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
2743 | 2742 |
2744 // Connect groups. We're building the following cycle: | 2743 // Connect groups. We're building the following cycle: |
2745 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2744 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
2746 // groups. | 2745 // groups. |
2747 { | 2746 { |
(...skipping 14 matching lines...) Expand all Loading... |
2762 V8::AddObjectGroup(iso, g4_objects, 2); | 2761 V8::AddObjectGroup(iso, g4_objects, 2); |
2763 V8::AddImplicitReferences(g4s1, g4_children, 1); | 2762 V8::AddImplicitReferences(g4s1, g4_children, 1); |
2764 } | 2763 } |
2765 // Do a single full GC | 2764 // Do a single full GC |
2766 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2765 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2767 | 2766 |
2768 // All object should be alive. | 2767 // All object should be alive. |
2769 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2768 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2770 | 2769 |
2771 // Weaken the root. | 2770 // Weaken the root. |
2772 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2771 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
2773 | 2772 |
2774 // Groups are deleted, rebuild groups. | 2773 // Groups are deleted, rebuild groups. |
2775 { | 2774 { |
2776 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2775 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2777 Persistent<Value> g1_children[] = { g2s1 }; | 2776 Persistent<Value> g1_children[] = { g2s1 }; |
2778 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2777 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2779 Persistent<Value> g2_children[] = { g3s1 }; | 2778 Persistent<Value> g2_children[] = { g3s1 }; |
2780 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2779 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
2781 Persistent<Value> g3_children[] = { g4s1 }; | 2780 Persistent<Value> g3_children[] = { g4s1 }; |
2782 Persistent<Value> g4_objects[] = { g4s1, g4s2 }; | 2781 Persistent<Value> g4_objects[] = { g4s1, g4s2 }; |
(...skipping 28 matching lines...) Expand all Loading... |
2811 Persistent<Object> g2s2; | 2810 Persistent<Object> g2s2; |
2812 Persistent<Object> g3s1; | 2811 Persistent<Object> g3s1; |
2813 Persistent<Object> g3s2; | 2812 Persistent<Object> g3s2; |
2814 Persistent<Object> g4s1; | 2813 Persistent<Object> g4s1; |
2815 Persistent<Object> g4s2; | 2814 Persistent<Object> g4s2; |
2816 | 2815 |
2817 { | 2816 { |
2818 HandleScope scope(iso); | 2817 HandleScope scope(iso); |
2819 g1s1 = Persistent<Object>::New(iso, Object::New()); | 2818 g1s1 = Persistent<Object>::New(iso, Object::New()); |
2820 g1s2 = Persistent<Object>::New(iso, Object::New()); | 2819 g1s2 = Persistent<Object>::New(iso, Object::New()); |
2821 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2820 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2822 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2821 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2823 CHECK(g1s1.IsWeak(iso)); | 2822 CHECK(g1s1.IsWeak(iso)); |
2824 CHECK(g1s2.IsWeak(iso)); | 2823 CHECK(g1s2.IsWeak(iso)); |
2825 | 2824 |
2826 g2s1 = Persistent<Object>::New(iso, Object::New()); | 2825 g2s1 = Persistent<Object>::New(iso, Object::New()); |
2827 g2s2 = Persistent<Object>::New(iso, Object::New()); | 2826 g2s2 = Persistent<Object>::New(iso, Object::New()); |
2828 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2827 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2829 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2828 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2830 CHECK(g2s1.IsWeak(iso)); | 2829 CHECK(g2s1.IsWeak(iso)); |
2831 CHECK(g2s2.IsWeak(iso)); | 2830 CHECK(g2s2.IsWeak(iso)); |
2832 | 2831 |
2833 g3s1 = Persistent<Object>::New(iso, Object::New()); | 2832 g3s1 = Persistent<Object>::New(iso, Object::New()); |
2834 g3s2 = Persistent<Object>::New(iso, Object::New()); | 2833 g3s2 = Persistent<Object>::New(iso, Object::New()); |
2835 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2834 g3s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2836 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2835 g3s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2837 CHECK(g3s1.IsWeak(iso)); | 2836 CHECK(g3s1.IsWeak(iso)); |
2838 CHECK(g3s2.IsWeak(iso)); | 2837 CHECK(g3s2.IsWeak(iso)); |
2839 | 2838 |
2840 g4s1 = Persistent<Object>::New(iso, Object::New()); | 2839 g4s1 = Persistent<Object>::New(iso, Object::New()); |
2841 g4s2 = Persistent<Object>::New(iso, Object::New()); | 2840 g4s2 = Persistent<Object>::New(iso, Object::New()); |
2842 g4s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2841 g4s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2843 g4s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2842 g4s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2844 CHECK(g4s1.IsWeak(iso)); | 2843 CHECK(g4s1.IsWeak(iso)); |
2845 CHECK(g4s2.IsWeak(iso)); | 2844 CHECK(g4s2.IsWeak(iso)); |
2846 } | 2845 } |
2847 | 2846 |
2848 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. | 2847 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
2849 | 2848 |
2850 // Connect groups. We're building the following cycle: | 2849 // Connect groups. We're building the following cycle: |
2851 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2850 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
2852 // groups. | 2851 // groups. |
2853 { | 2852 { |
(...skipping 16 matching lines...) Expand all Loading... |
2870 } | 2869 } |
2871 // Do a single full GC | 2870 // Do a single full GC |
2872 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 2871 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
2873 iso)->heap(); | 2872 iso)->heap(); |
2874 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2873 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2875 | 2874 |
2876 // All object should be alive. | 2875 // All object should be alive. |
2877 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2876 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2878 | 2877 |
2879 // Weaken the root. | 2878 // Weaken the root. |
2880 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2879 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
2881 | 2880 |
2882 // Groups are deleted, rebuild groups. | 2881 // Groups are deleted, rebuild groups. |
2883 { | 2882 { |
2884 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); | 2883 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
2885 UniqueId id2(reinterpret_cast<intptr_t>(*g2s1)); | 2884 UniqueId id2(reinterpret_cast<intptr_t>(*g2s1)); |
2886 UniqueId id3(reinterpret_cast<intptr_t>(*g3s1)); | 2885 UniqueId id3(reinterpret_cast<intptr_t>(*g3s1)); |
2887 UniqueId id4(reinterpret_cast<intptr_t>(*g4s1)); | 2886 UniqueId id4(reinterpret_cast<intptr_t>(*g4s1)); |
2888 iso->SetObjectGroupId(g1s1, id1); | 2887 iso->SetObjectGroupId(g1s1, id1); |
2889 iso->SetObjectGroupId(g1s2, id1); | 2888 iso->SetObjectGroupId(g1s2, id1); |
2890 iso->SetReferenceFromGroup(id1, g2s1); | 2889 iso->SetReferenceFromGroup(id1, g2s1); |
(...skipping 30 matching lines...) Expand all Loading... |
2921 Persistent<Object> g1s2; | 2920 Persistent<Object> g1s2; |
2922 Persistent<Object> g2s1; | 2921 Persistent<Object> g2s1; |
2923 Persistent<Object> g2s2; | 2922 Persistent<Object> g2s2; |
2924 Persistent<Object> g3s1; | 2923 Persistent<Object> g3s1; |
2925 Persistent<Object> g3s2; | 2924 Persistent<Object> g3s2; |
2926 | 2925 |
2927 { | 2926 { |
2928 HandleScope scope(iso); | 2927 HandleScope scope(iso); |
2929 g1s1 = Persistent<Object>::New(iso, Object::New()); | 2928 g1s1 = Persistent<Object>::New(iso, Object::New()); |
2930 g1s2 = Persistent<Object>::New(iso, Object::New()); | 2929 g1s2 = Persistent<Object>::New(iso, Object::New()); |
2931 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2930 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2932 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2931 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2933 | 2932 |
2934 g2s1 = Persistent<Object>::New(iso, Object::New()); | 2933 g2s1 = Persistent<Object>::New(iso, Object::New()); |
2935 g2s2 = Persistent<Object>::New(iso, Object::New()); | 2934 g2s2 = Persistent<Object>::New(iso, Object::New()); |
2936 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2935 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2937 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2936 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2938 | 2937 |
2939 g3s1 = Persistent<Object>::New(iso, Object::New()); | 2938 g3s1 = Persistent<Object>::New(iso, Object::New()); |
2940 g3s2 = Persistent<Object>::New(iso, Object::New()); | 2939 g3s2 = Persistent<Object>::New(iso, Object::New()); |
2941 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2940 g3s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
2942 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2941 g3s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
2943 } | 2942 } |
2944 | 2943 |
2945 // Make a root. | 2944 // Make a root. |
2946 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); | 2945 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); |
2947 root.MarkPartiallyDependent(iso); | 2946 root.MarkPartiallyDependent(iso); |
2948 | 2947 |
2949 // Connect groups. We're building the following cycle: | 2948 // Connect groups. We're building the following cycle: |
2950 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2949 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
2951 // groups. | 2950 // groups. |
2952 { | 2951 { |
(...skipping 13 matching lines...) Expand all Loading... |
2966 V8::AddObjectGroup(g3_objects, 2); | 2965 V8::AddObjectGroup(g3_objects, 2); |
2967 g3s1->Set(v8_str("x"), Handle<Object>(*g1s1)); | 2966 g3s1->Set(v8_str("x"), Handle<Object>(*g1s1)); |
2968 } | 2967 } |
2969 | 2968 |
2970 HEAP->CollectGarbage(i::NEW_SPACE); | 2969 HEAP->CollectGarbage(i::NEW_SPACE); |
2971 | 2970 |
2972 // All objects should be alive. | 2971 // All objects should be alive. |
2973 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2972 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2974 | 2973 |
2975 // Weaken the root. | 2974 // Weaken the root. |
2976 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2975 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
2977 root.MarkPartiallyDependent(iso); | 2976 root.MarkPartiallyDependent(iso); |
2978 | 2977 |
2979 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 2978 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
2980 // Groups are deleted, rebuild groups. | 2979 // Groups are deleted, rebuild groups. |
2981 { | 2980 { |
2982 g1s1.MarkPartiallyDependent(isolate); | 2981 g1s1.MarkPartiallyDependent(isolate); |
2983 g1s2.MarkPartiallyDependent(isolate); | 2982 g1s2.MarkPartiallyDependent(isolate); |
2984 g2s1.MarkPartiallyDependent(isolate); | 2983 g2s1.MarkPartiallyDependent(isolate); |
2985 g2s2.MarkPartiallyDependent(isolate); | 2984 g2s2.MarkPartiallyDependent(isolate); |
2986 g3s1.MarkPartiallyDependent(isolate); | 2985 g3s1.MarkPartiallyDependent(isolate); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3018 Persistent<Object> g1s2; | 3017 Persistent<Object> g1s2; |
3019 Persistent<Object> g2s1; | 3018 Persistent<Object> g2s1; |
3020 Persistent<Object> g2s2; | 3019 Persistent<Object> g2s2; |
3021 Persistent<Object> g3s1; | 3020 Persistent<Object> g3s1; |
3022 Persistent<Object> g3s2; | 3021 Persistent<Object> g3s2; |
3023 | 3022 |
3024 { | 3023 { |
3025 HandleScope scope(iso); | 3024 HandleScope scope(iso); |
3026 g1s1 = Persistent<Object>::New(iso, Object::New()); | 3025 g1s1 = Persistent<Object>::New(iso, Object::New()); |
3027 g1s2 = Persistent<Object>::New(iso, Object::New()); | 3026 g1s2 = Persistent<Object>::New(iso, Object::New()); |
3028 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3027 g1s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
3029 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3028 g1s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
3030 | 3029 |
3031 g2s1 = Persistent<Object>::New(iso, Object::New()); | 3030 g2s1 = Persistent<Object>::New(iso, Object::New()); |
3032 g2s2 = Persistent<Object>::New(iso, Object::New()); | 3031 g2s2 = Persistent<Object>::New(iso, Object::New()); |
3033 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3032 g2s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
3034 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3033 g2s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
3035 | 3034 |
3036 g3s1 = Persistent<Object>::New(iso, Object::New()); | 3035 g3s1 = Persistent<Object>::New(iso, Object::New()); |
3037 g3s2 = Persistent<Object>::New(iso, Object::New()); | 3036 g3s2 = Persistent<Object>::New(iso, Object::New()); |
3038 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3037 g3s1.MakeWeak(iso, &counter, &WeakPointerCallback); |
3039 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3038 g3s2.MakeWeak(iso, &counter, &WeakPointerCallback); |
3040 } | 3039 } |
3041 | 3040 |
3042 // Make a root. | 3041 // Make a root. |
3043 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); | 3042 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); |
3044 root.MarkPartiallyDependent(iso); | 3043 root.MarkPartiallyDependent(iso); |
3045 | 3044 |
3046 // Connect groups. We're building the following cycle: | 3045 // Connect groups. We're building the following cycle: |
3047 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 3046 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
3048 // groups. | 3047 // groups. |
3049 { | 3048 { |
(...skipping 15 matching lines...) Expand all Loading... |
3065 } | 3064 } |
3066 | 3065 |
3067 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( | 3066 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
3068 iso)->heap(); | 3067 iso)->heap(); |
3069 heap->CollectGarbage(i::NEW_SPACE); | 3068 heap->CollectGarbage(i::NEW_SPACE); |
3070 | 3069 |
3071 // All objects should be alive. | 3070 // All objects should be alive. |
3072 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 3071 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
3073 | 3072 |
3074 // Weaken the root. | 3073 // Weaken the root. |
3075 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 3074 root.MakeWeak(iso, &counter, &WeakPointerCallback); |
3076 root.MarkPartiallyDependent(iso); | 3075 root.MarkPartiallyDependent(iso); |
3077 | 3076 |
3078 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 3077 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
3079 // Groups are deleted, rebuild groups. | 3078 // Groups are deleted, rebuild groups. |
3080 { | 3079 { |
3081 g1s1.MarkPartiallyDependent(isolate); | 3080 g1s1.MarkPartiallyDependent(isolate); |
3082 g1s2.MarkPartiallyDependent(isolate); | 3081 g1s2.MarkPartiallyDependent(isolate); |
3083 g2s1.MarkPartiallyDependent(isolate); | 3082 g2s1.MarkPartiallyDependent(isolate); |
3084 g2s2.MarkPartiallyDependent(isolate); | 3083 g2s2.MarkPartiallyDependent(isolate); |
3085 g3s1.MarkPartiallyDependent(isolate); | 3084 g3s1.MarkPartiallyDependent(isolate); |
(...skipping 2865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5951 | 5950 |
5952 public: | 5951 public: |
5953 static const int kObjectCount = 256; | 5952 static const int kObjectCount = 256; |
5954 int cursor_; | 5953 int cursor_; |
5955 v8::Isolate* isolate_; | 5954 v8::Isolate* isolate_; |
5956 v8::Persistent<v8::Object> objects_[kObjectCount]; | 5955 v8::Persistent<v8::Object> objects_[kObjectCount]; |
5957 v8::Persistent<Script> script_; | 5956 v8::Persistent<Script> script_; |
5958 }; | 5957 }; |
5959 | 5958 |
5960 static void HandleWeakReference(v8::Isolate* isolate, | 5959 static void HandleWeakReference(v8::Isolate* isolate, |
5961 v8::Persistent<v8::Value> obj, | 5960 v8::Persistent<v8::Value>* obj, |
5962 void* data) { | 5961 Snorkel* snorkel) { |
5963 Snorkel* snorkel = reinterpret_cast<Snorkel*>(data); | |
5964 delete snorkel; | 5962 delete snorkel; |
5965 obj.ClearWeak(isolate); | 5963 obj->ClearWeak(isolate); |
5966 } | 5964 } |
5967 | 5965 |
5968 v8::Handle<Value> WhammyPropertyGetter(Local<String> name, | 5966 v8::Handle<Value> WhammyPropertyGetter(Local<String> name, |
5969 const AccessorInfo& info) { | 5967 const AccessorInfo& info) { |
5970 Whammy* whammy = | 5968 Whammy* whammy = |
5971 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); | 5969 static_cast<Whammy*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); |
5972 | 5970 |
5973 v8::Persistent<v8::Object> prev = whammy->objects_[whammy->cursor_]; | 5971 v8::Persistent<v8::Object> prev = whammy->objects_[whammy->cursor_]; |
5974 | 5972 |
5975 v8::Handle<v8::Object> obj = v8::Object::New(); | 5973 v8::Handle<v8::Object> obj = v8::Object::New(); |
5976 v8::Persistent<v8::Object> global = | 5974 v8::Persistent<v8::Object> global = |
5977 v8::Persistent<v8::Object>::New(info.GetIsolate(), obj); | 5975 v8::Persistent<v8::Object>::New(info.GetIsolate(), obj); |
5978 if (!prev.IsEmpty()) { | 5976 if (!prev.IsEmpty()) { |
5979 prev->Set(v8_str("next"), obj); | 5977 prev->Set(v8_str("next"), obj); |
5980 prev.MakeWeak(info.GetIsolate(), new Snorkel(), &HandleWeakReference); | 5978 prev.MakeWeak<Value, Snorkel>(info.GetIsolate(), |
| 5979 new Snorkel(), |
| 5980 &HandleWeakReference); |
5981 whammy->objects_[whammy->cursor_].Clear(); | 5981 whammy->objects_[whammy->cursor_].Clear(); |
5982 } | 5982 } |
5983 whammy->objects_[whammy->cursor_] = global; | 5983 whammy->objects_[whammy->cursor_] = global; |
5984 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; | 5984 whammy->cursor_ = (whammy->cursor_ + 1) % Whammy::kObjectCount; |
5985 return whammy->getScript()->Run(); | 5985 return whammy->getScript()->Run(); |
5986 } | 5986 } |
5987 | 5987 |
5988 THREADED_TEST(WeakReference) { | 5988 THREADED_TEST(WeakReference) { |
5989 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); | 5989 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); |
5990 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); | 5990 v8::Handle<v8::ObjectTemplate> templ= v8::ObjectTemplate::New(); |
(...skipping 18 matching lines...) Expand all Loading... |
6009 "}" | 6009 "}" |
6010 "gc();" | 6010 "gc();" |
6011 "4"; | 6011 "4"; |
6012 v8::Handle<Value> result = CompileRun(code); | 6012 v8::Handle<Value> result = CompileRun(code); |
6013 CHECK_EQ(4.0, result->NumberValue()); | 6013 CHECK_EQ(4.0, result->NumberValue()); |
6014 delete whammy; | 6014 delete whammy; |
6015 } | 6015 } |
6016 | 6016 |
6017 | 6017 |
6018 static void DisposeAndSetFlag(v8::Isolate* isolate, | 6018 static void DisposeAndSetFlag(v8::Isolate* isolate, |
6019 v8::Persistent<v8::Value> obj, | 6019 v8::Persistent<v8::Object>* obj, |
6020 void* data) { | 6020 bool* data) { |
6021 obj.Dispose(isolate); | 6021 obj->Dispose(isolate); |
6022 obj.Clear(); | 6022 *(data) = true; |
6023 *(reinterpret_cast<bool*>(data)) = true; | |
6024 } | 6023 } |
6025 | 6024 |
6026 | 6025 |
6027 THREADED_TEST(IndependentWeakHandle) { | 6026 THREADED_TEST(IndependentWeakHandle) { |
6028 v8::Isolate* iso = v8::Isolate::GetCurrent(); | 6027 v8::Isolate* iso = v8::Isolate::GetCurrent(); |
6029 v8::HandleScope scope(iso); | 6028 v8::HandleScope scope(iso); |
6030 v8::Handle<Context> context = Context::New(iso); | 6029 v8::Handle<Context> context = Context::New(iso); |
6031 Context::Scope context_scope(context); | 6030 Context::Scope context_scope(context); |
6032 | 6031 |
6033 v8::Persistent<v8::Object> object_a, object_b; | 6032 v8::Persistent<v8::Object> object_a, object_b; |
(...skipping 22 matching lines...) Expand all Loading... |
6056 HEAP->PerformScavenge(); | 6055 HEAP->PerformScavenge(); |
6057 } | 6056 } |
6058 | 6057 |
6059 | 6058 |
6060 static void InvokeMarkSweep() { | 6059 static void InvokeMarkSweep() { |
6061 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 6060 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
6062 } | 6061 } |
6063 | 6062 |
6064 | 6063 |
6065 static void ForceScavenge(v8::Isolate* isolate, | 6064 static void ForceScavenge(v8::Isolate* isolate, |
6066 v8::Persistent<v8::Value> obj, | 6065 v8::Persistent<v8::Object>* obj, |
6067 void* data) { | 6066 bool* data) { |
6068 obj.Dispose(isolate); | 6067 obj->Dispose(isolate); |
6069 obj.Clear(); | 6068 *(data) = true; |
6070 *(reinterpret_cast<bool*>(data)) = true; | |
6071 InvokeScavenge(); | 6069 InvokeScavenge(); |
6072 } | 6070 } |
6073 | 6071 |
6074 | 6072 |
6075 static void ForceMarkSweep(v8::Isolate* isolate, | 6073 static void ForceMarkSweep(v8::Isolate* isolate, |
6076 v8::Persistent<v8::Value> obj, | 6074 v8::Persistent<v8::Object>* obj, |
6077 void* data) { | 6075 bool* data) { |
6078 obj.Dispose(isolate); | 6076 obj->Dispose(isolate); |
6079 obj.Clear(); | 6077 *(data) = true; |
6080 *(reinterpret_cast<bool*>(data)) = true; | |
6081 InvokeMarkSweep(); | 6078 InvokeMarkSweep(); |
6082 } | 6079 } |
6083 | 6080 |
6084 | 6081 |
6085 THREADED_TEST(GCFromWeakCallbacks) { | 6082 THREADED_TEST(GCFromWeakCallbacks) { |
6086 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 6083 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
6087 v8::HandleScope scope(isolate); | 6084 v8::HandleScope scope(isolate); |
6088 v8::Handle<Context> context = Context::New(isolate); | 6085 v8::Handle<Context> context = Context::New(isolate); |
6089 Context::Scope context_scope(context); | 6086 Context::Scope context_scope(context); |
6090 | 6087 |
6091 static const int kNumberOfGCTypes = 2; | 6088 static const int kNumberOfGCTypes = 2; |
6092 v8::NearDeathCallback gc_forcing_callback[kNumberOfGCTypes] = | 6089 typedef v8::WeakReferenceCallbacks<v8::Object, bool>::Revivable Callback; |
| 6090 Callback gc_forcing_callback[kNumberOfGCTypes] = |
6093 {&ForceScavenge, &ForceMarkSweep}; | 6091 {&ForceScavenge, &ForceMarkSweep}; |
6094 | 6092 |
6095 typedef void (*GCInvoker)(); | 6093 typedef void (*GCInvoker)(); |
6096 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; | 6094 GCInvoker invoke_gc[kNumberOfGCTypes] = {&InvokeScavenge, &InvokeMarkSweep}; |
6097 | 6095 |
6098 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { | 6096 for (int outer_gc = 0; outer_gc < kNumberOfGCTypes; outer_gc++) { |
6099 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { | 6097 for (int inner_gc = 0; inner_gc < kNumberOfGCTypes; inner_gc++) { |
6100 v8::Persistent<v8::Object> object; | 6098 v8::Persistent<v8::Object> object; |
6101 { | 6099 { |
6102 v8::HandleScope handle_scope(isolate); | 6100 v8::HandleScope handle_scope(isolate); |
6103 object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 6101 object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
6104 } | 6102 } |
6105 bool disposed = false; | 6103 bool disposed = false; |
6106 object.MakeWeak(isolate, &disposed, gc_forcing_callback[inner_gc]); | 6104 object.MakeWeak(isolate, &disposed, gc_forcing_callback[inner_gc]); |
6107 object.MarkIndependent(isolate); | 6105 object.MarkIndependent(isolate); |
6108 invoke_gc[outer_gc](); | 6106 invoke_gc[outer_gc](); |
6109 CHECK(disposed); | 6107 CHECK(disposed); |
6110 } | 6108 } |
6111 } | 6109 } |
6112 } | 6110 } |
6113 | 6111 |
6114 | 6112 |
6115 static void RevivingCallback(v8::Isolate* isolate, | 6113 static void RevivingCallback(v8::Isolate* isolate, |
6116 v8::Persistent<v8::Value> obj, | 6114 v8::Persistent<v8::Object>* obj, |
6117 void* data) { | 6115 bool* data) { |
6118 obj.ClearWeak(isolate); | 6116 obj->ClearWeak(isolate); |
6119 *(reinterpret_cast<bool*>(data)) = true; | 6117 *(data) = true; |
6120 } | 6118 } |
6121 | 6119 |
6122 | 6120 |
6123 THREADED_TEST(IndependentHandleRevival) { | 6121 THREADED_TEST(IndependentHandleRevival) { |
6124 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 6122 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
6125 v8::HandleScope scope(isolate); | 6123 v8::HandleScope scope(isolate); |
6126 v8::Handle<Context> context = Context::New(isolate); | 6124 v8::Handle<Context> context = Context::New(isolate); |
6127 Context::Scope context_scope(context); | 6125 Context::Scope context_scope(context); |
6128 | 6126 |
6129 v8::Persistent<v8::Object> object; | 6127 v8::Persistent<v8::Object> object; |
(...skipping 5674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11804 v8::V8::ContextDisposedNotification(); | 11802 v8::V8::ContextDisposedNotification(); |
11805 CheckSurvivingGlobalObjectsCount(0); | 11803 CheckSurvivingGlobalObjectsCount(0); |
11806 } | 11804 } |
11807 } | 11805 } |
11808 | 11806 |
11809 | 11807 |
11810 v8::Persistent<v8::Object> some_object; | 11808 v8::Persistent<v8::Object> some_object; |
11811 v8::Persistent<v8::Object> bad_handle; | 11809 v8::Persistent<v8::Object> bad_handle; |
11812 | 11810 |
11813 void NewPersistentHandleCallback(v8::Isolate* isolate, | 11811 void NewPersistentHandleCallback(v8::Isolate* isolate, |
11814 v8::Persistent<v8::Value> handle, | 11812 v8::Persistent<v8::Value>* handle, |
11815 void*) { | 11813 void*) { |
11816 v8::HandleScope scope(isolate); | 11814 v8::HandleScope scope(isolate); |
11817 bad_handle = v8::Persistent<v8::Object>::New(isolate, some_object); | 11815 bad_handle = v8::Persistent<v8::Object>::New(isolate, some_object); |
11818 handle.Dispose(isolate); | 11816 handle->Dispose(isolate); |
11819 } | 11817 } |
11820 | 11818 |
11821 | 11819 |
11822 THREADED_TEST(NewPersistentHandleFromWeakCallback) { | 11820 THREADED_TEST(NewPersistentHandleFromWeakCallback) { |
11823 LocalContext context; | 11821 LocalContext context; |
11824 v8::Isolate* isolate = context->GetIsolate(); | 11822 v8::Isolate* isolate = context->GetIsolate(); |
11825 | 11823 |
11826 v8::Persistent<v8::Object> handle1, handle2; | 11824 v8::Persistent<v8::Object> handle1, handle2; |
11827 { | 11825 { |
11828 v8::HandleScope scope(isolate); | 11826 v8::HandleScope scope(isolate); |
11829 some_object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11827 some_object = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11830 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11828 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11831 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11829 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11832 } | 11830 } |
11833 // Note: order is implementation dependent alas: currently | 11831 // Note: order is implementation dependent alas: currently |
11834 // global handle nodes are processed by PostGarbageCollectionProcessing | 11832 // global handle nodes are processed by PostGarbageCollectionProcessing |
11835 // in reverse allocation order, so if second allocated handle is deleted, | 11833 // in reverse allocation order, so if second allocated handle is deleted, |
11836 // weak callback of the first handle would be able to 'reallocate' it. | 11834 // weak callback of the first handle would be able to 'reallocate' it. |
11837 handle1.MakeWeak(isolate, NULL, NewPersistentHandleCallback); | 11835 handle1.MakeWeak<v8::Value, void>(isolate, |
| 11836 NULL, |
| 11837 NewPersistentHandleCallback); |
11838 handle2.Dispose(isolate); | 11838 handle2.Dispose(isolate); |
11839 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 11839 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11840 } | 11840 } |
11841 | 11841 |
11842 | 11842 |
11843 v8::Persistent<v8::Object> to_be_disposed; | 11843 v8::Persistent<v8::Object> to_be_disposed; |
11844 | 11844 |
11845 void DisposeAndForceGcCallback(v8::Isolate* isolate, | 11845 void DisposeAndForceGcCallback(v8::Isolate* isolate, |
11846 v8::Persistent<v8::Value> handle, | 11846 v8::Persistent<v8::Value>* handle, |
11847 void*) { | 11847 void*) { |
11848 to_be_disposed.Dispose(isolate); | 11848 to_be_disposed.Dispose(isolate); |
11849 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 11849 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11850 handle.Dispose(isolate); | 11850 handle->Dispose(isolate); |
11851 } | 11851 } |
11852 | 11852 |
11853 | 11853 |
11854 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 11854 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
11855 LocalContext context; | 11855 LocalContext context; |
11856 v8::Isolate* isolate = context->GetIsolate(); | 11856 v8::Isolate* isolate = context->GetIsolate(); |
11857 | 11857 |
11858 v8::Persistent<v8::Object> handle1, handle2; | 11858 v8::Persistent<v8::Object> handle1, handle2; |
11859 { | 11859 { |
11860 v8::HandleScope scope(isolate); | 11860 v8::HandleScope scope(isolate); |
11861 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11861 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11862 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11862 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11863 } | 11863 } |
11864 handle1.MakeWeak(isolate, NULL, DisposeAndForceGcCallback); | 11864 handle1.MakeWeak<v8::Value, void>(isolate, NULL, DisposeAndForceGcCallback); |
11865 to_be_disposed = handle2; | 11865 to_be_disposed = handle2; |
11866 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 11866 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11867 } | 11867 } |
11868 | 11868 |
11869 void DisposingCallback(v8::Isolate* isolate, | 11869 void DisposingCallback(v8::Isolate* isolate, |
11870 v8::Persistent<v8::Value> handle, | 11870 v8::Persistent<v8::Value>* handle, |
11871 void*) { | 11871 void*) { |
11872 handle.Dispose(isolate); | 11872 handle->Dispose(isolate); |
11873 } | 11873 } |
11874 | 11874 |
11875 void HandleCreatingCallback(v8::Isolate* isolate, | 11875 void HandleCreatingCallback(v8::Isolate* isolate, |
11876 v8::Persistent<v8::Value> handle, | 11876 v8::Persistent<v8::Value>* handle, |
11877 void*) { | 11877 void*) { |
11878 v8::HandleScope scope(isolate); | 11878 v8::HandleScope scope(isolate); |
11879 v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11879 v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11880 handle.Dispose(isolate); | 11880 handle->Dispose(isolate); |
11881 } | 11881 } |
11882 | 11882 |
11883 | 11883 |
11884 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 11884 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
11885 LocalContext context; | 11885 LocalContext context; |
11886 v8::Isolate* isolate = context->GetIsolate(); | 11886 v8::Isolate* isolate = context->GetIsolate(); |
11887 | 11887 |
11888 v8::Persistent<v8::Object> handle1, handle2, handle3; | 11888 v8::Persistent<v8::Object> handle1, handle2, handle3; |
11889 { | 11889 { |
11890 v8::HandleScope scope(isolate); | 11890 v8::HandleScope scope(isolate); |
11891 handle3 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11891 handle3 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11892 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11892 handle2 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11893 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); | 11893 handle1 = v8::Persistent<v8::Object>::New(isolate, v8::Object::New()); |
11894 } | 11894 } |
11895 handle2.MakeWeak(isolate, NULL, DisposingCallback); | 11895 handle2.MakeWeak<v8::Value, void>(isolate, NULL, DisposingCallback); |
11896 handle3.MakeWeak(isolate, NULL, HandleCreatingCallback); | 11896 handle3.MakeWeak<v8::Value, void>(isolate, NULL, HandleCreatingCallback); |
11897 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 11897 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
11898 } | 11898 } |
11899 | 11899 |
11900 | 11900 |
11901 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 11901 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
11902 v8::V8::Initialize(); | 11902 v8::V8::Initialize(); |
11903 | 11903 |
11904 const int nof = 2; | 11904 const int nof = 2; |
11905 const char* sources[nof] = { | 11905 const char* sources[nof] = { |
11906 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 11906 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
(...skipping 6986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18893 i::Semaphore* sem_; | 18893 i::Semaphore* sem_; |
18894 volatile int sem_value_; | 18894 volatile int sem_value_; |
18895 }; | 18895 }; |
18896 | 18896 |
18897 | 18897 |
18898 THREADED_TEST(SemaphoreInterruption) { | 18898 THREADED_TEST(SemaphoreInterruption) { |
18899 ThreadInterruptTest().RunTest(); | 18899 ThreadInterruptTest().RunTest(); |
18900 } | 18900 } |
18901 | 18901 |
18902 #endif // WIN32 | 18902 #endif // WIN32 |
OLD | NEW |