Re: Runtime-JIT, the whole enchilada
| From: | Ilia Alshanetsky | Date: | Wed, 24 Jan 2007 21:27:44 +0000 |
| Subject: | Re: Runtime-JIT, the whole enchilada | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-27640@lists.php.net to get a copy of this message | ||
What are the numbers before the patch?
On 24-Jan-07, at 2:58 PM, Sara Golemon wrote:
Dmitry- You asked for it, you get it :) Hopefully it'll be self-explanatory, the one part I hope you don't notice is that I put the auto_global check back into fetch_simple_variable_ex in order toIlia Alshanetskyforce direct access to autoglobals ($foo = $_GET; foreach($_POST as ...) etc...) as non-auto-globals. Ultimately this made catching the difference between a whole var access and a dim/obj access much more straight-forward and computationally cheap. It comes at a slight cost for those fetches, but hopefully they're in the minority.Bench numbers with this patch:simple 0.461 simplecall 1.985 simpleucall 2.900 simpleudcall 3.488 mandel 2.136 mandel2 3.192 ackermann(7) 3.490 ary(50000) 0.154 ary2(50000) 0.137 ary3(2000) 1.076 fibo(30) 9.766 hash1(50000) 0.423 hash2(500) 0.307 heapsort(20000) 0.799 matrix(20) 0.526 nestedloop(12) 0.866 sieve(30) 0.630 strcat(200000) 0.303------------------------Total 32.639-Sara Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.736 diff -u -p -r1.736 zend_compile.c --- Zend/zend_compile.c 20 Jan 2007 20:36:55 -0000 1.736 +++ Zend/zend_compile.c 24 Jan 2007 19:50:52 -0000 @@ -290,7 +290,8 @@ static int lookup_cv(zend_op_array *op_a op_array->vars[i].name = name; /* estrndup(name, name_len); */ op_array->vars[i].name_len = name_len; op_array->vars[i].hash_value = hash_value; - op_array->vars[i].fetch_type = zend_u_is_auto_global(type, name, name_len TSRMLS_CC) ? ZEND_FETCH_GLOBAL : ZEND_FETCH_LOCAL; + op_array->vars[i].auto_global = NULL; + op_array->vars[i].fetch_type = zend_u_is_auto_global(type, name, name_len, &(op_array->vars[i].auto_global) TSRMLS_CC) ? ZEND_FETCH_GLOBAL : ZEND_FETCH_LOCAL; return i; } @@ -383,6 +384,7 @@ void fetch_simple_variable_ex(znode *resZ_TYPE(varname->u.constant) == IS_UNICODE) && !(Z_UNILEN(varname->u.constant) == (sizeof("this")-1) && ZEND_U_EQUAL(Z_TYPE(varname->u.constant), Z_UNIVAL(varname-u.constant), Z_UNILEN(varname->u.constant), "this", sizeof("this")-1)) && + !zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), NULL TSRMLS_CC) && (CG(active_op_array)->last == 0 || CG(active_op_array)->opcodes[CG(active_op_array)-last-1].opcode != ZEND_BEGIN_SILENCE)) {result->op_type = IS_CV; @@ -410,7 +412,7 @@ void fetch_simple_variable_ex(znode *res if (varname->op_type == IS_CONST &&(Z_TYPE(varname->u.constant) == IS_STRING || Z_TYPE(varname->u.constant) == IS_UNICODE)) { - if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant) TSRMLS_CC)) { + if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), NULL TSRMLS_CC)) {opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL; } } @@ -492,6 +494,29 @@ void fetch_array_dim(znode *result, znod zend_op opline; zend_llist *fetch_list_ptr; + zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); + if (fetch_list_ptr->count == 1) { + zend_llist_element *le = fetch_list_ptr->head; + zend_op *parentop = (zend_op*)le->data; + + if (parentop && parentop->opcode == ZEND_FETCH_W && + parent->op_type == IS_VAR && parentop->result.op_type == IS_VAR && parent->u.var == parentop->result.u.var && + parentop->op1.op_type == IS_CONST && + (Z_TYPE(parentop->op1.u.constant) == IS_STRING || Z_TYPE(parentop->op1.u.constant) == IS_UNICODE) && + !(Z_UNILEN(parentop->op1.u.constant) == (sizeof("this")-1) && ZEND_U_EQUAL(Z_TYPE(parentop->op1.u.constant), Z_UNIVAL(parentop-op1.u.constant), Z_UNILEN(parentop->op1.u.constant), "this", sizeof("this")-1)) ) { + /* Recompile CV and rewrite previous op to direct FETCH_DIM */ + zval tmp = parentop->op1.u.constant; + parentop->opcode = ZEND_FETCH_DIM_W; + parentop->op1.op_type = IS_CV; + parentop->op1.u.var = lookup_cv(CG(active_op_array), Z_TYPE(tmp), Z_UNIVAL(tmp), Z_UNILEN(tmp) TSRMLS_CC); + parentop->op1.u.EA.type = 0; + parentop->op2 = *dim; + parentop->extended_value = ZEND_FETCH_STANDARD; + *result = parentop->result; + return; + } + } + init_op(&opline TSRMLS_CC); opline.opcode = ZEND_FETCH_DIM_W; /* the backpatching routine assumes W */ opline.result.op_type = IS_VAR; @@ -502,7 +527,6 @@ void fetch_array_dim(znode *result, znod opline.extended_value = ZEND_FETCH_STANDARD; *result = opline.result; - zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); zend_llist_add_element(fetch_list_ptr, &opline); } @@ -3261,7 +3285,6 @@ void zend_do_fetch_property(znode *resul zend_op *opline_ptr=NULL; zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); - if (fetch_list_ptr->count == 1) { zend_llist_element *le; @@ -3295,6 +3318,19 @@ void zend_do_fetch_property(znode *resul } *result = opline_ptr->result; return; + } else if (opline_ptr && opline_ptr->opcode == ZEND_FETCH_W && + object->op_type == IS_VAR && opline_ptr->result.op_type == IS_VAR && object->u.var == opline_ptr->result.u.var && + opline_ptr->op1.op_type == IS_CONST && + (Z_TYPE(opline_ptr->op1.u.constant) == IS_STRING || Z_TYPE(opline_ptr->op1.u.constant) == IS_UNICODE) ) { + /* Recompile CV and rewrite previous op to direct FETCH_OBJ */ + zval tmp = opline_ptr->op1.u.constant; + opline_ptr->opcode = ZEND_FETCH_OBJ_W; + opline_ptr->op1.op_type = IS_CV; + opline_ptr->op1.u.var = lookup_cv(CG(active_op_array), Z_TYPE(tmp), Z_UNIVAL(tmp), Z_UNILEN(tmp) TSRMLS_CC); + opline_ptr->op1.u.EA.type = 0; + opline_ptr->op2 = *property; + *result = opline_ptr->result; + return; } } @@ -4312,13 +4348,16 @@ void zend_auto_global_dtor(zend_auto_glo } -zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len TSRMLS_DC) +zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len, zend_auto_global **pauto TSRMLS_DC) { zend_auto_global *auto_global; if (zend_u_hash_find(CG(auto_globals), type, name, name_len+1, (void **) &auto_global)==SUCCESS) { if (auto_global->armed) { - auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC); + auto_global->armed = auto_global->auto_global_callback(auto_global, ZEND_CT, NULL, 0, NULL TSRMLS_CC); + } + if (pauto) { + *pauto = auto_global; } return 1; } @@ -4327,21 +4366,26 @@ zend_bool zend_u_is_auto_global(zend_uch zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC) { - return zend_u_is_auto_global(IS_STRING, ZSTR(name), name_len TSRMLS_CC); + return zend_u_is_auto_global(IS_STRING, ZSTR(name), name_len, NULL TSRMLS_CC); } -int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC) +int zend_register_auto_global_ex(char *name, uint name_len, zend_auto_global_callback auto_global_callback, zend_auto_global **pauto TSRMLS_DC) { zend_auto_global auto_global; auto_global.name = zend_strndup(name, name_len); auto_global.name_len = name_len; auto_global.auto_global_callback = auto_global_callback; + auto_global.armed = auto_global_callback ? 1 : 0; - return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL); + return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), (void**)pauto); } +int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC) +{ + return zend_register_auto_global_ex(name, name_len, auto_global_callback, NULL TSRMLS_CC); +} int zendlex(znode *zendlval TSRMLS_DC) { Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.353 diff -u -p -r1.353 zend_compile.h --- Zend/zend_compile.h 20 Jan 2007 20:36:55 -0000 1.353 +++ Zend/zend_compile.h 24 Jan 2007 19:50:52 -0000 @@ -51,6 +51,7 @@ typedef struct _zend_op_array zend_op_array; typedef struct _zend_op zend_op; +typedef struct _zend_auto_global zend_auto_global; typedef struct _znode { int op_type; @@ -175,6 +176,7 @@ typedef struct _zend_compiled_variable { int name_len; ulong hash_value; zend_uint fetch_type; + zend_auto_global *auto_global; } zend_compiled_variable; struct _zend_op_array { @@ -575,18 +577,19 @@ ZEND_API char *zend_make_compiled_string ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC); int zend_get_class_fetch_type(zend_uchar type, zstr class_name, uint class_name_len); -typedef zend_bool (*zend_auto_global_callback)(char *name, uint name_len TSRMLS_DC); -typedef struct _zend_auto_global { +typedef zend_bool (*zend_auto_global_callback)(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC); +struct _zend_auto_global { char *name; uint name_len; zend_auto_global_callback auto_global_callback; zend_bool armed; -} zend_auto_global; +}; void zend_auto_global_dtor(zend_auto_global *auto_global); +ZEND_API int zend_register_auto_global_ex(char *name, uint name_len, zend_auto_global_callback auto_global_callback, zend_auto_global **pauto TSRMLS_DC); ZEND_API int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC); ZEND_API zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC); -ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len TSRMLS_DC); +ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len, zend_auto_global **pauto TSRMLS_DC); ZEND_API int zend_auto_global_disable_jit(char *varname, zend_uint varname_length TSRMLS_DC); int zendlex(znode *zendlval TSRMLS_DC); Index: Zend/zend_execute.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute.c,v retrieving revision 1.758 diff -u -p -r1.758 zend_execute.c --- Zend/zend_execute.c 20 Jan 2007 20:36:55 -0000 1.758 +++ Zend/zend_execute.c 24 Jan 2007 19:50:52 -0000 @@ -903,8 +903,17 @@ static inline HashTable *zend_get_target break; case ZEND_FETCH_GLOBAL: case ZEND_FETCH_GLOBAL_LOCK: + { + zend_auto_global *auto_global; + + if ((Z_TYPE_P(variable) == IS_STRING || Z_TYPE_P(variable) == IS_UNICODE) && + SUCCESS == zend_u_hash_find(CG(auto_globals), Z_TYPE_P(variable), Z_UNIVAL_P(variable), Z_UNILEN_P(variable) + 1, (void **) &auto_global) && + auto_global->armed && auto_global->auto_global_callback) { + auto_global->armed = auto_global->auto_global_callback(auto_global, ZEND_RT, NULL, ZEND_FETCH_R + (3 * type), NULL TSRMLS_CC); + } return &EG(symbol_table); break; + } case ZEND_FETCH_STATIC: if (!EG(active_op_array)->static_variables) { ALLOC_HASHTABLE(EG(active_op_array)->static_variables); @@ -1030,7 +1039,7 @@ fetch_string_dim: return retval; } -static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) +static void zend_fetch_dimension_address(znode *container_node, temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC) { zval *container; @@ -1039,6 +1048,13 @@ static void zend_fetch_dimension_address } container = *container_ptr; + if (container_node->op_type == IS_CV) { + zend_auto_global *auto_global = CV_DEF_OF(container_node-u.var).auto_global; + + if (auto_global && auto_global->armed && auto_global-auto_global_callback) { + auto_global->armed = auto_global->auto_global_callback(auto_global, ZEND_RT, container, ZEND_FETCH_DIM_R + (3 * type), dim TSRMLS_CC); + } + } if (container == EG(error_zval_ptr)) { if (result) { @@ -1232,11 +1248,19 @@ static void zend_fetch_dimension_address } } -static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC) +static void zend_fetch_property_address(znode *container_node, temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC) { zval *container; container = *container_ptr; + if (container_node->op_type == IS_CV) { + zend_auto_global *auto_global = CV_DEF_OF(container_node-u.var).auto_global; + + if (auto_global && auto_global->armed && auto_global-auto_global_callback) { + auto_global->armed = auto_global->auto_global_callback(auto_global, ZEND_RT, container, ZEND_FETCH_OBJ_R + (3 * type), prop_ptr TSRMLS_CC); + } + } + if (container == EG(error_zval_ptr)) { if (result) { result->var.ptr_ptr = &EG(error_zval_ptr); Index: Zend/zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.155 diff -u -p -r1.155 zend_vm_def.h --- Zend/zend_vm_def.h 11 Jan 2007 22:35:36 -0000 1.155 +++ Zend/zend_vm_def.h 24 Jan 2007 19:50:52 -0000 @@ -418,7 +418,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_ zend_op *op_data = opline+1; zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, &EX_T(op_data-op2.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW); increment_opline = 1; @@ -1066,7 +1066,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAEX_T(opline->op1.u.var).var.ptr_ptr) {PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC); FREE_OP2(); FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE(); @@ -1078,7 +1078,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VA zend_free_op free_op1, free_op2; zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && OP1_FREE &&READY_TO_DESTROY(free_op1.var) &&@@ -1095,7 +1095,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, V zend_free_op free_op1, free_op2; zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && OP1_FREE &&READY_TO_DESTROY(free_op1.var) &&@@ -1112,7 +1112,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, V zend_free_op free_op1, free_op2; zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC); FREE_OP2(); FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE(); @@ -1129,7 +1129,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && type == BP_VAR_W && OP1_FREE &&READY_TO_DESTROY(free_op1.var) &&@@ -1157,7 +1157,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, IS_OP2_TMP_FREE(), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, IS_OP2_TMP_FREE(), BP_VAR_UNSET TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && OP1_FREE &&READY_TO_DESTROY(free_op1.var) &&@@ -1218,6 +1218,14 @@ ZEND_VM_HELPER_EX(zend_fetch_property_ad MAKE_REAL_ZVAL_PTR(offset); } + if (opline->op1.op_type == IS_CV) { + zend_auto_global *auto_global = CV_DEF_OF(opline-op1.u.var).auto_global; + + if (auto_global && auto_global->armed && auto_global-auto_global_callback) { + auto_global->armed = auto_global->auto_global_callback(auto_global, ZEND_RT, container, ZEND_FETCH_OBJ_R + (3 * type), offset TSRMLS_CC); + } + } + /* here we are sure we are dealing with an object */ *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC); @@ -1259,7 +1267,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VA if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC); if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&property); } else { @@ -1283,7 +1291,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, V if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW), property, BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW), property, BP_VAR_RW TSRMLS_CC); if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&property); } else { @@ -1315,7 +1323,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC); if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&property); } else { @@ -1348,7 +1356,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC); + zend_fetch_property_address(&opline->op1, RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC); if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&property); } else { @@ -1428,7 +1436,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VA zval *value; zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC); + zend_fetch_dimension_address(&opline->op1, &EX_T(op_data-op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC); FREE_OP2(); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); Index: main/php_variables.c =================================================================== RCS file: /repository/php-src/main/php_variables.c,v retrieving revision 1.136 diff -u -p -r1.136 php_variables.c --- main/php_variables.c 1 Jan 2007 09:29:35 -0000 1.136 +++ main/php_variables.c 24 Jan 2007 19:50:52 -0000 @@ -628,9 +628,9 @@ void _php_import_environment_variables(z } } -zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC) +zend_bool php_std_auto_global_callback(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC) { - zend_printf("%s\n", name); + zend_printf("%s\n", auto_global->name); return 0; /* don't rearm */ } @@ -802,9 +802,13 @@ static void php_autoglobal_merge(HashTab } /* }}} */ -static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC); -static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC); -static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRMLS_DC); +static zend_auto_global *php_server_auto_global = NULL; +static zend_auto_global *php_env_auto_global = NULL; +static zend_auto_global *php_request_auto_global = NULL; + +static zend_bool php_auto_globals_create_server(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC); +static zend_bool php_auto_globals_create_env(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC); +static zend_bool php_auto_globals_create_request(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC); /* {{{ php_hash_environment */ @@ -861,16 +865,14 @@ int php_hash_environment(TSRMLS_D) case 'e': case 'E': if (!jit_initialization && !_gpc_flags[3]) { - zend_auto_global_disable_jit("_ENV", sizeof("_ENV")-1 TSRMLS_CC); - php_auto_globals_create_env("_ENV", sizeof("_ENV")-1 TSRMLS_CC); + php_env_auto_global->armed = php_auto_globals_create_env(php_env_auto_global, ZEND_RT, NULL, ZEND_FETCH_R, NULL TSRMLS_CC); _gpc_flags[3] = 1; } break; case 's': case 'S': if (!jit_initialization && !_gpc_flags[4]) { - zend_auto_global_disable_jit("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); - php_register_server_variables(TSRMLS_C); + php_server_auto_global->armed = php_auto_globals_create_server(php_server_auto_global, ZEND_RT, NULL, ZEND_FETCH_R, NULL TSRMLS_CC); _gpc_flags[4] = 1; } break; @@ -904,15 +906,14 @@ int php_hash_environment(TSRMLS_D) /* Create _REQUEST */ if (!jit_initialization) { - zend_auto_global_disable_jit("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC); - php_auto_globals_create_request("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC); + php_request_auto_global->armed = php_auto_globals_create_request(php_request_auto_global, ZEND_RT, NULL, ZEND_FETCH_R, NULL TSRMLS_CC); } return SUCCESS; } /* }}} */ -static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_server(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC) { if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) { php_register_server_variables(TSRMLS_C); @@ -944,13 +945,13 @@ static zend_bool php_auto_globals_create PG(http_globals)[TRACK_VARS_SERVER] = server_vars; } - zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL); + zend_ascii_hash_update(&EG(symbol_table), auto_global->name, auto_global->name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL); PG(http_globals)[TRACK_VARS_SERVER]->refcount++; return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_env(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC) { zval *env_vars = NULL; ALLOC_ZVAL(env_vars); @@ -965,13 +966,13 @@ static zend_bool php_auto_globals_create php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC); } - zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL); + zend_ascii_hash_update(&EG(symbol_table), auto_global->name, auto_global->name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL); PG(http_globals)[TRACK_VARS_ENV]->refcount++; return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_request(zend_auto_global *auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC) { zval *form_variables; unsigned char _gpc_flags[3] = {0, 0, 0}; @@ -1007,7 +1008,7 @@ static zend_bool php_auto_globals_create } } - zend_ascii_hash_update(&EG(symbol_table), "_REQUEST", sizeof("_REQUEST"), &form_variables, sizeof(zval *), NULL); + zend_ascii_hash_update(&EG(symbol_table), auto_global->name, auto_global->name_len + 1, &form_variables, sizeof(zval *), NULL); return 0; } @@ -1016,9 +1017,9 @@ void php_startup_auto_globals(TSRMLS_D) zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC); zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC); zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL TSRMLS_CC); - zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server TSRMLS_CC); - zend_register_auto_global("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env TSRMLS_CC); - zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request TSRMLS_CC); + zend_register_auto_global_ex("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server, &php_server_auto_global TSRMLS_CC); + zend_register_auto_global_ex("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env, &php_env_auto_global TSRMLS_CC); + zend_register_auto_global_ex("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request, &php_request_auto_global TSRMLS_CC); zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC); } --PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php