51
51
* with more specialized routines when the requested size is known.
52
52
*/
53
53
54
- #include "php.h"
55
54
#include "zend.h"
56
55
#include "zend_alloc.h"
57
56
#include "zend_globals.h"
@@ -200,6 +199,13 @@ typedef struct _zend_mm_huge_list zend_mm_huge_list;
200
199
201
200
static bool zend_mm_use_huge_pages = false;
202
201
202
+ struct _zend_mm_observer {
203
+ void (* malloc )(size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
204
+ void (* free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
205
+ void (* realloc )(void * , size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
206
+ zend_mm_observer * next ;
207
+ };
208
+
203
209
/*
204
210
* Memory is retrieved from OS by chunks of fixed size 2MB.
205
211
* Inside chunk it's managed by pages of fixed size 4096B.
@@ -231,23 +237,6 @@ static bool zend_mm_use_huge_pages = false;
231
237
* (5 bits) bin number (e.g. 0 for sizes 0-2, 1 for 3-4,
232
238
* 2 for 5-8, 3 for 9-16 etc) see zend_alloc_sizes.h
233
239
*/
234
-
235
-
236
- struct _zend_mm_observer {
237
- void (* malloc )(size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
238
- void (* free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
239
- void (* realloc )(void * , size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
240
- zend_mm_observer * next ;
241
- };
242
- zend_mm_observer * zend_mm_observers = NULL ;
243
-
244
- typedef struct _zend_mm_heap_observer zend_mm_heap_observer ;
245
- struct _zend_mm_heap_observer {
246
- zend_mm_observer * observer ;
247
- bool enabled ;
248
- zend_mm_heap_observer * next ;
249
- };
250
-
251
240
struct _zend_mm_heap {
252
241
#if ZEND_MM_CUSTOM
253
242
int use_custom_heap ; /* bitflag */
@@ -295,7 +284,7 @@ struct _zend_mm_heap {
295
284
} debug ;
296
285
} custom_heap ;
297
286
HashTable * tracked_allocs ;
298
- zend_mm_heap_observer * observers ;
287
+ zend_mm_observer * observers ;
299
288
#endif
300
289
};
301
290
@@ -1957,7 +1946,6 @@ static zend_mm_heap *zend_mm_init(void)
1957
1946
#if ZEND_MM_CUSTOM
1958
1947
heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE ;
1959
1948
heap -> observers = NULL ;
1960
- zend_mm_observers_startup (heap );
1961
1949
#endif
1962
1950
#if ZEND_MM_STORAGE
1963
1951
heap -> storage = NULL ;
@@ -2500,10 +2488,10 @@ static ZEND_COLD void* ZEND_FASTCALL _malloc_custom(size_t size ZEND_FILE_LINE_D
2500
2488
ptr = zend_mm_alloc_heap (AG (mm_heap ), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2501
2489
}
2502
2490
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED ) {
2503
- zend_mm_heap_observer * current = heap -> observers ;
2491
+ zend_mm_observer * current = heap -> observers ;
2504
2492
while (current != NULL ) {
2505
- if (current -> enabled && current -> observer != NULL && current -> observer -> malloc != NULL ) {
2506
- current -> observer -> malloc (size , ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2493
+ if (current -> malloc != NULL ) {
2494
+ current -> malloc (size , ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2507
2495
}
2508
2496
current = current -> next ;
2509
2497
}
@@ -2517,10 +2505,10 @@ static ZEND_COLD void ZEND_FASTCALL _efree_custom(void *ptr ZEND_FILE_LINE_DC ZE
2517
2505
int use_custom_heap = heap -> use_custom_heap ;
2518
2506
2519
2507
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED ) {
2520
- zend_mm_heap_observer * current = heap -> observers ;
2508
+ zend_mm_observer * current = heap -> observers ;
2521
2509
while (current != NULL ) {
2522
- if (current -> enabled && current -> observer != NULL && current -> observer -> free != NULL ) {
2523
- current -> observer -> free (ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2510
+ if (current -> free != NULL ) {
2511
+ current -> free (ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2524
2512
}
2525
2513
current = current -> next ;
2526
2514
}
@@ -2550,10 +2538,10 @@ static ZEND_COLD void* ZEND_FASTCALL _realloc_custom(void *ptr, size_t size ZEND
2550
2538
new_ptr = zend_mm_realloc_heap (AG (mm_heap ), ptr , size , 0 , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2551
2539
}
2552
2540
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED ) {
2553
- zend_mm_heap_observer * current = heap -> observers ;
2541
+ zend_mm_observer * current = heap -> observers ;
2554
2542
while (current != NULL ) {
2555
- if (current -> enabled && current -> observer != NULL && current -> observer -> realloc != NULL ) {
2556
- current -> observer -> realloc (ptr , size , new_ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2543
+ if (current -> realloc != NULL ) {
2544
+ current -> realloc (ptr , size , new_ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2557
2545
}
2558
2546
current = current -> next ;
2559
2547
}
@@ -2977,7 +2965,6 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
2977
2965
mm_heap -> tracked_allocs = malloc (sizeof (HashTable ));
2978
2966
zend_hash_init (mm_heap -> tracked_allocs , 1024 , NULL , NULL , 1 );
2979
2967
}
2980
- zend_mm_observers_startup (mm_heap );
2981
2968
return ;
2982
2969
}
2983
2970
#endif
@@ -3036,10 +3023,13 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
3036
3023
#endif
3037
3024
}
3038
3025
3039
- ZEND_API bool zend_mm_is_observed (zend_mm_heap * new_heap )
3026
+ ZEND_API bool zend_mm_is_observed (zend_mm_heap * heap )
3040
3027
{
3041
3028
#if ZEND_MM_CUSTOM
3042
- return (AG (mm_heap )-> use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED ) != 0 ;
3029
+ if (!heap && !(heap = AG (mm_heap ))) {
3030
+ return false;
3031
+ }
3032
+ return (heap -> use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED ) != 0 ;
3043
3033
#else
3044
3034
return false;
3045
3035
#endif
@@ -3092,199 +3082,101 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3092
3082
}
3093
3083
3094
3084
/*
3095
- * Use this function to register observers to the ZendMM. Make sure to call this
3096
- * function only during PHP module startup phase and not later. Observers will
3097
- * not be called directly after registering them, but only after
3098
- * `zend_mm_observers_startup()` was run, which will take place after the PHP
3099
- * module startup phase.
3085
+ * Use this function to register observers to the ZendMM.
3100
3086
*/
3101
3087
ZEND_API zend_mm_observer * zend_mm_observer_register (
3088
+ zend_mm_heap * heap ,
3102
3089
void (* malloc )(size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC ),
3103
3090
void (* free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC ),
3104
3091
void (* realloc )(void * , size_t , void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC )
3105
3092
) {
3106
3093
#if ZEND_MM_CUSTOM
3094
+ if (!heap && !(heap = AG (mm_heap ))) {
3095
+ return false;
3096
+ }
3097
+
3107
3098
zend_mm_observer * node = pemalloc (sizeof (zend_mm_observer ), 1 );
3108
3099
node -> malloc = malloc ;
3109
3100
node -> free = free ;
3110
3101
node -> realloc = realloc ;
3111
3102
node -> next = NULL ;
3112
- if (zend_mm_observers == NULL ) {
3113
- zend_mm_observers = node ;
3114
- return zend_mm_observers ;
3103
+
3104
+ // set bitflag for observers being around
3105
+ heap -> use_custom_heap |= ZEND_MM_CUSTOM_HEAP_OBSERVED ;
3106
+
3107
+ if (heap -> observers == NULL ) {
3108
+ heap -> observers = node ;
3109
+ return node ;
3115
3110
}
3116
- zend_mm_observer * current = zend_mm_observers ;
3111
+ zend_mm_observer * current = heap -> observers ;
3117
3112
while (current -> next != NULL ) {
3118
3113
current = current -> next ;
3119
3114
}
3120
3115
current -> next = node ;
3116
+
3121
3117
return node ;
3122
3118
#else
3123
3119
return NULL ;
3124
3120
#endif
3125
3121
}
3126
3122
3127
- /*
3128
- * This function will activate the global registered observers for the current
3129
- * heap. After this has been run, observering functions will be called.
3130
- */
3131
- void zend_mm_observers_startup (zend_mm_heap * heap )
3123
+ ZEND_API bool zend_mm_observer_unregister (zend_mm_heap * heap , zend_mm_observer * observer )
3132
3124
{
3133
3125
#if ZEND_MM_CUSTOM
3134
- if (heap == NULL ) {
3135
- heap = AG ( mm_heap ) ;
3126
+ if (! heap && !( heap = AG ( mm_heap )) ) {
3127
+ return false ;
3136
3128
}
3137
- zend_mm_observer * current_observer = zend_mm_observers ;
3138
- if (current_observer == NULL ) {
3139
- // no observers installed
3140
- return ;
3129
+
3130
+ zend_mm_observer * current = heap -> observers , * prev = NULL ;
3131
+
3132
+ if (current == observer ) {
3133
+ heap -> observers = observer -> next ;
3134
+ pefree (observer , 1 );
3135
+ // this was the one and only installed observer
3136
+ heap -> use_custom_heap &= ~ZEND_MM_CUSTOM_HEAP_OBSERVED ;
3137
+ return true;
3141
3138
}
3142
- // copy observers into heap
3143
- zend_mm_heap_observer * node = NULL ;
3144
- zend_mm_heap_observer * current_heap_observer = NULL ;
3145
- while (current_observer != NULL ) {
3146
- node = pemalloc (sizeof (zend_mm_heap_observer ), 1 );
3147
- node -> observer = current_observer ;
3148
- node -> enabled = true;
3149
- node -> next = NULL ;
3150
- if (current_heap_observer == NULL ) {
3151
- heap -> observers = node ;
3152
- } else {
3153
- current_heap_observer -> next = node ;
3154
- }
3155
- current_heap_observer = node ;
3156
- current_observer = current_observer -> next ;
3139
+
3140
+ while (current != NULL && current != observer ) {
3141
+ prev = current ;
3142
+ current = current -> next ;
3157
3143
}
3158
- // set bitflag for observers being around
3159
- heap -> use_custom_heap |= ZEND_MM_CUSTOM_HEAP_OBSERVED ;
3144
+
3145
+ // did not find observer or NULL was given
3146
+ if (current == NULL )
3147
+ return false;
3148
+
3149
+ prev -> next = current -> next ;
3150
+ pefree (observer , 1 );
3151
+ return true;
3152
+ #else
3153
+ return false;
3160
3154
#endif
3161
3155
}
3162
3156
3163
3157
/*
3164
3158
* This function will shutdown the observers for the current heap and free
3165
- * global structures. This will be called before PHP module shutdown phase.
3159
+ * memory
3166
3160
*/
3167
3161
void zend_mm_observers_shutdown (zend_mm_heap * heap )
3168
3162
{
3169
3163
#if ZEND_MM_CUSTOM
3170
- if (heap == NULL ) {
3171
- heap = AG (mm_heap );
3172
- if (heap == NULL ) {
3173
- return ;
3174
- }
3175
- }
3176
- zend_mm_heap_observer * current_heap_observer = heap -> observers ;
3177
- zend_mm_heap_observer * next_heap_observer = NULL ;
3178
- while (current_heap_observer != NULL ) {
3179
- next_heap_observer = current_heap_observer -> next ;
3180
- pefree (current_heap_observer , 1 );
3181
- current_heap_observer = next_heap_observer ;
3164
+ if (!heap && !(heap = AG (mm_heap ))) {
3165
+ return ;
3182
3166
}
3183
- heap -> observers = NULL ;
3184
- return ;
3185
- #endif
3186
- }
3187
-
3188
- void zend_mm_observers_unregister (void )
3189
- {
3190
- #if ZEND_MM_CUSTOM
3191
- zend_mm_observer * current = zend_mm_observers ;
3167
+ zend_mm_observer * current = heap -> observers ;
3192
3168
zend_mm_observer * next = NULL ;
3193
3169
while (current != NULL ) {
3194
3170
next = current -> next ;
3195
3171
pefree (current , 1 );
3196
3172
current = next ;
3197
3173
}
3198
- zend_mm_observers = NULL ;
3199
- #endif
3200
- }
3201
-
3202
- /*
3203
- * This internal function will check if there are still enabled observer on the
3204
- * heap. In case there are, it will set the `ZEND_MM_CUSTOM_HEAP_OBSERVED` flag
3205
- * otherwise it will unset the flag.
3206
- */
3207
- void zend_mm_observer_sync_flag (bool enabled_observer ) {
3208
- #if ZEND_MM_CUSTOM
3209
- zend_mm_heap * heap = AG (mm_heap );
3210
- if (heap == NULL ) {
3211
- return ;
3212
- }
3213
- if (enabled_observer ) {
3214
- // When an observer was enabled, we don't need to find if there were
3215
- // enabled observers
3216
- heap -> use_custom_heap |= ZEND_MM_CUSTOM_HEAP_OBSERVED ;
3217
- return ;
3218
- }
3219
- // An observer got disabled, so we need to check if there are still enabled
3220
- // observers left in the list
3221
- zend_mm_heap_observer * current = heap -> observers ;
3222
- while (current != NULL ) {
3223
- if (current -> enabled == true) {
3224
- // in case we find an enabled observer there is nothing to do
3225
- return ;
3226
- }
3227
- current = current -> next ;
3228
- }
3174
+ heap -> observers = NULL ;
3229
3175
heap -> use_custom_heap &= ~ZEND_MM_CUSTOM_HEAP_OBSERVED ;
3176
+ return ;
3230
3177
#endif
3231
3178
}
3232
3179
3233
- zend_mm_heap_observer * zend_mm_observer_find_heap_observer (zend_mm_heap * heap , zend_mm_observer * node ) {
3234
- if (heap == NULL ) {
3235
- heap = AG (mm_heap );
3236
- if (heap == NULL ) {
3237
- return NULL ;
3238
- }
3239
- }
3240
- zend_mm_heap_observer * current = heap -> observers ;
3241
- while (current != NULL ) {
3242
- if (current -> observer == node ) {
3243
- return current ;
3244
- }
3245
- current = current -> next ;
3246
- }
3247
- return NULL ;
3248
- }
3249
-
3250
- ZEND_API bool zend_mm_observer_enabled (zend_mm_heap * heap , zend_mm_observer * node ) {
3251
- #if ZEND_MM_CUSTOM
3252
- zend_mm_heap_observer * heap_observer = zend_mm_observer_find_heap_observer (heap , node );
3253
- if (heap_observer == NULL ) {
3254
- return false;
3255
- }
3256
- return heap_observer -> enabled ;
3257
- #endif
3258
- return false;
3259
- }
3260
-
3261
- ZEND_API bool zend_mm_observer_set_state (zend_mm_heap * heap , zend_mm_observer * node , bool state ) {
3262
- #if ZEND_MM_CUSTOM
3263
- zend_mm_heap_observer * heap_observer = zend_mm_observer_find_heap_observer (heap , node );
3264
- if (heap_observer == NULL ) {
3265
- false;
3266
- }
3267
- heap_observer -> enabled = state ;
3268
- zend_mm_observer_sync_flag (state );
3269
- return true;
3270
- #endif
3271
- return false;
3272
- }
3273
-
3274
- ZEND_API bool zend_mm_observer_enable (zend_mm_heap * heap , zend_mm_observer * node ) {
3275
- #if ZEND_MM_CUSTOM
3276
- return zend_mm_observer_set_state (heap , node , true);
3277
- #endif
3278
- return false;
3279
- }
3280
-
3281
- ZEND_API bool zend_mm_observer_disable (zend_mm_heap * heap , zend_mm_observer * node ) {
3282
- #if ZEND_MM_CUSTOM
3283
- return zend_mm_observer_set_state (heap , node , false);
3284
- #endif
3285
- return false;
3286
- }
3287
-
3288
3180
#if ZEND_DEBUG
3289
3181
ZEND_API void zend_mm_set_custom_debug_handlers (zend_mm_heap * heap ,
3290
3182
void * (* _malloc )(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC ),
0 commit comments