Changeset 212
Legend:
- Unmodified
- Added
- Removed
-
trunk/coverager.c
r208 r212 147 147 for (; len >= sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) { 148 148 if (zend_hash_index_find(cov, p[0], (void**)&phits) == SUCCESS) { 149 if (p[1] == 0) {149 if (p[1] == -1) { 150 150 /* OPTIMIZE: already marked */ 151 151 continue; 152 152 } 153 p[1] += *phits; 153 if (*phits != -1) { 154 p[1] += *phits; 155 } 154 156 } 155 157 zend_hash_index_update(cov, p[0], &p[1], sizeof(p[1]), NULL); … … 219 221 long hits = *phits; 220 222 221 if (hits != 0) {222 hits = 0;223 if (hits != -1) { 224 hits = -1; 223 225 zend_hash_index_update(cov, pos2->h, &hits, sizeof(hits), NULL); 224 226 } … … 377 379 } 378 380 if (zend_hash_index_find(cov, line, (void**)&poldhits) == SUCCESS) { 379 if (hits == 0) {380 /* OPTIMIZE: already marked */381 if (hits == -1) { 382 /* OPTIMIZE: -1 == init-ing, but it's already initized */ 381 383 return; 382 384 } 383 hits += *poldhits; 385 if (*poldhits != -1) { 386 hits += *poldhits; 387 } 384 388 } 385 389 zend_hash_index_update(cov, line, &hits, sizeof(hits), NULL); … … 430 434 case ZEND_EXT_FCALL_END: 431 435 #endif 432 xc_coverager_add_hits(cov, op_array->opcodes[i].lineno, 0TSRMLS_CC);436 xc_coverager_add_hits(cov, op_array->opcodes[i].lineno, -1 TSRMLS_CC); 433 437 break; 434 438 } -
trunk/processor/processor.m4
r200 r212 474 474 DEF_STRUCT_P_FUNC(`zend_op_array', , `dnl {{{ 475 475 IFRESTORE(` 476 if (!processor->readonly_protection) { 476 dnl shadow copy must NOT meet: 477 dnl readonly_protection=on 478 dnl main op_array && have early binding 479 if (!processor->readonly_protection && !(src == processor->xce_src->data.php->op_array && processor->xce_src->data.php->have_early_binding)) { 477 480 /* really fast shallow copy */ 478 481 memcpy(dst, src, sizeof(src[0])); … … 685 688 STRUCT(zend_class_entry, cest) 686 689 #endif 690 DISPATCH(int, oplineno) 687 691 ') 688 692 dnl }}} … … 715 719 ') 716 720 STRUCT_ARRAY(classinfo_cnt, xc_classinfo_t, classinfos) 721 DISPATCH(zend_bool, have_early_binding) 717 722 popdef(`BEFORE_LOOP') 718 723 ') -
trunk/utils.c
r210 r212 1 #include "php.h" 1 2 2 #include "xcache.h" 3 3 #include "utils.h" … … 9 9 #include "assert.h" 10 10 11 #ifndef ZEND_VM_SET_OPCODE_HANDLER 12 # define ZEND_VM_SET_OPCODE_HANDLER(opline) do { } while (0) 13 #endif 14 15 #define OP_ZVAL_DTOR(op) do { \ 16 (op).u.constant.is_ref = 0; \ 17 zval_dtor(&(op).u.constant); \ 18 } while(0) 11 19 xc_compile_result_t *xc_compile_result_init(xc_compile_result_t *cr, /* {{{ */ 12 20 zend_op_array *op_array, … … 264 272 /* }}} */ 265 273 #endif 274 275 int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC) /* {{{ */ 276 { 277 zend_op *opline, *begin, *end, *next = NULL; 278 xc_cest_t cest; 279 280 opline = begin = op_array->opcodes; 281 end = opline + op_array->last; 282 while (opline < end) { 283 switch (opline->opcode) { 284 case ZEND_JMP: 285 next = begin + opline->op1.u.opline_num; 286 break; 287 288 case ZEND_JMPZNZ: 289 next = begin + max(opline->op2.u.opline_num, opline->extended_value); 290 break; 291 292 case ZEND_JMPZ: 293 case ZEND_JMPNZ: 294 case ZEND_JMPZ_EX: 295 case ZEND_JMPNZ_EX: 296 next = begin + opline->op2.u.opline_num; 297 break; 298 299 case ZEND_RETURN: 300 opline = end; 301 break; 302 303 case ZEND_DECLARE_INHERITED_CLASS: 304 callback(opline, opline - begin, data TSRMLS_CC); 305 break; 306 } 307 308 if (opline < next) { 309 opline = next; 310 } 311 else { 312 opline ++; 313 } 314 } 315 } 316 /* }}} */ 317 int xc_do_early_binding(zend_op_array *op_array, HashTable *class_table, int oplineno TSRMLS_DC) /* {{{ */ 318 { 319 zend_op *opline, *opcodes; 320 321 #ifdef DEBUG 322 fprintf(stderr, "binding %d\n", oplineno); 323 #endif 324 assert(oplineno >= 0); 325 326 /* do early binding */ 327 opline = &(op_array->opcodes[oplineno]); 328 329 switch (opline->opcode) { 330 case ZEND_DECLARE_INHERITED_CLASS: 331 #ifdef ZEND_ENGINE_2 332 { 333 zval *parent_name; 334 zend_class_entry **pce; 335 parent_name = &(opline - 1)->op2.u.constant; 336 #ifdef DEBUG 337 fprintf(stderr, "binding with parent %s\n", Z_STRVAL_P(parent_name)); 338 #endif 339 if (zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) { 340 return FAILURE; 341 } 342 343 if (do_bind_inherited_class(opline, class_table, *pce, 1 TSRMLS_CC) == NULL) { 344 return FAILURE; 345 } 346 } 347 #else 348 if (do_bind_function_or_class(opline, NULL, class_table, 1) == FAILURE) { 349 return FAILURE; 350 } 351 #endif 352 353 #ifdef ZEND_FETCH_CLASS 354 /* clear unnecessary ZEND_FETCH_CLASS opcode */ 355 if (opline > op_array->opcodes 356 && (opline - 1)->opcode == ZEND_FETCH_CLASS) { 357 zend_op *fetch_class_opline = opline - 1; 358 359 #ifdef DEBUG 360 fprintf(stderr, "%s %p\n", Z_STRVAL(fetch_class_opline->op2.u.constant), Z_STRVAL(fetch_class_opline->op2.u.constant)); 361 #endif 362 OP_ZVAL_DTOR(fetch_class_opline->op2); 363 fetch_class_opline->opcode = ZEND_NOP; 364 ZEND_VM_SET_OPCODE_HANDLER(fetch_class_opline); 365 memset(&fetch_class_opline->op1, 0, sizeof(znode)); 366 memset(&fetch_class_opline->op2, 0, sizeof(znode)); 367 SET_UNUSED(fetch_class_opline->op1); 368 SET_UNUSED(fetch_class_opline->op2); 369 SET_UNUSED(fetch_class_opline->result); 370 } 371 #endif 372 break; 373 374 default: 375 return FAILURE; 376 } 377 378 zend_hash_del(class_table, opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len); 379 OP_ZVAL_DTOR(opline->op1); 380 OP_ZVAL_DTOR(opline->op2); 381 opline->opcode = ZEND_NOP; 382 ZEND_VM_SET_OPCODE_HANDLER(opline); 383 memset(&opline->op1, 0, sizeof(znode)); 384 memset(&opline->op2, 0, sizeof(znode)); 385 SET_UNUSED(opline->op1); 386 SET_UNUSED(opline->op2); 387 return SUCCESS; 388 } 389 /* }}} */ 266 390 267 391 #ifdef HAVE_XCACHE_CONSTANT … … 320 444 } 321 445 /* }}} */ 322 ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, zstr key, uint len TSRMLS_DC) /* {{{ */446 ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, zstr key, uint len TSRMLS_DC) /* {{{ */ 323 447 { 324 448 zend_bool istmpkey; … … 336 460 ZESW(&stored_ce_ptr, NULL) 337 461 ); 462 if (oplineno != -1) { 463 xc_do_early_binding(CG(active_op_array), CG(class_table), oplineno TSRMLS_CC); 464 } 338 465 } 339 466 else if (zend_u_hash_add(CG(class_table), type, key, len, … … 349 476 zend_error(E_ERROR, "Cannot redeclare class %s", cep->name); 350 477 #endif 478 assert(oplineno == -1); 351 479 } 352 480 ZESW(return (xc_cest_t *) stored_ce_ptr, NOTHING); … … 403 531 404 532 return sandbox; 533 } 534 /* }}} */ 535 static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */ 536 { 537 xc_sandbox_t *sandbox = (xc_sandbox_t *) data; 538 xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC); 405 539 } 406 540 /* }}} */ … … 433 567 /* install class */ 434 568 while (b != NULL) { 435 xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, 569 xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1, 436 570 BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength TSRMLS_CC); 437 571 b = b->pListNext; 438 572 } 573 xc_undo_pass_two(CG(active_op_array) TSRMLS_CC); 574 xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC); 575 xc_redo_pass_two(CG(active_op_array) TSRMLS_CC); 439 576 440 577 i = 1; -
trunk/utils.h
r209 r212 25 25 zend_uchar xc_get_fixed_opcode(zend_uchar opcode, int line); 26 26 27 int xc_foreach_early_binding_class(zend_op_array *op_array, void (*callback)(zend_op *opline, int oplineno, void *data TSRMLS_DC), void *data TSRMLS_DC); 28 27 29 /* installer */ 28 30 #ifdef HAVE_XCACHE_CONSTANT … … 30 32 #endif 31 33 void xc_install_function(char *filename, zend_function *func, zend_uchar type, zstr key, uint len TSRMLS_DC); 32 ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, zend_uchar type, zstr key, uint len TSRMLS_DC);34 ZESW(xc_cest_t *, void) xc_install_class(char *filename, xc_cest_t *cest, int oplineno, zend_uchar type, zstr key, uint len TSRMLS_DC); 33 35 34 36 /* sandbox */ -
trunk/xcache.c
r205 r212 66 66 } \ 67 67 } while(0) 68 69 #ifndef max 70 #define max(a, b) ((a) < (b) ? (b) : (a)) 71 #endif 68 72 69 73 /* }}} */ … … 542 546 #endif 543 547 548 CG(active_op_array) = p->op_array; 549 544 550 #ifdef HAVE_XCACHE_CONSTANT 545 551 /* install constant */ … … 571 577 new_cest_ptrs[i] = 572 578 #endif 573 xc_install_class(xce->name.str.val, &ci->cest, 579 xc_install_class(xce->name.str.val, &ci->cest, ci->oplineno, 574 580 UNISW(0, ci->type), ci->key, ci->key_size TSRMLS_CC); 575 581 } … … 771 777 xce->type = XC_TYPE_PHP; 772 778 return 1; 779 } 780 /* }}} */ 781 static void xc_cache_early_binding_class_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */ 782 { 783 char *class_name; 784 int i, class_len; 785 xc_cest_t cest; 786 xc_entry_data_php_t *php = (xc_entry_data_php_t *) data; 787 788 class_name = opline->op1.u.constant.value.str.val; 789 class_len = opline->op1.u.constant.value.str.len; 790 if (zend_hash_find(CG(class_table), class_name, class_len, (void **) &cest) == FAILURE) { 791 assert(0); 792 } 793 #ifdef DEBUG 794 fprintf(stderr, "got ZEND_DECLARE_INHERITED_CLASS: %s\n", class_name + 1); 795 #endif 796 /* let's see which class */ 797 for (i = 0; i < php->classinfo_cnt; i ++) { 798 if (memcmp(ZSTR_S(php->classinfos[i].key), class_name, class_len) == 0) { 799 php->classinfos[i].oplineno = oplineno; 800 php->have_early_binding = 1; 801 break; 802 } 803 } 804 805 if (i == php->classinfo_cnt) { 806 assert(0); 807 } 773 808 } 774 809 /* }}} */ … … 785 820 char opened_path_buffer[MAXPATHLEN]; 786 821 int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt; 822 int i; 787 823 788 824 if (!xc_initized) { … … 895 931 #ifdef HAVE_INODE 896 932 if (xce.data.php->inode) 897 #endif898 933 { 899 934 if (xce.name.str.val != filename) { … … 902 937 } 903 938 } 939 #endif 904 940 905 941 #ifdef HAVE_XCACHE_OPTIMIZER … … 908 944 } 909 945 #endif 910 946 /* }}} */ 947 /* {{{ prepare */ 911 948 php.op_array = op_array; 912 949 … … 972 1009 } 973 1010 /* }}} */ 1011 /* {{{ find inherited classes that should be early-binding */ 1012 php.have_early_binding = 0; 1013 for (i = 0; i < php.classinfo_cnt; i ++) { 1014 php.classinfos[i].oplineno = -1; 1015 } 1016 1017 xc_undo_pass_two(php.op_array TSRMLS_CC); 1018 xc_foreach_early_binding_class(php.op_array, xc_cache_early_binding_class_cb, (void *) &php TSRMLS_CC); 1019 xc_redo_pass_two(php.op_array TSRMLS_CC); 1020 /* }}} */ 974 1021 ENTER_LOCK_EX(cache) { /* {{{ store/add entry */ 975 1022 stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); … … 1001 1048 } 1002 1049 else { 1050 CG(active_op_array) = op_array; 1003 1051 xc_sandbox_free(&sandbox, 1 TSRMLS_CC); 1004 1052 } -
trunk/xcache.h
r200 r212 169 169 zend_uint key_size; 170 170 xc_cest_t cest; 171 int oplineno; 171 172 } xc_classinfo_t; 172 173 /* }}} */ … … 215 216 zend_uint classinfo_cnt; 216 217 xc_classinfo_t *classinfos; 218 zend_bool have_early_binding; 217 219 } xc_entry_data_php_t; 218 220 /* }}} */

