Workflow: Performance Evaluation
Use this skill when tasked with improving the performance or memory usage of a
workload in V8. This workflow focuses on identifying bottlenecks and applying
V8-side optimizations.
Activation Criteria
- User requests to optimize a specific benchmark or script.
- Goal is to reduce execution time, CPU cycles, or memory footprint.
Core Principles
- Data-Driven: Always base optimization decisions on profiling data, not
intuition.
- V8-Centric: For V8 engineers, performance work usually means changing V8
to better handle the JS pattern, rather than changing the JS itself (though
both are valid for general users).
- Holistic View: Look for general efficiency improvements, not just the
single hottest function.
- Contextual Interpretation: Assume unknown terms in performance tasks are
likely benchmark names or domain-specific concepts, not environmental terms
(e.g., "WSL" is likely a JetStream story, not the OS). Verify before
assuming. If in doubt, ask the user.
- Mandatory Orchestration: The agent executing this workflow MUST act as an
Orchestrator. Delegate execution of benchmarks, profiles, or searches to
subagents to maximize parallelism.
- Local Experiment Baseline: Whenever asked to perform a local experiment,
always compile the baseline first and store it in a separate directory like
x64.release-baseline for better gm.py integration. This avoids
recompiling at later stages.
Workflow
Planning
For performance analysis, you do NOT need to create a full
implementation_plan.md until you are actually fixing the performance issue
you've detected. Instead, maintain an Analysis Plan (e.g., in task.md or
as a list of questions to answer) to guide the investigation.
1. Parallel Track Initialization
Initialize the following tracks concurrently:
- Track A: Profiling & Tracing:
- Run the workload with the v8-profiling skill (e.g. linux-perf and/or pprof).
- Use V8 tracing flags to gather specific runtime telemetry.
- Track B: V8 Log Analysis
- Use the v8-log skill to extract v8.log and analyze internal state of V8
- Track C: JS Source Analysis:
- Study the JavaScript benchmark to understand the core operations and
potential hotspots.
- Benchmark Source Access: If benchmark sources (such as JetStream 3) are
not locally available under
test/benchmarks/, enable
"checkout_benchmarks": True in your ../.gclient configuration
(custom_vars) and run gclient sync.
- Track D: Static V8 Research:
- Search for known optimization patterns or issues related to the observed JS
patterns in the V8 codebase.
3. Running Benchmarks / Pages in Chrome with with Crossbench
- Generate Performance Logs and Profiles: use the crossbench skill to gather
v8.log, detailed perfetto traces and sampling profiles from pages or
benchmarks.
- Probes:
- Use
--probe=profiling for full-browser or d8 profiles
- Use
--probe=perfetto for detailed perfetto traces
- Use
--probe=v8.log for extracting internal v8 logs from chrome
4. Alternative: Running Benchmarks with jsb_run_bench
In the jetski environment, you can also use the jsb_run_bench tool from
v8-utils as an alternative for quick runs.
- Run for Scores: Call
jsb_run_bench with paths to d8 binaries to
compare performance.
- Profile: Supports
record: "perf" and record: "v8log".
5. Profile Analysis & Tick Processor
- Generate and Analyze Profile: Use the v8-profiling skill to generate and
analyze linux-perf and tickprocessor profiles. Note that you can use
crossbench for generating chromium-level profiles.
- Cross Reference:
- Correlate JS sources with v8.log to understand what V8 is doing when
executing the JS sources.
- Use the v8.log to further drill down on internal v8 state to understand
bottlenecks.
- Interpretation:
- Look at the C++ entry points and JS functions taking the most ticks.
- Check if time is spent in runtime functions vs. generated code.
- Identify if specific builtins are taking significant time.
- Identify inefficient JS code patterns in the workloads
- Suggest builtins, C++ code that can be optimized
6. Tracing Compiler Graphs (Turbolizer)
For peak performance, it is often necessary to inspect the intermediate
representations (IR) of the optimizing compiler (TurboFan or Turboshaft).
- Generate Graph Data: Run
d8 --trace-turbo script.js or pass flags in
Crossbench/jsb_run_bench. This generates JSON files containing the graph state
at various optimization phases (e.g., turbo-*.json).
- Visualize with Turbolizer: Use the Turbolizer tool (available internally
at
go/turbolizer or in the V8 repository under tools/turbolizer).
- Analysis:
- Inspect the graph at different phases to see how nodes are simplified,
combined, or eliminated.
- Look for missed optimizations, such as redundant checks that were not
hoisted or allocations that failed to be eliminated by escape analysis.
- Identify unexpected deoptimization points.
7. Identifying General Efficiency Improvements
Beyond hotspots, look for areas where V8 can be improved to handle patterns
better:
- Reducing Allocations: High GC overhead implies frequent allocations.
Investigate if V8 can optimize allocation folding, escape analysis, or if the
allocations are unavoidable.
- Optimizing Hot Loops: Ensure loops are not deoptimizing in V8. Check if
checks can be hoisted by the compiler or if loop peeling is effective in the
VM.
- Hidden Class (Map) Stability: Understand how object shapes evolve and
cause polymorphic or megamorphic IC states. Investigate if V8 can be optimized
to handle these transitions better.
8. Analysis & Reprioritization
- Analyze profile results (e.g., flamegraphs, top functions).
- Dynamic Reprioritization:
- High GC Time: If profile shows significant time in GC, pivot to
allocation analysis and reducing memory churn. Also explain which JS code is
causing frequent allocations.
- High IC Misses: If
--log-ic shows frequent misses, pivot to
investigating object layout and stabilizing hidden classes.
- Dominant Hotspot: If a single function dominates execution time, focus
all efforts on that component.
- Pattern Identification: If a V8 change is identified that could improve
the pattern generally, prioritize implementing and testing it over further
analysis.
9. Optimization & Verification
- Propose a V8 change to improve performance (e.g., specialized builtin,
improved optimization pass).
- Verification on Pinpoint (Preferred):
- Local Verification:
- Re-run the benchmark locally if Pinpoint is unavailable.
- Compare
perf stats (cycles, instructions).
- Ensure no regressions in correctness or other benchmarks.
1---2name: workflow-perf3description: Workflow for performance and memory evaluation in V8. Use when tasked with improving the performance or memory usage of a workload in V8. Do not use when debugging a crash or functionality issue.4---56# Workflow: Performance Evaluation78Use this skill when tasked with improving the performance or memory usage of a9workload in V8. This workflow focuses on identifying bottlenecks and applying10V8-side optimizations.1112## Activation Criteria1314- User requests to optimize a specific benchmark or script.15- Goal is to reduce execution time, CPU cycles, or memory footprint.1617## Core Principles18191. **Data-Driven**: Always base optimization decisions on profiling data, not20 intuition.212. **V8-Centric**: For V8 engineers, performance work usually means changing V822 to better handle the JS pattern, rather than changing the JS itself (though23 both are valid for general users).243. **Holistic View**: Look for general efficiency improvements, not just the25 single hottest function.264. **Contextual Interpretation**: Assume unknown terms in performance tasks are27 likely benchmark names or domain-specific concepts, not environmental terms28 (e.g., "WSL" is likely a JetStream story, not the OS). Verify before29 assuming. If in doubt, ask the user.305. **Mandatory Orchestration**: The agent executing this workflow MUST act as an31 Orchestrator. Delegate execution of benchmarks, profiles, or searches to32 subagents to maximize parallelism.336. **Local Experiment Baseline**: Whenever asked to perform a local experiment,34 always compile the baseline first and store it in a separate directory like35 `x64.release-baseline` for better `gm.py` integration. This avoids36 recompiling at later stages.3738## Workflow3940### Planning4142For performance analysis, you do NOT need to create a full43`implementation_plan.md` until you are actually _fixing_ the performance issue44you've detected. Instead, maintain an **Analysis Plan** (e.g., in `task.md` or45as a list of questions to answer) to guide the investigation.4647### 1. Parallel Track Initialization4849Initialize the following tracks concurrently:5051- **Track A: Profiling & Tracing**:52 - Run the workload with the v8-profiling skill (e.g. linux-perf and/or pprof).53 - Use V8 tracing flags to gather specific runtime telemetry.54- **Track B: V8 Log Analysis**55 - Use the v8-log skill to extract v8.log and analyze internal state of V856- **Track C: JS Source Analysis**:57 - Study the JavaScript benchmark to understand the core operations and58 potential hotspots.59 - **Benchmark Source Access**: If benchmark sources (such as JetStream 3) are60 not locally available under `test/benchmarks/`, enable61 `"checkout_benchmarks": True` in your `../.gclient` configuration62 (`custom_vars`) and run `gclient sync`.63- **Track D: Static V8 Research**:64 - Search for known optimization patterns or issues related to the observed JS65 patterns in the V8 codebase.6667### 3. Running Benchmarks / Pages in Chrome with with Crossbench6869- **Generate Performance Logs and Profiles**: use the crossbench skill to gather70 v8.log, detailed perfetto traces and sampling profiles from pages or71 benchmarks.72- **Probes**:73 - Use `--probe=profiling` for full-browser or d8 profiles74 - Use `--probe=perfetto` for detailed perfetto traces75 - Use `--probe=v8.log` for extracting internal v8 logs from chrome7677### 4. Alternative: Running Benchmarks with jsb_run_bench7879In the `jetski` environment, you can also use the `jsb_run_bench` tool from80`v8-utils` as an alternative for quick runs.8182- **Run for Scores**: Call `jsb_run_bench` with paths to `d8` binaries to83 compare performance.84- **Profile**: Supports `record: "perf"` and `record: "v8log"`.8586### 5. Profile Analysis & Tick Processor8788- **Generate and Analyze Profile**: Use the v8-profiling skill to generate and89 analyze linux-perf and tickprocessor profiles. Note that you can use90 crossbench for generating chromium-level profiles.91- **Cross Reference**:92 - Correlate JS sources with v8.log to understand what V8 is doing when93 executing the JS sources.94 - Use the v8.log to further drill down on internal v8 state to understand95 bottlenecks.96- **Interpretation**:97 - Look at the C++ entry points and JS functions taking the most ticks.98 - Check if time is spent in runtime functions vs. generated code.99 - Identify if specific builtins are taking significant time.100 - Identify inefficient JS code patterns in the workloads101 - Suggest builtins, C++ code that can be optimized102103### 6. Tracing Compiler Graphs (Turbolizer)104105For peak performance, it is often necessary to inspect the intermediate106representations (IR) of the optimizing compiler (TurboFan or Turboshaft).107108- **Generate Graph Data**: Run `d8 --trace-turbo script.js` or pass flags in109 Crossbench/jsb_run_bench. This generates JSON files containing the graph state110 at various optimization phases (e.g., `turbo-*.json`).111- **Visualize with Turbolizer**: Use the Turbolizer tool (available internally112 at `go/turbolizer` or in the V8 repository under `tools/turbolizer`).113- **Analysis**:114 - Inspect the graph at different phases to see how nodes are simplified,115 combined, or eliminated.116 - Look for missed optimizations, such as redundant checks that were not117 hoisted or allocations that failed to be eliminated by escape analysis.118 - Identify unexpected deoptimization points.119120### 7. Identifying General Efficiency Improvements121122Beyond hotspots, look for areas where V8 can be improved to handle patterns123better:124125- **Reducing Allocations**: High GC overhead implies frequent allocations.126 Investigate if V8 can optimize allocation folding, escape analysis, or if the127 allocations are unavoidable.128- **Optimizing Hot Loops**: Ensure loops are not deoptimizing in V8. Check if129 checks can be hoisted by the compiler or if loop peeling is effective in the130 VM.131- **Hidden Class (Map) Stability**: Understand how object shapes evolve and132 cause polymorphic or megamorphic IC states. Investigate if V8 can be optimized133 to handle these transitions better.134135### 8. Analysis & Reprioritization136137- Analyze profile results (e.g., flamegraphs, top functions).138- **Dynamic Reprioritization**:139 - **High GC Time**: If profile shows significant time in GC, pivot to140 allocation analysis and reducing memory churn. Also explain which JS code is141 causing frequent allocations.142 - **High IC Misses**: If `--log-ic` shows frequent misses, pivot to143 investigating object layout and stabilizing hidden classes.144 - **Dominant Hotspot**: If a single function dominates execution time, focus145 all efforts on that component.146 - **Pattern Identification**: If a V8 change is identified that could improve147 the pattern generally, prioritize implementing and testing it over further148 analysis.149150### 9. Optimization & Verification151152- Propose a V8 change to improve performance (e.g., specialized builtin,153 improved optimization pass).154- **Verification on Pinpoint (Preferred)**:155 - Commit changes to a local branch.156 - Use the automation script to upload a CL and start a Pinpoint job:157 ```bash158 scripts/upload_and_pinpoint.py \159 --benchmark=<benchmark_name> \160 --bot=<bot_name> \161 --message="Experiment: My performance optimization"162 ```163 - Use `./cb.py pinpoint help` to understand the available options.164- **Local Verification**:165 - Re-run the benchmark locally if Pinpoint is unavailable.166 - Compare `perf` stats (cycles, instructions).167 - Ensure no regressions in correctness or other benchmarks.