Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 077c18a

Browse files
committed
Remove cache slot from ZEND_VERIFY_TYPE and arg RECV opcodes
1 parent ac9392b commit 077c18a

File tree

9 files changed

+53
-187
lines changed

9 files changed

+53
-187
lines changed

‎Zend/Optimizer/compact_literals.c

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -43,50 +43,6 @@ typedef struct _literal_info {
4343
info[n].num_related = (related); \
4444
} while (0)
4545

46-
static size_t type_num_classes(const zend_op_array *op_array, uint32_t arg_num)
47-
{
48-
zend_arg_info *arg_info;
49-
if (arg_num > 0) {
50-
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
51-
return 0;
52-
}
53-
if (EXPECTED(arg_num <= op_array->num_args)) {
54-
arg_info = &op_array->arg_info[arg_num-1];
55-
} else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
56-
arg_info = &op_array->arg_info[op_array->num_args];
57-
} else {
58-
return 0;
59-
}
60-
} else {
61-
arg_info = op_array->arg_info - 1;
62-
}
63-
64-
if (ZEND_TYPE_IS_COMPLEX(arg_info->type)) {
65-
if (ZEND_TYPE_HAS_LIST(arg_info->type)) {
66-
/* Intersection types cannot have nested list types */
67-
if (ZEND_TYPE_IS_INTERSECTION(arg_info->type)) {
68-
return ZEND_TYPE_LIST(arg_info->type)->num_types;
69-
}
70-
ZEND_ASSERT(ZEND_TYPE_IS_UNION(arg_info->type));
71-
size_t count = 0;
72-
zend_type *list_type;
73-
74-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), list_type) {
75-
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
76-
count += ZEND_TYPE_LIST(*list_type)->num_types;
77-
} else {
78-
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
79-
count += 1;
80-
}
81-
} ZEND_TYPE_LIST_FOREACH_END();
82-
return count;
83-
}
84-
return 1;
85-
}
86-
87-
return 0;
88-
}
89-
9046
static uint32_t add_static_slot(HashTable *hash,
9147
zend_op_array *op_array,
9248
uint32_t op1,
@@ -504,26 +460,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
504460
opline->op2.constant = map[opline->op2.constant];
505461
}
506462
switch (opline->opcode) {
507-
case ZEND_RECV_INIT:
508-
case ZEND_RECV:
509-
case ZEND_RECV_VARIADIC:
510-
{
511-
size_t num_classes = type_num_classes(op_array, opline->op1.num);
512-
if (num_classes) {
513-
opline->extended_value = cache_size;
514-
cache_size += num_classes * sizeof(void *);
515-
}
516-
break;
517-
}
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-
}
527463
case ZEND_ASSIGN_STATIC_PROP_OP:
528464
if (opline->op1_type == IS_CONST) {
529465
// op1 static property

‎Zend/zend_compile.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,33 +2620,6 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */
26202620
}
26212621
/* }}} */
26222622

2623-
/* Remember to update type_num_classes() in compact_literals.c when changing this function */
2624-
static size_t zend_type_get_num_classes(zend_type type) {
2625-
if (!ZEND_TYPE_IS_COMPLEX(type)) {
2626-
return 0;
2627-
}
2628-
if (ZEND_TYPE_HAS_LIST(type)) {
2629-
/* Intersection types cannot have nested list types */
2630-
if (ZEND_TYPE_IS_INTERSECTION(type)) {
2631-
return ZEND_TYPE_LIST(type)->num_types;
2632-
}
2633-
ZEND_ASSERT(ZEND_TYPE_IS_UNION(type));
2634-
size_t count = 0;
2635-
zend_type *list_type;
2636-
2637-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) {
2638-
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
2639-
count += ZEND_TYPE_LIST(*list_type)->num_types;
2640-
} else {
2641-
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
2642-
count += 1;
2643-
}
2644-
} ZEND_TYPE_LIST_FOREACH_END();
2645-
return count;
2646-
}
2647-
return 1;
2648-
}
2649-
26502623
static void zend_emit_return_type_check(
26512624
znode *expr, zend_arg_info *return_info, bool implicit) /* {{{ */
26522625
{
@@ -2708,8 +2681,6 @@ static void zend_emit_return_type_check(
27082681
opline->result_type = expr->op_type = IS_TMP_VAR;
27092682
opline->result.var = expr->u.op.var = get_temporary_variable();
27102683
}
2711-
2712-
opline->op2.num = zend_alloc_cache_slots(zend_type_get_num_classes(return_info->type));
27132684
}
27142685
}
27152686
/* }}} */
@@ -7754,12 +7725,6 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
77547725
SET_NODE(opline->result, &var_node);
77557726
opline->op1.num = i + 1;
77567727

7757-
if (type_ast) {
7758-
/* Allocate cache slot to speed-up run-time class resolution */
7759-
opline->extended_value =
7760-
zend_alloc_cache_slots(zend_type_get_num_classes(arg_info->type));
7761-
}
7762-
77637728
uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, /* is_tentative */ 0)
77647729
| (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0);
77657730
ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags;

‎Zend/zend_execute.c

Lines changed: 24 additions & 51 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++;
@@ -1508,7 +1481,7 @@ ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret)
15081481
return 1;
15091482
}
15101483

1511-
if (UNEXPECTED(!zend_check_type(&ret_info->type, ret, /* cache_slot */NULL, NULL, 1, /* is_internal */ 1))) {
1484+
if (UNEXPECTED(!zend_check_type(&ret_info->type, ret, NULL, 1, /* is_internal */ 1))) {
15121485
zend_verify_internal_return_error(zf, ret);
15131486
return 0;
15141487
}

‎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);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /