Skip to content

Commit 7b2b9b4

Browse files
committed
Improved JIT for TYPE_CHECK opcode
1 parent aa45eed commit 7b2b9b4

File tree

2 files changed

+76
-26
lines changed

2 files changed

+76
-26
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,19 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
18431843
case ZEND_CHECK_UNDEF_ARGS:
18441844
case ZEND_INCLUDE_OR_EVAL:
18451845
max_used_stack = used_stack = -1;
1846+
break;
1847+
case ZEND_TYPE_CHECK:
1848+
if (opline->extended_value == MAY_BE_RESOURCE) {
1849+
// TODO: support for is_resource() ???
1850+
break;
1851+
}
1852+
if (op1_type != IS_UNKNOWN
1853+
&& (opline->extended_value == (1 << op1_type)
1854+
|| opline->extended_value == MAY_BE_ANY - (1 << op1_type))) {
1855+
/* add guards only for exact checks, to avoid code duplication */
1856+
ADD_OP1_TRACE_GUARD();
1857+
}
1858+
break;
18461859
default:
18471860
break;
18481861
}
@@ -4900,6 +4913,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49004913
break;
49014914
}
49024915
op1_info = OP1_INFO();
4916+
CHECK_OP1_TRACE_TYPE();
49034917
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
49044918
bool exit_if_true = 0;
49054919
const zend_op *exit_opline = zend_jit_trace_get_exit_opline(p + 1, opline + 1, &exit_if_true);

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10908,7 +10908,6 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar
1090810908
static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
1090910909
{
1091010910
uint32_t mask;
10911-
zend_uchar type;
1091210911
zend_jit_addr op1_addr = OP1_ADDR();
1091310912

1091410913
// TODO: support for is_resource() ???
@@ -10952,19 +10951,6 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t
1095210951

1095310952
if (op1_info & (MAY_BE_ANY|MAY_BE_REF)) {
1095410953
mask = opline->extended_value;
10955-
switch (mask) {
10956-
case MAY_BE_NULL: type = IS_NULL; break;
10957-
case MAY_BE_FALSE: type = IS_FALSE; break;
10958-
case MAY_BE_TRUE: type = IS_TRUE; break;
10959-
case MAY_BE_LONG: type = IS_LONG; break;
10960-
case MAY_BE_DOUBLE: type = IS_DOUBLE; break;
10961-
case MAY_BE_STRING: type = IS_STRING; break;
10962-
case MAY_BE_ARRAY: type = IS_ARRAY; break;
10963-
case MAY_BE_OBJECT: type = IS_OBJECT; break;
10964-
default:
10965-
type = 0;
10966-
}
10967-
1096810954
if (!(op1_info & MAY_BE_GUARD) && !(op1_info & (MAY_BE_ANY - mask))) {
1096910955
| FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
1097010956
if (exit_addr) {
@@ -10984,6 +10970,31 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t
1098410970
return 0;
1098510971
}
1098610972
} else {
10973+
bool invert = 0;
10974+
zend_uchar type;
10975+
10976+
switch (mask) {
10977+
case MAY_BE_NULL: type = IS_NULL; break;
10978+
case MAY_BE_FALSE: type = IS_FALSE; break;
10979+
case MAY_BE_TRUE: type = IS_TRUE; break;
10980+
case MAY_BE_LONG: type = IS_LONG; break;
10981+
case MAY_BE_DOUBLE: type = IS_DOUBLE; break;
10982+
case MAY_BE_STRING: type = IS_STRING; break;
10983+
case MAY_BE_ARRAY: type = IS_ARRAY; break;
10984+
case MAY_BE_OBJECT: type = IS_OBJECT; break;
10985+
case MAY_BE_ANY - MAY_BE_NULL: type = IS_NULL; invert = 1; break;
10986+
case MAY_BE_ANY - MAY_BE_FALSE: type = IS_FALSE; invert = 1; break;
10987+
case MAY_BE_ANY - MAY_BE_TRUE: type = IS_TRUE; invert = 1; break;
10988+
case MAY_BE_ANY - MAY_BE_LONG: type = IS_LONG; invert = 1; break;
10989+
case MAY_BE_ANY - MAY_BE_DOUBLE: type = IS_DOUBLE; invert = 1; break;
10990+
case MAY_BE_ANY - MAY_BE_STRING: type = IS_STRING; invert = 1; break;
10991+
case MAY_BE_ANY - MAY_BE_ARRAY: type = IS_ARRAY; invert = 1; break;
10992+
case MAY_BE_ANY - MAY_BE_OBJECT: type = IS_OBJECT; invert = 1; break;
10993+
case MAY_BE_ANY - MAY_BE_RESOURCE: type = IS_OBJECT; invert = 1; break;
10994+
default:
10995+
type = 0;
10996+
}
10997+
1098710998
if (op1_info & MAY_BE_REF) {
1098810999
| LOAD_ZVAL_ADDR r0, op1_addr
1098911000
| ZVAL_DEREF r0, op1_info
@@ -11115,26 +11126,51 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t
1111511126
}
1111611127
}
1111711128
if (exit_addr) {
11118-
if (smart_branch_opcode == ZEND_JMPNZ) {
11119-
| je &exit_addr
11129+
if (invert) {
11130+
if (smart_branch_opcode == ZEND_JMPNZ) {
11131+
| jne &exit_addr
11132+
} else {
11133+
| je &exit_addr
11134+
}
1112011135
} else {
11121-
| jne &exit_addr
11136+
if (smart_branch_opcode == ZEND_JMPNZ) {
11137+
| je &exit_addr
11138+
} else {
11139+
| jne &exit_addr
11140+
}
1112211141
}
1112311142
} else if (smart_branch_opcode) {
11124-
if (smart_branch_opcode == ZEND_JMPZ) {
11125-
| jne =>target_label
11126-
} else if (smart_branch_opcode == ZEND_JMPNZ) {
11127-
| je =>target_label
11128-
} else if (smart_branch_opcode == ZEND_JMPZNZ) {
11129-
| jne =>target_label
11130-
| jmp =>target_label2
11143+
if (invert) {
11144+
if (smart_branch_opcode == ZEND_JMPZ) {
11145+
| je =>target_label
11146+
} else if (smart_branch_opcode == ZEND_JMPNZ) {
11147+
| jne =>target_label
11148+
} else if (smart_branch_opcode == ZEND_JMPZNZ) {
11149+
| je =>target_label
11150+
| jmp =>target_label2
11151+
} else {
11152+
ZEND_UNREACHABLE();
11153+
}
1113111154
} else {
11132-
ZEND_UNREACHABLE();
11155+
if (smart_branch_opcode == ZEND_JMPZ) {
11156+
| jne =>target_label
11157+
} else if (smart_branch_opcode == ZEND_JMPNZ) {
11158+
| je =>target_label
11159+
} else if (smart_branch_opcode == ZEND_JMPZNZ) {
11160+
| jne =>target_label
11161+
| jmp =>target_label2
11162+
} else {
11163+
ZEND_UNREACHABLE();
11164+
}
1113311165
}
1113411166
} else {
1113511167
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
1113611168

11137-
| sete al
11169+
if (invert) {
11170+
| setne al
11171+
} else {
11172+
| sete al
11173+
}
1113811174
| movzx eax, al
1113911175
| add eax, 2
1114011176
| SET_ZVAL_TYPE_INFO res_addr, eax

0 commit comments

Comments
 (0)