Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c0d92b2

Browse files
make observer less complex
1 parent a954662 commit c0d92b2

File tree

3 files changed

+81
-187
lines changed

3 files changed

+81
-187
lines changed

‎Zend/zend_alloc.c‎

Lines changed: 77 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
* with more specialized routines when the requested size is known.
5252
*/
5353

54-
#include "php.h"
5554
#include "zend.h"
5655
#include "zend_alloc.h"
5756
#include "zend_globals.h"
@@ -200,6 +199,13 @@ typedef struct _zend_mm_huge_list zend_mm_huge_list;
200199

201200
static bool zend_mm_use_huge_pages = false;
202201

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+
203209
/*
204210
* Memory is retrieved from OS by chunks of fixed size 2MB.
205211
* Inside chunk it's managed by pages of fixed size 4096B.
@@ -231,23 +237,6 @@ static bool zend_mm_use_huge_pages = false;
231237
* (5 bits) bin number (e.g. 0 for sizes 0-2, 1 for 3-4,
232238
* 2 for 5-8, 3 for 9-16 etc) see zend_alloc_sizes.h
233239
*/
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-
251240
struct _zend_mm_heap {
252241
#if ZEND_MM_CUSTOM
253242
int use_custom_heap; /* bitflag */
@@ -295,7 +284,7 @@ struct _zend_mm_heap {
295284
} debug;
296285
} custom_heap;
297286
HashTable *tracked_allocs;
298-
zend_mm_heap_observer *observers;
287+
zend_mm_observer *observers;
299288
#endif
300289
};
301290

@@ -1957,7 +1946,6 @@ static zend_mm_heap *zend_mm_init(void)
19571946
#if ZEND_MM_CUSTOM
19581947
heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE;
19591948
heap->observers = NULL;
1960-
zend_mm_observers_startup(heap);
19611949
#endif
19621950
#if ZEND_MM_STORAGE
19631951
heap->storage = NULL;
@@ -2500,10 +2488,10 @@ static ZEND_COLD void* ZEND_FASTCALL _malloc_custom(size_t size ZEND_FILE_LINE_D
25002488
ptr = zend_mm_alloc_heap(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
25012489
}
25022490
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED) {
2503-
zend_mm_heap_observer *current = heap->observers;
2491+
zend_mm_observer *current = heap->observers;
25042492
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);
25072495
}
25082496
current = current->next;
25092497
}
@@ -2517,10 +2505,10 @@ static ZEND_COLD void ZEND_FASTCALL _efree_custom(void *ptr ZEND_FILE_LINE_DC ZE
25172505
int use_custom_heap = heap->use_custom_heap;
25182506

25192507
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED) {
2520-
zend_mm_heap_observer *current = heap->observers;
2508+
zend_mm_observer *current = heap->observers;
25212509
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);
25242512
}
25252513
current = current->next;
25262514
}
@@ -2550,10 +2538,10 @@ static ZEND_COLD void* ZEND_FASTCALL _realloc_custom(void *ptr, size_t size ZEND
25502538
new_ptr = zend_mm_realloc_heap(AG(mm_heap), ptr, size, 0, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
25512539
}
25522540
if (use_custom_heap & ZEND_MM_CUSTOM_HEAP_OBSERVED) {
2553-
zend_mm_heap_observer *current = heap->observers;
2541+
zend_mm_observer *current = heap->observers;
25542542
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);
25572545
}
25582546
current = current->next;
25592547
}
@@ -2977,7 +2965,6 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
29772965
mm_heap->tracked_allocs = malloc(sizeof(HashTable));
29782966
zend_hash_init(mm_heap->tracked_allocs, 1024, NULL, NULL, 1);
29792967
}
2980-
zend_mm_observers_startup(mm_heap);
29812968
return;
29822969
}
29832970
#endif
@@ -3036,10 +3023,13 @@ ZEND_API bool zend_mm_is_custom_heap(zend_mm_heap *new_heap)
30363023
#endif
30373024
}
30383025

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)
30403027
{
30413028
#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;
30433033
#else
30443034
return false;
30453035
#endif
@@ -3092,199 +3082,111 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
30923082
}
30933083

30943084
/*
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.
3086+
* This function operates on the thread local heap and is meant to be called in
3087+
* RINIT. Calling it in MINIT works only in NTS builds, but not in ZTS.
31003088
*/
31013089
ZEND_API zend_mm_observer* zend_mm_observer_register(
3090+
zend_mm_heap* heap,
31023091
void (*malloc)(size_t, void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
31033092
void (*free)(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
31043093
void (*realloc)(void *, size_t, void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
31053094
) {
31063095
#if ZEND_MM_CUSTOM
3096+
if (!heap && !(heap = AG(mm_heap))) {
3097+
return false;
3098+
}
3099+
31073100
zend_mm_observer *node = pemalloc(sizeof(zend_mm_observer), 1);
31083101
node->malloc = malloc;
31093102
node->free = free;
31103103
node->realloc = realloc;
31113104
node->next = NULL;
3112-
if (zend_mm_observers == NULL) {
3113-
zend_mm_observers = node;
3114-
return zend_mm_observers;
3105+
3106+
// set bitflag for observers being around
3107+
heap->use_custom_heap |= ZEND_MM_CUSTOM_HEAP_OBSERVED;
3108+
3109+
if (heap->observers == NULL) {
3110+
heap->observers = node;
3111+
return node;
31153112
}
3116-
zend_mm_observer *current = zend_mm_observers;
3113+
zend_mm_observer *current = heap->observers;
31173114
while (current->next != NULL) {
31183115
current = current->next;
31193116
}
31203117
current->next = node;
3118+
31213119
return node;
31223120
#else
31233121
return NULL;
31243122
#endif
31253123
}
31263124

31273125
/*
3128-
* This function will activate the global registered observers for the current
3129-
* heap. After this has been run, observering functions will be called.
3126+
* Use this function to unregister your observer at any given time. In case your
3127+
* observer was the last one to be unregistered, this will also reset the
3128+
* `heap->use_custom_heap` bitflag.
31303129
*/
3131-
voidzend_mm_observers_startup(zend_mm_heap *heap)
3130+
ZEND_APIboolzend_mm_observer_unregister(zend_mm_heap *heap, zend_mm_observer*observer)
31323131
{
31333132
#if ZEND_MM_CUSTOM
3134-
if (heap == NULL) {
3135-
heap = AG(mm_heap);
3136-
}
3137-
zend_mm_observer *current_observer = zend_mm_observers;
3138-
if (current_observer == NULL) {
3139-
// no observers installed
3140-
return;
3133+
if (!heap && !(heap = AG(mm_heap))) {
3134+
return false;
31413135
}
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;
3136+
3137+
zend_mm_observer *current = heap->observers, *prev = NULL;
3138+
3139+
if (current == observer) {
3140+
heap->observers = observer->next;
3141+
pefree(observer, 1);
3142+
if (!heap->observers)
3143+
{
3144+
// this was the one and only installed observer
3145+
heap->use_custom_heap &= ~ZEND_MM_CUSTOM_HEAP_OBSERVED;
31543146
}
3155-
current_heap_observer = node;
3156-
current_observer = current_observer->next;
3147+
return true;
31573148
}
3158-
// set bitflag for observers being around
3159-
heap->use_custom_heap |= ZEND_MM_CUSTOM_HEAP_OBSERVED;
3149+
3150+
while (current != NULL && current != observer) {
3151+
prev = current;
3152+
current = current->next;
3153+
}
3154+
3155+
// did not find observer or NULL was given
3156+
if (current == NULL)
3157+
return false;
3158+
3159+
prev->next = current->next;
3160+
pefree(observer, 1);
3161+
return true;
3162+
#else
3163+
return false;
31603164
#endif
31613165
}
31623166

31633167
/*
31643168
* This function will shutdown the observers for the current heap and free
3165-
* global structures. This will be called before PHP module shutdown phase.
3169+
* memory
31663170
*/
31673171
void zend_mm_observers_shutdown(zend_mm_heap *heap)
31683172
{
31693173
#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;
3174+
if (!heap && !(heap = AG(mm_heap))) {
3175+
return;
31823176
}
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;
3177+
zend_mm_observer *current = heap->observers;
31923178
zend_mm_observer *next = NULL;
31933179
while (current != NULL) {
31943180
next = current->next;
31953181
pefree(current, 1);
31963182
current = next;
31973183
}
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-
}
3184+
heap->observers = NULL;
32293185
heap->use_custom_heap &= ~ZEND_MM_CUSTOM_HEAP_OBSERVED;
3186+
return;
32303187
#endif
32313188
}
32323189

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-
32883190
#if ZEND_DEBUG
32893191
ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap,
32903192
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /