Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: php/php-src
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: nielsdos/php-src
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: merge-jmp-frameless-cache-slots
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Mar 16, 2025

  1. Merge JMP_FRAMELESS cache slots in Optimizer/compact_literals

    This avoids repeated lookups in the function table for the same
    function name.
    Although this optimization is observable, i.e. defining a function via
    an include in between 2 JMP_FRAMELESS for the same function, this cannot
    be relied on already as far as I know if the optimizer runs.
    nielsdos committed Mar 16, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    nielsdos Niels Dossche
    Copy the full SHA
    f3443a4 View commit details

Commits on Mar 17, 2025

  1. split case

    nielsdos committed Mar 17, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    nielsdos Niels Dossche
    Copy the full SHA
    9387145 View commit details
Showing with 17 additions and 4 deletions.
  1. +17 −4 Zend/Optimizer/compact_literals.c
21 changes: 17 additions & 4 deletions Zend/Optimizer/compact_literals.c
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
HashTable hash;
zend_string *key = NULL;
void *checkpoint = zend_arena_checkpoint(ctx->arena);
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot, *jmp_slot;

if (op_array->last_literal) {
info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info));
@@ -175,6 +175,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
end = opline + op_array->last;
while (opline < end) {
switch (opline->opcode) {
case ZEND_JMP_FRAMELESS:
LITERAL_INFO(opline->op1.constant, 1);
break;
case ZEND_INIT_FCALL_BY_NAME:
LITERAL_INFO(opline->op2.constant, 2);
break;
@@ -480,13 +483,14 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
zend_hash_clean(&hash);
op_array->last_literal = j;

const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
memset(const_slot, -1, j * 6 * sizeof(int));
const_slot = zend_arena_alloc(&ctx->arena, j * 7 * sizeof(int));
memset(const_slot, -1, j * 7 * sizeof(int));
class_slot = const_slot + j;
func_slot = class_slot + j;
bind_var_slot = func_slot + j;
property_slot = bind_var_slot + j;
method_slot = property_slot + j;
jmp_slot = method_slot + j;

/* Update opcodes to use new literals table */
cache_size = zend_op_array_extension_handles * sizeof(void*);
@@ -773,10 +777,19 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
break;
case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_CLASS_DELAYED:
case ZEND_JMP_FRAMELESS:
opline->extended_value = cache_size;
cache_size += sizeof(void *);
break;
case ZEND_JMP_FRAMELESS:
// op1 func
if (jmp_slot[opline->op1.constant] >= 0) {
opline->extended_value = jmp_slot[opline->op1.constant];
} else {
opline->extended_value = cache_size;
cache_size += sizeof(void *);
jmp_slot[opline->op1.constant] = opline->extended_value;
}
break;
case ZEND_SEND_VAL:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR: