From: Dmitry Stogov Date: Mon, 15 May 2006 15:31:50 +0000 (+0000) Subject: Optimized require_once/include_once (eliminated fopen() on second usage) X-Git-Tag: BEFORE_NEW_OUTPUT_API~190 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb1a172cae6dbc1a7fed661160f132b66d4a4b3d;p=php Optimized require_once/include_once (eliminated fopen() on second usage) --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index f3d9b6a76b..b44e4517be 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -38,6 +38,9 @@ #include "zend_vm.h" #include "zend_unicode.h" +/* Virtual current working directory support */ +#include "tsrm_virtual_cwd.h" + #define _CONST_CODE 0 #define _TMP_CODE 1 #define _VAR_CODE 2 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 5889bcfc0e..9901ab06fc 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2761,16 +2761,28 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) switch (Z_LVAL(opline->op2.u.constant)) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - int dummy = 1; zend_file_handle file_handle; + char cwd[MAXPATHLEN]; + cwd_state state; - if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { + cwd[0] = '\0'; + } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { + cwd[0] = '\0'; + } + + state.cwd_length = strlen(cwd); + state.cwd = zend_strndup(cwd, state.cwd_length); + if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && + zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) { + failure_retval=1; + } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); } - if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -2784,7 +2796,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } - break; + free(state.cwd); } break; case ZEND_INCLUDE: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 8535ad8ea4..3b24001536 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -659,6 +659,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A unsigned int function_name_strlen; zend_bool is_const = (IS_CONST == IS_CONST); + if (is_const) { function_name_strval = Z_UNIVAL(opline->op2.u.constant); function_name_strlen = Z_UNILEN(opline->op2.u.constant); @@ -1192,6 +1193,8 @@ static int ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval *class_name; + + if (IS_CV == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); @@ -1880,16 +1883,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) switch (Z_LVAL(opline->op2.u.constant)) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - int dummy = 1; zend_file_handle file_handle; + char cwd[MAXPATHLEN]; + cwd_state state; + + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { + cwd[0] = '\0'; + } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { + cwd[0] = '\0'; + } - if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + state.cwd_length = strlen(cwd); + state.cwd = zend_strndup(cwd, state.cwd_length); + if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && + zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) { + failure_retval=1; + } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); } - if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -1903,7 +1918,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } - break; + free(state.cwd); } break; case ZEND_INCLUDE: @@ -2013,8 +2028,8 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } } - ex = ex->prev_execute_data; - } while (ex && ex->symbol_table == target_symbol_table); + ex = ex->prev_execute_data; + } while (ex && ex->symbol_table == target_symbol_table); } } @@ -4376,16 +4391,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) switch (Z_LVAL(opline->op2.u.constant)) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - int dummy = 1; zend_file_handle file_handle; + char cwd[MAXPATHLEN]; + cwd_state state; + + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { + cwd[0] = '\0'; + } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { + cwd[0] = '\0'; + } - if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + state.cwd_length = strlen(cwd); + state.cwd = zend_strndup(cwd, state.cwd_length); + if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && + zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) { + failure_retval=1; + } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); } - if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -4399,7 +4426,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } - break; + free(state.cwd); } break; case ZEND_INCLUDE: @@ -4509,8 +4536,8 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } } - ex = ex->prev_execute_data; - } while (ex && ex->symbol_table == target_symbol_table); + ex = ex->prev_execute_data; + } while (ex && ex->symbol_table == target_symbol_table); } } @@ -7469,16 +7496,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) switch (Z_LVAL(opline->op2.u.constant)) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - int dummy = 1; zend_file_handle file_handle; + char cwd[MAXPATHLEN]; + cwd_state state; + + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { + cwd[0] = '\0'; + } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { + cwd[0] = '\0'; + } - if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + state.cwd_length = strlen(cwd); + state.cwd = zend_strndup(cwd, state.cwd_length); + if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && + zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) { + failure_retval=1; + } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); } - if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -7492,7 +7531,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } - break; + free(state.cwd); } break; case ZEND_INCLUDE: @@ -7602,8 +7641,8 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } } - ex = ex->prev_execute_data; - } while (ex && ex->symbol_table == target_symbol_table); + ex = ex->prev_execute_data; + } while (ex && ex->symbol_table == target_symbol_table); } } @@ -20094,16 +20133,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) switch (Z_LVAL(opline->op2.u.constant)) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - int dummy = 1; zend_file_handle file_handle; + char cwd[MAXPATHLEN]; + cwd_state state; - if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) { + cwd[0] = '\0'; + } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { + cwd[0] = '\0'; + } + + state.cwd_length = strlen(cwd); + state.cwd = zend_strndup(cwd, state.cwd_length); + if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) && + zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) { + failure_retval=1; + } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) { if (!file_handle.opened_path) { file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); } - if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -20117,7 +20168,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename)); } } - break; + free(state.cwd); } break; case ZEND_INCLUDE: @@ -20227,8 +20278,8 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } } - ex = ex->prev_execute_data; - } while (ex && ex->symbol_table == target_symbol_table); + ex = ex->prev_execute_data; + } while (ex && ex->symbol_table == target_symbol_table); } }