Skip to content

Commit 3e9da35

Browse files
committed
Cache FFI types in opcache SHM (incomplete)
1 parent 5627ed6 commit 3e9da35

File tree

7 files changed

+388
-42
lines changed

7 files changed

+388
-42
lines changed

Zend/zend.c

+4
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes)(void *bytes, si
9898
ZEND_ATTRIBUTE_NONNULL ZEND_API void (*zend_random_bytes_insecure)(zend_random_bytes_insecure_state *state, void *bytes, size_t size) = NULL;
9999

100100
ZEND_API zend_class_entry *zend_ffi_cdata_ce = NULL;
101+
ZEND_API zend_ffi* (*zend_ffi_cache_cdef_get)(zend_string *cdef) = NULL;
102+
ZEND_API zend_ffi* (*zend_ffi_cache_cdef_add)(zend_string *cdef, zend_ffi *ffi) = NULL;
103+
ZEND_API zend_result (*zend_ffi_cache_type_get)(zend_string *str, zend_ffi_dcl *dcl) = NULL;
104+
ZEND_API zend_result (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl) = NULL;
101105

102106
/* This callback must be signal handler safe! */
103107
void (*zend_on_timeout)(int seconds);

Zend/zend.h

+11
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,19 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn,
387387
#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def
388388
extern ZEND_API zend_class_entry *zend_standard_class_def;
389389
extern ZEND_API zend_utility_values zend_uv;
390+
391+
/* FFI/OPCache interopability API */
390392
extern ZEND_API zend_class_entry *zend_ffi_cdata_ce;
391393

394+
typedef struct _zend_ffi zend_ffi;
395+
typedef struct _zend_ffi_dcl zend_ffi_dcl;
396+
397+
ZEND_API extern zend_ffi* (*zend_ffi_cache_cdef_get)(zend_string *cdef);
398+
ZEND_API extern zend_ffi* (*zend_ffi_cache_cdef_add)(zend_string *cdef, zend_ffi *ffi);
399+
ZEND_API extern zend_result (*zend_ffi_cache_type_get)(zend_string *str, zend_ffi_dcl *dcl);
400+
ZEND_API extern zend_result (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl);
401+
402+
392403
/* If DTrace is available and enabled */
393404
extern ZEND_API bool zend_dtrace_enabled;
394405
END_EXTERN_C()

Zend/zend_types.h

+2
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,8 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
821821
#define IS_STR_PERSISTENT GC_PERSISTENT /* allocated using malloc */
822822
#define IS_STR_PERMANENT (1<<8) /* relives request boundary */
823823
#define IS_STR_VALID_UTF8 (1<<9) /* valid UTF-8 according to PCRE */
824+
#define IS_STR_FFI_TYPE (1<<10) /* intrned string associated with FFI type */
825+
#define IS_STR_FFI_DECL (1<<11) /* intrned string associated with FFI declaration object */
824826

825827
/* array flags */
826828
#define IS_ARRAY_IMMUTABLE GC_IMMUTABLE

ext/ffi/ffi.c

+68-37
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static zend_internal_function zend_ffi_cast_fn;
128128
static zend_internal_function zend_ffi_type_fn;
129129

130130
/* forward declarations */
131-
static void _zend_ffi_type_dtor(zend_ffi_type *type);
131+
//???static void _zend_ffi_type_dtor(zend_ffi_type *type);
132132
static void zend_ffi_finalize_type(zend_ffi_dcl *dcl);
133133
static bool zend_ffi_is_same_type(zend_ffi_type *type1, zend_ffi_type *type2);
134134
static zend_ffi_type *zend_ffi_remember_type(zend_ffi_type *type);
@@ -2205,7 +2205,7 @@ static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */
22052205
}
22062206
/* }}} */
22072207

2208-
static void _zend_ffi_type_dtor(zend_ffi_type *type) /* {{{ */
2208+
ZEND_API void _zend_ffi_type_dtor(zend_ffi_type *type) /* {{{ */
22092209
{
22102210
type = ZEND_FFI_TYPE(type);
22112211

@@ -2922,6 +2922,13 @@ ZEND_METHOD(FFI, cdef) /* {{{ */
29222922
FFI_G(tags) = NULL;
29232923

29242924
if (code && ZSTR_LEN(code)) {
2925+
if (zend_ffi_cache_cdef_get) {
2926+
ffi = zend_ffi_cache_cdef_get(code);
2927+
if (ffi) {
2928+
RETURN_OBJ(&ffi->std);
2929+
}
2930+
}
2931+
29252932
/* Parse C definitions */
29262933
FFI_G(default_type_attr) = ZEND_FFI_ATTR_STORED;
29272934

@@ -2971,6 +2978,10 @@ ZEND_METHOD(FFI, cdef) /* {{{ */
29712978
ffi->symbols = FFI_G(symbols);
29722979
ffi->tags = FFI_G(tags);
29732980

2981+
if (zend_ffi_cache_cdef_add) {
2982+
ffi = zend_ffi_cache_cdef_add(code, ffi);
2983+
}
2984+
29742985
FFI_G(symbols) = NULL;
29752986
FFI_G(tags) = NULL;
29762987

@@ -3714,7 +3725,10 @@ ZEND_METHOD(FFI, new) /* {{{ */
37143725

37153726
FFI_G(default_type_attr) = 0;
37163727

3717-
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
3728+
if (zend_ffi_cache_type_get
3729+
&& zend_ffi_cache_type_get(type_def, &dcl) == SUCCESS) {
3730+
/* pass */
3731+
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
37183732
zend_ffi_type_dtor(dcl.type);
37193733
if (clean_tags && FFI_G(tags)) {
37203734
zend_hash_destroy(FFI_G(tags));
@@ -3727,24 +3741,28 @@ ZEND_METHOD(FFI, new) /* {{{ */
37273741
FFI_G(symbols) = NULL;
37283742
}
37293743
return;
3744+
} else {
3745+
if (clean_tags && FFI_G(tags)) {
3746+
zend_ffi_tags_cleanup(&dcl);
3747+
}
3748+
if (clean_symbols && FFI_G(symbols)) {
3749+
zend_hash_destroy(FFI_G(symbols));
3750+
efree(FFI_G(symbols));
3751+
FFI_G(symbols) = NULL;
3752+
}
3753+
FFI_G(symbols) = NULL;
3754+
FFI_G(tags) = NULL;
3755+
3756+
if (zend_ffi_cache_type_add) {
3757+
zend_ffi_cache_type_add(type_def, &dcl);
3758+
}
37303759
}
37313760

37323761
type = ZEND_FFI_TYPE(dcl.type);
37333762
if (dcl.attr & ZEND_FFI_ATTR_CONST) {
37343763
is_const = 1;
37353764
}
37363765

3737-
if (clean_tags && FFI_G(tags)) {
3738-
zend_ffi_tags_cleanup(&dcl);
3739-
}
3740-
if (clean_symbols && FFI_G(symbols)) {
3741-
zend_hash_destroy(FFI_G(symbols));
3742-
efree(FFI_G(symbols));
3743-
FFI_G(symbols) = NULL;
3744-
}
3745-
FFI_G(symbols) = NULL;
3746-
FFI_G(tags) = NULL;
3747-
37483766
type_ptr = dcl.type;
37493767
} else {
37503768
zend_ffi_ctype *ctype = (zend_ffi_ctype*) type_obj;
@@ -3864,7 +3882,10 @@ ZEND_METHOD(FFI, cast) /* {{{ */
38643882

38653883
FFI_G(default_type_attr) = 0;
38663884

3867-
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
3885+
if (zend_ffi_cache_type_get
3886+
&& zend_ffi_cache_type_get(type_def, &dcl) == SUCCESS) {
3887+
/* pass */
3888+
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
38683889
zend_ffi_type_dtor(dcl.type);
38693890
if (clean_tags && FFI_G(tags)) {
38703891
zend_hash_destroy(FFI_G(tags));
@@ -3877,24 +3898,28 @@ ZEND_METHOD(FFI, cast) /* {{{ */
38773898
FFI_G(symbols) = NULL;
38783899
}
38793900
return;
3901+
} else {
3902+
if (clean_tags && FFI_G(tags)) {
3903+
zend_ffi_tags_cleanup(&dcl);
3904+
}
3905+
if (clean_symbols && FFI_G(symbols)) {
3906+
zend_hash_destroy(FFI_G(symbols));
3907+
efree(FFI_G(symbols));
3908+
FFI_G(symbols) = NULL;
3909+
}
3910+
FFI_G(symbols) = NULL;
3911+
FFI_G(tags) = NULL;
3912+
3913+
if (zend_ffi_cache_type_add) {
3914+
zend_ffi_cache_type_add(type_def, &dcl);
3915+
}
38803916
}
38813917

38823918
type = ZEND_FFI_TYPE(dcl.type);
38833919
if (dcl.attr & ZEND_FFI_ATTR_CONST) {
38843920
is_const = 1;
38853921
}
38863922

3887-
if (clean_tags && FFI_G(tags)) {
3888-
zend_ffi_tags_cleanup(&dcl);
3889-
}
3890-
if (clean_symbols && FFI_G(symbols)) {
3891-
zend_hash_destroy(FFI_G(symbols));
3892-
efree(FFI_G(symbols));
3893-
FFI_G(symbols) = NULL;
3894-
}
3895-
FFI_G(symbols) = NULL;
3896-
FFI_G(tags) = NULL;
3897-
38983923
type_ptr = dcl.type;
38993924
} else {
39003925
zend_ffi_ctype *ctype = (zend_ffi_ctype*) ztype;
@@ -4036,7 +4061,10 @@ ZEND_METHOD(FFI, type) /* {{{ */
40364061

40374062
FFI_G(default_type_attr) = 0;
40384063

4039-
if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
4064+
if (zend_ffi_cache_type_get
4065+
&& zend_ffi_cache_type_get(type_def, &dcl) == SUCCESS) {
4066+
/* pass */
4067+
} else if (zend_ffi_parse_type(ZSTR_VAL(type_def), ZSTR_LEN(type_def), &dcl) == FAILURE) {
40404068
zend_ffi_type_dtor(dcl.type);
40414069
if (clean_tags && FFI_G(tags)) {
40424070
zend_hash_destroy(FFI_G(tags));
@@ -4049,18 +4077,21 @@ ZEND_METHOD(FFI, type) /* {{{ */
40494077
FFI_G(symbols) = NULL;
40504078
}
40514079
return;
4052-
}
4053-
4054-
if (clean_tags && FFI_G(tags)) {
4055-
zend_ffi_tags_cleanup(&dcl);
4056-
}
4057-
if (clean_symbols && FFI_G(symbols)) {
4058-
zend_hash_destroy(FFI_G(symbols));
4059-
efree(FFI_G(symbols));
4080+
} else {
4081+
if (clean_tags && FFI_G(tags)) {
4082+
zend_ffi_tags_cleanup(&dcl);
4083+
}
4084+
if (clean_symbols && FFI_G(symbols)) {
4085+
zend_hash_destroy(FFI_G(symbols));
4086+
efree(FFI_G(symbols));
4087+
FFI_G(symbols) = NULL;
4088+
}
40604089
FFI_G(symbols) = NULL;
4090+
FFI_G(tags) = NULL;
4091+
if (zend_ffi_cache_type_add) {
4092+
zend_ffi_cache_type_add(type_def, &dcl);
4093+
}
40614094
}
4062-
FFI_G(symbols) = NULL;
4063-
FFI_G(tags) = NULL;
40644095

40654096
ctype = (zend_ffi_ctype*)zend_ffi_ctype_new(zend_ffi_ctype_ce);
40664097
ctype->type = dcl.type;

ext/ffi/php_ffi.h

+2
Original file line numberDiff line numberDiff line change
@@ -368,4 +368,6 @@ typedef struct _zend_ffi_ctype {
368368
#define ZEND_FFI_TYPE_IS_OWNED(t) \
369369
(((uintptr_t)(t)) & ZEND_FFI_TYPE_OWNED)
370370

371+
ZEND_API void _zend_ffi_type_dtor(zend_ffi_type *type);
372+
371373
#endif /* PHP_FFI_H */

0 commit comments

Comments
 (0)