Skip to content

Commit 34e71a4

Browse files
committed
WIP: remove cache slot from type verify / arg recv
1 parent ac9392b commit 34e71a4

File tree

9 files changed

+45
-91
lines changed

9 files changed

+45
-91
lines changed

Zend/Optimizer/compact_literals.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -515,15 +515,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
515515
}
516516
break;
517517
}
518-
case ZEND_VERIFY_RETURN_TYPE:
519-
{
520-
size_t num_classes = type_num_classes(op_array, 0);
521-
if (num_classes) {
522-
opline->op2.num = cache_size;
523-
cache_size += num_classes * sizeof(void *);
524-
}
525-
break;
526-
}
527518
case ZEND_ASSIGN_STATIC_PROP_OP:
528519
if (opline->op1_type == IS_CONST) {
529520
// op1 static property

Zend/zend_compile.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,8 +2708,6 @@ static void zend_emit_return_type_check(
27082708
opline->result_type = expr->op_type = IS_TMP_VAR;
27092709
opline->result.var = expr->u.op.var = get_temporary_variable();
27102710
}
2711-
2712-
opline->op2.num = zend_alloc_cache_slots(zend_type_get_num_classes(return_info->type));
27132711
}
27142712
}
27152713
/* }}} */

Zend/zend_execute.c

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,23 +1099,10 @@ static zend_always_inline bool zend_value_instanceof_static(zval *zv) {
10991099
return instanceof_function(Z_OBJCE_P(zv), called_scope);
11001100
}
11011101

1102-
/* The cache_slot may only be NULL in debug builds, where arginfo verification of
1103-
* internal functions is enabled. Avoid unnecessary checks in release builds. */
1104-
#if ZEND_DEBUG
1105-
# define HAVE_CACHE_SLOT (cache_slot != NULL)
1106-
#else
1107-
# define HAVE_CACHE_SLOT 1
1108-
#endif
1109-
1110-
#define PROGRESS_CACHE_SLOT() if (HAVE_CACHE_SLOT) {cache_slot++;}
1111-
1102+
// TODO: new name
11121103
static zend_always_inline zend_class_entry *zend_fetch_ce_from_cache_slot(
1113-
void **cache_slot, zend_type *type)
1104+
zend_type *type)
11141105
{
1115-
if (EXPECTED(HAVE_CACHE_SLOT && *cache_slot)) {
1116-
return (zend_class_entry *) *cache_slot;
1117-
}
1118-
11191106
zend_string *name = ZEND_TYPE_NAME(*type);
11201107
zend_class_entry *ce;
11211108
if (ZSTR_HAS_CE_CACHE(name)) {
@@ -1134,39 +1121,27 @@ static zend_always_inline zend_class_entry *zend_fetch_ce_from_cache_slot(
11341121
return NULL;
11351122
}
11361123
}
1137-
if (HAVE_CACHE_SLOT) {
1138-
*cache_slot = (void *) ce;
1139-
}
11401124
return ce;
11411125
}
11421126

11431127
static bool zend_check_intersection_type_from_cache_slot(zend_type_list *intersection_type_list,
1144-
zend_class_entry *arg_ce, void ***cache_slot_ptr)
1128+
zend_class_entry *arg_ce)
11451129
{
1146-
void **cache_slot = *cache_slot_ptr;
11471130
zend_class_entry *ce;
11481131
zend_type *list_type;
1149-
bool status = true;
11501132
ZEND_TYPE_LIST_FOREACH(intersection_type_list, list_type) {
1151-
/* Only check classes if the type might be valid */
1152-
if (status) {
1153-
ce = zend_fetch_ce_from_cache_slot(cache_slot, list_type);
1154-
/* If type is not an instance of one of the types taking part in the
1155-
* intersection it cannot be a valid instance of the whole intersection type. */
1156-
if (!ce || !instanceof_function(arg_ce, ce)) {
1157-
status = false;
1158-
}
1133+
ce = zend_fetch_ce_from_cache_slot(list_type);
1134+
/* If type is not an instance of one of the types taking part in the
1135+
* intersection it cannot be a valid instance of the whole intersection type. */
1136+
if (!ce || !instanceof_function(arg_ce, ce)) {
1137+
return false;
11591138
}
1160-
PROGRESS_CACHE_SLOT();
11611139
} ZEND_TYPE_LIST_FOREACH_END();
1162-
if (HAVE_CACHE_SLOT) {
1163-
*cache_slot_ptr = cache_slot;
1164-
}
1165-
return status;
1140+
return true;
11661141
}
11671142

11681143
static zend_always_inline bool zend_check_type_slow(
1169-
zend_type *type, zval *arg, zend_reference *ref, void **cache_slot,
1144+
zend_type *type, zval *arg, zend_reference *ref,
11701145
bool is_return_type, bool is_internal)
11711146
{
11721147
uint32_t type_mask;
@@ -1175,27 +1150,25 @@ static zend_always_inline bool zend_check_type_slow(
11751150
if (UNEXPECTED(ZEND_TYPE_HAS_LIST(*type))) {
11761151
zend_type *list_type;
11771152
if (ZEND_TYPE_IS_INTERSECTION(*type)) {
1178-
return zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*type), Z_OBJCE_P(arg), &cache_slot);
1153+
return zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*type), Z_OBJCE_P(arg));
11791154
} else {
11801155
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), list_type) {
11811156
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
1182-
if (zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*list_type), Z_OBJCE_P(arg), &cache_slot)) {
1157+
if (zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*list_type), Z_OBJCE_P(arg))) {
11831158
return true;
11841159
}
1185-
/* The cache_slot is progressed in zend_check_intersection_type_from_cache_slot() */
11861160
} else {
11871161
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
1188-
ce = zend_fetch_ce_from_cache_slot(cache_slot, list_type);
1162+
ce = zend_fetch_ce_from_cache_slot(list_type);
11891163
/* Instance of a single type part of a union is sufficient to pass the type check */
11901164
if (ce && instanceof_function(Z_OBJCE_P(arg), ce)) {
11911165
return true;
11921166
}
1193-
PROGRESS_CACHE_SLOT();
11941167
}
11951168
} ZEND_TYPE_LIST_FOREACH_END();
11961169
}
11971170
} else {
1198-
ce = zend_fetch_ce_from_cache_slot(cache_slot, type);
1171+
ce = zend_fetch_ce_from_cache_slot(type);
11991172
/* If we have a CE we check if it satisfies the type constraint,
12001173
* otherwise it will check if a standard type satisfies it. */
12011174
if (ce && instanceof_function(Z_OBJCE_P(arg), ce)) {
@@ -1232,7 +1205,7 @@ static zend_always_inline bool zend_check_type_slow(
12321205
}
12331206

12341207
static zend_always_inline bool zend_check_type(
1235-
zend_type *type, zval *arg, void **cache_slot, zend_class_entry *scope,
1208+
zend_type *type, zval *arg, zend_class_entry *scope,
12361209
bool is_return_type, bool is_internal)
12371210
{
12381211
zend_reference *ref = NULL;
@@ -1247,25 +1220,25 @@ static zend_always_inline bool zend_check_type(
12471220
return 1;
12481221
}
12491222

1250-
return zend_check_type_slow(type, arg, ref, cache_slot, is_return_type, is_internal);
1223+
return zend_check_type_slow(type, arg, ref, is_return_type, is_internal);
12511224
}
12521225

12531226
ZEND_API bool zend_check_user_type_slow(
1254-
zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, bool is_return_type)
1227+
zend_type *type, zval *arg, zend_reference *ref, bool is_return_type)
12551228
{
12561229
return zend_check_type_slow(
1257-
type, arg, ref, cache_slot, is_return_type, /* is_internal */ false);
1230+
type, arg, ref, is_return_type, /* is_internal */ false);
12581231
}
12591232

1260-
static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, void **cache_slot)
1233+
static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint32_t arg_num, zval *arg)
12611234
{
12621235
zend_arg_info *cur_arg_info;
12631236

12641237
ZEND_ASSERT(arg_num <= zf->common.num_args);
12651238
cur_arg_info = &zf->common.arg_info[arg_num-1];
12661239

12671240
if (ZEND_TYPE_IS_SET(cur_arg_info->type)
1268-
&& UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
1241+
&& UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, zf->common.scope, 0, 0))) {
12691242
zend_verify_arg_error(zf, cur_arg_info, arg_num, arg);
12701243
return 0;
12711244
}
@@ -1274,10 +1247,10 @@ static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint
12741247
}
12751248

12761249
static zend_always_inline bool zend_verify_variadic_arg_type(
1277-
zend_function *zf, zend_arg_info *arg_info, uint32_t arg_num, zval *arg, void **cache_slot)
1250+
zend_function *zf, zend_arg_info *arg_info, uint32_t arg_num, zval *arg)
12781251
{
12791252
ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type));
1280-
if (UNEXPECTED(!zend_check_type(&arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
1253+
if (UNEXPECTED(!zend_check_type(&arg_info->type, arg, zf->common.scope, 0, 0))) {
12811254
zend_verify_arg_error(zf, arg_info, arg_num, arg);
12821255
return 0;
12831256
}
@@ -1302,7 +1275,7 @@ static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_typ
13021275
}
13031276

13041277
if (ZEND_TYPE_IS_SET(cur_arg_info->type)
1305-
&& UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, /* cache_slot */ NULL, fbc->common.scope, 0, /* is_internal */ 1))) {
1278+
&& UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, fbc->common.scope, 0, /* is_internal */ 1))) {
13061279
return 0;
13071280
}
13081281
arg++;

Zend/zend_execute.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ ZEND_API ZEND_COLD void zend_verify_never_error(
106106
const zend_function *zf);
107107
ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref);
108108
ZEND_API bool zend_check_user_type_slow(
109-
zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, bool is_return_type);
109+
zend_type *type, zval *arg, zend_reference *ref, bool is_return_type);
110110

111111
#if ZEND_DEBUG
112112
ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call);

Zend/zend_vm_def.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,7 +4423,7 @@ ZEND_VM_C_LABEL(fcall_end):
44234423
ZEND_VM_CONTINUE();
44244424
}
44254425

4426-
ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED|CACHE_SLOT)
4426+
ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED)
44274427
{
44284428
if (OP1_TYPE == IS_UNUSED) {
44294429
SAVE_OPLINE();
@@ -4465,7 +4465,6 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44654465
}
44664466

44674467
zend_reference *ref = NULL;
4468-
void *cache_slot = CACHE_ADDR(opline->op2.num);
44694468
if (UNEXPECTED(retval_ref != retval_ptr)) {
44704469
if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
44714470
ref = Z_REF_P(retval_ref);
@@ -4482,7 +4481,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44824481
}
44834482

44844483
SAVE_OPLINE();
4485-
if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) {
4484+
if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
44864485
zend_verify_return_error(EX(func), retval_ptr);
44874486
HANDLE_EXCEPTION();
44884487
}
@@ -5671,7 +5670,7 @@ ZEND_VM_HELPER(zend_verify_recv_arg_type_helper, ANY, ANY, zval *op_1)
56715670
USE_OPLINE
56725671

56735672
SAVE_OPLINE();
5674-
if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), opline->op1.num, op_1, CACHE_ADDR(opline->extended_value)))) {
5673+
if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), opline->op1.num, op_1))) {
56755674
HANDLE_EXCEPTION();
56765675
}
56775676

@@ -5749,7 +5748,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT)
57495748
ZEND_VM_C_LABEL(recv_init_check_type):
57505749
if ((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
57515750
SAVE_OPLINE();
5752-
if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
5751+
if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param))) {
57535752
HANDLE_EXCEPTION();
57545753
}
57555754
}
@@ -5782,7 +5781,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT)
57825781
if (ZEND_TYPE_IS_SET(arg_info->type)) {
57835782
ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS);
57845783
do {
5785-
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
5784+
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) {
57865785
ZEND_HASH_FILL_FINISH();
57875786
HANDLE_EXCEPTION();
57885787
}
@@ -5810,7 +5809,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT)
58105809
if (ZEND_TYPE_IS_SET(arg_info->type)) {
58115810
SEPARATE_ARRAY(params);
58125811
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) {
5813-
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
5812+
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) {
58145813
HANDLE_EXCEPTION();
58155814
}
58165815
Z_TRY_ADDREF_P(param);

Zend/zend_vm_execute.h

Lines changed: 9 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_vm_opcodes.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)