Skip to content

Commit 7fbdae4

Browse files
committed
Make FFI type cache context senseive
1 parent 0e61fcf commit 7fbdae4

File tree

4 files changed

+75
-53
lines changed

4 files changed

+75
-53
lines changed

Zend/zend.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ ZEND_ATTRIBUTE_NONNULL ZEND_API void (*zend_random_bytes_insecure)(zend_random_b
9999

100100
ZEND_API zend_class_entry *zend_ffi_ce = NULL;
101101
ZEND_API zend_class_entry *zend_ffi_cdata_ce = NULL;
102-
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str) = NULL;
103-
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl) = NULL;
102+
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str, void *context) = NULL;
103+
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl, void *context) = NULL;
104104
ZEND_API zend_ffi_scope* (*zend_ffi_cache_scope_get)(zend_string *str) = NULL;
105105
ZEND_API zend_ffi_scope* (*zend_ffi_cache_scope_add)(zend_string *str, zend_ffi_scope *scope) = NULL;
106106

Zend/zend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,8 @@ extern ZEND_API zend_class_entry *zend_ffi_cdata_ce;
397397
typedef struct _zend_ffi_dcl zend_ffi_dcl;
398398
typedef struct _zend_ffi_scope zend_ffi_scope;
399399

400-
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str);
401-
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl);
400+
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str, void *context);
401+
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl, void *context);
402402
ZEND_API extern zend_ffi_scope* (*zend_ffi_cache_scope_get)(zend_string *str);
403403
ZEND_API extern zend_ffi_scope* (*zend_ffi_cache_scope_add)(zend_string *str, zend_ffi_scope *scope);
404404

ext/ffi/ffi.c

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,7 +3748,7 @@ ZEND_METHOD(FFI, new) /* {{{ */
37483748
FFI_G(default_type_attr) = 0;
37493749

37503750
if (zend_ffi_cache_type_get
3751-
&& (cached_dcl = zend_ffi_cache_type_get(type_def))) {
3751+
&& (cached_dcl = zend_ffi_cache_type_get(type_def, FFI_G(symbols)))) {
37523752
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
37533753
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
37543754
zend_ffi_type_dtor(dcl.type);
@@ -3767,23 +3767,24 @@ ZEND_METHOD(FFI, new) /* {{{ */
37673767
if (clean_tags && FFI_G(tags)) {
37683768
zend_ffi_tags_cleanup(&dcl);
37693769
}
3770-
if (clean_symbols && FFI_G(symbols)) {
3771-
zend_hash_destroy(FFI_G(symbols));
3772-
efree(FFI_G(symbols));
3773-
FFI_G(symbols) = NULL;
3774-
}
3775-
FFI_G(symbols) = NULL;
3776-
FFI_G(tags) = NULL;
37773770

37783771
if (zend_ffi_cache_type_add) {
3779-
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl);
3772+
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl, FFI_G(symbols));
37803773
if (cached_dcl) {
37813774
if (ZEND_FFI_TYPE_IS_OWNED(dcl.type)) {
37823775
_zend_ffi_type_dtor(dcl.type);
37833776
}
37843777
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
37853778
}
37863779
}
3780+
3781+
if (clean_symbols && FFI_G(symbols)) {
3782+
zend_hash_destroy(FFI_G(symbols));
3783+
efree(FFI_G(symbols));
3784+
FFI_G(symbols) = NULL;
3785+
}
3786+
FFI_G(symbols) = NULL;
3787+
FFI_G(tags) = NULL;
37873788
}
37883789

37893790
type = ZEND_FFI_TYPE(dcl.type);
@@ -3912,7 +3913,7 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39123913
FFI_G(default_type_attr) = 0;
39133914

39143915
if (zend_ffi_cache_type_get
3915-
&& (cached_dcl = zend_ffi_cache_type_get(type_def))) {
3916+
&& (cached_dcl = zend_ffi_cache_type_get(type_def, FFI_G(symbols)))) {
39163917
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
39173918
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
39183919
zend_ffi_type_dtor(dcl.type);
@@ -3931,23 +3932,24 @@ ZEND_METHOD(FFI, cast) /* {{{ */
39313932
if (clean_tags && FFI_G(tags)) {
39323933
zend_ffi_tags_cleanup(&dcl);
39333934
}
3934-
if (clean_symbols && FFI_G(symbols)) {
3935-
zend_hash_destroy(FFI_G(symbols));
3936-
efree(FFI_G(symbols));
3937-
FFI_G(symbols) = NULL;
3938-
}
3939-
FFI_G(symbols) = NULL;
3940-
FFI_G(tags) = NULL;
39413935

39423936
if (zend_ffi_cache_type_add) {
3943-
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl);
3937+
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl, FFI_G(symbols));
39443938
if (cached_dcl) {
39453939
if (ZEND_FFI_TYPE_IS_OWNED(dcl.type)) {
39463940
_zend_ffi_type_dtor(dcl.type);
39473941
}
39483942
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
39493943
}
39503944
}
3945+
3946+
if (clean_symbols && FFI_G(symbols)) {
3947+
zend_hash_destroy(FFI_G(symbols));
3948+
efree(FFI_G(symbols));
3949+
FFI_G(symbols) = NULL;
3950+
}
3951+
FFI_G(symbols) = NULL;
3952+
FFI_G(tags) = NULL;
39513953
}
39523954

39533955
type = ZEND_FFI_TYPE(dcl.type);
@@ -4098,7 +4100,7 @@ ZEND_METHOD(FFI, type) /* {{{ */
40984100
FFI_G(default_type_attr) = 0;
40994101

41004102
if (zend_ffi_cache_type_get
4101-
&& (cached_dcl = zend_ffi_cache_type_get(type_def))) {
4103+
&& (cached_dcl = zend_ffi_cache_type_get(type_def, FFI_G(symbols)))) {
41024104
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
41034105
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
41044106
zend_ffi_type_dtor(dcl.type);
@@ -4117,22 +4119,24 @@ ZEND_METHOD(FFI, type) /* {{{ */
41174119
if (clean_tags && FFI_G(tags)) {
41184120
zend_ffi_tags_cleanup(&dcl);
41194121
}
4120-
if (clean_symbols && FFI_G(symbols)) {
4121-
zend_hash_destroy(FFI_G(symbols));
4122-
efree(FFI_G(symbols));
4123-
FFI_G(symbols) = NULL;
4124-
}
4125-
FFI_G(symbols) = NULL;
4126-
FFI_G(tags) = NULL;
4122+
41274123
if (zend_ffi_cache_type_add) {
4128-
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl);
4124+
cached_dcl = zend_ffi_cache_type_add(type_def, &dcl, FFI_G(symbols));
41294125
if (cached_dcl) {
41304126
if (ZEND_FFI_TYPE_IS_OWNED(dcl.type)) {
41314127
_zend_ffi_type_dtor(dcl.type);
41324128
}
41334129
memcpy(&dcl, cached_dcl, sizeof(zend_ffi_dcl));
41344130
}
41354131
}
4132+
4133+
if (clean_symbols && FFI_G(symbols)) {
4134+
zend_hash_destroy(FFI_G(symbols));
4135+
efree(FFI_G(symbols));
4136+
FFI_G(symbols) = NULL;
4137+
}
4138+
FFI_G(symbols) = NULL;
4139+
FFI_G(tags) = NULL;
41364140
}
41374141

41384142
ctype = (zend_ffi_ctype*)zend_ffi_ctype_new(zend_ffi_ctype_ce);

ext/opcache/ZendAccelerator.c

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,6 +2464,14 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24642464
#if HAVE_FFI
24652465
#include "ext/ffi/php_ffi.h"
24662466

2467+
typedef struct _accel_ffi_cache_type_entry accel_ffi_cache_type_entry;
2468+
2469+
struct _accel_ffi_cache_type_entry {
2470+
accel_ffi_cache_type_entry *next;
2471+
void *context;
2472+
zend_ffi_dcl dcl;
2473+
};
2474+
24672475
static ssize_t accel_ffi_persist_type_calc(zend_ffi_type *type)
24682476
{
24692477
HashTable *ht;
@@ -2655,9 +2663,10 @@ static zend_ffi_type* accel_ffi_persist_type_copy(void** ptr, zend_ffi_type *typ
26552663
return new_type;
26562664
}
26572665

2658-
static zend_ffi_dcl* accel_ffi_persist_type(zend_ffi_dcl *dcl)
2666+
static accel_ffi_cache_type_entry* accel_ffi_persist_type(zend_ffi_dcl *dcl, void *context)
26592667
{
26602668
void *ptr;
2669+
accel_ffi_cache_type_entry *entry;
26612670
zend_ffi_dcl *new_dcl;
26622671
ssize_t size;
26632672

@@ -2668,59 +2677,68 @@ static zend_ffi_dcl* accel_ffi_persist_type(zend_ffi_dcl *dcl)
26682677
if (size == -1) {
26692678
return NULL;
26702679
}
2671-
ptr = zend_shared_alloc(sizeof(zend_ffi_dcl) + size);
2672-
if (!ptr) {
2680+
entry = zend_shared_alloc(sizeof(accel_ffi_cache_type_entry) + size);
2681+
if (!entry) {
26732682
return NULL;
26742683
}
26752684

26762685
zend_shared_alloc_init_xlat_table();
26772686

2678-
new_dcl = (zend_ffi_dcl*)ptr;
2679-
ptr = (void*)((char*)ptr + sizeof(zend_ffi_dcl));
2687+
entry->next = NULL;
2688+
entry->context = context;
2689+
new_dcl = &entry->dcl;
26802690
memcpy(new_dcl, dcl, sizeof(zend_ffi_dcl));
2691+
ptr = entry + 1;
26812692
new_dcl->type = accel_ffi_persist_type_copy(&ptr, new_dcl->type);
26822693

26832694
zend_shared_alloc_destroy_xlat_table();
26842695

2685-
return new_dcl;
2696+
return entry;
26862697
}
26872698

2688-
static zend_ffi_dcl* accel_ffi_cache_type_get(zend_string *str)
2699+
static zend_ffi_dcl* accel_ffi_cache_type_get(zend_string *str, void *context)
26892700
{
26902701
str = accel_find_interned_string(str);
26912702
if (str && (str->gc.u.type_info & IS_STR_FFI_TYPE)) {
26922703
// TODO: ???
2693-
zend_ffi_dcl *ptr = (zend_ffi_dcl*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2694-
return ptr;
2704+
accel_ffi_cache_type_entry *ptr =
2705+
(accel_ffi_cache_type_entry*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2706+
while (ptr && ptr->context != context) {
2707+
ptr = ptr->next;
2708+
}
2709+
if (ptr) {
2710+
return &ptr->dcl;
2711+
}
26952712
}
26962713
return NULL;
26972714
}
26982715

2699-
static zend_ffi_dcl* accel_ffi_cache_type_add(zend_string *str, zend_ffi_dcl *dcl)
2716+
static zend_ffi_dcl* accel_ffi_cache_type_add(zend_string *str, zend_ffi_dcl *dcl, void *context)
27002717
{
27012718
zend_ffi_dcl *new_dcl = NULL;
27022719

2703-
if (!ZEND_FFI_TYPE_IS_OWNED(dcl->type)
2704-
&& (dcl->type->attr & ZEND_FFI_ATTR_PERSISTENT)) {
2705-
return NULL;
2706-
}
2707-
27082720
SHM_UNPROTECT();
27092721
zend_shared_alloc_lock();
27102722

2711-
new_dcl = accel_ffi_cache_type_get(str);
2723+
new_dcl = accel_ffi_cache_type_get(str, context);
27122724
if (!new_dcl) {
27132725
str = accel_new_interned_string(zend_string_copy(str));
27142726
if (IS_ACCEL_INTERNED(str)) {
2715-
new_dcl = accel_ffi_persist_type(dcl);
2716-
if (new_dcl) {
2727+
accel_ffi_cache_type_entry *ptr = accel_ffi_persist_type(dcl, context);
2728+
if (ptr) {
27172729
// TODO: ???
2718-
ZEND_ASSERT(!(str->gc.u.type_info & (IS_STR_CLASS_NAME_MAP_PTR|IS_STR_FFI_TYPE|IS_STR_FFI_SCOPE)));
2719-
ZEND_ASSERT((char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p > 0 &&
2730+
ZEND_ASSERT(!(str->gc.u.type_info & (IS_STR_CLASS_NAME_MAP_PTR|IS_STR_FFI_SCOPE)));
2731+
ZEND_ASSERT((char*)ptr - (char*)ZSMMG(shared_segments)[0]->p > 0 &&
27202732
(char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p < 0x7fffffff);
2721-
str->gc.u.type_info |= IS_STR_FFI_TYPE;
2733+
if (str->gc.u.type_info & IS_STR_FFI_TYPE) {
2734+
ptr->next = (accel_ffi_cache_type_entry*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2735+
} else {
2736+
ptr->next = NULL;
2737+
str->gc.u.type_info |= IS_STR_FFI_TYPE;
2738+
}
27222739
// TODO: ???
2723-
str->gc.refcount = (char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p;
2740+
str->gc.refcount = (char*)ptr - (char*)ZSMMG(shared_segments)[0]->p;
2741+
new_dcl = &ptr->dcl;
27242742
}
27252743
}
27262744
}

0 commit comments

Comments
 (0)