Skip to content

Commit 33a4e1f

Browse files
committed
Merge branch 'master' into jit-dynasm
* master: Implemented a faster way to access predefined TSRM resources - CG(), EG(), etc. Integrate README.EXT_SKEL to help option test reversed Fix duplicate symbols _zend_ce_weakrefs [ci skip] Mention removed m4 macros Sync with ZEND_ENABLE_STATIC_TSRMLS_CACHE enablement in ext/mbstring
2 parents f8c9f47 + 2dd2dca commit 33a4e1f

34 files changed

+339
-135
lines changed

README.EXT_SKEL

Lines changed: 0 additions & 43 deletions
This file was deleted.

README.SELF-CONTAINED-EXTENSIONS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ CREATING SOURCE FILES
104104

105105
ext_skel can be of great help when creating the common code for all modules
106106
in PHP for you and also writing basic function definitions and C code for
107-
handling arguments passed to your functions. See README.EXT_SKEL for further
108-
information.
107+
handling arguments passed to your functions. See `./ext/ext_skel.php --help`
108+
for further information.
109109

110110
As for the rest, you are currently alone here. There are a lot of existing
111111
modules, use a simple module as a starting point and add your own code.

TSRM/TSRM.c

Lines changed: 120 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef struct {
3434
size_t size;
3535
ts_allocate_ctor ctor;
3636
ts_allocate_dtor dtor;
37+
size_t fast_offset;
3738
int done;
3839
} tsrm_resource_type;
3940

@@ -47,6 +48,9 @@ static ts_rsrc_id id_count;
4748
static tsrm_resource_type *resource_types_table=NULL;
4849
static int resource_types_table_size;
4950

51+
/* Reserved space for fast globals access */
52+
static size_t tsrm_reserved_pos = 0;
53+
static size_t tsrm_reserved_size = 0;
5054

5155
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
5256

@@ -160,6 +164,10 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
160164
tsmm_mutex = tsrm_mutex_alloc();
161165

162166
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
167+
168+
tsrm_reserved_pos = 0;
169+
tsrm_reserved_size = 0;
170+
163171
return 1;
164172
}/*}}}*/
165173

@@ -187,7 +195,9 @@ TSRM_API void tsrm_shutdown(void)
187195
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
188196
resource_types_table[j].dtor(p->storage[j]);
189197
}
190-
free(p->storage[j]);
198+
if (!resource_types_table[j].fast_offset) {
199+
free(p->storage[j]);
200+
}
191201
}
192202
}
193203
free(p->storage);
@@ -222,14 +232,46 @@ TSRM_API void tsrm_shutdown(void)
222232
tsrm_new_thread_begin_handler = NULL;
223233
tsrm_new_thread_end_handler = NULL;
224234
tsrm_shutdown_handler = NULL;
235+
236+
tsrm_reserved_pos = 0;
237+
tsrm_reserved_size = 0;
225238
}/*}}}*/
226239

227240

228-
/* allocates a new thread-safe-resource id */
229-
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
241+
/* enlarge the arrays for the already active threads */
242+
static void tsrm_update_active_threads(void)
230243
{/*{{{*/
231244
int i;
232245

246+
for (i=0; i<tsrm_tls_table_size; i++) {
247+
tsrm_tls_entry *p = tsrm_tls_table[i];
248+
249+
while (p) {
250+
if (p->count < id_count) {
251+
int j;
252+
253+
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
254+
for (j=p->count; j<id_count; j++) {
255+
if (resource_types_table[j].fast_offset) {
256+
p->storage[j] = (void *) (((char*)p) + resource_types_table[j].fast_offset);
257+
} else {
258+
p->storage[j] = (void *) malloc(resource_types_table[j].size);
259+
}
260+
if (resource_types_table[j].ctor) {
261+
resource_types_table[j].ctor(p->storage[j]);
262+
}
263+
}
264+
p->count = id_count;
265+
}
266+
p = p->next;
267+
}
268+
}
269+
}/*}}}*/
270+
271+
272+
/* allocates a new thread-safe-resource id */
273+
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
274+
{/*{{{*/
233275
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
234276

235277
tsrm_mutex_lock(tsmm_mutex);
@@ -254,28 +296,68 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
254296
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
255297
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
256298
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
299+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = 0;
257300
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
258301

259-
/* enlarge the arrays for the already active threads */
260-
for (i=0; i<tsrm_tls_table_size; i++) {
261-
tsrm_tls_entry *p = tsrm_tls_table[i];
302+
tsrm_update_active_threads();
303+
tsrm_mutex_unlock(tsmm_mutex);
262304

263-
while (p) {
264-
if (p->count < id_count) {
265-
int j;
305+
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
306+
return *rsrc_id;
307+
}/*}}}*/
266308

267-
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
268-
for (j=p->count; j<id_count; j++) {
269-
p->storage[j] = (void *) malloc(resource_types_table[j].size);
270-
if (resource_types_table[j].ctor) {
271-
resource_types_table[j].ctor(p->storage[j]);
272-
}
273-
}
274-
p->count = id_count;
275-
}
276-
p = p->next;
309+
310+
/* Reserve space for fast thread-safe-resources */
311+
TSRM_API void tsrm_reserve(size_t size)
312+
{/*{{{*/
313+
tsrm_reserved_pos = 0;
314+
tsrm_reserved_size = TSRM_ALIGNED_SIZE(size);
315+
}/*}}}*/
316+
317+
318+
/* allocates a new fast thread-safe-resource id */
319+
TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
320+
{/*{{{*/
321+
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new fast resource id, %d bytes", size));
322+
323+
tsrm_mutex_lock(tsmm_mutex);
324+
325+
/* obtain a resource id */
326+
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
327+
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
328+
329+
size = TSRM_ALIGNED_SIZE(size);
330+
if (tsrm_reserved_size - tsrm_reserved_pos < size) {
331+
tsrm_mutex_unlock(tsmm_mutex);
332+
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate space for fast resource"));
333+
*rsrc_id = 0;
334+
*offset = 0;
335+
return 0;
336+
}
337+
338+
*offset = TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_pos;
339+
tsrm_reserved_pos += size;
340+
341+
/* store the new resource type in the resource sizes table */
342+
if (resource_types_table_size < id_count) {
343+
tsrm_resource_type *_tmp;
344+
_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
345+
if (!_tmp) {
346+
tsrm_mutex_unlock(tsmm_mutex);
347+
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
348+
*rsrc_id = 0;
349+
return 0;
277350
}
351+
resource_types_table = _tmp;
352+
resource_types_table_size = id_count;
278353
}
354+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
355+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
356+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
357+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = *offset;
358+
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
359+
360+
tsrm_update_active_threads();
279361
tsrm_mutex_unlock(tsmm_mutex);
280362

281363
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
@@ -288,7 +370,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
288370
int i;
289371

290372
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
291-
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
373+
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_size);
292374
(*thread_resources_ptr)->storage = NULL;
293375
if (id_count > 0) {
294376
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
@@ -307,9 +389,12 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
307389
for (i=0; i<id_count; i++) {
308390
if (resource_types_table[i].done) {
309391
(*thread_resources_ptr)->storage[i] = NULL;
310-
} else
311-
{
312-
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
392+
} else {
393+
if (resource_types_table[i].fast_offset) {
394+
(*thread_resources_ptr)->storage[i] = (void *) (((char*)(*thread_resources_ptr)) + resource_types_table[i].fast_offset);
395+
} else {
396+
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
397+
}
313398
if (resource_types_table[i].ctor) {
314399
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
315400
}
@@ -402,7 +487,9 @@ void tsrm_free_interpreter_context(void *context)
402487
}
403488
}
404489
for (i=0; i<thread_resources->count; i++) {
405-
free(thread_resources->storage[i]);
490+
if (!resource_types_table[i].fast_offset) {
491+
free(thread_resources->storage[i]);
492+
}
406493
}
407494
free(thread_resources->storage);
408495
free(thread_resources);
@@ -467,7 +554,9 @@ void ts_free_thread(void)
467554
}
468555
}
469556
for (i=0; i<thread_resources->count; i++) {
470-
free(thread_resources->storage[i]);
557+
if (!resource_types_table[i].fast_offset) {
558+
free(thread_resources->storage[i]);
559+
}
471560
}
472561
free(thread_resources->storage);
473562
if (last) {
@@ -509,7 +598,9 @@ void ts_free_worker_threads(void)
509598
}
510599
}
511600
for (i=0; i<thread_resources->count; i++) {
512-
free(thread_resources->storage[i]);
601+
if (!resource_types_table[i].fast_offset) {
602+
free(thread_resources->storage[i]);
603+
}
513604
}
514605
free(thread_resources->storage);
515606
if (last) {
@@ -553,7 +644,9 @@ void ts_free_id(ts_rsrc_id id)
553644
if (resource_types_table && resource_types_table[j].dtor) {
554645
resource_types_table[j].dtor(p->storage[j]);
555646
}
556-
free(p->storage[j]);
647+
if (!resource_types_table[j].fast_offset) {
648+
free(p->storage[j]);
649+
}
557650
p->storage[j] = NULL;
558651
}
559652
p = p->next;

TSRM/TSRM.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ typedef uintptr_t tsrm_uintptr_t;
5757
#include <TLS.h>
5858
#endif
5959

60+
#if SIZEOF_SIZE_T == 4
61+
# define TSRM_ALIGNED_SIZE(size) \
62+
(((size) + INT32_C(15)) & ~INT32_C(15))
63+
#else
64+
# define TSRM_ALIGNED_SIZE(size) \
65+
(((size) + INT64_C(15)) & ~INT64_C(15))
66+
#endif
67+
6068
typedef int ts_rsrc_id;
6169

6270
/* Define THREAD_T and MUTEX_T */
@@ -94,6 +102,10 @@ TSRM_API void tsrm_shutdown(void);
94102
/* allocates a new thread-safe-resource id */
95103
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
96104

105+
/* Fast resource in reserved (pre-allocated) space */
106+
TSRM_API void tsrm_reserve(size_t size);
107+
TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
108+
97109
/* fetches the requested resource for the current thread */
98110
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
99111
#define ts_resource(id) ts_resource_ex(id, NULL)
@@ -162,9 +174,13 @@ TSRM_API const char *tsrm_api_name(void);
162174
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache()
163175
#define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element)
164176
#define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])
177+
#define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element)
178+
#define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset)))
165179

166180
#define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element)
167181
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
182+
#define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element)
183+
#define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset)))
168184
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
169185
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
170186
#if ZEND_DEBUG

UPGRADING

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ PHP 8.0 UPGRADE NOTES
5757

5858
// With
5959
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
60-
if (error_reporting() & $err_no) {
60+
if (!(error_reporting() & $err_no)) {
6161
return; // Silenced
6262
}
6363
// ...

Zend/zend.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ static size_t global_map_ptr_last = 0;
3838
#ifdef ZTS
3939
ZEND_API int compiler_globals_id;
4040
ZEND_API int executor_globals_id;
41+
ZEND_API size_t compiler_globals_offset;
42+
ZEND_API size_t executor_globals_offset;
4143
static HashTable *global_function_table = NULL;
4244
static HashTable *global_class_table = NULL;
4345
static HashTable *global_constants_table = NULL;
@@ -868,10 +870,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
868870
zend_init_rsrc_list_dtors();
869871

870872
#ifdef ZTS
871-
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
872-
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
873-
ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
874-
ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
873+
ts_allocate_fast_id(&compiler_globals_id, &compiler_globals_offset, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
874+
ts_allocate_fast_id(&executor_globals_id, &executor_globals_offset, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
875+
ts_allocate_fast_id(&language_scanner_globals_id, &language_scanner_globals_offset, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
876+
ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
875877
compiler_globals = ts_resource(compiler_globals_id);
876878
executor_globals = ts_resource(executor_globals_id);
877879

Zend/zend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@
5555

5656
#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
5757
#define ZEND_TSRMG TSRMG_STATIC
58+
#define ZEND_TSRMG_FAST TSRMG_FAST_STATIC
5859
#define ZEND_TSRMLS_CACHE_EXTERN() TSRMLS_CACHE_EXTERN()
5960
#define ZEND_TSRMLS_CACHE_DEFINE() TSRMLS_CACHE_DEFINE()
6061
#define ZEND_TSRMLS_CACHE_UPDATE() TSRMLS_CACHE_UPDATE()
6162
#define ZEND_TSRMLS_CACHE TSRMLS_CACHE
6263
#else
6364
#define ZEND_TSRMG TSRMG
65+
#define ZEND_TSRMG_FAST TSRMG_FAST
6466
#define ZEND_TSRMLS_CACHE_EXTERN()
6567
#define ZEND_TSRMLS_CACHE_DEFINE()
6668
#define ZEND_TSRMLS_CACHE_UPDATE()

0 commit comments

Comments
 (0)