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 "include/dart_api.h" | 6 #include "include/dart_api.h" |
7 #include "include/dart_mirrors_api.h" | 7 #include "include/dart_mirrors_api.h" |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "include/dart_tools_api.h" | 9 #include "include/dart_tools_api.h" |
10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
(...skipping 2735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2746 static const intptr_t kWeak1ExternalSize = 1 * KB; | 2746 static const intptr_t kWeak1ExternalSize = 1 * KB; |
2747 { | 2747 { |
2748 Dart_EnterScope(); | 2748 Dart_EnterScope(); |
2749 Dart_Handle obj = NewString("weakly referenced string"); | 2749 Dart_Handle obj = NewString("weakly referenced string"); |
2750 EXPECT_VALID(obj); | 2750 EXPECT_VALID(obj); |
2751 weak1 = Dart_NewWeakPersistentHandle(obj, | 2751 weak1 = Dart_NewWeakPersistentHandle(obj, |
2752 NULL, | 2752 NULL, |
2753 kWeak1ExternalSize, | 2753 kWeak1ExternalSize, |
2754 NopCallback); | 2754 NopCallback); |
2755 EXPECT_VALID(AsHandle(weak1)); | 2755 EXPECT_VALID(AsHandle(weak1)); |
2756 EXPECT(!Dart_IsPrologueWeakPersistentHandle(weak1)); | |
2757 Dart_ExitScope(); | 2756 Dart_ExitScope(); |
2758 } | 2757 } |
2759 Dart_PersistentHandle strong_ref = NULL; | 2758 Dart_PersistentHandle strong_ref = NULL; |
2760 Dart_WeakPersistentHandle weak2 = NULL; | 2759 Dart_WeakPersistentHandle weak2 = NULL; |
2761 static const intptr_t kWeak2ExternalSize = 2 * KB; | 2760 static const intptr_t kWeak2ExternalSize = 2 * KB; |
2762 { | 2761 { |
2763 Dart_EnterScope(); | 2762 Dart_EnterScope(); |
2764 Dart_Handle obj = NewString("strongly referenced string"); | 2763 Dart_Handle obj = NewString("strongly referenced string"); |
2765 EXPECT_VALID(obj); | 2764 EXPECT_VALID(obj); |
2766 strong_ref = Dart_NewPersistentHandle(obj); | 2765 strong_ref = Dart_NewPersistentHandle(obj); |
(...skipping 14 matching lines...) Expand all Loading... |
2781 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize); | 2780 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize); |
2782 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2781 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
2783 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 2782 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
2784 Dart_DeleteWeakPersistentHandle(isolate, weak2); | 2783 Dart_DeleteWeakPersistentHandle(isolate, weak2); |
2785 Dart_DeletePersistentHandle(strong_ref); | 2784 Dart_DeletePersistentHandle(strong_ref); |
2786 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2785 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
2787 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | 2786 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); |
2788 } | 2787 } |
2789 | 2788 |
2790 | 2789 |
2791 TEST_CASE(PrologueWeakPersistentHandleExternalAllocationSize) { | |
2792 Heap* heap = Isolate::Current()->heap(); | |
2793 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | |
2794 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | |
2795 Dart_WeakPersistentHandle pwph = NULL; | |
2796 static const intptr_t kWeakExternalSize = 1 * KB; | |
2797 { | |
2798 Dart_EnterScope(); | |
2799 Dart_Handle obj = NewString("a string"); | |
2800 EXPECT_VALID(obj); | |
2801 pwph = Dart_NewPrologueWeakPersistentHandle( | |
2802 obj, NULL, kWeakExternalSize, NopCallback); | |
2803 EXPECT_VALID(AsHandle(pwph)); | |
2804 Dart_ExitScope(); | |
2805 } | |
2806 EXPECT(heap->ExternalInWords(Heap::kNew) == kWeakExternalSize / kWordSize); | |
2807 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | |
2808 // Promoting the string should transfer the external size to old. | |
2809 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | |
2810 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | |
2811 EXPECT(heap->ExternalInWords(Heap::kNew) == 0); | |
2812 EXPECT(heap->ExternalInWords(Heap::kOld) == kWeakExternalSize / kWordSize); | |
2813 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
2814 EXPECT(heap->ExternalInWords(Heap::kOld) == 0); | |
2815 } | |
2816 | |
2817 | |
2818 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) { | 2790 TEST_CASE(WeakPersistentHandleExternalAllocationSizeNewspaceGC) { |
2819 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); | 2791 Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current()); |
2820 Heap* heap = Isolate::Current()->heap(); | 2792 Heap* heap = Isolate::Current()->heap(); |
2821 Dart_WeakPersistentHandle weak1 = NULL; | 2793 Dart_WeakPersistentHandle weak1 = NULL; |
2822 // Large enough to exceed any new space limit. Not actually allocated. | 2794 // Large enough to exceed any new space limit. Not actually allocated. |
2823 const intptr_t kWeak1ExternalSize = 500 * MB; | 2795 const intptr_t kWeak1ExternalSize = 500 * MB; |
2824 { | 2796 { |
2825 Dart_EnterScope(); | 2797 Dart_EnterScope(); |
2826 Dart_Handle obj = NewString("weakly referenced string"); | 2798 Dart_Handle obj = NewString("weakly referenced string"); |
2827 EXPECT_VALID(obj); | 2799 EXPECT_VALID(obj); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2920 Dart_DeleteWeakPersistentHandle(isolate, weak1); | 2892 Dart_DeleteWeakPersistentHandle(isolate, weak1); |
2921 Dart_DeleteWeakPersistentHandle(isolate, weak2); | 2893 Dart_DeleteWeakPersistentHandle(isolate, weak2); |
2922 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 2894 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
2923 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); | 2895 EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld)); |
2924 } | 2896 } |
2925 | 2897 |
2926 | 2898 |
2927 static Dart_WeakPersistentHandle weak1 = NULL; | 2899 static Dart_WeakPersistentHandle weak1 = NULL; |
2928 static Dart_WeakPersistentHandle weak2 = NULL; | 2900 static Dart_WeakPersistentHandle weak2 = NULL; |
2929 static Dart_WeakPersistentHandle weak3 = NULL; | 2901 static Dart_WeakPersistentHandle weak3 = NULL; |
2930 static Dart_WeakPersistentHandle weak4 = NULL; | |
2931 | |
2932 | |
2933 static void ObjectGroupsCallback(void* isolate_callback_data, | |
2934 Dart_WeakPersistentHandle handle, | |
2935 void* peer) { | |
2936 if (handle == weak1) { | |
2937 weak1 = NULL; | |
2938 } else if (handle == weak2) { | |
2939 weak2 = NULL; | |
2940 } else if (handle == weak3) { | |
2941 weak3 = NULL; | |
2942 } else if (handle == weak4) { | |
2943 weak4 = NULL; | |
2944 } | |
2945 } | |
2946 | |
2947 | |
2948 TEST_CASE(ObjectGroups) { | |
2949 Dart_PersistentHandle strong = NULL; | |
2950 Dart_WeakPersistentHandle strong_weak = NULL; | |
2951 | |
2952 Dart_EnterScope(); | |
2953 { | |
2954 Isolate* isolate = Isolate::Current(); | |
2955 DARTSCOPE(Thread::Current()); | |
2956 | |
2957 Dart_Handle local = Api::NewHandle( | |
2958 isolate, String::New("strongly reachable", Heap::kOld)); | |
2959 strong = Dart_NewPersistentHandle(local); | |
2960 strong_weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback); | |
2961 EXPECT_VALID(AsHandle(strong)); | |
2962 EXPECT(!Dart_IsNull(AsHandle(strong))); | |
2963 | |
2964 weak1 = Dart_NewWeakPersistentHandle( | |
2965 Api::NewHandle(isolate, String::New("weakly reachable 1", Heap::kOld)), | |
2966 NULL, 0, ObjectGroupsCallback); | |
2967 EXPECT_VALID(AsHandle(weak1)); | |
2968 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
2969 | |
2970 weak2 = Dart_NewWeakPersistentHandle( | |
2971 Api::NewHandle(isolate, String::New("weakly reachable 2", Heap::kOld)), | |
2972 NULL, 0, ObjectGroupsCallback); | |
2973 EXPECT_VALID(AsHandle(weak2)); | |
2974 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
2975 | |
2976 weak3 = Dart_NewWeakPersistentHandle( | |
2977 Api::NewHandle(isolate, String::New("weakly reachable 3", Heap::kOld)), | |
2978 NULL, 0, ObjectGroupsCallback); | |
2979 EXPECT_VALID(AsHandle(weak3)); | |
2980 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
2981 | |
2982 weak4 = Dart_NewWeakPersistentHandle( | |
2983 Api::NewHandle(isolate, String::New("weakly reachable 4", Heap::kOld)), | |
2984 NULL, 0, ObjectGroupsCallback); | |
2985 EXPECT_VALID(AsHandle(weak4)); | |
2986 EXPECT(!Dart_IsNull(AsHandle(weak4))); | |
2987 } | |
2988 Dart_ExitScope(); | |
2989 | |
2990 { | |
2991 Dart_EnterScope(); | |
2992 EXPECT_VALID(AsHandle(strong)); | |
2993 EXPECT_VALID(AsHandle(weak1)); | |
2994 EXPECT_VALID(AsHandle(weak2)); | |
2995 EXPECT_VALID(AsHandle(weak3)); | |
2996 EXPECT_VALID(AsHandle(weak4)); | |
2997 Dart_ExitScope(); | |
2998 } | |
2999 | |
3000 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | |
3001 | |
3002 { | |
3003 Dart_EnterScope(); | |
3004 // New space collection should not affect old space objects | |
3005 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3006 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3007 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
3008 EXPECT(!Dart_IsNull(AsHandle(weak4))); | |
3009 Dart_ExitScope(); | |
3010 } | |
3011 | |
3012 { | |
3013 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3014 EXPECT_NOTNULL(builder); | |
3015 | |
3016 Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1); | |
3017 EXPECT_NOTNULL(set); | |
3018 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak)); | |
3019 | |
3020 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3021 EXPECT_NOTNULL(set); | |
3022 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1)); | |
3023 | |
3024 set = Dart_NewWeakReferenceSet(builder, weak3, weak3); | |
3025 EXPECT_NOTNULL(set); | |
3026 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak2, weak2)); | |
3027 | |
3028 set = Dart_NewWeakReferenceSet(builder, weak4, weak4); | |
3029 EXPECT_NOTNULL(set); | |
3030 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3)); | |
3031 | |
3032 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3033 } | |
3034 | |
3035 { | |
3036 Dart_EnterScope(); | |
3037 // All weak references should be preserved. | |
3038 EXPECT(!Dart_IsNull(AsHandle(strong_weak))); | |
3039 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3040 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3041 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
3042 EXPECT(!Dart_IsNull(AsHandle(weak4))); | |
3043 Dart_ExitScope(); | |
3044 } | |
3045 | |
3046 { | |
3047 Dart_EnterScope(); | |
3048 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3049 EXPECT_NOTNULL(builder); | |
3050 | |
3051 Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1); | |
3052 EXPECT_NOTNULL(set); | |
3053 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak)); | |
3054 | |
3055 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3056 EXPECT_NOTNULL(set); | |
3057 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1)); | |
3058 | |
3059 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3060 EXPECT_NOTNULL(set); | |
3061 | |
3062 // Strong reference to weak3 to retain weak3 and weak4. | |
3063 Dart_PersistentHandle weak3_strong_ref = | |
3064 Dart_NewPersistentHandle(AsHandle(weak3)); | |
3065 EXPECT_VALID(AsHandle(weak3_strong_ref)); | |
3066 | |
3067 set = Dart_NewWeakReferenceSet(builder, weak4, weak4); | |
3068 EXPECT_NOTNULL(set); | |
3069 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3)); | |
3070 | |
3071 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3072 | |
3073 // Delete strong reference to weak3. | |
3074 Dart_DeletePersistentHandle(weak3_strong_ref); | |
3075 Dart_ExitScope(); | |
3076 } | |
3077 | |
3078 { | |
3079 Dart_EnterScope(); | |
3080 // All weak references should be preserved. | |
3081 EXPECT(!Dart_IsNull(AsHandle(strong_weak))); | |
3082 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3083 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3084 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
3085 EXPECT(!Dart_IsNull(AsHandle(weak4))); | |
3086 Dart_ExitScope(); | |
3087 } | |
3088 | |
3089 { | |
3090 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3091 EXPECT_NOTNULL(builder); | |
3092 | |
3093 Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1); | |
3094 EXPECT_NOTNULL(set); | |
3095 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak)); | |
3096 | |
3097 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3098 EXPECT_NOTNULL(set); | |
3099 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak1, weak1)); | |
3100 | |
3101 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3102 EXPECT_NOTNULL(set); | |
3103 | |
3104 set = Dart_NewWeakReferenceSet(builder, weak4, weak4); | |
3105 EXPECT_NOTNULL(set); | |
3106 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak3)); | |
3107 | |
3108 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3109 } | |
3110 | |
3111 { | |
3112 Dart_EnterScope(); | |
3113 // Only weak1 and weak2 should be preserved. | |
3114 EXPECT(!Dart_IsNull(AsHandle(strong_weak))); | |
3115 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3116 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3117 EXPECT(weak3 == NULL); | |
3118 EXPECT(weak4 == NULL); | |
3119 Dart_ExitScope(); | |
3120 } | |
3121 | |
3122 { | |
3123 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3124 EXPECT_NOTNULL(builder); | |
3125 | |
3126 Dart_WeakPersistentHandle lweak3 = Dart_NewWeakPersistentHandle( | |
3127 Dart_Null(), NULL, 0, NopCallback); | |
3128 | |
3129 Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak1, weak1); | |
3130 EXPECT_NOTNULL(set); | |
3131 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, strong_weak, strong_weak)); | |
3132 | |
3133 // lweak3 is unreferenced so weak2 is unreferenced and should be cleared | |
3134 set = Dart_NewWeakReferenceSet(builder, weak2, weak2); | |
3135 EXPECT_NOTNULL(set); | |
3136 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak3, lweak3)); | |
3137 | |
3138 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3139 } | |
3140 | |
3141 { | |
3142 Dart_EnterScope(); | |
3143 // Only weak1 should be preserved, weak3 should not preserve weak2. | |
3144 EXPECT(!Dart_IsNull(AsHandle(strong_weak))); | |
3145 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3146 EXPECT(weak2 == NULL); | |
3147 EXPECT(weak3 == NULL); // was cleared, should remain cleared | |
3148 EXPECT(weak4 == NULL); // was cleared, should remain cleared | |
3149 Dart_ExitScope(); | |
3150 } | |
3151 | |
3152 { | |
3153 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3154 EXPECT_NOTNULL(builder); | |
3155 | |
3156 Dart_WeakPersistentHandle lweak2 = Dart_NewWeakPersistentHandle( | |
3157 Dart_Null(), NULL, 0, NopCallback); | |
3158 Dart_WeakPersistentHandle lweak3 = Dart_NewWeakPersistentHandle( | |
3159 Dart_Null(), NULL, 0, NopCallback); | |
3160 Dart_WeakPersistentHandle lweak4 = Dart_NewWeakPersistentHandle( | |
3161 Dart_Null(), NULL, 0, NopCallback); | |
3162 // lweak{2,3,4} are cleared and should have no effect on weak1 | |
3163 Dart_WeakReferenceSet set = | |
3164 Dart_NewWeakReferenceSet(builder, strong_weak, strong_weak); | |
3165 EXPECT_NOTNULL(set); | |
3166 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak2, lweak2)); | |
3167 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak3, lweak3)); | |
3168 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, lweak4, lweak4)); | |
3169 | |
3170 // weak1 is weakly reachable and should be cleared | |
3171 set = Dart_NewWeakReferenceSet(builder, weak1, weak1); | |
3172 EXPECT_NOTNULL(set); | |
3173 | |
3174 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3175 } | |
3176 | |
3177 { | |
3178 Dart_EnterScope(); | |
3179 // All weak references should now be cleared. | |
3180 EXPECT(!Dart_IsNull(AsHandle(strong_weak))); | |
3181 EXPECT(weak1 == NULL); | |
3182 EXPECT(weak2 == NULL); | |
3183 EXPECT(weak3 == NULL); | |
3184 EXPECT(weak4 == NULL); | |
3185 Dart_ExitScope(); | |
3186 } | |
3187 } | |
3188 | |
3189 | |
3190 TEST_CASE(DuplicateWeakReferenceSetEntries) { | |
3191 Isolate* isolate = Isolate::Current(); | |
3192 Dart_PersistentHandle strong = NULL; | |
3193 Dart_WeakPersistentHandle weak = NULL; // A weak handle to strong. | |
3194 | |
3195 Dart_EnterScope(); | |
3196 { | |
3197 DARTSCOPE(Thread::Current()); | |
3198 | |
3199 // Strong handle to keep the reference set alive. | |
3200 Dart_Handle local = Api::NewHandle(isolate, String::New("string")); | |
3201 strong = Dart_NewPersistentHandle(local); | |
3202 EXPECT_VALID(AsHandle(strong)); | |
3203 EXPECT(!Dart_IsNull(AsHandle(strong))); | |
3204 // Corresponding weak handle to use as key and duplicated value. | |
3205 weak = Dart_NewWeakPersistentHandle(local, NULL, 0, NopCallback); | |
3206 EXPECT_VALID(AsHandle(weak)); | |
3207 EXPECT(!Dart_IsNull(AsHandle(weak))); | |
3208 } | |
3209 Dart_ExitScope(); | |
3210 | |
3211 { | |
3212 Dart_EnterScope(); | |
3213 // Create the weak reference set. | |
3214 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3215 EXPECT_NOTNULL(builder); | |
3216 // Register the key and the first copy of the value. | |
3217 Dart_WeakReferenceSet set = Dart_NewWeakReferenceSet(builder, weak, weak); | |
3218 EXPECT_NOTNULL(set); | |
3219 // Add the second copy of the value. | |
3220 Dart_Handle result = Dart_AppendValueToWeakReferenceSet(set, weak); | |
3221 EXPECT_VALID(result); | |
3222 | |
3223 // Trigger GC to ensure that we can visit duplicate entries in weak | |
3224 // reference sets. | |
3225 isolate->heap()->CollectGarbage(Heap::kNew); | |
3226 Dart_ExitScope(); | |
3227 } | |
3228 } | |
3229 | |
3230 | |
3231 static Dart_WeakPersistentHandle old_pwph = NULL; | |
3232 static Dart_WeakPersistentHandle new_pwph = NULL; | |
3233 | |
3234 | |
3235 static void PrologueWeakHandleCallback(void* isolate_callback_data, | |
3236 Dart_WeakPersistentHandle handle, | |
3237 void* peer) { | |
3238 if (handle == old_pwph) { | |
3239 old_pwph = NULL; | |
3240 } else if (handle == new_pwph) { | |
3241 new_pwph = NULL; | |
3242 } | |
3243 } | |
3244 | |
3245 | |
3246 TEST_CASE(PrologueWeakPersistentHandles) { | |
3247 Dart_EnterScope(); | |
3248 { | |
3249 Isolate* isolate = Isolate::Current(); | |
3250 DARTSCOPE(Thread::Current()); | |
3251 new_pwph = Dart_NewPrologueWeakPersistentHandle( | |
3252 Api::NewHandle(isolate, | |
3253 String::New("new space prologue weak", Heap::kNew)), | |
3254 NULL, 0, PrologueWeakHandleCallback); | |
3255 EXPECT_VALID(AsHandle(new_pwph)); | |
3256 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | |
3257 old_pwph = Dart_NewPrologueWeakPersistentHandle( | |
3258 Api::NewHandle(isolate, | |
3259 String::New("old space prologue weak", Heap::kOld)), | |
3260 NULL, 0, PrologueWeakHandleCallback); | |
3261 EXPECT_VALID(AsHandle(old_pwph)); | |
3262 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | |
3263 } | |
3264 Dart_ExitScope(); | |
3265 | |
3266 { | |
3267 Dart_EnterScope(); | |
3268 EXPECT_VALID(AsHandle(new_pwph)); | |
3269 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | |
3270 EXPECT(Dart_IsPrologueWeakPersistentHandle(new_pwph)); | |
3271 EXPECT_VALID(AsHandle(old_pwph)); | |
3272 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | |
3273 EXPECT(Dart_IsPrologueWeakPersistentHandle(old_pwph)); | |
3274 Dart_ExitScope(); | |
3275 } | |
3276 | |
3277 // Garbage collect new space without invoking API callbacks. | |
3278 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | |
3279 | |
3280 { | |
3281 Dart_EnterScope(); | |
3282 // Both prologue weak handles should be preserved. | |
3283 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | |
3284 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | |
3285 Dart_ExitScope(); | |
3286 } | |
3287 | |
3288 // Garbage collect old space without invoking API callbacks. | |
3289 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | |
3290 Heap::kIgnoreApiCallbacks, | |
3291 Heap::kGCTestCase); | |
3292 | |
3293 { | |
3294 Dart_EnterScope(); | |
3295 // Both prologue weak handles should be preserved. | |
3296 EXPECT(!Dart_IsNull(AsHandle(new_pwph))); | |
3297 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | |
3298 Dart_ExitScope(); | |
3299 } | |
3300 | |
3301 // Garbage collect new space invoking API callbacks. | |
3302 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); | |
3303 | |
3304 { | |
3305 Dart_EnterScope(); | |
3306 // The prologue weak handle with a new space referent should now be | |
3307 // cleared. The old space referent should be preserved. | |
3308 EXPECT(new_pwph == NULL); | |
3309 EXPECT(!Dart_IsNull(AsHandle(old_pwph))); | |
3310 Dart_ExitScope(); | |
3311 } | |
3312 | |
3313 Isolate::Current()->heap()->CollectGarbage(Heap::kOld, | |
3314 Heap::kInvokeApiCallbacks, | |
3315 Heap::kGCTestCase); | |
3316 | |
3317 { | |
3318 Dart_EnterScope(); | |
3319 // The prologue weak handle with an old space referent should now be | |
3320 // cleared. The new space referent should remain cleared. | |
3321 EXPECT(new_pwph == NULL); | |
3322 EXPECT(old_pwph == NULL); | |
3323 Dart_ExitScope(); | |
3324 } | |
3325 } | |
3326 | 2902 |
3327 | 2903 |
3328 static void ImplicitReferencesCallback(void* isolate_callback_data, | 2904 static void ImplicitReferencesCallback(void* isolate_callback_data, |
3329 Dart_WeakPersistentHandle handle, | 2905 Dart_WeakPersistentHandle handle, |
3330 void* peer) { | 2906 void* peer) { |
3331 if (handle == weak1) { | 2907 if (handle == weak1) { |
3332 weak1 = NULL; | 2908 weak1 = NULL; |
3333 } else if (handle == weak2) { | 2909 } else if (handle == weak2) { |
3334 weak2 = NULL; | 2910 weak2 = NULL; |
3335 } else if (handle == weak3) { | 2911 } else if (handle == weak3) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3391 | 2967 |
3392 { | 2968 { |
3393 Dart_EnterScope(); | 2969 Dart_EnterScope(); |
3394 // New space collection should not affect old space objects | 2970 // New space collection should not affect old space objects |
3395 EXPECT_VALID(AsHandle(strong_weak)); | 2971 EXPECT_VALID(AsHandle(strong_weak)); |
3396 EXPECT(!Dart_IsNull(AsHandle(weak1))); | 2972 EXPECT(!Dart_IsNull(AsHandle(weak1))); |
3397 EXPECT(!Dart_IsNull(AsHandle(weak2))); | 2973 EXPECT(!Dart_IsNull(AsHandle(weak2))); |
3398 EXPECT(!Dart_IsNull(AsHandle(weak3))); | 2974 EXPECT(!Dart_IsNull(AsHandle(weak3))); |
3399 Dart_ExitScope(); | 2975 Dart_ExitScope(); |
3400 } | 2976 } |
3401 | |
3402 // A strongly referenced key should preserve all the values. | |
3403 { | |
3404 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3405 EXPECT_NOTNULL(builder); | |
3406 | |
3407 Dart_WeakReferenceSet set = | |
3408 Dart_NewWeakReferenceSet(builder, strong_weak, 0); | |
3409 EXPECT_NOTNULL(set); | |
3410 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak1)); | |
3411 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak2)); | |
3412 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak3)); | |
3413 | |
3414 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3415 } | |
3416 | |
3417 { | |
3418 Dart_EnterScope(); | |
3419 // All weak references should be preserved. | |
3420 EXPECT_VALID(AsHandle(strong_weak)); | |
3421 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3422 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3423 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
3424 Dart_ExitScope(); | |
3425 } | |
3426 | |
3427 // Key membership does not imply a strong reference. | |
3428 { | |
3429 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3430 EXPECT_NOTNULL(builder); | |
3431 | |
3432 Dart_WeakReferenceSet set = | |
3433 Dart_NewWeakReferenceSet(builder, strong_weak, weak1); | |
3434 EXPECT_NOTNULL(set); | |
3435 EXPECT_VALID(Dart_AppendToWeakReferenceSet(set, weak3, weak2)); | |
3436 | |
3437 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
3438 } | |
3439 | |
3440 { | |
3441 Dart_EnterScope(); | |
3442 // All weak references except weak3 should be preserved. | |
3443 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3444 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3445 EXPECT(weak3 == NULL); | |
3446 Dart_ExitScope(); | |
3447 } | |
3448 } | 2977 } |
3449 | 2978 |
3450 | 2979 |
3451 TEST_CASE(ImplicitReferencesNewSpace) { | 2980 TEST_CASE(ImplicitReferencesNewSpace) { |
3452 Dart_PersistentHandle strong = NULL; | 2981 Dart_PersistentHandle strong = NULL; |
3453 Dart_WeakPersistentHandle strong_weak = NULL; | 2982 Dart_WeakPersistentHandle strong_weak = NULL; |
3454 | 2983 |
3455 | 2984 |
3456 Dart_EnterScope(); | 2985 Dart_EnterScope(); |
3457 { | 2986 { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3501 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | 3030 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); |
3502 | 3031 |
3503 { | 3032 { |
3504 Dart_EnterScope(); | 3033 Dart_EnterScope(); |
3505 // Old space collection should not affect old space objects. | 3034 // Old space collection should not affect old space objects. |
3506 EXPECT(!Dart_IsNull(AsHandle(weak1))); | 3035 EXPECT(!Dart_IsNull(AsHandle(weak1))); |
3507 EXPECT(!Dart_IsNull(AsHandle(weak2))); | 3036 EXPECT(!Dart_IsNull(AsHandle(weak2))); |
3508 EXPECT(!Dart_IsNull(AsHandle(weak3))); | 3037 EXPECT(!Dart_IsNull(AsHandle(weak3))); |
3509 Dart_ExitScope(); | 3038 Dart_ExitScope(); |
3510 } | 3039 } |
3511 | |
3512 // A strongly referenced key should preserve all the values. | |
3513 { | |
3514 Dart_WeakReferenceSetBuilder builder = Dart_NewWeakReferenceSetBuilder(); | |
3515 EXPECT_NOTNULL(builder); | |
3516 | |
3517 Dart_WeakReferenceSet set = | |
3518 Dart_NewWeakReferenceSet(builder, strong_weak, 0); | |
3519 EXPECT_NOTNULL(set); | |
3520 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak1)); | |
3521 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak2)); | |
3522 EXPECT_VALID(Dart_AppendValueToWeakReferenceSet(set, weak3)); | |
3523 | |
3524 GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks); | |
3525 } | |
3526 | |
3527 { | |
3528 Dart_EnterScope(); | |
3529 // All weak references should be preserved. | |
3530 EXPECT(!Dart_IsNull(AsHandle(weak1))); | |
3531 EXPECT(!Dart_IsNull(AsHandle(weak2))); | |
3532 EXPECT(!Dart_IsNull(AsHandle(weak3))); | |
3533 Dart_ExitScope(); | |
3534 } | |
3535 | |
3536 GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks); | |
3537 | |
3538 { | |
3539 Dart_EnterScope(); | |
3540 // No weak references should be preserved. | |
3541 EXPECT(weak1 == NULL); | |
3542 EXPECT(weak2 == NULL); | |
3543 EXPECT(weak3 == NULL); | |
3544 Dart_ExitScope(); | |
3545 } | |
3546 } | 3040 } |
3547 | 3041 |
3548 | 3042 |
3549 static int global_prologue_callback_status; | 3043 static int global_prologue_callback_status; |
3550 | 3044 |
3551 | 3045 |
3552 static void PrologueCallbackTimes2() { | 3046 static void PrologueCallbackTimes2() { |
3553 global_prologue_callback_status *= 2; | 3047 global_prologue_callback_status *= 2; |
3554 } | 3048 } |
3555 | 3049 |
(...skipping 6287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9843 | 9337 |
9844 // Heartbeat test for new events. | 9338 // Heartbeat test for new events. |
9845 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); | 9339 EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer); |
9846 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); | 9340 EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer); |
9847 | 9341 |
9848 // Free buffer allocated by AppendStreamConsumer | 9342 // Free buffer allocated by AppendStreamConsumer |
9849 free(data.buffer); | 9343 free(data.buffer); |
9850 } | 9344 } |
9851 | 9345 |
9852 } // namespace dart | 9346 } // namespace dart |
OLD | NEW |