forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 56
[JSC] Cap the per-thread cached AssemblerBuffer size #476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+15
−7
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Minor: the constructor unconditionally moves the cached buffer out of
threadSpecificAssemblerData()(resetting the slot to InlineCapacity=128), so when an oversized compile skips donation here the slot is left at 128 bytes — not "~1 MB" as the Cost section says. The very next compile on that thread starts from 128 bytes and needs ~20+grow()steps, not 4–6. No correctness impact and still microseconds, but you may want to either correct the description before upstreaming or donate back a buffer capped atcacheLimit.Extended reasoning...
What this is
The PR's Cost section says: "on the next oversized compile the buffer has to be re-malloc'd and grown from the ~1 MB cached one (about 4–6 realloc steps at 1.5×)". That implies the thread-specific cache retains a ~1 MB buffer after an oversized compile. For
AssemblerDataImplit does not — the cache is drained to 128 bytes.Step-by-step trace
Assume the thread-specific slot currently holds a ~900 KB buffer from prior compiles.
AssemblerDataImpl()): initializesthistom_inlineBuffer/InlineCapacity(128), then callsthis->takeBufferIfLarger(*threadSpecificAssemblerData()).takeBufferIfLarger(lines 168–184): the slot is not inline and 900 KB > 128, so it moves the slot's buffer intothisand resets the slot:other.m_buffer = other.m_inlineBuffer; other.m_capacity = InlineCapacity;. The thread-specific slot is now at 128 bytes.grow()s past 1 MB — say to 12 MB.cacheLimit = 1 MB,m_capacity = 12 MB > cacheLimit, so theifbody is skipped andclear()frees the 12 MB buffer. Nothing is donated back.takeBufferIfLargeron the slot;other.isInlineBuffer()is true so it returns immediately. This compile starts from 128 bytes. Reaching 1 MB takes ~22grow()calls at 1.5×; reaching 12 MB takes ~28 — not the 4–6 the description states.Why the description's model doesn't hold here
The description reads as if the cap leaves the cache at ~1 MB and only the excess is dropped. In practice, because the constructor always drains the slot (it takes ownership, not a copy), skipping the destructor donation leaves the slot empty. So the behaviour is "cap = drain to InlineCapacity on any oversized compile", not "cap = clamp to 1 MB".
BranchCompactionLinkBufferis different: its constructor only takes the cached buffer whenthreadSpecific->size() >= size; otherwise itmallocs fresh and leaves the cache intact. So for that class, an oversized compile does leave the ~1 MB cache in place, and the description holds. The discrepancy is only inAssemblerDataImpl.Impact
reallocs instead of ~4–6. That is still microseconds against a multi-MB codegen pass. In the PR's own workload ("oversized compile happens once or twice per process"), a normal-sized compile will typically run in between and refill the cache before the next oversized one anyway.Suggested fix
Either is fine:
AssemblerDataImplcompile, so the next compile starts fromInlineCapacity.reallocdown tocacheLimitand then donate, or only skip donation if the slot is already ≥cacheLimit. That would make the code match the described "cap" semantics.Not blocking — flagging mainly because the PR is headed upstream and the cost model in the description doesn't match
AssemblerDataImpl's actual behaviour.