Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(zra): Remove when tests are ready to enable. | 5 // TODO(zra): Remove when tests are ready to enable. |
| 6 #include "platform/globals.h" | 6 #include "platform/globals.h" |
| 7 #if !defined(TARGET_ARCH_ARM64) | 7 #if !defined(TARGET_ARCH_ARM64) |
| 8 | 8 |
| 9 #include "bin/builtin.h" | 9 #include "bin/builtin.h" |
| 10 #include "include/dart_api.h" | 10 #include "include/dart_api.h" |
| (...skipping 2293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2304 // Promoting the string should transfer the external size to old. | 2304 // Promoting the string should transfer the external size to old. |
| 2305 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2305 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2306 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2306 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2307 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | 2307 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); |
| 2308 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeakExternalSize / kWordSize); | 2308 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeakExternalSize / kWordSize); |
| 2309 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2309 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2310 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 2310 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); |
| 2311 } | 2311 } |
| 2312 | 2312 |
| 2313 | 2313 |
| 2314 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOversized) { | 2314 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) { |
| 2315 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2315 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 2316 Heap* heap = Isolate::Current()->heap(); | 2316 Heap* heap = Isolate::Current()->heap(); |
| 2317 Dart_WeakPersistentHandle weak1 = NULL; | 2317 Dart_WeakPersistentHandle weak1 = NULL; |
| 2318 // Large enough to exceed any new space limit. Not actually allocated. | 2318 // Large enough to exceed any new space limit. Not actually allocated. |
| 2319 const intptr_t kWeak1ExternalSize = 500 * MB; | 2319 const intptr_t kWeak1ExternalSize = 500 * MB; |
| 2320 { | 2320 { |
| 2321 Dart_EnterScope(); | 2321 Dart_EnterScope(); |
| 2322 Dart_Handle obj = NewString("weakly referenced string"); | 2322 Dart_Handle obj = NewString("weakly referenced string"); |
| 2323 EXPECT_VALID(obj); | 2323 EXPECT_VALID(obj); |
| 2324 // Triggers a scavenge immediately, since kWeak1ExternalSize is above limit. | 2324 // Triggers a scavenge immediately, since kWeak1ExternalSize is above limit. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2345 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | 2345 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); |
| 2346 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak1ExternalSize / kWordSize); | 2346 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak1ExternalSize / kWordSize); |
| 2347 Dart_ExitScope(); | 2347 Dart_ExitScope(); |
| 2348 } | 2348 } |
| 2349 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 2349 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
| 2350 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2350 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2351 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 2351 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); |
| 2352 } | 2352 } |
| 2353 | 2353 |
| 2354 | 2354 |
| 2355 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOldspaceGC) { | |
| 2356 // Check that external allocation in old space can trigger GC. | |
| 2357 Isolate* isolate = Isolate::Current(); | |
| 2358 Dart_EnterScope(); | |
| 2359 Dart_Handle live = Api::NewHandle(isolate, String::New("live", Heap::kOld)); | |
| 2360 EXPECT_VALID(live); | |
| 2361 Dart_WeakPersistentHandle weak = NULL; | |
| 2362 EXPECT_EQ(0, isolate->heap()->ExternalInWords(Heap::kOld)); | |
| 2363 const intptr_t kSmallExternalSize = 1 * KB; | |
| 2364 { | |
| 2365 Dart_EnterScope(); | |
| 2366 Dart_Handle dead = Api::NewHandle(isolate, String::New("dead", Heap::kOld)); | |
| 2367 EXPECT_VALID(dead); | |
| 2368 weak = Dart_NewWeakPersistentHandle(dead, | |
| 2369 NULL, | |
| 2370 kSmallExternalSize, | |
| 2371 NopCallback); | |
| 2372 EXPECT_VALID(AsHandle(weak)); | |
| 2373 Dart_ExitScope(); | |
| 2374 } | |
| 2375 EXPECT_EQ(kSmallExternalSize, | |
| 2376 isolate->heap()->ExternalInWords(Heap::kOld) * kWordSize); | |
| 2377 // Large enough to trigger GC in old space. Not actually allocated. | |
| 2378 const intptr_t kHugeExternalSize = 1000 * MB; | |
| 2379 Dart_NewWeakPersistentHandle(live, | |
| 2380 NULL, | |
| 2381 kHugeExternalSize, | |
| 2382 NopCallback); | |
| 2383 // Expect small garbage to be collected. | |
| 2384 EXPECT_EQ(kHugeExternalSize, | |
| 2385 isolate->heap()->ExternalInWords(Heap::kOld) * kWordSize); | |
| 2386 Dart_DeleteWeakPersistentHandle(reinterpret_cast<Dart_Isolate>(isolate), | |
| 2387 weak); | |
| 2388 Dart_ExitScope(); | |
| 2389 } | |
| 2390 | |
| 2391 | |
| 2355 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOddReferents) { | 2392 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOddReferents) { |
| 2356 Heap* heap = Isolate::Current()->heap(); | 2393 Heap* heap = Isolate::Current()->heap(); |
| 2357 Dart_WeakPersistentHandle weak1 = NULL; | 2394 Dart_WeakPersistentHandle weak1 = NULL; |
| 2358 static const intptr_t kWeak1ExternalSize = 1 * KB; | 2395 static const intptr_t kWeak1ExternalSize = 1 * KB; |
| 2359 Dart_WeakPersistentHandle weak2 = NULL; | 2396 Dart_WeakPersistentHandle weak2 = NULL; |
| 2360 static const intptr_t kWeak2ExternalSize = 2 * KB; | 2397 static const intptr_t kWeak2ExternalSize = 2 * KB; |
| 2361 { | 2398 { |
| 2362 Dart_EnterScope(); | 2399 Dart_EnterScope(); |
| 2363 Dart_Handle dart_null = Dart_Null(); // VM heap object. | 2400 Dart_Handle dart_true = Dart_True(); // VM heap object. |
|
Ivan Posva
2014/04/18 16:41:21
Better now! And thanks for the explanation.
| |
| 2364 EXPECT_VALID(dart_null); | 2401 EXPECT_VALID(dart_true); |
| 2365 weak1 = Dart_NewWeakPersistentHandle( | 2402 weak1 = Dart_NewWeakPersistentHandle( |
| 2366 dart_null, NULL, kWeak1ExternalSize, NopCallback); | 2403 dart_true, NULL, kWeak1ExternalSize, NopCallback); |
| 2367 EXPECT_VALID(AsHandle(weak1)); | 2404 EXPECT_VALID(AsHandle(weak1)); |
| 2368 Dart_Handle zero = Dart_NewInteger(0); // Smi. | 2405 Dart_Handle zero = Dart_NewInteger(0); // Smi. |
| 2369 EXPECT_VALID(dart_null); | 2406 EXPECT_VALID(zero); |
| 2370 weak2 = Dart_NewWeakPersistentHandle( | 2407 weak2 = Dart_NewWeakPersistentHandle( |
| 2371 zero, NULL, kWeak2ExternalSize, NopCallback); | 2408 zero, NULL, kWeak2ExternalSize, NopCallback); |
| 2372 EXPECT_VALID(AsHandle(weak2)); | 2409 EXPECT_VALID(AsHandle(weak2)); |
| 2373 // Both should be charged to old space. | 2410 // Both should be charged to old space. |
| 2374 EXPECT(heap->ExternalInWords(Heap::kOld) == | 2411 EXPECT(heap->ExternalInWords(Heap::kOld) == |
| 2375 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); | 2412 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); |
| 2376 Dart_ExitScope(); | 2413 Dart_ExitScope(); |
| 2377 } | 2414 } |
| 2378 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2415 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 2379 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 2416 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
| 2380 Dart_DeleteWeakPersistentHandle(isolate, weak2); | 2417 Dart_DeleteWeakPersistentHandle(isolate, weak2); |
| 2381 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2418 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2382 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 2419 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); |
| 2383 } | 2420 } |
| 2384 | 2421 |
| 2385 | 2422 |
| 2386 static Dart_WeakPersistentHandle weak1 = NULL; | 2423 static Dart_WeakPersistentHandle weak1 = NULL; |
| 2387 static Dart_WeakPersistentHandle weak2 = NULL; | 2424 static Dart_WeakPersistentHandle weak2 = NULL; |
| 2388 static Dart_WeakPersistentHandle weak3 = NULL; | 2425 static Dart_WeakPersistentHandle weak3 = NULL; |
| 2389 static Dart_WeakPersistentHandle weak4 = NULL; | 2426 static Dart_WeakPersistentHandle weak4 = NULL; |
| 2390 | 2427 |
| 2391 | 2428 |
| 2392 static void ObjectGroupsCallback(void* isolate_callback_data, | 2429 static void ObjectGroupsCallback(void* isolate_callback_data, |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2685 { | 2722 { |
| 2686 Dart_EnterScope(); | 2723 Dart_EnterScope(); |
| 2687 // Both prologue weak handles should be preserved. | 2724 // Both prologue weak handles should be preserved. |
| 2688 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | 2725 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); |
| 2689 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | 2726 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); |
| 2690 Dart_ExitScope(); | 2727 Dart_ExitScope(); |
| 2691 } | 2728 } |
| 2692 | 2729 |
| 2693 // Garbage collect old space without invoking API callbacks. | 2730 // Garbage collect old space without invoking API callbacks. |
| 2694 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | 2731 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 2695 Heap::kIgnoreApiCallbacks); | 2732 Heap::kIgnoreApiCallbacks, |
| 2733 Heap::kGCTestCase); | |
| 2696 | 2734 |
| 2697 { | 2735 { |
| 2698 Dart_EnterScope(); | 2736 Dart_EnterScope(); |
| 2699 // Both prologue weak handles should be preserved. | 2737 // Both prologue weak handles should be preserved. |
| 2700 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | 2738 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); |
| 2701 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | 2739 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); |
| 2702 Dart_ExitScope(); | 2740 Dart_ExitScope(); |
| 2703 } | 2741 } |
| 2704 | 2742 |
| 2705 // Garbage collect new space invoking API callbacks. | 2743 // Garbage collect new space invoking API callbacks. |
| 2706 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); | 2744 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); |
| 2707 | 2745 |
| 2708 { | 2746 { |
| 2709 Dart_EnterScope(); | 2747 Dart_EnterScope(); |
| 2710 // The prologue weak handle with a new space referent should now be | 2748 // The prologue weak handle with a new space referent should now be |
| 2711 // cleared. The old space referent should be preserved. | 2749 // cleared. The old space referent should be preserved. |
| 2712 EXPECT(new_pwph == NULL); | 2750 EXPECT(new_pwph == NULL); |
| 2713 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | 2751 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); |
| 2714 Dart_ExitScope(); | 2752 Dart_ExitScope(); |
| 2715 } | 2753 } |
| 2716 | 2754 |
| 2717 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | 2755 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 2718 Heap::kInvokeApiCallbacks); | 2756 Heap::kInvokeApiCallbacks, |
| 2757 Heap::kGCTestCase); | |
| 2719 | 2758 |
| 2720 { | 2759 { |
| 2721 Dart_EnterScope(); | 2760 Dart_EnterScope(); |
| 2722 // The prologue weak handle with an old space referent should now be | 2761 // The prologue weak handle with an old space referent should now be |
| 2723 // cleared. The new space referent should remain cleared. | 2762 // cleared. The new space referent should remain cleared. |
| 2724 EXPECT(new_pwph == NULL); | 2763 EXPECT(new_pwph == NULL); |
| 2725 EXPECT(old_pwph == NULL); | 2764 EXPECT(old_pwph == NULL); |
| 2726 Dart_ExitScope(); | 2765 Dart_ExitScope(); |
| 2727 } | 2766 } |
| 2728 } | 2767 } |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3015 global_epilogue_callback_status = 7; | 3054 global_epilogue_callback_status = 7; |
| 3016 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); | 3055 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); |
| 3017 EXPECT_EQ(6, global_prologue_callback_status); | 3056 EXPECT_EQ(6, global_prologue_callback_status); |
| 3018 EXPECT_EQ(7, global_epilogue_callback_status); | 3057 EXPECT_EQ(7, global_epilogue_callback_status); |
| 3019 | 3058 |
| 3020 // Garbage collect old space ignoring callbacks. This should invoke | 3059 // Garbage collect old space ignoring callbacks. This should invoke |
| 3021 // the prologue callback. The prologue status value should change. | 3060 // the prologue callback. The prologue status value should change. |
| 3022 global_prologue_callback_status = 3; | 3061 global_prologue_callback_status = 3; |
| 3023 global_epilogue_callback_status = 7; | 3062 global_epilogue_callback_status = 7; |
| 3024 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | 3063 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 3025 Heap::kIgnoreApiCallbacks); | 3064 Heap::kIgnoreApiCallbacks, |
| 3065 Heap::kGCTestCase); | |
| 3026 EXPECT_EQ(3, global_prologue_callback_status); | 3066 EXPECT_EQ(3, global_prologue_callback_status); |
| 3027 EXPECT_EQ(7, global_epilogue_callback_status); | 3067 EXPECT_EQ(7, global_epilogue_callback_status); |
| 3028 | 3068 |
| 3029 // Garbage collect old space. This should invoke the prologue | 3069 // Garbage collect old space. This should invoke the prologue |
| 3030 // callback. The prologue status value should change. | 3070 // callback. The prologue status value should change. |
| 3031 global_prologue_callback_status = 3; | 3071 global_prologue_callback_status = 3; |
| 3032 global_epilogue_callback_status = 7; | 3072 global_epilogue_callback_status = 7; |
| 3033 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3073 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 3034 EXPECT_EQ(6, global_prologue_callback_status); | 3074 EXPECT_EQ(6, global_prologue_callback_status); |
| 3035 EXPECT_EQ(7, global_epilogue_callback_status); | 3075 EXPECT_EQ(7, global_epilogue_callback_status); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3065 // should change. | 3105 // should change. |
| 3066 global_prologue_callback_status = 3; | 3106 global_prologue_callback_status = 3; |
| 3067 global_epilogue_callback_status = 7; | 3107 global_epilogue_callback_status = 7; |
| 3068 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3108 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 3069 EXPECT_EQ(6, global_prologue_callback_status); | 3109 EXPECT_EQ(6, global_prologue_callback_status); |
| 3070 EXPECT_EQ(28, global_epilogue_callback_status); | 3110 EXPECT_EQ(28, global_epilogue_callback_status); |
| 3071 | 3111 |
| 3072 // Garbage collect old space again without invoking callbacks. | 3112 // Garbage collect old space again without invoking callbacks. |
| 3073 // Nothing should change. | 3113 // Nothing should change. |
| 3074 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | 3114 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, |
| 3075 Heap::kIgnoreApiCallbacks); | 3115 Heap::kIgnoreApiCallbacks, |
| 3116 Heap::kGCTestCase); | |
| 3076 EXPECT_EQ(6, global_prologue_callback_status); | 3117 EXPECT_EQ(6, global_prologue_callback_status); |
| 3077 EXPECT_EQ(28, global_epilogue_callback_status); | 3118 EXPECT_EQ(28, global_epilogue_callback_status); |
| 3078 | 3119 |
| 3079 // Garbage collect old space again. Callbacks are persistent so the | 3120 // Garbage collect old space again. Callbacks are persistent so the |
| 3080 // prologue and epilogue status values should change again. | 3121 // prologue and epilogue status values should change again. |
| 3081 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3122 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 3082 EXPECT_EQ(12, global_prologue_callback_status); | 3123 EXPECT_EQ(12, global_prologue_callback_status); |
| 3083 EXPECT_EQ(112, global_epilogue_callback_status); | 3124 EXPECT_EQ(112, global_epilogue_callback_status); |
| 3084 | 3125 |
| 3085 // Remove the prologue and epilogue callbacks | 3126 // Remove the prologue and epilogue callbacks |
| (...skipping 5010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8096 dart_args); | 8137 dart_args); |
| 8097 int64_t value = 0; | 8138 int64_t value = 0; |
| 8098 result = Dart_IntegerToInt64(result, &value); | 8139 result = Dart_IntegerToInt64(result, &value); |
| 8099 EXPECT_VALID(result); | 8140 EXPECT_VALID(result); |
| 8100 EXPECT_EQ(6, value); | 8141 EXPECT_EQ(6, value); |
| 8101 } | 8142 } |
| 8102 | 8143 |
| 8103 } // namespace dart | 8144 } // namespace dart |
| 8104 | 8145 |
| 8105 #endif // !defined(TARGET_ARCH_ARM64) | 8146 #endif // !defined(TARGET_ARCH_ARM64) |
| OLD | NEW |