This source file includes following definitions.
- zend_objects_store_init
- zend_objects_store_destroy
- zend_objects_store_call_destructors
- zend_objects_store_mark_destructed
- zend_objects_store_free_object_storage
- zend_objects_store_put
- zend_objects_store_free
- zend_objects_store_del
- zend_object_store_set_object
- zend_object_store_ctor_failed
- zend_get_std_object_handlers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include "zend.h"
24 #include "zend_globals.h"
25 #include "zend_variables.h"
26 #include "zend_API.h"
27 #include "zend_objects_API.h"
28
29 ZEND_API void zend_objects_store_init(zend_objects_store *objects, uint32_t init_size)
30 {
31 objects->object_buckets = (zend_object **) emalloc(init_size * sizeof(zend_object*));
32 objects->top = 1;
33 objects->size = init_size;
34 objects->free_list_head = -1;
35 memset(&objects->object_buckets[0], 0, sizeof(zend_object*));
36 }
37
38 ZEND_API void zend_objects_store_destroy(zend_objects_store *objects)
39 {
40 efree(objects->object_buckets);
41 objects->object_buckets = NULL;
42 }
43
44 ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects)
45 {
46 if (objects->top > 1) {
47 zend_object **obj_ptr = objects->object_buckets + 1;
48 zend_object **end = objects->object_buckets + objects->top;
49
50 do {
51 zend_object *obj = *obj_ptr;
52
53 if (IS_OBJ_VALID(obj)) {
54 if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
55 GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
56 GC_REFCOUNT(obj)++;
57 obj->handlers->dtor_obj(obj);
58 GC_REFCOUNT(obj)--;
59 }
60 }
61 obj_ptr++;
62 } while (obj_ptr != end);
63 }
64 }
65
66 ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects)
67 {
68 if (objects->object_buckets && objects->top > 1) {
69 zend_object **obj_ptr = objects->object_buckets + 1;
70 zend_object **end = objects->object_buckets + objects->top;
71
72 do {
73 zend_object *obj = *obj_ptr;
74
75 if (IS_OBJ_VALID(obj)) {
76 GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
77 }
78 obj_ptr++;
79 } while (obj_ptr != end);
80 }
81 }
82
83 ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects)
84 {
85 zend_object **obj_ptr, **end, *obj;
86
87 if (objects->top <= 1) {
88 return;
89 }
90
91
92 end = objects->object_buckets + 1;
93 obj_ptr = objects->object_buckets + objects->top;
94
95 do {
96 obj_ptr--;
97 obj = *obj_ptr;
98 if (IS_OBJ_VALID(obj)) {
99 if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
100 GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
101 if (obj->handlers->free_obj) {
102 GC_REFCOUNT(obj)++;
103 obj->handlers->free_obj(obj);
104 GC_REFCOUNT(obj)--;
105 }
106 }
107 }
108 } while (obj_ptr != end);
109 }
110
111
112
113
114 ZEND_API void zend_objects_store_put(zend_object *object)
115 {
116 int handle;
117
118 if (EG(objects_store).free_list_head != -1) {
119 handle = EG(objects_store).free_list_head;
120 EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
121 } else {
122 if (EG(objects_store).top == EG(objects_store).size) {
123 EG(objects_store).size <<= 1;
124 EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, EG(objects_store).size * sizeof(zend_object*));
125 }
126 handle = EG(objects_store).top++;
127 }
128 object->handle = handle;
129 EG(objects_store).object_buckets[handle] = object;
130 }
131
132 #define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle) \
133 SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle], EG(objects_store).free_list_head); \
134 EG(objects_store).free_list_head = handle;
135
136 ZEND_API void zend_objects_store_free(zend_object *object)
137 {
138 uint32_t handle = object->handle;
139 void *ptr = ((char*)object) - object->handlers->offset;
140
141 GC_REMOVE_FROM_BUFFER(object);
142 efree(ptr);
143 ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle);
144 }
145
146
147 ZEND_API void zend_objects_store_del(zend_object *object)
148 {
149
150
151
152
153 if (EG(objects_store).object_buckets &&
154 IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle])) {
155 if (GC_REFCOUNT(object) == 0) {
156 int failure = 0;
157
158 if (!(GC_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
159 GC_FLAGS(object) |= IS_OBJ_DESTRUCTOR_CALLED;
160
161 if (object->handlers->dtor_obj) {
162 GC_REFCOUNT(object)++;
163 zend_try {
164 object->handlers->dtor_obj(object);
165 } zend_catch {
166 failure = 1;
167 } zend_end_try();
168 GC_REFCOUNT(object)--;
169 }
170 }
171
172 if (GC_REFCOUNT(object) == 0) {
173 uint32_t handle = object->handle;
174 void *ptr;
175
176 EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
177 if (!(GC_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
178 GC_FLAGS(object) |= IS_OBJ_FREE_CALLED;
179 if (object->handlers->free_obj) {
180 zend_try {
181 GC_REFCOUNT(object)++;
182 object->handlers->free_obj(object);
183 GC_REFCOUNT(object)--;
184 } zend_catch {
185 failure = 1;
186 } zend_end_try();
187 }
188 }
189 ptr = ((char*)object) - object->handlers->offset;
190 GC_REMOVE_FROM_BUFFER(object);
191 efree(ptr);
192 ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle);
193 }
194
195 if (failure) {
196 zend_bailout();
197 }
198 } else {
199 GC_REFCOUNT(object)--;
200 }
201 }
202 }
203
204
205
206
207
208
209
210
211
212 ZEND_API void zend_object_store_set_object(zval *zobject, zend_object *object)
213 {
214 EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)] = object;
215 }
216
217
218 ZEND_API void zend_object_store_ctor_failed(zend_object *obj)
219 {
220 GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
221 }
222
223 ZEND_API zend_object_handlers *zend_get_std_object_handlers(void)
224 {
225 return &std_object_handlers;
226 }
227
228
229
230
231
232
233
234