Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:27640 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 9380 invoked by uid 1010); 24 Jan 2007 21:27:52 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 9365 invoked from network); 24 Jan 2007 21:27:52 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Jan 2007 21:27:52 -0000 Authentication-Results: pb1.pair.com header.from=ilia@prohost.org; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=ilia@prohost.org; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain prohost.org from 64.233.166.183 cause and error) X-PHP-List-Original-Sender: ilia@prohost.org X-Host-Fingerprint: 64.233.166.183 py-out-1112.google.com Linux 2.4/2.6 Received: from [64.233.166.183] ([64.233.166.183:54357] helo=py-out-1112.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 3D/D9-43654-85FC7B54 for ; Wed, 24 Jan 2007 16:27:52 -0500 Received: by py-out-1112.google.com with SMTP id a25so145352pyi for ; Wed, 24 Jan 2007 13:27:49 -0800 (PST) Received: by 10.35.78.9 with SMTP id f9mr2335782pyl.1169674069599; Wed, 24 Jan 2007 13:27:49 -0800 (PST) Received: from ?192.168.1.150? ( [204.101.63.110]) by mx.google.com with ESMTP id f78sm1142797pyh.2007.01.24.13.27.47; Wed, 24 Jan 2007 13:27:48 -0800 (PST) In-Reply-To: <45B7BA56.40406@php.net> References: <45B7BA56.40406@php.net> Mime-Version: 1.0 (Apple Message framework v752.3) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-ID: <513F1B99-45BC-40EB-BD1E-7715C4F415AD@prohost.org> Cc: "internals@lists.php.net List" Content-Transfer-Encoding: 7bit Date: Wed, 24 Jan 2007 16:27:44 -0500 To: Sara Golemon X-Mailer: Apple Mail (2.752.3) Subject: Re: [PHP-DEV] Runtime-JIT, the whole enchilada From: ilia@prohost.org (Ilia Alshanetsky) 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 to > force 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 *res > Z_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, VA > EX_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 Ilia Alshanetsky