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 #include "bin/builtin.h" | 5 #include "bin/builtin.h" |
| 6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "include/dart_mirrors_api.h" | 8 #include "include/dart_mirrors_api.h" |
| 9 #include "include/dart_native_api.h" | 9 #include "include/dart_native_api.h" |
| 10 #include "include/dart_tools_api.h" | 10 #include "include/dart_tools_api.h" |
| (...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1210 // The normal call to CollectGarbage(Heap::kNew) could potentially trigger | 1210 // The normal call to CollectGarbage(Heap::kNew) could potentially trigger |
| 1211 // an old gen collection if there is a promotion failure and this could | 1211 // an old gen collection if there is a promotion failure and this could |
| 1212 // perturb the test. | 1212 // perturb the test. |
| 1213 class GCTestHelper : public AllStatic { | 1213 class GCTestHelper : public AllStatic { |
| 1214 public: | 1214 public: |
| 1215 static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) { | 1215 static void CollectNewSpace(Heap::ApiCallbacks api_callbacks) { |
| 1216 bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks); | 1216 bool invoke_api_callbacks = (api_callbacks == Heap::kInvokeApiCallbacks); |
| 1217 Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks); | 1217 Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks); |
| 1218 } | 1218 } |
| 1219 | 1219 |
| 1220 static void WaitForFinalizationTasks() { | 1220 static void WaitForGCTasks() { |
| 1221 Thread* thread = Thread::Current(); | 1221 Thread* thread = Thread::Current(); |
| 1222 Heap* heap = thread->isolate()->heap(); | 1222 PageSpace* old_space = thread->isolate()->heap()->old_space(); |
| 1223 MonitorLocker ml(heap->finalization_tasks_lock()); | 1223 MonitorLocker ml(old_space->tasks_lock()); |
| 1224 while (heap->finalization_tasks() > 0) { | 1224 while (old_space->tasks() > 0) { |
| 1225 ml.WaitWithSafepointCheck(thread); | 1225 ml.WaitWithSafepointCheck(thread); |
| 1226 } | 1226 } |
| 1227 } | 1227 } |
| 1228 }; | 1228 }; |
| 1229 | 1229 |
| 1230 | 1230 |
| 1231 static void ExternalStringCallbackFinalizer(void* peer) { | 1231 static void ExternalStringCallbackFinalizer(void* peer) { |
| 1232 *static_cast<int*>(peer) *= 2; | 1232 *static_cast<int*>(peer) *= 2; |
| 1233 } | 1233 } |
| 1234 | 1234 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1257 EXPECT_VALID(obj16); | 1257 EXPECT_VALID(obj16); |
| 1258 | 1258 |
| 1259 Dart_ExitScope(); | 1259 Dart_ExitScope(); |
| 1260 } | 1260 } |
| 1261 | 1261 |
| 1262 { | 1262 { |
| 1263 TransitionNativeToVM transition(thread); | 1263 TransitionNativeToVM transition(thread); |
| 1264 EXPECT_EQ(40, peer8); | 1264 EXPECT_EQ(40, peer8); |
| 1265 EXPECT_EQ(41, peer16); | 1265 EXPECT_EQ(41, peer16); |
| 1266 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 1266 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 1267 GCTestHelper::WaitForFinalizationTasks(); | 1267 GCTestHelper::WaitForGCTasks(); |
| 1268 EXPECT_EQ(40, peer8); | 1268 EXPECT_EQ(40, peer8); |
| 1269 EXPECT_EQ(41, peer16); | 1269 EXPECT_EQ(41, peer16); |
| 1270 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 1270 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 1271 GCTestHelper::WaitForFinalizationTasks(); | 1271 GCTestHelper::WaitForGCTasks(); |
| 1272 EXPECT_EQ(80, peer8); | 1272 EXPECT_EQ(80, peer8); |
| 1273 EXPECT_EQ(82, peer16); | 1273 EXPECT_EQ(82, peer16); |
| 1274 } | 1274 } |
| 1275 } | 1275 } |
| 1276 | 1276 |
| 1277 | 1277 |
| 1278 TEST_CASE(ExternalStringPretenure) { | 1278 TEST_CASE(ExternalStringPretenure) { |
| 1279 { | 1279 { |
| 1280 Dart_EnterScope(); | 1280 Dart_EnterScope(); |
| 1281 static const uint8_t big_data8[16*MB] = {0, }; | 1281 static const uint8_t big_data8[16*MB] = {0, }; |
| (...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2373 EXPECT(value); | 2373 EXPECT(value); |
| 2374 } | 2374 } |
| 2375 | 2375 |
| 2376 | 2376 |
| 2377 static void NopCallback(void* isolate_callback_data, | 2377 static void NopCallback(void* isolate_callback_data, |
| 2378 Dart_WeakPersistentHandle handle, | 2378 Dart_WeakPersistentHandle handle, |
| 2379 void* peer) { | 2379 void* peer) { |
| 2380 } | 2380 } |
| 2381 | 2381 |
| 2382 | 2382 |
| 2383 static void UnreachedCallback(void* isolate_callback_data, | |
| 2384 Dart_WeakPersistentHandle handle, | |
| 2385 void* peer) { | |
| 2386 UNREACHABLE(); | |
| 2387 } | |
| 2388 | |
| 2389 | |
| 2383 static void ExternalTypedDataFinalizer(void* isolate_callback_data, | 2390 static void ExternalTypedDataFinalizer(void* isolate_callback_data, |
| 2384 Dart_WeakPersistentHandle handle, | 2391 Dart_WeakPersistentHandle handle, |
| 2385 void* peer) { | 2392 void* peer) { |
| 2386 *static_cast<int*>(peer) = 42; | 2393 *static_cast<int*>(peer) = 42; |
| 2387 } | 2394 } |
| 2388 | 2395 |
| 2389 | 2396 |
| 2390 TEST_CASE(ExternalTypedDataCallback) { | 2397 TEST_CASE(ExternalTypedDataCallback) { |
| 2391 int peer = 0; | 2398 int peer = 0; |
| 2392 { | 2399 { |
| 2393 Dart_EnterScope(); | 2400 Dart_EnterScope(); |
| 2394 uint8_t data[] = { 1, 2, 3, 4 }; | 2401 uint8_t data[] = { 1, 2, 3, 4 }; |
| 2395 Dart_Handle obj = Dart_NewExternalTypedData( | 2402 Dart_Handle obj = Dart_NewExternalTypedData( |
| 2396 Dart_TypedData_kUint8, | 2403 Dart_TypedData_kUint8, |
| 2397 data, | 2404 data, |
| 2398 ARRAY_SIZE(data)); | 2405 ARRAY_SIZE(data)); |
| 2399 Dart_NewWeakPersistentHandle( | 2406 Dart_NewWeakPersistentHandle( |
| 2400 obj, &peer, sizeof(data), ExternalTypedDataFinalizer); | 2407 obj, &peer, sizeof(data), ExternalTypedDataFinalizer); |
| 2401 EXPECT_VALID(obj); | 2408 EXPECT_VALID(obj); |
| 2402 Dart_ExitScope(); | 2409 Dart_ExitScope(); |
| 2403 } | 2410 } |
| 2404 { | 2411 { |
| 2405 TransitionNativeToVM transition(thread); | 2412 TransitionNativeToVM transition(thread); |
| 2406 EXPECT(peer == 0); | 2413 EXPECT(peer == 0); |
| 2407 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2414 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2408 GCTestHelper::WaitForFinalizationTasks(); | 2415 GCTestHelper::WaitForGCTasks(); |
| 2409 EXPECT(peer == 0); | 2416 EXPECT(peer == 0); |
| 2410 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 2417 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 2411 GCTestHelper::WaitForFinalizationTasks(); | 2418 GCTestHelper::WaitForGCTasks(); |
| 2412 EXPECT(peer == 42); | 2419 EXPECT(peer == 42); |
| 2413 } | 2420 } |
| 2414 } | 2421 } |
| 2415 | 2422 |
| 2416 | 2423 |
| 2417 static Monitor* slow_finalizers_monitor = NULL; | |
| 2418 static intptr_t slow_finalizers_waiting = 0; | |
| 2419 | |
| 2420 | |
| 2421 static void SlowFinalizer(void* isolate_callback_data, | 2424 static void SlowFinalizer(void* isolate_callback_data, |
| 2422 Dart_WeakPersistentHandle handle, | 2425 Dart_WeakPersistentHandle handle, |
| 2423 void* peer) { | 2426 void* peer) { |
| 2424 { | 2427 OS::Sleep(10); |
|
siva
2016/08/29 22:05:09
Why is this sleep necessary as you now make sure o
rmacnak
2016/08/29 23:09:45
Trying to stress the situation where the marker ha
| |
| 2425 MonitorLocker ml(slow_finalizers_monitor); | |
| 2426 slow_finalizers_waiting++; | |
| 2427 while (slow_finalizers_waiting < 10) { | |
| 2428 ml.Wait(); | |
| 2429 } | |
| 2430 ml.NotifyAll(); | |
| 2431 } | |
| 2432 | |
| 2433 intptr_t* count = reinterpret_cast<intptr_t*>(peer); | 2428 intptr_t* count = reinterpret_cast<intptr_t*>(peer); |
| 2434 AtomicOperations::IncrementBy(count, 1); | 2429 (*count)++; |
| 2435 } | 2430 } |
| 2436 | 2431 |
| 2437 | 2432 |
| 2438 TEST_CASE(SlowFinalizer) { | 2433 TEST_CASE(SlowFinalizer) { |
| 2439 slow_finalizers_monitor = new Monitor(); | |
| 2440 | |
| 2441 intptr_t count = 0; | 2434 intptr_t count = 0; |
| 2442 for (intptr_t i = 0; i < 10; i++) { | 2435 for (intptr_t i = 0; i < 10; i++) { |
| 2443 Dart_EnterScope(); | 2436 Dart_EnterScope(); |
| 2444 Dart_Handle str1 = Dart_NewStringFromCString("Live fast"); | 2437 Dart_Handle str1 = Dart_NewStringFromCString("Live fast"); |
| 2445 Dart_NewWeakPersistentHandle(str1, &count, 0, SlowFinalizer); | 2438 Dart_NewWeakPersistentHandle(str1, &count, 0, SlowFinalizer); |
| 2446 Dart_Handle str2 = Dart_NewStringFromCString("Die young"); | 2439 Dart_Handle str2 = Dart_NewStringFromCString("Die young"); |
| 2447 Dart_NewWeakPersistentHandle(str2, &count, 0, SlowFinalizer); | 2440 Dart_NewWeakPersistentHandle(str2, &count, 0, SlowFinalizer); |
| 2448 Dart_ExitScope(); | 2441 Dart_ExitScope(); |
| 2449 | 2442 |
| 2450 { | 2443 { |
| 2451 TransitionNativeToVM transition(thread); | 2444 TransitionNativeToVM transition(thread); |
| 2452 Isolate::Current()->heap()->CollectAllGarbage(); | 2445 Isolate::Current()->heap()->CollectAllGarbage(); |
| 2453 } | 2446 } |
| 2454 } | 2447 } |
| 2455 | 2448 |
| 2456 { | 2449 { |
| 2457 TransitionNativeToVM transition(thread); | 2450 TransitionNativeToVM transition(thread); |
| 2458 GCTestHelper::WaitForFinalizationTasks(); | 2451 GCTestHelper::WaitForGCTasks(); |
| 2459 } | 2452 } |
| 2460 | 2453 |
| 2461 EXPECT_EQ(20, count); | 2454 EXPECT_EQ(20, count); |
| 2462 | |
| 2463 delete slow_finalizers_monitor; | |
| 2464 } | 2455 } |
| 2465 | 2456 |
| 2466 | 2457 |
| 2467 static void CheckFloat32x4Data(Dart_Handle obj) { | 2458 static void CheckFloat32x4Data(Dart_Handle obj) { |
| 2468 void* raw_data = NULL; | 2459 void* raw_data = NULL; |
| 2469 intptr_t len; | 2460 intptr_t len; |
| 2470 Dart_TypedData_Type type; | 2461 Dart_TypedData_Type type; |
| 2471 EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len)); | 2462 EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len)); |
| 2472 EXPECT_EQ(Dart_TypedData_kFloat32x4, type); | 2463 EXPECT_EQ(Dart_TypedData_kFloat32x4, type); |
| 2473 EXPECT_EQ(len, 10); | 2464 EXPECT_EQ(len, 10); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2508 Dart_Handle lcl = Dart_NewExternalTypedData( | 2499 Dart_Handle lcl = Dart_NewExternalTypedData( |
| 2509 Dart_TypedData_kFloat32x4, data, 10); | 2500 Dart_TypedData_kFloat32x4, data, 10); |
| 2510 Dart_NewWeakPersistentHandle( | 2501 Dart_NewWeakPersistentHandle( |
| 2511 lcl, &peer, sizeof(data), ExternalTypedDataFinalizer); | 2502 lcl, &peer, sizeof(data), ExternalTypedDataFinalizer); |
| 2512 CheckFloat32x4Data(lcl); | 2503 CheckFloat32x4Data(lcl); |
| 2513 } | 2504 } |
| 2514 Dart_ExitScope(); | 2505 Dart_ExitScope(); |
| 2515 { | 2506 { |
| 2516 TransitionNativeToVM transition(thread); | 2507 TransitionNativeToVM transition(thread); |
| 2517 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 2508 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 2518 GCTestHelper::WaitForFinalizationTasks(); | 2509 GCTestHelper::WaitForGCTasks(); |
| 2519 EXPECT(peer == 42); | 2510 EXPECT(peer == 42); |
| 2520 } | 2511 } |
| 2521 } | 2512 } |
| 2522 | 2513 |
| 2523 | 2514 |
| 2524 // Unit test for entering a scope, creating a local handle and exiting | 2515 // Unit test for entering a scope, creating a local handle and exiting |
| 2525 // the scope. | 2516 // the scope. |
| 2526 UNIT_TEST_CASE(EnterExitScope) { | 2517 UNIT_TEST_CASE(EnterExitScope) { |
| 2527 TestIsolateScope __test_isolate__; | 2518 TestIsolateScope __test_isolate__; |
| 2528 | 2519 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2785 EXPECT(Dart_IdentityEquals(old_ref, AsHandle(weak_old_ref))); | 2776 EXPECT(Dart_IdentityEquals(old_ref, AsHandle(weak_old_ref))); |
| 2786 | 2777 |
| 2787 // Delete local (strong) references. | 2778 // Delete local (strong) references. |
| 2788 Dart_ExitScope(); | 2779 Dart_ExitScope(); |
| 2789 } | 2780 } |
| 2790 | 2781 |
| 2791 { | 2782 { |
| 2792 TransitionNativeToVM transition(thread); | 2783 TransitionNativeToVM transition(thread); |
| 2793 // Garbage collect new space again. | 2784 // Garbage collect new space again. |
| 2794 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2785 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2795 GCTestHelper::WaitForFinalizationTasks(); | 2786 GCTestHelper::WaitForGCTasks(); |
| 2796 } | 2787 } |
| 2797 | 2788 |
| 2798 { | 2789 { |
| 2799 Dart_EnterScope(); | 2790 Dart_EnterScope(); |
| 2800 // Weak ref to new space object should now be cleared. | 2791 // Weak ref to new space object should now be cleared. |
| 2801 EXPECT(weak_new_ref == NULL); | 2792 EXPECT(weak_new_ref == NULL); |
| 2802 EXPECT_VALID(AsHandle(weak_old_ref)); | 2793 EXPECT_VALID(AsHandle(weak_old_ref)); |
| 2803 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref))); | 2794 EXPECT(!Dart_IsNull(AsHandle(weak_old_ref))); |
| 2804 Dart_ExitScope(); | 2795 Dart_ExitScope(); |
| 2805 } | 2796 } |
| 2806 | 2797 |
| 2807 { | 2798 { |
| 2808 TransitionNativeToVM transition(thread); | 2799 TransitionNativeToVM transition(thread); |
| 2809 // Garbage collect old space again. | 2800 // Garbage collect old space again. |
| 2810 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2801 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2811 GCTestHelper::WaitForFinalizationTasks(); | 2802 GCTestHelper::WaitForGCTasks(); |
| 2812 } | 2803 } |
| 2813 | 2804 |
| 2814 { | 2805 { |
| 2815 Dart_EnterScope(); | 2806 Dart_EnterScope(); |
| 2816 // Weak ref to old space object should now be cleared. | 2807 // Weak ref to old space object should now be cleared. |
| 2817 EXPECT(weak_new_ref == NULL); | 2808 EXPECT(weak_new_ref == NULL); |
| 2818 EXPECT(weak_old_ref == NULL); | 2809 EXPECT(weak_old_ref == NULL); |
| 2819 Dart_ExitScope(); | 2810 Dart_ExitScope(); |
| 2820 } | 2811 } |
| 2821 | 2812 |
| 2822 { | 2813 { |
| 2823 TransitionNativeToVM transition(thread); | 2814 TransitionNativeToVM transition(thread); |
| 2824 // Garbage collect one last time to revisit deleted handles. | 2815 // Garbage collect one last time to revisit deleted handles. |
| 2825 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); | 2816 Isolate::Current()->heap()->CollectGarbage(Heap::kNew); |
| 2826 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2817 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2827 } | 2818 } |
| 2828 } | 2819 } |
| 2829 | 2820 |
| 2830 | 2821 |
| 2822 TEST_CASE(WeakPersistentHandleErrors) { | |
| 2823 Dart_EnterScope(); | |
| 2824 | |
| 2825 // NULL callback. | |
| 2826 Dart_Handle obj1 = NewString("new string"); | |
| 2827 EXPECT_VALID(obj1); | |
| 2828 Dart_WeakPersistentHandle ref1 = Dart_NewWeakPersistentHandle( | |
| 2829 obj1, NULL, 0, NULL); | |
| 2830 EXPECT_EQ(ref1, static_cast<void*>(NULL)); | |
| 2831 | |
| 2832 // Immediate object. | |
| 2833 Dart_Handle obj2 = Dart_NewInteger(0); | |
| 2834 EXPECT_VALID(obj2); | |
| 2835 Dart_WeakPersistentHandle ref2 = Dart_NewWeakPersistentHandle( | |
| 2836 obj2, NULL, 0, WeakPersistentHandleCallback); | |
| 2837 EXPECT_EQ(ref2, static_cast<void*>(NULL)); | |
| 2838 | |
| 2839 Dart_ExitScope(); | |
| 2840 } | |
| 2841 | |
| 2842 | |
| 2831 static void WeakPersistentHandlePeerFinalizer(void* isolate_callback_data, | 2843 static void WeakPersistentHandlePeerFinalizer(void* isolate_callback_data, |
| 2832 Dart_WeakPersistentHandle handle, | 2844 Dart_WeakPersistentHandle handle, |
| 2833 void* peer) { | 2845 void* peer) { |
| 2834 *static_cast<int*>(peer) = 42; | 2846 *static_cast<int*>(peer) = 42; |
| 2835 } | 2847 } |
| 2836 | 2848 |
| 2837 | 2849 |
| 2838 TEST_CASE(WeakPersistentHandleCallback) { | 2850 TEST_CASE(WeakPersistentHandleCallback) { |
| 2839 Dart_WeakPersistentHandle weak_ref = NULL; | 2851 Dart_WeakPersistentHandle weak_ref = NULL; |
| 2840 int peer = 0; | 2852 int peer = 0; |
| 2841 { | 2853 { |
| 2842 Dart_EnterScope(); | 2854 Dart_EnterScope(); |
| 2843 Dart_Handle obj = NewString("new string"); | 2855 Dart_Handle obj = NewString("new string"); |
| 2844 EXPECT_VALID(obj); | 2856 EXPECT_VALID(obj); |
| 2845 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 0, | 2857 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 0, |
| 2846 WeakPersistentHandlePeerFinalizer); | 2858 WeakPersistentHandlePeerFinalizer); |
| 2847 EXPECT_VALID(AsHandle(weak_ref)); | 2859 EXPECT_VALID(AsHandle(weak_ref)); |
| 2848 EXPECT(peer == 0); | 2860 EXPECT(peer == 0); |
| 2849 Dart_ExitScope(); | 2861 Dart_ExitScope(); |
| 2850 } | 2862 } |
| 2851 { | 2863 { |
| 2852 TransitionNativeToVM transition(thread); | 2864 TransitionNativeToVM transition(thread); |
| 2853 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2865 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2854 EXPECT(peer == 0); | 2866 EXPECT(peer == 0); |
| 2855 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2867 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2856 GCTestHelper::WaitForFinalizationTasks(); | 2868 GCTestHelper::WaitForGCTasks(); |
| 2857 EXPECT(peer == 42); | 2869 EXPECT(peer == 42); |
| 2858 } | 2870 } |
| 2859 } | 2871 } |
| 2860 | 2872 |
| 2861 | 2873 |
| 2862 TEST_CASE(WeakPersistentHandleNoCallback) { | 2874 TEST_CASE(WeakPersistentHandleNoCallback) { |
| 2863 Dart_WeakPersistentHandle weak_ref = NULL; | 2875 Dart_WeakPersistentHandle weak_ref = NULL; |
| 2864 int peer = 0; | 2876 int peer = 0; |
| 2865 { | 2877 { |
| 2866 Dart_EnterScope(); | 2878 Dart_EnterScope(); |
| 2867 Dart_Handle obj = NewString("new string"); | 2879 Dart_Handle obj = NewString("new string"); |
| 2868 EXPECT_VALID(obj); | 2880 EXPECT_VALID(obj); |
| 2869 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 0, | 2881 weak_ref = Dart_NewWeakPersistentHandle(obj, &peer, 0, |
| 2870 WeakPersistentHandlePeerFinalizer); | 2882 WeakPersistentHandlePeerFinalizer); |
| 2871 Dart_ExitScope(); | 2883 Dart_ExitScope(); |
| 2872 } | 2884 } |
| 2873 // A finalizer is not invoked on a deleted handle. Therefore, the | 2885 // A finalizer is not invoked on a deleted handle. Therefore, the |
| 2874 // peer value should not change after the referent is collected. | 2886 // peer value should not change after the referent is collected. |
| 2875 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2887 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 2876 Dart_DeleteWeakPersistentHandle(isolate, weak_ref); | 2888 Dart_DeleteWeakPersistentHandle(isolate, weak_ref); |
| 2877 EXPECT(peer == 0); | 2889 EXPECT(peer == 0); |
| 2878 { | 2890 { |
| 2879 TransitionNativeToVM transition(thread); | 2891 TransitionNativeToVM transition(thread); |
| 2880 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2892 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2881 EXPECT(peer == 0); | 2893 EXPECT(peer == 0); |
| 2882 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2894 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2883 GCTestHelper::WaitForFinalizationTasks(); | 2895 GCTestHelper::WaitForGCTasks(); |
| 2884 EXPECT(peer == 0); | 2896 EXPECT(peer == 0); |
| 2885 } | 2897 } |
| 2886 } | 2898 } |
| 2887 | 2899 |
| 2888 | 2900 |
| 2889 UNIT_TEST_CASE(WeakPersistentHandlesCallbackShutdown) { | 2901 UNIT_TEST_CASE(WeakPersistentHandlesCallbackShutdown) { |
| 2890 TestCase::CreateTestIsolate(); | 2902 TestCase::CreateTestIsolate(); |
| 2891 Dart_EnterScope(); | 2903 Dart_EnterScope(); |
| 2892 Dart_Handle ref = Dart_True(); | 2904 Dart_Handle ref = Dart_True(); |
| 2893 int peer = 1234; | 2905 int peer = 1234; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2934 Dart_ExitScope(); | 2946 Dart_ExitScope(); |
| 2935 } | 2947 } |
| 2936 { | 2948 { |
| 2937 TransitionNativeToVM transition(thread); | 2949 TransitionNativeToVM transition(thread); |
| 2938 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2950 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2939 EXPECT(heap->ExternalInWords(Heap::kNew) == | 2951 EXPECT(heap->ExternalInWords(Heap::kNew) == |
| 2940 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); | 2952 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); |
| 2941 // Collect weakly referenced string, and promote strongly referenced string. | 2953 // Collect weakly referenced string, and promote strongly referenced string. |
| 2942 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2954 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2943 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | 2955 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); |
| 2944 GCTestHelper::WaitForFinalizationTasks(); | 2956 GCTestHelper::WaitForGCTasks(); |
| 2945 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | 2957 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); |
| 2946 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize); | 2958 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize); |
| 2947 } | 2959 } |
| 2948 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2960 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 2949 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 2961 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
| 2950 Dart_DeleteWeakPersistentHandle(isolate, weak2); | 2962 Dart_DeleteWeakPersistentHandle(isolate, weak2); |
| 2951 Dart_DeletePersistentHandle(strong_ref); | 2963 Dart_DeletePersistentHandle(strong_ref); |
| 2952 { | 2964 { |
| 2953 TransitionNativeToVM transition(thread); | 2965 TransitionNativeToVM transition(thread); |
| 2954 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2966 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 2955 GCTestHelper::WaitForFinalizationTasks(); | 2967 GCTestHelper::WaitForGCTasks(); |
| 2956 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 2968 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); |
| 2957 } | 2969 } |
| 2958 } | 2970 } |
| 2959 | 2971 |
| 2960 | 2972 |
| 2961 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) { | 2973 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) { |
| 2962 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2974 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 2963 Heap* heap = Isolate::Current()->heap(); | 2975 Heap* heap = Isolate::Current()->heap(); |
| 2964 Dart_WeakPersistentHandle weak1 = NULL; | 2976 Dart_WeakPersistentHandle weak1 = NULL; |
| 2965 // Large enough to exceed any new space limit. Not actually allocated. | 2977 // Large enough to exceed any new space limit. Not actually allocated. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2991 EXPECT(handle.IsOld()); | 3003 EXPECT(handle.IsOld()); |
| 2992 } | 3004 } |
| 2993 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | 3005 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); |
| 2994 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak1ExternalSize / kWordSize); | 3006 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak1ExternalSize / kWordSize); |
| 2995 Dart_ExitScope(); | 3007 Dart_ExitScope(); |
| 2996 } | 3008 } |
| 2997 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 3009 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
| 2998 { | 3010 { |
| 2999 TransitionNativeToVM transition(thread); | 3011 TransitionNativeToVM transition(thread); |
| 3000 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3012 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 3001 GCTestHelper::WaitForFinalizationTasks(); | 3013 GCTestHelper::WaitForGCTasks(); |
| 3002 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 3014 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); |
| 3003 } | 3015 } |
| 3004 } | 3016 } |
| 3005 | 3017 |
| 3006 | 3018 |
| 3007 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOldspaceGC) { | 3019 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOldspaceGC) { |
| 3008 // Check that external allocation in old space can trigger GC. | 3020 // Check that external allocation in old space can trigger GC. |
| 3009 Isolate* isolate = Isolate::Current(); | 3021 Isolate* isolate = Isolate::Current(); |
| 3010 Dart_EnterScope(); | 3022 Dart_EnterScope(); |
| 3011 Dart_Handle live = Api::NewHandle(thread, String::New("live", Heap::kOld)); | 3023 Dart_Handle live = Api::NewHandle(thread, String::New("live", Heap::kOld)); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3038 Dart_ExitScope(); | 3050 Dart_ExitScope(); |
| 3039 } | 3051 } |
| 3040 | 3052 |
| 3041 | 3053 |
| 3042 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOddReferents) { | 3054 TEST_CASE(WeakPersistentHandleExternalAllocationSizeOddReferents) { |
| 3043 Heap* heap = Isolate::Current()->heap(); | 3055 Heap* heap = Isolate::Current()->heap(); |
| 3044 Dart_WeakPersistentHandle weak1 = NULL; | 3056 Dart_WeakPersistentHandle weak1 = NULL; |
| 3045 static const intptr_t kWeak1ExternalSize = 1 * KB; | 3057 static const intptr_t kWeak1ExternalSize = 1 * KB; |
| 3046 Dart_WeakPersistentHandle weak2 = NULL; | 3058 Dart_WeakPersistentHandle weak2 = NULL; |
| 3047 static const intptr_t kWeak2ExternalSize = 2 * KB; | 3059 static const intptr_t kWeak2ExternalSize = 2 * KB; |
| 3060 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); | |
| 3048 { | 3061 { |
| 3049 Dart_EnterScope(); | 3062 Dart_EnterScope(); |
| 3050 Dart_Handle dart_true = Dart_True(); // VM heap object. | 3063 Dart_Handle dart_true = Dart_True(); // VM heap object. |
| 3051 EXPECT_VALID(dart_true); | 3064 EXPECT_VALID(dart_true); |
| 3052 weak1 = Dart_NewWeakPersistentHandle( | 3065 weak1 = Dart_NewWeakPersistentHandle( |
| 3053 dart_true, NULL, kWeak1ExternalSize, NopCallback); | 3066 dart_true, NULL, kWeak1ExternalSize, UnreachedCallback); |
| 3054 EXPECT_VALID(AsHandle(weak1)); | 3067 EXPECT_VALID(AsHandle(weak1)); |
| 3055 Dart_Handle zero = Dart_NewInteger(0); // Smi. | 3068 Dart_Handle zero = Dart_False(); // VM heap object. |
| 3056 EXPECT_VALID(zero); | 3069 EXPECT_VALID(zero); |
| 3057 weak2 = Dart_NewWeakPersistentHandle( | 3070 weak2 = Dart_NewWeakPersistentHandle( |
| 3058 zero, NULL, kWeak2ExternalSize, NopCallback); | 3071 zero, NULL, kWeak2ExternalSize, UnreachedCallback); |
| 3059 EXPECT_VALID(AsHandle(weak2)); | 3072 EXPECT_VALID(AsHandle(weak2)); |
| 3060 // Both should be charged to old space. | 3073 // Both should be charged to old space. |
| 3061 EXPECT(heap->ExternalInWords(Heap::kOld) == | 3074 EXPECT(heap->ExternalInWords(Heap::kOld) == |
| 3062 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); | 3075 (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize); |
| 3063 Dart_ExitScope(); | 3076 Dart_ExitScope(); |
| 3064 } | 3077 } |
| 3065 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 3078 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
| 3066 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 3079 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
| 3067 Dart_DeleteWeakPersistentHandle(isolate, weak2); | 3080 Dart_DeleteWeakPersistentHandle(isolate, weak2); |
| 3081 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); | |
| 3068 { | 3082 { |
| 3069 TransitionNativeToVM transition(thread); | 3083 TransitionNativeToVM transition(thread); |
| 3070 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3084 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
| 3071 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); | 3085 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); |
| 3072 } | 3086 } |
| 3073 } | 3087 } |
| 3074 | 3088 |
| 3075 | 3089 |
| 3076 static Dart_WeakPersistentHandle weak1 = NULL; | 3090 static Dart_WeakPersistentHandle weak1 = NULL; |
| 3077 static Dart_WeakPersistentHandle weak2 = NULL; | 3091 static Dart_WeakPersistentHandle weak2 = NULL; |
| (...skipping 5739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8817 } | 8831 } |
| 8818 | 8832 |
| 8819 Dart_ExitScope(); | 8833 Dart_ExitScope(); |
| 8820 } | 8834 } |
| 8821 EXPECT_EQ(40, peer8); | 8835 EXPECT_EQ(40, peer8); |
| 8822 EXPECT_EQ(41, peer16); | 8836 EXPECT_EQ(41, peer16); |
| 8823 EXPECT_EQ(42, canonical_str_peer); | 8837 EXPECT_EQ(42, canonical_str_peer); |
| 8824 { | 8838 { |
| 8825 TransitionNativeToVM transition(thread); | 8839 TransitionNativeToVM transition(thread); |
| 8826 Isolate::Current()->heap()->CollectAllGarbage(); | 8840 Isolate::Current()->heap()->CollectAllGarbage(); |
| 8827 GCTestHelper::WaitForFinalizationTasks(); | 8841 GCTestHelper::WaitForGCTasks(); |
| 8828 } | 8842 } |
| 8829 EXPECT_EQ(80, peer8); | 8843 EXPECT_EQ(80, peer8); |
| 8830 EXPECT_EQ(82, peer16); | 8844 EXPECT_EQ(82, peer16); |
| 8831 EXPECT_EQ(42, canonical_str_peer); // "*" Symbol is not removed on GC. | 8845 EXPECT_EQ(42, canonical_str_peer); // "*" Symbol is not removed on GC. |
| 8832 | 8846 |
| 8833 FLAG_support_externalizable_strings = saved_flag; | 8847 FLAG_support_externalizable_strings = saved_flag; |
| 8834 } | 8848 } |
| 8835 | 8849 |
| 8836 | 8850 |
| 8837 TEST_CASE(ExternalizeConstantStrings) { | 8851 TEST_CASE(ExternalizeConstantStrings) { |
| (...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10200 result = Dart_Invoke(lib, | 10214 result = Dart_Invoke(lib, |
| 10201 NewString("foozoo"), | 10215 NewString("foozoo"), |
| 10202 0, | 10216 0, |
| 10203 NULL); | 10217 NULL); |
| 10204 EXPECT(Dart_IsError(result)); | 10218 EXPECT(Dart_IsError(result)); |
| 10205 } | 10219 } |
| 10206 | 10220 |
| 10207 #endif // !PRODUCT | 10221 #endif // !PRODUCT |
| 10208 | 10222 |
| 10209 } // namespace dart | 10223 } // namespace dart |
| OLD | NEW |