Skip to content

feat(memory): merge the 8.4 allocator seam up to master (#223) - #226

Merged
lisachenko merged 1 commit into
masterfrom
claude/php-coroutines-plan-5vovsz
Aug 15, 2026
Merged

feat(memory): merge the 8.4 allocator seam up to master (#223)#226
lisachenko merged 1 commit into
masterfrom
claude/php-coroutines-plan-5vovsz

Conversation

@lisachenko

Copy link
Copy Markdown
Owner

What this changes

Cascade merge of branch 8.4 into master per the branch flow in AGENTS.md
(.github/branch-flow.json: 8.4 -> master). It carries the allocator seam work
of #223 — merged into 8.4 as #224 — up to the PHP 8.5 line.

What arrives on master:

  • ZEngine\Memory\Allocator — the allocation seam interface, with
    ZEngine\Memory\EngineAllocator (the three modes the persistent primitives used
    to hardcode: tracked-persistent, tracked-request, untracked-persistent) and
    ZEngine\Memory\AllocationException.
  • The allocator threaded through the persistent primitives: PersistentHashTable,
    PersistentObjectFactory, PersistentGraphCloner, StringEntry, HashTable.
  • The external arData install API on HashTable/PersistentHashTable, plus
    PersistentHashTable::addInterned() for caller-owned key strings.
  • Object-store registration encapsulated on ObjectEntry
    (register()/unregister()), and ReflectionClass::fromClassTable() — a
    class-table probe that does not autoload.
  • Core::offsetOfField(), the named form of
    type(...)->getStructFieldOffset(...) so no raw FFI\CType crosses the API
    boundary.
  • Test coverage: tests/Memory/AllocatorSeamTest.php,
    tests/Memory/EngineAllocatorTest.php,
    tests/Type/ObjectEntryRegistrationTest.php,
    tests/Type/PersistentHashTableExternalStorageTest.php,
    tests/Stub/RecordingArenaAllocator.php.

This unblocks the red PHP 8.5 CI legs on
lisachenko/php-shared-data-extension#21, which needs the seam on the 8.5 line.

Refs #223, merges #224.

Conflict resolution

The merge applied without textual conflicts. Master's 8.5-specific work and the
8.4 seam work turned out to be almost disjoint, so the only two files needing a
three-way merge were resolved by git and verified by hand:

  • src/Core.php — master's 8.5 constants and boot guard are untouched
    (SUPPORTED_PHP_VERSION_ID = [80500, 80600], ZEND_ACC_USE_GUARDS = 0x40000000
    "was 0x800 before PHP 8.5", the "for PHP 8.5" doc header); the seam contributes
    only the new offsetOfField() method, appended after free().
  • tests/Reflection/ReflectionClassTest.php — master's 8.5 adaptation survives
    (@ini_set('report_memleaks', …), deprecated on 8.5); the seam appends the two
    fromClassTable() tests.

The remaining seam files (src/Memory/*, src/Type/{HashTable,PersistentHashTable, PersistentObjectFactory,StringEntry,ObjectEntry,TypeOperationException}.php,
src/Memory/PersistentGraphCloner.php, src/Reflection/ReflectionClass.php,
docs/persistent-heap.md, the new tests) had no counterpart change on master and
came across as fast-forwards/additions. src/System/ObjectStore.php was not touched
by the seam PR at all.

Nothing under include/, stubs/ or .phpstorm.meta.php is in this merge — the
seam PR touched no generated artifacts, so no conflict arose there and no
regeneration is required. The seam code carries no PHP_VERSION_ID branches and
dereferences no struct whose 8.5 layout differs (it does not touch op_array, so
the 8.5 literals/refcount differences are not in play).

8.5 gate evidence

Every run below is php8.5 -d ffi.enable=1 -d opcache.jit=off. Each suite run was
compared against a baseline run of origin/master in the same checkout.

Gate origin/master baseline This merge
composer test 465 tests, 3 errors, 5 failures, 5 skipped, 5 incomplete 500 tests, same 3 errors / 5 failures (identical test names), 5 skipped, 5 incomplete
composer test:internal (--group internal --process-isolation) 163 tests, 4 failures, 28 skipped, 1 incomplete 163 tests, same 4 failures (identical test names)
seam tests (--filter 'EngineAllocator|AllocatorSeam|ExternalStorage|ObjectEntryRegistration') n/a OK (32 tests, 891 assertions)
the same under MALLOC_CHECK_=3 MALLOC_PERTURB_=85 n/a OK (32 tests, 891 assertions), exit 0
composer phpstan (level max) [OK] No errors
composer cs:check (@PER-CS2.0) 0 of 320 files need fixing

The merge adds 35 passing tests and no new failures: the pre-existing red tests
on the 8.5 line (ClassSpecializerSlotTest, ExecutionDataTest,
RedefineLeakPlateauTest, PersistentHeapRequestCycleTest,
SharedMemoryExceptionTest, FunctionLikeInfoTest, ReflectionClassParentTest,
ReflectionClassResolutionHandlersTest, ReflectionFunctionTest::testRedefine)
fail identically before and after, and are out of scope for this merge-up.

The MALLOC_CHECK_/MALLOC_PERTURB_ run specifically confirms that the
use-after-free fix from 8.4 commit 1a6acb6 ("drop the materialized alias before
freeing a registered clone") survived the merge intact — src/Type/ObjectEntry.php
and tests/Type/ObjectEntryRegistrationTest.php are byte-identical to their 8.4
state, and the run that used to abort with
malloc(): unaligned tcache chunk detected completes cleanly. No segfaults or
aborts were observed in any run.

Environment it was verified on

  • PHP version (full first line of php -v): PHP 8.5.9 (cli) (built: Jul 30 2026 15:13:42) (NTS)
  • Thread safety: NTS
  • OS / architecture: Linux x86_64 (Ubuntu)
  • Debug build (--enable-debug)? no

Checklist

🤖 Generated with Claude Code

https://claude.ai/code/session_01B9xaBchjdo1atarNZ6sZqe


Generated by Claude Code

Brings the allocator seam, ObjectEntry store registration and the external
arData install API from the 8.4 line up to master (PHP 8.5), per the branch
flow in AGENTS.md. Master's 8.5-specific engine handling is preserved as-is;
the seam touches no generated artifacts under include/, stubs/ or
.phpstorm.meta.php.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B9xaBchjdo1atarNZ6sZqe
@lisachenko
lisachenko marked this pull request as ready for review August 15, 2026 20:24
@lisachenko
lisachenko merged commit 7be2b98 into master Aug 15, 2026
28 checks passed
@lisachenko
lisachenko deleted the claude/php-coroutines-plan-5vovsz branch August 15, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants