@@ -3044,15 +3044,55 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
3044
3044
3045
3045
static int zend_jit_collect_calls (zend_op_array * op_array , zend_script * script )
3046
3046
{
3047
- zend_func_info * func_info =
3048
- zend_arena_calloc (& CG (arena ), 1 , sizeof (zend_func_info ));
3047
+ zend_func_info * func_info ;
3049
3048
3050
- ZEND_SET_FUNC_INFO (op_array , func_info );
3049
+ if (JIT_G (trigger ) == ZEND_JIT_ON_FIRST_EXEC ||
3050
+ JIT_G (trigger ) == ZEND_JIT_ON_PROF_REQUEST ||
3051
+ JIT_G (trigger ) == ZEND_JIT_ON_HOT_COUNTERS ) {
3052
+ func_info = ZEND_FUNC_INFO (op_array );
3053
+ } else {
3054
+ func_info = zend_arena_calloc (& CG (arena ), 1 , sizeof (zend_func_info ));
3055
+ ZEND_SET_FUNC_INFO (op_array , func_info );
3056
+ }
3051
3057
func_info -> num_args = -1 ;
3052
3058
func_info -> return_value_used = -1 ;
3053
3059
return zend_analyze_calls (& CG (arena ), script , ZEND_CALL_TREE , op_array , func_info );
3054
3060
}
3055
3061
3062
+ static void zend_jit_cleanup_func_info (zend_op_array * op_array )
3063
+ {
3064
+ zend_func_info * func_info = ZEND_FUNC_INFO (op_array );
3065
+ zend_call_info * caller_info , * callee_info ;
3066
+
3067
+ if (func_info ) {
3068
+ caller_info = func_info -> caller_info ;
3069
+ callee_info = func_info -> callee_info ;
3070
+
3071
+ if (JIT_G (trigger ) == ZEND_JIT_ON_FIRST_EXEC ||
3072
+ JIT_G (trigger ) == ZEND_JIT_ON_PROF_REQUEST ||
3073
+ JIT_G (trigger ) == ZEND_JIT_ON_HOT_COUNTERS ) {
3074
+ memset (func_info , 0 , sizeof (zend_func_info ));
3075
+ func_info -> num_args = -1 ;
3076
+ func_info -> return_value_used = -1 ;
3077
+ } else {
3078
+ ZEND_SET_FUNC_INFO (op_array , NULL );
3079
+ }
3080
+
3081
+ while (caller_info ) {
3082
+ if (caller_info -> caller_op_array ) {
3083
+ zend_jit_cleanup_func_info (caller_info -> caller_op_array );
3084
+ }
3085
+ caller_info = caller_info -> next_caller ;
3086
+ }
3087
+ while (callee_info ) {
3088
+ if (callee_info -> callee_func && callee_info -> callee_func -> type == ZEND_USER_FUNCTION ) {
3089
+ zend_jit_cleanup_func_info (& callee_info -> callee_func -> op_array );
3090
+ }
3091
+ callee_info = callee_info -> next_callee ;
3092
+ }
3093
+ }
3094
+ }
3095
+
3056
3096
static int zend_real_jit_func (zend_op_array * op_array , zend_script * script , const zend_op * rt_opline )
3057
3097
{
3058
3098
zend_ssa ssa ;
@@ -3074,7 +3114,6 @@ static int zend_real_jit_func(zend_op_array *op_array, zend_script *script, cons
3074
3114
3075
3115
if (JIT_G (opt_level ) >= ZEND_JIT_LEVEL_OPT_FUNCS ) {
3076
3116
if (zend_jit_collect_calls (op_array , script ) != SUCCESS ) {
3077
- ZEND_SET_FUNC_INFO (op_array , NULL );
3078
3117
goto jit_failure ;
3079
3118
}
3080
3119
func_info = ZEND_FUNC_INFO (op_array );
@@ -3096,14 +3135,12 @@ static int zend_real_jit_func(zend_op_array *op_array, zend_script *script, cons
3096
3135
goto jit_failure ;
3097
3136
}
3098
3137
3099
- if (JIT_G (opt_level ) >= ZEND_JIT_LEVEL_OPT_FUNCS ) {
3100
- ZEND_SET_FUNC_INFO (op_array , NULL );
3101
- }
3102
-
3138
+ zend_jit_cleanup_func_info (op_array );
3103
3139
zend_arena_release (& CG (arena ), checkpoint );
3104
3140
return SUCCESS ;
3105
3141
3106
3142
jit_failure :
3143
+ zend_jit_cleanup_func_info (op_array );
3107
3144
zend_arena_release (& CG (arena ), checkpoint );
3108
3145
return FAILURE ;
3109
3146
}
@@ -3114,6 +3151,7 @@ static void ZEND_FASTCALL zend_runtime_jit(void)
3114
3151
zend_execute_data * execute_data = EG (current_execute_data );
3115
3152
zend_op_array * op_array = & EX (func )-> op_array ;
3116
3153
zend_op * opline = op_array -> opcodes ;
3154
+ zend_jit_op_array_extension * jit_extension ;
3117
3155
3118
3156
zend_shared_alloc_lock ();
3119
3157
@@ -3127,8 +3165,8 @@ static void ZEND_FASTCALL zend_runtime_jit(void)
3127
3165
opline ++ ;
3128
3166
}
3129
3167
}
3130
- opline -> handler = ZEND_FUNC_INFO (op_array );
3131
- ZEND_SET_FUNC_INFO ( op_array , NULL ) ;
3168
+ jit_extension = ( zend_jit_op_array_extension * ) ZEND_FUNC_INFO (op_array );
3169
+ opline -> handler = jit_extension -> orig_handler ;
3132
3170
3133
3171
/* perform real JIT for this function */
3134
3172
zend_real_jit_func (op_array , NULL , NULL );
@@ -3147,6 +3185,7 @@ void zend_jit_check_funcs(HashTable *function_table, zend_bool is_method) {
3147
3185
zend_function * func ;
3148
3186
zend_op_array * op_array ;
3149
3187
uintptr_t counter ;
3188
+ zend_jit_op_array_extension * jit_extension ;
3150
3189
3151
3190
ZEND_HASH_REVERSE_FOREACH_PTR (function_table , func ) {
3152
3191
if (func -> type == ZEND_INTERNAL_FUNCTION ) {
@@ -3165,8 +3204,8 @@ void zend_jit_check_funcs(HashTable *function_table, zend_bool is_method) {
3165
3204
}
3166
3205
counter = (uintptr_t )ZEND_COUNTER_INFO (op_array );
3167
3206
ZEND_COUNTER_INFO (op_array ) = 0 ;
3168
- opline -> handler = ZEND_FUNC_INFO (op_array );
3169
- ZEND_SET_FUNC_INFO ( op_array , NULL ) ;
3207
+ jit_extension = ( zend_jit_op_array_extension * ) ZEND_FUNC_INFO (op_array );
3208
+ opline -> handler = jit_extension -> orig_handler ;
3170
3209
if (((double )counter / (double )zend_jit_profile_counter ) > ZEND_JIT_PROF_THRESHOLD ) {
3171
3210
zend_real_jit_func (op_array , NULL , NULL );
3172
3211
}
@@ -3190,7 +3229,6 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend
3190
3229
for (i = 0 ; i < op_array -> last ; i ++ ) {
3191
3230
op_array -> opcodes [i ].handler = jit_extension -> orig_handlers [i ];
3192
3231
}
3193
- ZEND_SET_FUNC_INFO (op_array , NULL );
3194
3232
3195
3233
/* perform real JIT for this function */
3196
3234
zend_real_jit_func (op_array , NULL , opline );
@@ -3274,6 +3312,7 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
3274
3312
}
3275
3313
3276
3314
if (JIT_G (trigger ) == ZEND_JIT_ON_FIRST_EXEC ) {
3315
+ zend_jit_op_array_extension * jit_extension ;
3277
3316
zend_op * opline = op_array -> opcodes ;
3278
3317
3279
3318
/* Set run-time JIT handler */
@@ -3283,11 +3322,17 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
3283
3322
opline ++ ;
3284
3323
}
3285
3324
}
3286
- ZEND_SET_FUNC_INFO (op_array , (void * )opline -> handler );
3325
+ jit_extension = (zend_jit_op_array_extension * )zend_shared_alloc (sizeof (zend_jit_op_array_extension ));
3326
+ memset (& jit_extension -> func_info , 0 , sizeof (zend_func_info ));
3327
+ jit_extension -> func_info .num_args = -1 ;
3328
+ jit_extension -> func_info .return_value_used = -1 ;
3329
+ jit_extension -> orig_handler = (void * )opline -> handler ;
3330
+ ZEND_SET_FUNC_INFO (op_array , (void * )jit_extension );
3287
3331
opline -> handler = (const void * )zend_jit_runtime_jit_handler ;
3288
3332
3289
3333
return SUCCESS ;
3290
3334
} else if (JIT_G (trigger ) == ZEND_JIT_ON_PROF_REQUEST ) {
3335
+ zend_jit_op_array_extension * jit_extension ;
3291
3336
zend_op * opline = op_array -> opcodes ;
3292
3337
3293
3338
ZEND_ASSERT (zend_jit_profile_jit_handler != NULL );
@@ -3297,7 +3342,12 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
3297
3342
opline ++ ;
3298
3343
}
3299
3344
}
3300
- ZEND_SET_FUNC_INFO (op_array , (void * )opline -> handler );
3345
+ jit_extension = (zend_jit_op_array_extension * )zend_shared_alloc (sizeof (zend_jit_op_array_extension ));
3346
+ memset (& jit_extension -> func_info , 0 , sizeof (zend_func_info ));
3347
+ jit_extension -> func_info .num_args = -1 ;
3348
+ jit_extension -> func_info .return_value_used = -1 ;
3349
+ jit_extension -> orig_handler = (void * )opline -> handler ;
3350
+ ZEND_SET_FUNC_INFO (op_array , (void * )jit_extension );
3301
3351
opline -> handler = (const void * )zend_jit_profile_jit_handler ;
3302
3352
}
3303
3353
@@ -3344,7 +3394,6 @@ ZEND_EXT_API int zend_jit_script(zend_script *script)
3344
3394
JIT_G (trigger ) == ZEND_JIT_ON_HOT_COUNTERS ||
3345
3395
JIT_G (trigger ) == ZEND_JIT_ON_HOT_TRACE ) {
3346
3396
for (i = 0 ; i < call_graph .op_arrays_count ; i ++ ) {
3347
- ZEND_SET_FUNC_INFO (call_graph .op_arrays [i ], NULL );
3348
3397
if (zend_jit_op_array (call_graph .op_arrays [i ], script ) != SUCCESS ) {
3349
3398
goto jit_failure ;
3350
3399
}
@@ -3435,8 +3484,11 @@ ZEND_EXT_API int zend_jit_script(zend_script *script)
3435
3484
return SUCCESS ;
3436
3485
3437
3486
jit_failure :
3438
- for (i = 0 ; i < call_graph .op_arrays_count ; i ++ ) {
3439
- ZEND_SET_FUNC_INFO (call_graph .op_arrays [i ], NULL );
3487
+ if (JIT_G (trigger ) == ZEND_JIT_ON_SCRIPT_LOAD ||
3488
+ JIT_G (trigger ) == ZEND_JIT_ON_DOC_COMMENT ) {
3489
+ for (i = 0 ; i < call_graph .op_arrays_count ; i ++ ) {
3490
+ ZEND_SET_FUNC_INFO (call_graph .op_arrays [i ], NULL );
3491
+ }
3440
3492
}
3441
3493
zend_arena_release (& CG (arena ), checkpoint );
3442
3494
return FAILURE ;
0 commit comments