Skip to content

Instantly share code, notes, and snippets.

@dstogov
Created October 23, 2014 11:29
Show Gist options
  • Save dstogov/8d5c3224105f77ec4b84 to your computer and use it in GitHub Desktop.
Save dstogov/8d5c3224105f77ec4b84 to your computer and use it in GitHub Desktop.
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index b91ac5b..08205c2 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -46,6 +46,49 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
while (opline < end) {
switch (opline->opcode) {
+#if 1
+ case ZEND_DECLARE_INHERITED_CLASS:
+ case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
+ /* Try to perform inheritance */
+ if (zend_hash_num_elements(&ctx->script->class_table) > 1
+ && (opline+1)->opcode != ZEND_ADD_INTERFACE
+ && (opline+1)->opcode != ZEND_ADD_TRAIT
+ && (opline+1)->opcode != ZEND_BIND_TRAITS
+ && (opline+1)->opcode != ZEND_VERIFY_ABSTRACT_CLASS) {
+ /* The parent class name may be found as the second operand
+ * of the previous ZEND_FETCH_CLASS opcode */
+ zval *parent_name = &op_array->literals[(opline-1)->op2.constant + 1];
+ zend_class_entry *ce = zend_hash_find_ptr(&ctx->script->class_table, Z_STR_P(parent_name));
+
+ if (ce) {
+ if (do_bind_inherited_class(op_array, opline, &ctx->script->class_table, ce, 1) != NULL) {
+ zend_hash_del(&ctx->script->class_table, Z_STR(op_array->literals[opline->op1.constant]));
+
+ if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
+ /* delete from delayed early_binding list */
+ uint32_t *opline_num = &op_array->early_binding;
+
+ while (*opline_num != (uint32_t)-1) {
+ if (*opline_num == opline - op_array->opcodes) {
+ *opline_num = opline->result.opline_num;
+ break;
+ }
+ opline_num = &op_array->opcodes[*opline_num].result.opline_num;
+ }
+ }
+
+ /* delete DECLARE... and ZEND_FETCH_CLASS opcodes */
+ literal_dtor(&ZEND_OP2_LITERAL(opline));
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ MAKE_NOP(opline);
+
+ literal_dtor(&ZEND_OP2_LITERAL(opline-1));
+ MAKE_NOP((opline-1));
+ }
+ }
+ }
+ break;
+#endif
case ZEND_ADD:
case ZEND_SUB:
case ZEND_MUL:
# master
$ sapi/cgi/php-cgi -T 100000 test.php > /dev/null
Elapsed time: 2.109146 sec
# master + patch
$ sapi/cgi/php-cgi -T 100000 test.php > /dev/null
Elapsed time: 2.241658 sec
<?php
class B extends A {
function a() {}
function b($a, $b) {}
function c($a, $b, $c) {}
}
class A {
function b($a, $b) {}
function c($a, $b, $c) {}
function d($a, $b, $c, $d) {}
}
$x = new B();
var_dump($x);
@jpauli
Copy link

jpauli commented Oct 24, 2014

I got not the same signature.
I dont know where zend_optimizer_ctx *ctx comes from.

My code looks like if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment