| 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 |