From 2febfbab8e29945bad32e66ae8059b4e2cff46df Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 17 Jul 2014 11:18:44 +0400 Subject: [PATCH] Micro optimization for the main interpreter loop --- Zend/zend_vm_execute.h | 23 +++++++++-------------- Zend/zend_vm_gen.php | 31 +++++++++++++------------------ 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 950f487c005..214ab51bebd 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -326,10 +326,10 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o #define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE() #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE() #define LOAD_REGS() -#define ZEND_VM_CONTINUE() return 0 -#define ZEND_VM_RETURN() return 1 -#define ZEND_VM_ENTER() return 2 -#define ZEND_VM_LEAVE() return 3 +#define ZEND_VM_CONTINUE() return 0 +#define ZEND_VM_RETURN() return -1 +#define ZEND_VM_ENTER() return 1 +#define ZEND_VM_LEAVE() return 2 #define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC @@ -351,16 +351,11 @@ ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC) } #endif - if ((ret = OPLINE->handler(execute_data TSRMLS_CC)) > 0) { - switch (ret) { - case 1: - return; - case 2: - case 3: - execute_data = EG(current_execute_data); - break; - default: - break; + if (UNEXPECTED((ret = OPLINE->handler(execute_data TSRMLS_CC)) != 0)) { + if (EXPECTED(ret > 0)) { + execute_data = EG(current_execute_data); + } else { + return; } } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index b0a642084dc..50506f566bf 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -914,10 +914,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n"); out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n"); out($f,"#define LOAD_REGS()\n"); - out($f,"#define ZEND_VM_CONTINUE() return 0\n"); - out($f,"#define ZEND_VM_RETURN() return 1\n"); - out($f,"#define ZEND_VM_ENTER() return 2\n"); - out($f,"#define ZEND_VM_LEAVE() return 3\n"); + out($f,"#define ZEND_VM_CONTINUE() return 0\n"); + out($f,"#define ZEND_VM_RETURN() return -1\n"); + out($f,"#define ZEND_VM_ENTER() return 1\n"); + out($f,"#define ZEND_VM_LEAVE() return 2\n"); out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n"); out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n"); break; @@ -1028,7 +1028,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, // Emit code that dispatches to opcode handler switch ($kind) { case ZEND_VM_KIND_CALL: - out($f, $m[1]."if ((ret = OPLINE->handler(execute_data TSRMLS_CC)) > 0)".$m[3]."\n"); + out($f, $m[1]."if (UNEXPECTED((ret = OPLINE->handler(execute_data TSRMLS_CC)) != 0))".$m[3]."\n"); break; case ZEND_VM_KIND_SWITCH: out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)dispatch_handler)".$m[3]."\n"); @@ -1041,15 +1041,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, case "INTERNAL_EXECUTOR": if ($kind == ZEND_VM_KIND_CALL) { // Executor is defined as a set of functions - out($f, $m[1]."switch (ret) {\n" . - $m[1]."\tcase 1:\n" . - $m[1]."\t\treturn;\n". - $m[1]."\tcase 2:\n" . - $m[1]."\tcase 3:\n" . - $m[1]."\t\texecute_data = EG(current_execute_data);\n". - $m[1]."\t\tbreak;\n" . - $m[1]."\tdefault:\n". - $m[1]."\t\tbreak;\n". + out($f, $m[1]."if (EXPECTED(ret > 0)) {\n" . + $m[1]."\texecute_data = EG(current_execute_data);\n". + $m[1]."} else {\n" . + $m[1]."\treturn;\n". $m[1]."}".$m[3]."\n"); } else { // Emit executor code @@ -1415,10 +1410,10 @@ function gen_vm($def, $skel) { out($f,"#undef ZEND_VM_LEAVE\n"); out($f,"#undef ZEND_VM_DISPATCH\n"); out($f,"#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL\n\n"); - out($f,"#define ZEND_VM_CONTINUE() return 0\n"); - out($f,"#define ZEND_VM_RETURN() return 1\n"); - out($f,"#define ZEND_VM_ENTER() return 2\n"); - out($f,"#define ZEND_VM_LEAVE() return 3\n"); + out($f,"#define ZEND_VM_CONTINUE() return 0\n"); + out($f,"#define ZEND_VM_RETURN() return -1\n"); + out($f,"#define ZEND_VM_ENTER() return 1\n"); + out($f,"#define ZEND_VM_LEAVE() return 2\n"); out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n"); out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n\n"); }