Skip to content

Commit

Permalink
Added specialized FE_FETCH_R handler for iteration over array
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Jun 20, 2017
1 parent 31a2198 commit 7802cf8
Show file tree
Hide file tree
Showing 2 changed files with 269 additions and 7 deletions.
51 changes: 51 additions & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -8749,6 +8749,57 @@ ZEND_VM_C_LABEL(send_var_by_ref_simple):
ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FE_FETCH_R, op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_FE_FETCH_R_SIMPLE, VAR, CV, JMP_ADDR, SPEC(RETVAL))
{
USE_OPLINE
zval *array;
zval *value, *variable_ptr;
uint32_t value_type;
HashTable *fe_ht;
HashPosition pos;
Bucket *p;

array = EX_VAR(opline->op1.var);
SAVE_OPLINE();
fe_ht = Z_ARRVAL_P(array);
pos = Z_FE_POS_P(array);
p = fe_ht->arData + pos;
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
value = &p->val;
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
if (UNEXPECTED(value_type == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
break;
}
} else {
break;
}
}
pos++;
p++;
}
Z_FE_POS_P(array) = pos + 1;
if (RETURN_VALUE_USED(opline)) {
if (!p->key) {
ZVAL_LONG(EX_VAR(opline->result.var), p->h);
} else {
ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
}
}

variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
zend_assign_to_variable(variable_ptr, value, IS_CV);
ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);

ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
Expand Down
225 changes: 218 additions & 7 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -17357,7 +17357,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
ZEND_VM_NEXT_OPCODE();
}


static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
Expand Down Expand Up @@ -17386,7 +17385,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
ZEND_VM_NEXT_OPCODE();
}


static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
Expand Down Expand Up @@ -24209,6 +24207,110 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
ZEND_VM_RETURN();
}

static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *array;
zval *value, *variable_ptr;
uint32_t value_type;
HashTable *fe_ht;
HashPosition pos;
Bucket *p;

array = EX_VAR(opline->op1.var);
SAVE_OPLINE();
fe_ht = Z_ARRVAL_P(array);
pos = Z_FE_POS_P(array);
p = fe_ht->arData + pos;
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
value = &p->val;
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
if (UNEXPECTED(value_type == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
break;
}
} else {
break;
}
}
pos++;
p++;
}
Z_FE_POS_P(array) = pos + 1;
if (0) {
if (!p->key) {
ZVAL_LONG(EX_VAR(opline->result.var), p->h);
} else {
ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
}
}

variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
zend_assign_to_variable(variable_ptr, value, IS_CV);
ZEND_VM_NEXT_OPCODE();
}


static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *array;
zval *value, *variable_ptr;
uint32_t value_type;
HashTable *fe_ht;
HashPosition pos;
Bucket *p;

array = EX_VAR(opline->op1.var);
SAVE_OPLINE();
fe_ht = Z_ARRVAL_P(array);
pos = Z_FE_POS_P(array);
p = fe_ht->arData + pos;
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
value = &p->val;
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
if (UNEXPECTED(value_type == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
value_type = Z_TYPE_INFO_P(value);
if (EXPECTED(value_type != IS_UNDEF)) {
break;
}
} else {
break;
}
}
pos++;
p++;
}
Z_FE_POS_P(array) = pos + 1;
if (1) {
if (!p->key) {
ZVAL_LONG(EX_VAR(opline->result.var), p->h);
} else {
ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
}
}

variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
zend_assign_to_variable(variable_ptr, value, IS_CV);
ZEND_VM_NEXT_OPCODE();
}


static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
Expand Down Expand Up @@ -34152,7 +34254,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
ZEND_VM_NEXT_OPCODE();
}


static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
Expand Down Expand Up @@ -34181,7 +34282,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
ZEND_VM_NEXT_OPCODE();
}


static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
Expand Down Expand Up @@ -58905,6 +59005,56 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_LABEL,
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_QUICK_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_LABEL,
(void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL
};
zend_opcode_handlers = (const void **) labels;
Expand Down Expand Up @@ -60583,6 +60733,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_CASE(ZEND_YIELD_SPEC_VAR_CV):
ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED):
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED):
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR):
ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
Expand Down Expand Up @@ -67783,6 +67939,56 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER,
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_QUICK_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER,
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER
};
static const uint32_t specs[] = {
Expand Down Expand Up @@ -67886,7 +68092,7 @@ void zend_init_opcodes_handlers(void)
2257 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2282 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2307 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
4821,
4871,
2332,
2333,
2334,
Expand Down Expand Up @@ -67971,7 +68177,7 @@ void zend_init_opcodes_handlers(void)
3531 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3556 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3581 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
4821,
4871,
3606 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
Expand All @@ -67982,7 +68188,7 @@ void zend_init_opcodes_handlers(void)
3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
4821
4871
};
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
zend_opcode_handler_funcs = labels;
Expand Down Expand Up @@ -68356,6 +68562,11 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
spec = 4811 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG;
}
break;
case ZEND_FE_FETCH_R:
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
spec = 4821 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_RETVAL;
}
break;
case ZEND_FETCH_DIM_R:
if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
spec = 4781 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
Expand Down

0 comments on commit 7802cf8

Please sign in to comment.