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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 using ::v8::Message; | 60 using ::v8::Message; |
61 using ::v8::MessageCallback; | 61 using ::v8::MessageCallback; |
62 using ::v8::Object; | 62 using ::v8::Object; |
63 using ::v8::ObjectTemplate; | 63 using ::v8::ObjectTemplate; |
64 using ::v8::Persistent; | 64 using ::v8::Persistent; |
65 using ::v8::Script; | 65 using ::v8::Script; |
66 using ::v8::StackTrace; | 66 using ::v8::StackTrace; |
67 using ::v8::String; | 67 using ::v8::String; |
68 using ::v8::TryCatch; | 68 using ::v8::TryCatch; |
69 using ::v8::Undefined; | 69 using ::v8::Undefined; |
| 70 using ::v8::UniqueId; |
70 using ::v8::V8; | 71 using ::v8::V8; |
71 using ::v8::Value; | 72 using ::v8::Value; |
72 | 73 |
73 | 74 |
74 static void ExpectString(const char* code, const char* expected) { | 75 static void ExpectString(const char* code, const char* expected) { |
75 Local<Value> result = CompileRun(code); | 76 Local<Value> result = CompileRun(code); |
76 CHECK(result->IsString()); | 77 CHECK(result->IsString()); |
77 String::AsciiValue ascii(result); | 78 String::AsciiValue ascii(result); |
78 CHECK_EQ(expected, *ascii); | 79 CHECK_EQ(expected, *ascii); |
79 } | 80 } |
(...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2438 static void WeakPointerCallback(v8::Isolate* isolate, | 2439 static void WeakPointerCallback(v8::Isolate* isolate, |
2439 Persistent<Value> handle, | 2440 Persistent<Value> handle, |
2440 void* id) { | 2441 void* id) { |
2441 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); | 2442 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); |
2442 CHECK_EQ(1234, counter->id()); | 2443 CHECK_EQ(1234, counter->id()); |
2443 counter->increment(); | 2444 counter->increment(); |
2444 handle.Dispose(isolate); | 2445 handle.Dispose(isolate); |
2445 } | 2446 } |
2446 | 2447 |
2447 | 2448 |
2448 THREADED_TEST(ApiObjectGroups) { | 2449 THREADED_TEST(OldApiObjectGroups) { |
2449 LocalContext env; | 2450 LocalContext env; |
2450 v8::Isolate* iso = env->GetIsolate(); | 2451 v8::Isolate* iso = env->GetIsolate(); |
2451 HandleScope scope(iso); | 2452 HandleScope scope(iso); |
2452 | 2453 |
2453 Persistent<Object> g1s1; | 2454 Persistent<Object> g1s1; |
2454 Persistent<Object> g1s2; | 2455 Persistent<Object> g1s2; |
2455 Persistent<Object> g1c1; | 2456 Persistent<Object> g1c1; |
2456 Persistent<Object> g2s1; | 2457 Persistent<Object> g2s1; |
2457 Persistent<Object> g2s2; | 2458 Persistent<Object> g2s2; |
2458 Persistent<Object> g2c1; | 2459 Persistent<Object> g2c1; |
(...skipping 24 matching lines...) Expand all Loading... |
2483 CHECK(g2s1->Set(0, g1s1)); | 2484 CHECK(g2s1->Set(0, g1s1)); |
2484 | 2485 |
2485 { | 2486 { |
2486 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2487 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2487 Persistent<Value> g1_children[] = { g1c1 }; | 2488 Persistent<Value> g1_children[] = { g1c1 }; |
2488 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2489 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2489 Persistent<Value> g2_children[] = { g2c1 }; | 2490 Persistent<Value> g2_children[] = { g2c1 }; |
2490 V8::AddObjectGroup(g1_objects, 2); | 2491 V8::AddObjectGroup(g1_objects, 2); |
2491 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2492 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2492 V8::AddObjectGroup(g2_objects, 2); | 2493 V8::AddObjectGroup(g2_objects, 2); |
2493 V8::AddImplicitReferences(g2s2, g2_children, 1); | 2494 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2494 } | 2495 } |
2495 // Do a single full GC, ensure incremental marking is stopped. | 2496 // Do a single full GC, ensure incremental marking is stopped. |
2496 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2497 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2497 | 2498 |
2498 // All object should be alive. | 2499 // All object should be alive. |
2499 CHECK_EQ(0, counter.NumberOfWeakCalls()); | 2500 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
2500 | 2501 |
2501 // Weaken the root. | 2502 // Weaken the root. |
2502 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2503 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2503 // But make children strong roots---all the objects (except for children) | 2504 // But make children strong roots---all the objects (except for children) |
2504 // should be collectable now. | 2505 // should be collectable now. |
2505 g1c1.ClearWeak(iso); | 2506 g1c1.ClearWeak(iso); |
2506 g2c1.ClearWeak(iso); | 2507 g2c1.ClearWeak(iso); |
2507 | 2508 |
2508 // Groups are deleted, rebuild groups. | 2509 // Groups are deleted, rebuild groups. |
2509 { | 2510 { |
2510 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2511 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
2511 Persistent<Value> g1_children[] = { g1c1 }; | 2512 Persistent<Value> g1_children[] = { g1c1 }; |
2512 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2513 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
2513 Persistent<Value> g2_children[] = { g2c1 }; | 2514 Persistent<Value> g2_children[] = { g2c1 }; |
2514 V8::AddObjectGroup(g1_objects, 2); | 2515 V8::AddObjectGroup(g1_objects, 2); |
2515 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2516 V8::AddImplicitReferences(g1s1, g1_children, 1); |
2516 V8::AddObjectGroup(g2_objects, 2); | 2517 V8::AddObjectGroup(g2_objects, 2); |
2517 V8::AddImplicitReferences(g2s2, g2_children, 1); | 2518 V8::AddImplicitReferences(g2s1, g2_children, 1); |
2518 } | 2519 } |
2519 | 2520 |
2520 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2521 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2521 | 2522 |
2522 // All objects should be gone. 5 global handles in total. | 2523 // All objects should be gone. 5 global handles in total. |
2523 CHECK_EQ(5, counter.NumberOfWeakCalls()); | 2524 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
2524 | 2525 |
2525 // And now make children weak again and collect them. | 2526 // And now make children weak again and collect them. |
2526 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2527 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2527 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); | 2528 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
2528 | 2529 |
2529 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2530 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2530 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 2531 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2531 } | 2532 } |
2532 | 2533 |
2533 | 2534 |
2534 THREADED_TEST(ApiObjectGroupsCycle) { | 2535 THREADED_TEST(ApiObjectGroups) { |
2535 LocalContext env; | 2536 LocalContext env; |
2536 v8::Isolate* iso = env->GetIsolate(); | 2537 v8::Isolate* iso = env->GetIsolate(); |
2537 HandleScope scope(iso); | 2538 HandleScope scope(iso); |
| 2539 |
| 2540 Persistent<Object> g1s1; |
| 2541 Persistent<Object> g1s2; |
| 2542 Persistent<Object> g1c1; |
| 2543 Persistent<Object> g2s1; |
| 2544 Persistent<Object> g2s2; |
| 2545 Persistent<Object> g2c1; |
| 2546 |
| 2547 WeakCallCounter counter(1234); |
| 2548 |
| 2549 { |
| 2550 HandleScope scope(iso); |
| 2551 g1s1 = Persistent<Object>::New(iso, Object::New()); |
| 2552 g1s2 = Persistent<Object>::New(iso, Object::New()); |
| 2553 g1c1 = Persistent<Object>::New(iso, Object::New()); |
| 2554 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2555 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2556 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2557 |
| 2558 g2s1 = Persistent<Object>::New(iso, Object::New()); |
| 2559 g2s2 = Persistent<Object>::New(iso, Object::New()); |
| 2560 g2c1 = Persistent<Object>::New(iso, Object::New()); |
| 2561 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2562 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2563 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2564 } |
| 2565 |
| 2566 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
| 2567 |
| 2568 // Connect group 1 and 2, make a cycle. |
| 2569 CHECK(g1s2->Set(0, g2s2)); |
| 2570 CHECK(g2s1->Set(0, g1s1)); |
| 2571 |
| 2572 { |
| 2573 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
| 2574 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); |
| 2575 iso->SetObjectGroupId(g1s1, id1); |
| 2576 iso->SetObjectGroupId(g1s2, id1); |
| 2577 iso->SetReferenceFromGroup(id1, g1c1); |
| 2578 iso->SetObjectGroupId(g2s1, id2); |
| 2579 iso->SetObjectGroupId(g2s2, id2); |
| 2580 iso->SetReferenceFromGroup(id2, g2c1); |
| 2581 } |
| 2582 // Do a single full GC, ensure incremental marking is stopped. |
| 2583 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
| 2584 iso)->heap(); |
| 2585 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 2586 |
| 2587 // All object should be alive. |
| 2588 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 2589 |
| 2590 // Weaken the root. |
| 2591 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2592 // But make children strong roots---all the objects (except for children) |
| 2593 // should be collectable now. |
| 2594 g1c1.ClearWeak(iso); |
| 2595 g2c1.ClearWeak(iso); |
| 2596 |
| 2597 // Groups are deleted, rebuild groups. |
| 2598 { |
| 2599 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
| 2600 UniqueId id2(reinterpret_cast<intptr_t>(*g2s2)); |
| 2601 iso->SetObjectGroupId(g1s1, id1); |
| 2602 iso->SetObjectGroupId(g1s2, id1); |
| 2603 iso->SetReferenceFromGroup(id1, g1c1); |
| 2604 iso->SetObjectGroupId(g2s1, id2); |
| 2605 iso->SetObjectGroupId(g2s2, id2); |
| 2606 iso->SetReferenceFromGroup(id2, g2c1); |
| 2607 } |
| 2608 |
| 2609 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 2610 |
| 2611 // All objects should be gone. 5 global handles in total. |
| 2612 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
| 2613 |
| 2614 // And now make children weak again and collect them. |
| 2615 g1c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2616 g2c1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2617 |
| 2618 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 2619 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 2620 } |
| 2621 |
| 2622 |
| 2623 THREADED_TEST(OldApiObjectGroupsCycle) { |
| 2624 LocalContext env; |
| 2625 v8::Isolate* iso = env->GetIsolate(); |
| 2626 HandleScope scope(iso); |
2538 | 2627 |
2539 WeakCallCounter counter(1234); | 2628 WeakCallCounter counter(1234); |
2540 | 2629 |
2541 Persistent<Object> g1s1; | 2630 Persistent<Object> g1s1; |
2542 Persistent<Object> g1s2; | 2631 Persistent<Object> g1s2; |
2543 Persistent<Object> g2s1; | 2632 Persistent<Object> g2s1; |
2544 Persistent<Object> g2s2; | 2633 Persistent<Object> g2s2; |
2545 Persistent<Object> g3s1; | 2634 Persistent<Object> g3s1; |
2546 Persistent<Object> g3s2; | 2635 Persistent<Object> g3s2; |
2547 Persistent<Object> g4s1; | 2636 Persistent<Object> g4s1; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2630 V8::AddImplicitReferences(g4s1, g4_children, 1); | 2719 V8::AddImplicitReferences(g4s1, g4_children, 1); |
2631 } | 2720 } |
2632 | 2721 |
2633 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 2722 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
2634 | 2723 |
2635 // All objects should be gone. 9 global handles in total. | 2724 // All objects should be gone. 9 global handles in total. |
2636 CHECK_EQ(9, counter.NumberOfWeakCalls()); | 2725 CHECK_EQ(9, counter.NumberOfWeakCalls()); |
2637 } | 2726 } |
2638 | 2727 |
2639 | 2728 |
| 2729 THREADED_TEST(ApiObjectGroupsCycle) { |
| 2730 LocalContext env; |
| 2731 v8::Isolate* iso = env->GetIsolate(); |
| 2732 HandleScope scope(iso); |
| 2733 |
| 2734 WeakCallCounter counter(1234); |
| 2735 |
| 2736 Persistent<Object> g1s1; |
| 2737 Persistent<Object> g1s2; |
| 2738 Persistent<Object> g2s1; |
| 2739 Persistent<Object> g2s2; |
| 2740 Persistent<Object> g3s1; |
| 2741 Persistent<Object> g3s2; |
| 2742 Persistent<Object> g4s1; |
| 2743 Persistent<Object> g4s2; |
| 2744 |
| 2745 { |
| 2746 HandleScope scope(iso); |
| 2747 g1s1 = Persistent<Object>::New(iso, Object::New()); |
| 2748 g1s2 = Persistent<Object>::New(iso, Object::New()); |
| 2749 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2750 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2751 CHECK(g1s1.IsWeak(iso)); |
| 2752 CHECK(g1s2.IsWeak(iso)); |
| 2753 |
| 2754 g2s1 = Persistent<Object>::New(iso, Object::New()); |
| 2755 g2s2 = Persistent<Object>::New(iso, Object::New()); |
| 2756 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2757 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2758 CHECK(g2s1.IsWeak(iso)); |
| 2759 CHECK(g2s2.IsWeak(iso)); |
| 2760 |
| 2761 g3s1 = Persistent<Object>::New(iso, Object::New()); |
| 2762 g3s2 = Persistent<Object>::New(iso, Object::New()); |
| 2763 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2764 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2765 CHECK(g3s1.IsWeak(iso)); |
| 2766 CHECK(g3s2.IsWeak(iso)); |
| 2767 |
| 2768 g4s1 = Persistent<Object>::New(iso, Object::New()); |
| 2769 g4s2 = Persistent<Object>::New(iso, Object::New()); |
| 2770 g4s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2771 g4s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2772 CHECK(g4s1.IsWeak(iso)); |
| 2773 CHECK(g4s2.IsWeak(iso)); |
| 2774 } |
| 2775 |
| 2776 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); // make a root. |
| 2777 |
| 2778 // Connect groups. We're building the following cycle: |
| 2779 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
| 2780 // groups. |
| 2781 { |
| 2782 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
| 2783 UniqueId id2(reinterpret_cast<intptr_t>(*g2s1)); |
| 2784 UniqueId id3(reinterpret_cast<intptr_t>(*g3s1)); |
| 2785 UniqueId id4(reinterpret_cast<intptr_t>(*g4s1)); |
| 2786 iso->SetObjectGroupId(g1s1, id1); |
| 2787 iso->SetObjectGroupId(g1s2, id1); |
| 2788 iso->SetReferenceFromGroup(id1, g2s1); |
| 2789 iso->SetObjectGroupId(g2s1, id2); |
| 2790 iso->SetObjectGroupId(g2s2, id2); |
| 2791 iso->SetReferenceFromGroup(id2, g3s1); |
| 2792 iso->SetObjectGroupId(g3s1, id3); |
| 2793 iso->SetObjectGroupId(g3s2, id3); |
| 2794 iso->SetReferenceFromGroup(id3, g4s1); |
| 2795 iso->SetObjectGroupId(g4s1, id4); |
| 2796 iso->SetObjectGroupId(g4s2, id4); |
| 2797 iso->SetReferenceFromGroup(id4, g1s1); |
| 2798 } |
| 2799 // Do a single full GC |
| 2800 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
| 2801 iso)->heap(); |
| 2802 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 2803 |
| 2804 // All object should be alive. |
| 2805 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 2806 |
| 2807 // Weaken the root. |
| 2808 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2809 |
| 2810 // Groups are deleted, rebuild groups. |
| 2811 { |
| 2812 UniqueId id1(reinterpret_cast<intptr_t>(*g1s1)); |
| 2813 UniqueId id2(reinterpret_cast<intptr_t>(*g2s1)); |
| 2814 UniqueId id3(reinterpret_cast<intptr_t>(*g3s1)); |
| 2815 UniqueId id4(reinterpret_cast<intptr_t>(*g4s1)); |
| 2816 iso->SetObjectGroupId(g1s1, id1); |
| 2817 iso->SetObjectGroupId(g1s2, id1); |
| 2818 iso->SetReferenceFromGroup(id1, g2s1); |
| 2819 iso->SetObjectGroupId(g2s1, id2); |
| 2820 iso->SetObjectGroupId(g2s2, id2); |
| 2821 iso->SetReferenceFromGroup(id2, g3s1); |
| 2822 iso->SetObjectGroupId(g3s1, id3); |
| 2823 iso->SetObjectGroupId(g3s2, id3); |
| 2824 iso->SetReferenceFromGroup(id3, g4s1); |
| 2825 iso->SetObjectGroupId(g4s1, id4); |
| 2826 iso->SetObjectGroupId(g4s2, id4); |
| 2827 iso->SetReferenceFromGroup(id4, g1s1); |
| 2828 } |
| 2829 |
| 2830 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 2831 |
| 2832 // All objects should be gone. 9 global handles in total. |
| 2833 CHECK_EQ(9, counter.NumberOfWeakCalls()); |
| 2834 } |
| 2835 |
| 2836 |
2640 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures | 2837 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures |
2641 // on the buildbots, so was made non-threaded for the time being. | 2838 // on the buildbots, so was made non-threaded for the time being. |
2642 TEST(ApiObjectGroupsCycleForScavenger) { | 2839 TEST(OldApiObjectGroupsCycleForScavenger) { |
2643 i::FLAG_stress_compaction = false; | 2840 i::FLAG_stress_compaction = false; |
2644 i::FLAG_gc_global = false; | 2841 i::FLAG_gc_global = false; |
2645 LocalContext env; | 2842 LocalContext env; |
2646 v8::Isolate* iso = env->GetIsolate(); | 2843 v8::Isolate* iso = env->GetIsolate(); |
2647 HandleScope scope(iso); | 2844 HandleScope scope(iso); |
2648 | 2845 |
2649 WeakCallCounter counter(1234); | 2846 WeakCallCounter counter(1234); |
2650 | 2847 |
2651 Persistent<Object> g1s1; | 2848 Persistent<Object> g1s1; |
2652 Persistent<Object> g1s2; | 2849 Persistent<Object> g1s2; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2727 g3s1->Set(v8_str("x"), g1s1); | 2924 g3s1->Set(v8_str("x"), g1s1); |
2728 } | 2925 } |
2729 | 2926 |
2730 HEAP->CollectGarbage(i::NEW_SPACE); | 2927 HEAP->CollectGarbage(i::NEW_SPACE); |
2731 | 2928 |
2732 // All objects should be gone. 7 global handles in total. | 2929 // All objects should be gone. 7 global handles in total. |
2733 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 2930 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
2734 } | 2931 } |
2735 | 2932 |
2736 | 2933 |
| 2934 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures |
| 2935 // on the buildbots, so was made non-threaded for the time being. |
| 2936 TEST(ApiObjectGroupsCycleForScavenger) { |
| 2937 i::FLAG_stress_compaction = false; |
| 2938 i::FLAG_gc_global = false; |
| 2939 LocalContext env; |
| 2940 v8::Isolate* iso = env->GetIsolate(); |
| 2941 HandleScope scope(iso); |
| 2942 |
| 2943 WeakCallCounter counter(1234); |
| 2944 |
| 2945 Persistent<Object> g1s1; |
| 2946 Persistent<Object> g1s2; |
| 2947 Persistent<Object> g2s1; |
| 2948 Persistent<Object> g2s2; |
| 2949 Persistent<Object> g3s1; |
| 2950 Persistent<Object> g3s2; |
| 2951 |
| 2952 { |
| 2953 HandleScope scope(iso); |
| 2954 g1s1 = Persistent<Object>::New(iso, Object::New()); |
| 2955 g1s2 = Persistent<Object>::New(iso, Object::New()); |
| 2956 g1s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2957 g1s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2958 |
| 2959 g2s1 = Persistent<Object>::New(iso, Object::New()); |
| 2960 g2s2 = Persistent<Object>::New(iso, Object::New()); |
| 2961 g2s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2962 g2s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2963 |
| 2964 g3s1 = Persistent<Object>::New(iso, Object::New()); |
| 2965 g3s2 = Persistent<Object>::New(iso, Object::New()); |
| 2966 g3s1.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2967 g3s2.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2968 } |
| 2969 |
| 2970 // Make a root. |
| 2971 Persistent<Object> root = Persistent<Object>::New(iso, g1s1); |
| 2972 root.MarkPartiallyDependent(iso); |
| 2973 |
| 2974 // Connect groups. We're building the following cycle: |
| 2975 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
| 2976 // groups. |
| 2977 { |
| 2978 g1s1.MarkPartiallyDependent(iso); |
| 2979 g1s2.MarkPartiallyDependent(iso); |
| 2980 g2s1.MarkPartiallyDependent(iso); |
| 2981 g2s2.MarkPartiallyDependent(iso); |
| 2982 g3s1.MarkPartiallyDependent(iso); |
| 2983 g3s2.MarkPartiallyDependent(iso); |
| 2984 iso->SetObjectGroupId(g1s1, UniqueId(1)); |
| 2985 iso->SetObjectGroupId(g1s2, UniqueId(1)); |
| 2986 g1s1->Set(v8_str("x"), g2s1); |
| 2987 iso->SetObjectGroupId(g2s1, UniqueId(2)); |
| 2988 iso->SetObjectGroupId(g2s2, UniqueId(2)); |
| 2989 g2s1->Set(v8_str("x"), g3s1); |
| 2990 iso->SetObjectGroupId(g3s1, UniqueId(3)); |
| 2991 iso->SetObjectGroupId(g3s2, UniqueId(3)); |
| 2992 g3s1->Set(v8_str("x"), g1s1); |
| 2993 } |
| 2994 |
| 2995 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
| 2996 iso)->heap(); |
| 2997 heap->CollectGarbage(i::NEW_SPACE); |
| 2998 |
| 2999 // All objects should be alive. |
| 3000 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 3001 |
| 3002 // Weaken the root. |
| 3003 root.MakeWeak(iso, reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 3004 root.MarkPartiallyDependent(iso); |
| 3005 |
| 3006 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 3007 // Groups are deleted, rebuild groups. |
| 3008 { |
| 3009 g1s1.MarkPartiallyDependent(isolate); |
| 3010 g1s2.MarkPartiallyDependent(isolate); |
| 3011 g2s1.MarkPartiallyDependent(isolate); |
| 3012 g2s2.MarkPartiallyDependent(isolate); |
| 3013 g3s1.MarkPartiallyDependent(isolate); |
| 3014 g3s2.MarkPartiallyDependent(isolate); |
| 3015 iso->SetObjectGroupId(g1s1, UniqueId(1)); |
| 3016 iso->SetObjectGroupId(g1s2, UniqueId(1)); |
| 3017 g1s1->Set(v8_str("x"), g2s1); |
| 3018 iso->SetObjectGroupId(g2s1, UniqueId(2)); |
| 3019 iso->SetObjectGroupId(g2s2, UniqueId(2)); |
| 3020 g2s1->Set(v8_str("x"), g3s1); |
| 3021 iso->SetObjectGroupId(g3s1, UniqueId(3)); |
| 3022 iso->SetObjectGroupId(g3s2, UniqueId(3)); |
| 3023 g3s1->Set(v8_str("x"), g1s1); |
| 3024 } |
| 3025 |
| 3026 heap->CollectGarbage(i::NEW_SPACE); |
| 3027 |
| 3028 // All objects should be gone. 7 global handles in total. |
| 3029 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 3030 } |
| 3031 |
| 3032 |
2737 THREADED_TEST(ScriptException) { | 3033 THREADED_TEST(ScriptException) { |
2738 LocalContext env; | 3034 LocalContext env; |
2739 v8::HandleScope scope(env->GetIsolate()); | 3035 v8::HandleScope scope(env->GetIsolate()); |
2740 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 3036 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
2741 v8::TryCatch try_catch; | 3037 v8::TryCatch try_catch; |
2742 Local<Value> result = script->Run(); | 3038 Local<Value> result = script->Run(); |
2743 CHECK(result.IsEmpty()); | 3039 CHECK(result.IsEmpty()); |
2744 CHECK(try_catch.HasCaught()); | 3040 CHECK(try_catch.HasCaught()); |
2745 String::AsciiValue exception_value(try_catch.Exception()); | 3041 String::AsciiValue exception_value(try_catch.Exception()); |
2746 CHECK_EQ(*exception_value, "panama!"); | 3042 CHECK_EQ(*exception_value, "panama!"); |
(...skipping 15647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18394 i::Semaphore* sem_; | 18690 i::Semaphore* sem_; |
18395 volatile int sem_value_; | 18691 volatile int sem_value_; |
18396 }; | 18692 }; |
18397 | 18693 |
18398 | 18694 |
18399 THREADED_TEST(SemaphoreInterruption) { | 18695 THREADED_TEST(SemaphoreInterruption) { |
18400 ThreadInterruptTest().RunTest(); | 18696 ThreadInterruptTest().RunTest(); |
18401 } | 18697 } |
18402 | 18698 |
18403 #endif // WIN32 | 18699 #endif // WIN32 |
OLD | NEW |