Repository navigation
Laravel: build memory (no MachineOutliner), per-request leaks to zero, cycle collection through untyped properties, #599 regressions - #602
Merged
Conversation
… Laravel part 13.7 GB -> 4.65 GB), one cold raise per guard site, table dispatch for $o->$name on a known class, nounwind runtime helpers called not invoked, cell_int_bad slow path out of line
…rded result, and a cell or array union read as borrowed in a conditional arm or a local
… a program that makes lazy ghosts every untyped read before a write was the uninitialized-property Error (Laravel Application::$appPath at boot)
…releases the +1 a conditional or literal callee holds: Laravel's call_user_func($cb ?? $default, ...) leaked the closure and all it captured per request
…ld and release a collected node's other cell slots: no cycle through an untyped property was ever collected, which kept Laravel's per-request Request/Route/closure graph and every string it held
…the compares: the strval() an erased subject is unboxed by leaked one class name per Laravel container make()
…ed as a callee (call_user_func($this->getRouteResolver())), a closure stored raw in a reference box whose cell drop skipped it ($default in Router::substituteImplicitBindings), and (array) over a minting operand retained again (Router::resolveMiddleware)
…me representation: call_user_func($this->getRouteResolver()) with @return \Closure leaked Laravel's route resolver and its Route per request
…the slot holds a bare cell, every class of it does. Model::$attributes celled through the parent while Note kept vec[cell], so Note's drop released a tagged word as an array buffer and every Laravel /api/notes request crashed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #600 (Laravel follow-up). This PR cuts build memory and per-request leaks, and fixes two Laravel regressions from #599.
Results (macOS arm64)
.o+1.5%)/api/pingheap growth aftergcmain8c95ce8)/api/notesmain)Typed property Application::$appPath must not be accessed before initialization(main)/hellostill grows by ~5 nodes per request. That is legitimate: withSESSION_DRIVER=arrayevery cookielesswrkrequest creates a new session andArraySessionHandlerstores it.Changes
Build memory and IR size
-mllvm -enable-machine-outliner=never. On arm64 the MachineOutliner is a module pass, so it keeps every MachineFunction of a part alive until the end of codegen. That was the main source of 9–13 GB per clang.emitColdRaise): pick the message withselectinstead of N separate throw blocks.$o->$nameon a known class dispatches through the reader table, not a strcmp chain with the full read path per name (Carbon::roundUnitwas 348K IR lines).call, notinvoke.cell_int_badslow path moved out of line.Ownership / leaks
json_decode('[]');).+inside a conditional arm, and a cell+stored to a local, are owned, not borrowed.env@56,GEN_HEADER56 → 64). This makes it safe for an invoke to release the +1 it holds for a conditional or literal callee.is_a()with an erased string subject releases thestrval()result it creates.callable-typed word (classified at run time by its allocator header).(array)over an operand that mints a value passes its +1 through instead of retaining it again.Correctness (regressions from #599)
Model::$attributeswas a cell inModelandvec[cell]inNote).Tests
leak_cell_union_cond_arm,leak_discarded_builtin_result,lazy_build_untyped_prop_null,leak_conditional_cell_callee,generator_closure_owns_env,gc_cycle_through_untyped_props,leak_is_a_erased_string_subject,closure_in_referenced_local_released,leak_array_cast_of_owned_call,leak_callable_call_result_callee.$a + $bover two barearrayparameters answers garbage. #517, fixes A named argument after a spread into a closure value is bound by position instead of by parameter name. #463, fixes A variadic method reached through __call and a dynamic spread receives the whole argument array as one argument. #476, fixes Named arguments passed to an undefined method are not collected into __call's $arguments under their names. #477, fixesnew $classwith the name of a class that does not exist returns null instead of throwing Error #565, fixes A named argument after a spread into a variadic function is bound by position instead of by parameter name. #464./api/notesis the check.Validation
5e4a0f72: leak, closure, callable, invoke, gen, cast, own, ref, prop, gc, lazy, is_a.5e4a0f72, not rerun since: array, class, inherit, async, fiber, str, json, tern, cell.xfail.shbefore the rebase: 45 XFAIL, 0 XPASS.Still open