Skip to content

Commit 8fd8514

Browse files
committed
Make FFI type cache context senseive
1 parent ed9c01a commit 8fd8514

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
@@ -395,8 +395,8 @@ extern ZEND_API zend_class_entry *zend_ffi_cdata_ce;
395395
typedef struct _zend_ffi_dcl zend_ffi_dcl;
396396
typedef struct _zend_ffi_scope zend_ffi_scope;
397397

398-
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str);
399-
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl);
398+
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str, void *context);
399+
ZEND_API extern zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl, void *context);
400400
ZEND_API extern zend_ffi_scope* (*zend_ffi_cache_scope_get)(zend_string *str);
401401
ZEND_API extern zend_ffi_scope* (*zend_ffi_cache_scope_add)(zend_string *str, zend_ffi_scope *scope);
402402

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
@@ -2457,6 +2457,14 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24572457
#if HAVE_FFI
24582458
#include "ext/ffi/php_ffi.h"
24592459

2460+
typedef struct _accel_ffi_cache_type_entry accel_ffi_cache_type_entry;
2461+
2462+
struct _accel_ffi_cache_type_entry {
2463+
accel_ffi_cache_type_entry *next;
2464+
void *context;
2465+
zend_ffi_dcl dcl;
2466+
};
2467+
24602468
static ssize_t accel_ffi_persist_type_calc(zend_ffi_type *type)
24612469
{
24622470
HashTable *ht;
@@ -2648,9 +2656,10 @@ static zend_ffi_type* accel_ffi_persist_type_copy(void** ptr, zend_ffi_type *typ
26482656
return new_type;
26492657
}
26502658

2651-
static zend_ffi_dcl* accel_ffi_persist_type(zend_ffi_dcl *dcl)
2659+
static accel_ffi_cache_type_entry* accel_ffi_persist_type(zend_ffi_dcl *dcl, void *context)
26522660
{
26532661
void *ptr;
2662+
accel_ffi_cache_type_entry *entry;
26542663
zend_ffi_dcl *new_dcl;
26552664
ssize_t size;
26562665

@@ -2661,59 +2670,68 @@ static zend_ffi_dcl* accel_ffi_persist_type(zend_ffi_dcl *dcl)
26612670
if (size == -1) {
26622671
return NULL;
26632672
}
2664-
ptr = zend_shared_alloc(sizeof(zend_ffi_dcl) + size);
2665-
if (!ptr) {
2673+
entry = zend_shared_alloc(sizeof(accel_ffi_cache_type_entry) + size);
2674+
if (!entry) {
26662675
return NULL;
26672676
}
26682677

26692678
zend_shared_alloc_init_xlat_table();
26702679

2671-
new_dcl = (zend_ffi_dcl*)ptr;
2672-
ptr = (void*)((char*)ptr + sizeof(zend_ffi_dcl));
2680+
entry->next = NULL;
2681+
entry->context = context;
2682+
new_dcl = &entry->dcl;
26732683
memcpy(new_dcl, dcl, sizeof(zend_ffi_dcl));
2684+
ptr = entry + 1;
26742685
new_dcl->type = accel_ffi_persist_type_copy(&ptr, new_dcl->type);
26752686

26762687
zend_shared_alloc_destroy_xlat_table();
26772688

2678-
return new_dcl;
2689+
return entry;
26792690
}
26802691

2681-
static zend_ffi_dcl* accel_ffi_cache_type_get(zend_string *str)
2692+
static zend_ffi_dcl* accel_ffi_cache_type_get(zend_string *str, void *context)
26822693
{
26832694
str = accel_find_interned_string(str);
26842695
if (str && (str->gc.u.type_info & IS_STR_FFI_TYPE)) {
26852696
// TODO: ???
2686-
zend_ffi_dcl *ptr = (zend_ffi_dcl*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2687-
return ptr;
2697+
accel_ffi_cache_type_entry *ptr =
2698+
(accel_ffi_cache_type_entry*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2699+
while (ptr && ptr->context != context) {
2700+
ptr = ptr->next;
2701+
}
2702+
if (ptr) {
2703+
return &ptr->dcl;
2704+
}
26882705
}
26892706
return NULL;
26902707
}
26912708

2692-
static zend_ffi_dcl* accel_ffi_cache_type_add(zend_string *str, zend_ffi_dcl *dcl)
2709+
static zend_ffi_dcl* accel_ffi_cache_type_add(zend_string *str, zend_ffi_dcl *dcl, void *context)
26932710
{
26942711
zend_ffi_dcl *new_dcl = NULL;
26952712

2696-
if (!ZEND_FFI_TYPE_IS_OWNED(dcl->type)
2697-
&& (dcl->type->attr & ZEND_FFI_ATTR_PERSISTENT)) {
2698-
return NULL;
2699-
}
2700-
27012713
SHM_UNPROTECT();
27022714
zend_shared_alloc_lock();
27032715

2704-
new_dcl = accel_ffi_cache_type_get(str);
2716+
new_dcl = accel_ffi_cache_type_get(str, context);
27052717
if (!new_dcl) {
27062718
str = accel_new_interned_string(zend_string_copy(str));
27072719
if (IS_ACCEL_INTERNED(str)) {
2708-
new_dcl = accel_ffi_persist_type(dcl);
2709-
if (new_dcl) {
2720+
accel_ffi_cache_type_entry *ptr = accel_ffi_persist_type(dcl, context);
2721+
if (ptr) {
27102722
// TODO: ???
2711-
ZEND_ASSERT(!(str->gc.u.type_info & (IS_STR_CLASS_NAME_MAP_PTR|IS_STR_FFI_TYPE|IS_STR_FFI_SCOPE)));
2712-
ZEND_ASSERT((char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p > 0 &&
2723+
ZEND_ASSERT(!(str->gc.u.type_info & (IS_STR_CLASS_NAME_MAP_PTR|IS_STR_FFI_SCOPE)));
2724+
ZEND_ASSERT((char*)ptr - (char*)ZSMMG(shared_segments)[0]->p > 0 &&
27132725
(char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p < 0x7fffffff);
2714-
str->gc.u.type_info |= IS_STR_FFI_TYPE;
2726+
if (str->gc.u.type_info & IS_STR_FFI_TYPE) {
2727+
ptr->next = (accel_ffi_cache_type_entry*)((char*)ZSMMG(shared_segments)[0]->p + str->gc.refcount);
2728+
} else {
2729+
ptr->next = NULL;
2730+
str->gc.u.type_info |= IS_STR_FFI_TYPE;
2731+
}
27152732
// TODO: ???
2716-
str->gc.refcount = (char*)new_dcl - (char*)ZSMMG(shared_segments)[0]->p;
2733+
str->gc.refcount = (char*)ptr - (char*)ZSMMG(shared_segments)[0]->p;
2734+
new_dcl = &ptr->dcl;
27172735
}
27182736
}
27192737
}

0 commit comments

Comments
 (0)