feat: use PIFE for callbacks passed to __esmMin wrapper#5319
Merged
Conversation
✅ Deploy Preview for rolldown-rs canceled.
|
Member
Author
graphite-app bot
pushed a commit
to oxc-project/oxc
that referenced
this pull request
Jul 20, 2025
PIFE is the abbreviation of "Possibly-Invoked Function Expressions". It is a function expression wrapped with a parenthesized expression. PIFEs annotate functions that are likely to be invoked eagerly. When v8 encounters such expressions, it compiles them eagerly (rather than compiling it later). See [v8's blog post](https://v8.dev/blog/preparser#pife) for more details. The blog post only mentions regular FunctionExpressions, but ArrowFunctions are also supported. The cases that will be eagerly compiled are: - when `!` comes before function literals ([code](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L3730-L3733)) (e.g. `!function(){}`) - when a function expression is wrapped with parenthesis ([code](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L2243-L2248)) (e.g. `(function () {})`, `(async function () {})`) - when an arrow function is wrapped with parenthesis ([code1](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L2173-L2174), [code2](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L2232-L2259), [code3](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L3297-L3298)) (e.g. `console.log((() => {}))`) - when `()` or ``` `` ``` (tagged templates) comes after function literals (only in some cases) ([code1](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L3987-L3992), [code2](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L4344-L4348)) (e.g. `~function(){}()`, ```~function(){}`` ```) - when [explicit compile hints](https://v8.dev/blog/explicit-compile-hints) are used ([code1](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser.cc#L2717-L2720), [code2](https://github.com/v8/v8/blob/328f6c467b940f322544567740c9c871064d045c/src/parsing/parser-base.h#L5070-L5073)) (e.g. `//# allFunctionsCalledOnLoad`) Keeping PIFEs as-is in the code generation will unlock optimizations like rolldown/rolldown#5319. _Note: this PR only implements arrow function PIFEs for now._
7d888e2 to
74b7e91
Compare
Contributor
Benchmarks Rust |
74b7e91 to
71e0985
Compare
This was referenced Jul 24, 2025
71e0985 to
5d80e7e
Compare
IWANABETHATGUY
approved these changes
Jul 24, 2025
This was referenced Jul 24, 2025
github-merge-queue bot
pushed a commit
that referenced
this pull request
Jul 25, 2025
Same with #5319 but for `createEsmInitializer`.
This was referenced Jul 25, 2025
github-merge-queue bot
pushed a commit
that referenced
this pull request
Jul 25, 2025
Same with #5319 but for `createCjsInitializer`.
Boshen
pushed a commit
that referenced
this pull request
Jul 30, 2025
## [1.0.0-beta.30] - 2025-07-30 ### 💥 BREAKING CHANGES - rolldown: remove unfinished module federation support (#5471) by @Boshen - disable `strictExecutionOrder` by default (#5436) by @hyf0 ### 🚀 Features - hmr: multiple changes should result to multiple updates (#5500) by @hyf0 - binding: add memory adjustment hint in fn write (#5375) by @Brooooooklyn - store sideEffects information about global var access (#5495) by @IWANABETHATGUY - merge side effects detail (#5486) by @IWANABETHATGUY - plugin/vite-resolve: add warn / debug logs (#5476) by @sapphi-red - plugin/vite-resolve: avoid wrapping errors with napi errors (#5483) by @sapphi-red - add `this.fs` support (#5475) by @sapphi-red - rolldown_plugin_asset: align `generate_bundle` logic (#5480) by @shulaoda - hmr: prepare to launch that batched edits should result to multiple hmr output (#5458) by @hyf0 - hmr: support `import.meta.hot.invalidate` (#5457) by @hyf0 - mark all `toESM` as pure (#5461) by @IWANABETHATGUY - rolldown_plugin_asset: align load hook logic (#5452) by @shulaoda - rolldown_plugin_utils: align `file_to_built_url` (#5450) by @shulaoda - rolldown_plugin_utils: align `should_inline` logic (#5308) by @AliceLanniste - rolldown_plugin_asset: add partial `file_to_built_url` support (#5445) by @shulaoda - expose `optimization.pifeForModuleWrappers` option (#5433) by @sapphi-red - add `optimization.pifeForModuleWrappers` option (#5432) by @sapphi-red - use PIFE for callback passed to `createCjsInitializer` (#5427) by @sapphi-red - use PIFE for callbacks passed to `__commonJSMin` / `_commonJS` wrapper (#5426) by @sapphi-red - use PIFE for callback passed to `createEsmInitializer` (#5425) by @sapphi-red - use PIFE for callbacks passed to `__esm` wrapper (#5424) by @sapphi-red - use PIFE for callbacks passed to `__esmMin` wrapper (#5319) by @sapphi-red - rolldown: oxc v0.78.0 (#5421) by @Boshen - rolldown: support `output.sourcemapBaseUrl` (#5413) by @situ2001 - mark all `__commonJS` CallExpression as **Pure** (#5419) by @IWANABETHATGUY - rolldown_plugin_alias: warn if alias resolves to non-absolute path (#5417) by @shulaoda - rolldown_plugin_asset: align `encode_uri_path` logic (#5410) by @shulaoda - add warning and conversion for `import.meta` for non-`esm` output format (#5378) by @7086cmd ### 🐛 Bug Fixes - use uuid_v4 to generate unique id for hook calls (#5501) by @hyf0 - modules that are sideeffect free but relies on the execution order is not wrapped (#5498) by @IWANABETHATGUY - missing_export warning should not be an hard error (#5493) by @sapphi-red - cli: remove unnecessary `await` (#5487) by @situ2001 - browser: stub fs/promises for browser build (#5484) by @sapphi-red - indirect requiring external module is not wrapped by `__toESM` in cjs format (#5454) by @IWANABETHATGUY - Panic on reexport external module in CJS format (#5430) by @IWANABETHATGUY - handle top-level return statements in CommonJS modules (#5437) by @hyf0 - panic when using preserveModules: true and certain dependencies (#5415) by @IWANABETHATGUY - rolldown_plugin_alias: only replace the first matched alias (#5412) by @shulaoda - canonical name not found panic happens with treeshake.commonjs=true (#5409) by @IWANABETHATGUY - hmr: shouldn't consider self-accepting module as hmr boundary for its importee (#5405) by @hyf0 - hmr: should detect hmr boundary correctly (#5400) by @hyf0 - optimization.inlineConst: true generates invalid code when importing a module statically and dynamically (#5398) by @IWANABETHATGUY - top level VarDeclaration is not hoisted when wrapped in `__esm` (#5396) by @IWANABETHATGUY ### 🚜 Refactor - use pascal case when naming bitflags field (#5497) by @IWANABETHATGUY - test/hmr: use sensible time to wait (#5490) by @hyf0 - hmr: update message types to use 'hmr:update' (#5489) by @hyf0 - hmr: replace `HmrOutput` with `HmrUpdate` (#5488) by @hyf0 - node/hmr: re-organize file structures (#5485) by @hyf0 - rolldown_plugin_utils: improve `asset_to_data_url` (#5481) by @shulaoda - replace pattern match for SideEffectsDetail with bitflags api (#5479) by @IWANABETHATGUY - rename stmtSideEffect to SideEffectDetail (#5478) by @IWANABETHATGUY - use bitflags store more details about side effects (#5477) by @IWANABETHATGUY - node/hmr: tweak package `test-dev-server` (#5462) by @hyf0 - hmr: tweak naming and add comments (#5459) by @hyf0 - test/hmr: remove hard-code edited content (#5189) by @hyf0 - rust: make `Log#code` an `Option` (#5416) by @shulaoda - hmr: should mark self-accept module correctly (#5406) by @hyf0 - hmr: remove unnecessary data during `propagate_update` (#5402) by @hyf0 - hmr: make hmr patch output less changeable (#5401) by @hyf0 - `__esm` top level bindings hoisted (#5397) by @IWANABETHATGUY - skip fast in esm format when transform import.meta (#5395) by @IWANABETHATGUY ### 📚 Documentation - clarify rolldown-rollup behavior difference around output generation (#5439) by @sapphi-red ### ⚡ Performance - reduce runtime symbol memory usage and hashtable lookup (#5460) by @IWANABETHATGUY ### 🧪 Testing - hmr: support to run mutiple test fixtures (#5456) by @hyf0 - basic tests for `optimization.pifeForModuleWrappers` (#5435) by @sapphi-red ### ⚙️ Miscellaneous Tasks - deps: update github-actions (#5509) by @renovate[bot] - debug: update default session ID to meaningful `unknown-session` (#5502) by @hyf0 - deps: update dependency rolldown-plugin-dts to v0.14.2 (#5492) by @renovate[bot] - auto generated runtime_helper bitflags (#5474) by @IWANABETHATGUY - fix wasi build failed (#5470) by @IWANABETHATGUY - deps: lock file maintenance (#5467) by @renovate[bot] - deps: lock file maintenance (#5466) by @renovate[bot] - deps: lock file maintenance rust crates (#5465) by @renovate[bot] - deps: lock file maintenance npm packages (#5464) by @renovate[bot] - deps: update github-actions (#5463) by @renovate[bot] - export `__commonJSMin` in runtime-base.js (#5455) by @IWANABETHATGUY - rolldown_plugin_utils: remove `file_to_dev_url` temporarily (#5446) by @shulaoda - rolldown_plugin_asset: move `remove_url_query` into `rolldown_plugin_utils` (#5444) by @shulaoda - rolldown: disable aarch64 atomics (#5447) by @Brooooooklyn - remove diff with esbuild (#5428) by @IWANABETHATGUY - dx/ai: add deepwiki badge to enable automatic refresh (#5423) by @hyf0 - dx/ai: Use `.cursorignore` to ignore meaningless files for AI (#5422) by @hyf0 - rolldown_plugin_alias: inline matches and remove redundant comment (#5418) by @shulaoda - rolldown_plugin_asset: remove unnecessary comments (#5411) by @shulaoda - rolldown_plugin_manifest: remove unnecessary code (#5408) by @shulaoda - deps: update dependency tsdown to v0.13.0 (#5392) by @renovate[bot]
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.

This PR changes the generated code to use PIFE for callbacks passed to
__esmMinwrapper. This improved the start up runtime performance by 2.1x in the case I tested.I tested this change on https://github.com/rolldown/benchmarks/tree/main/apps/10000 with the following config:
I also updated the HTML to measure the render time.
The results were (average of 5 times):
I tested this on Chrome 138.0.7204.101.
Also note that this change increases the output code size slightly:
Before: 6,338.19 kB (gzip: 1,871.28 kB)
After: 6,376.20 kB (gzip: 1,874.64 kB)
requires oxc-project/oxc#12353
Note: The same optimization can be applied to
__commonJSMin,__esm,__commonJS,createEsmInitializer.