summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-05-31 12:09:06 +0300
committerDmitry Stogov <dmitry@zend.com>2019-05-31 12:20:21 +0300
commit1df9f238fed314255b858e3996c35be8cdff917f (patch)
treeab3dbad2f11e44688926b6a98fb50b7c0c68d1b2
parent84333cad674890174c47f3c21b1b1cf85a4276ac (diff)
downloadphp-git-1df9f238fed314255b858e3996c35be8cdff917f.tar.gz
Better hot/cold code splitting
-rw-r--r--Zend/zend.c48
-rw-r--r--Zend/zend_API.c2
-rw-r--r--Zend/zend_API.h16
-rw-r--r--Zend/zend_compile.h11
-rw-r--r--Zend/zend_execute_API.c14
-rw-r--r--Zend/zend_weakrefs.c10
-rw-r--r--ext/opcache/ZendAccelerator.c14
7 files changed, 63 insertions, 52 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index 5670dae703..080a75a3c4 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -1401,7 +1401,7 @@ static ZEND_COLD void zend_error_va_list(
}
/* }}} */
-static void get_filename_lineno(int type, const char **filename, uint32_t *lineno) {
+static ZEND_COLD void get_filename_lineno(int type, const char **filename, uint32_t *lineno) {
/* Obtain relevant filename and lineno */
switch (type) {
case E_CORE_ERROR:
@@ -1612,29 +1612,25 @@ ZEND_API ZEND_COLD void zend_output_debug_string(zend_bool trigger_break, const
}
/* }}} */
-ZEND_API void zend_try_exception_handler() /* {{{ */
+ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */
{
- if (EG(exception)) {
- if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
- zval orig_user_exception_handler;
- zval params[1], retval2;
- zend_object *old_exception;
- old_exception = EG(exception);
- EG(exception) = NULL;
- ZVAL_OBJ(&params[0], old_exception);
- ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
+ zval orig_user_exception_handler;
+ zval params[1], retval2;
+ zend_object *old_exception;
+ old_exception = EG(exception);
+ EG(exception) = NULL;
+ ZVAL_OBJ(&params[0], old_exception);
+ ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
- if (call_user_function(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params) == SUCCESS) {
- zval_ptr_dtor(&retval2);
- if (EG(exception)) {
- OBJ_RELEASE(EG(exception));
- EG(exception) = NULL;
- }
- OBJ_RELEASE(old_exception);
- } else {
- EG(exception) = old_exception;
- }
+ if (call_user_function(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params) == SUCCESS) {
+ zval_ptr_dtor(&retval2);
+ if (EG(exception)) {
+ OBJ_RELEASE(EG(exception));
+ EG(exception) = NULL;
}
+ OBJ_RELEASE(old_exception);
+ } else {
+ EG(exception) = old_exception;
}
} /* }}} */
@@ -1660,9 +1656,13 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
if (op_array) {
zend_execute(op_array, retval);
zend_exception_restore();
- zend_try_exception_handler();
- if (EG(exception)) {
- zend_exception_error(EG(exception), E_ERROR);
+ if (UNEXPECTED(EG(exception))) {
+ if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
+ zend_user_exception_handler();
+ }
+ if (EG(exception)) {
+ zend_exception_error(EG(exception), E_ERROR);
+ }
}
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 1034d8410b..01ce2e5517 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -4402,7 +4402,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi
}
/* }}} */
-ZEND_API const char *zend_get_object_type(const zend_class_entry *ce) /* {{{ */
+ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce) /* {{{ */
{
if(ce->ce_flags & ZEND_ACC_TRAIT) {
return "trait";
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index bdf3b1ce2b..e8fa6e1e62 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -530,12 +530,24 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data);
ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data);
ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force);
ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, int force);
-ZEND_API int zend_forbid_dynamic_call(const char *func_name);
+
+static zend_always_inline int zend_forbid_dynamic_call(const char *func_name)
+{
+ zend_execute_data *ex = EG(current_execute_data);
+ ZEND_ASSERT(ex != NULL && ex->func != NULL);
+
+ if (ZEND_CALL_INFO(ex) & ZEND_CALL_DYNAMIC) {
+ zend_error(E_WARNING, "Cannot call %s dynamically", func_name);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
ZEND_API zend_string *zend_find_alias_name(zend_class_entry *ce, zend_string *name);
ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f);
-ZEND_API const char *zend_get_object_type(const zend_class_entry *ce);
+ZEND_API ZEND_COLD const char *zend_get_object_type(const zend_class_entry *ce);
ZEND_API zend_bool zend_is_iterable(zval *iterable);
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 9989011600..7745daf47e 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -766,7 +766,6 @@ ZEND_API void function_add_ref(zend_function *function);
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type);
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename);
ZEND_API zend_op_array *compile_filename(int type, zval *filename);
-ZEND_API void zend_try_exception_handler();
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...);
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle);
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size);
@@ -775,6 +774,16 @@ ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle);
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce);
ZEND_API void zend_cleanup_internal_classes(void);
+ZEND_API ZEND_COLD void zend_user_exception_handler(void);
+
+#define zend_try_exception_handler() do { \
+ if (UNEXPECTED(EG(exception))) { \
+ if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { \
+ zend_user_exception_handler(); \
+ } \
+ } \
+ } while (0)
+
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void zend_function_dtor(zval *zv);
ZEND_API void destroy_zend_class(zval *zv);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 478d902a0b..431031acba 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -1650,17 +1650,3 @@ ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, i
return FAILURE;
}
/* }}} */
-
-ZEND_API int zend_forbid_dynamic_call(const char *func_name) /* {{{ */
-{
- zend_execute_data *ex = EG(current_execute_data);
- ZEND_ASSERT(ex != NULL && ex->func != NULL);
-
- if (ZEND_CALL_INFO(ex) & ZEND_CALL_DYNAMIC) {
- zend_error(E_WARNING, "Cannot call %s dynamically", func_name);
- return FAILURE;
- }
-
- return SUCCESS;
-}
-/* }}} */
diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c
index b4eaf437c8..b73a5963aa 100644
--- a/Zend/zend_weakrefs.c
+++ b/Zend/zend_weakrefs.c
@@ -112,13 +112,13 @@ static void zend_weakref_free(zend_object *zo) {
#define zend_weakref_unsupported(thing) \
zend_throw_error(NULL, "WeakReference objects do not support " thing);
-static zval* zend_weakref_no_write(zval *object, zval *member, zval *value, void **rtc) {
+static ZEND_COLD zval* zend_weakref_no_write(zval *object, zval *member, zval *value, void **rtc) {
zend_weakref_unsupported("properties");
return &EG(uninitialized_zval);
}
-static zval* zend_weakref_no_read(zval *object, zval *member, int type, void **rtc, zval *rv) {
+static ZEND_COLD zval* zend_weakref_no_read(zval *object, zval *member, int type, void **rtc, zval *rv) {
if (!EG(exception)) {
zend_weakref_unsupported("properties");
}
@@ -126,19 +126,19 @@ static zval* zend_weakref_no_read(zval *object, zval *member, int type, void **r
return &EG(uninitialized_zval);
}
-static zval *zend_weakref_no_read_ptr(zval *object, zval *member, int type, void **rtc) {
+static ZEND_COLD zval *zend_weakref_no_read_ptr(zval *object, zval *member, int type, void **rtc) {
zend_weakref_unsupported("property references");
return NULL;
}
-static int zend_weakref_no_isset(zval *object, zval *member, int hse, void **rtc) {
+static ZEND_COLD int zend_weakref_no_isset(zval *object, zval *member, int hse, void **rtc) {
if (hse != 2) {
zend_weakref_unsupported("properties");
}
return 0;
}
-static void zend_weakref_no_unset(zval *object, zval *member, void **rtc) {
+static ZEND_COLD void zend_weakref_no_unset(zval *object, zval *member, void **rtc) {
zend_weakref_unsupported("properties");
}
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index b78dee73f6..0db2afa73d 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -4020,11 +4020,15 @@ static int accel_preload(const char *config)
if (op_array) {
zend_execute(op_array, NULL);
zend_exception_restore();
- zend_try_exception_handler();
- if (EG(exception)) {
- zend_exception_error(EG(exception), E_ERROR);
- CG(unclean_shutdown) = 1;
- ret = FAILURE;
+ if (UNEXPECTED(EG(exception))) {
+ if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
+ zend_user_exception_handler();
+ }
+ if (EG(exception)) {
+ zend_exception_error(EG(exception), E_ERROR);
+ CG(unclean_shutdown) = 1;
+ ret = FAILURE;
+ }
}
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));