]> granicus.if.org Git - php/commitdiff
Allow an experimental VM with tail call dispatch technique (disabled by default).
authorDmitry Stogov <dmitry@zend.com>
Fri, 25 Sep 2015 09:54:51 +0000 (12:54 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 25 Sep 2015 09:54:51 +0000 (12:54 +0300)
This VM may work only if all tail calls are optimized, otherwaise it will crach because of stack overflow.
Unfortunately, we can't guarantee tail call optimization in C.

Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 253a2d7a13ea6854dd1a4b769108c9ee8281d6d3..035f4ab7af0d5784d855c524d1042bb4a6951145 100644 (file)
@@ -337,8 +337,12 @@ register const zend_op* volatile opline __asm__(ZEND_VM_IP_GLOBAL_REG);
 #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
 # define ZEND_OPCODE_HANDLER_RET void
 # define ZEND_VM_TAIL_CALL(call) call; return
-# define ZEND_VM_CONTINUE()      return
-# define ZEND_VM_RETURN()        opline = NULL; ZEND_VM_CONTINUE()
+# ifdef ZEND_VM_TAIL_CALL_DISPATCH
+#  define ZEND_VM_CONTINUE()     ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return
+# else
+#  define ZEND_VM_CONTINUE()     return
+# endif
+# define ZEND_VM_RETURN()        opline = NULL; return
 #else
 # define ZEND_OPCODE_HANDLER_RET int
 # define ZEND_VM_TAIL_CALL(call) return call
index 8f06bb48945881028149ef3500425af92ee004f4..613b4c9338dc27a11bf8588b5acb32d41c4984d2 100644 (file)
@@ -1058,8 +1058,12 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                                                        out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
                                                        out($f,"# define ZEND_OPCODE_HANDLER_RET void\n");
                                                        out($f,"# define ZEND_VM_TAIL_CALL(call) call; return\n");
-                                                       out($f,"# define ZEND_VM_CONTINUE()      return\n");
-                                                       out($f,"# define ZEND_VM_RETURN()        opline = NULL; ZEND_VM_CONTINUE()\n");
+                                                       out($f,"# ifdef ZEND_VM_TAIL_CALL_DISPATCH\n");
+                                                       out($f,"#  define ZEND_VM_CONTINUE()     ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return\n");
+                                                       out($f,"# else\n");
+                                                       out($f,"#  define ZEND_VM_CONTINUE()     return\n");
+                                                       out($f,"# endif\n");
+                                                       out($f,"# define ZEND_VM_RETURN()        opline = NULL; return\n");
                                                        out($f,"#else\n");
                                                        out($f,"# define ZEND_OPCODE_HANDLER_RET int\n");
                                                        out($f,"# define ZEND_VM_TAIL_CALL(call) return call\n");