Commit 19d09c2a authored by Cao Ye's avatar Cao Ye


parent 6be26256
General Documentation
.. toctree::
:maxdepth: 2
:caption: Contents:
1. How is PicoRio compared to Raspberry Pi?
Inspired by the Raspberry Pi, we propose the PicoRio project, whose goal is to produce RISC-V based small-board computers at an affordable price point. PicoRio has some following differences in following aspects:
* **Open Source**: Unlike Raspberry Pi, which uses proprietary Broadcom SoCs, PicoRio will open source as many components as possible, including the CPU and main SoC design, chip package and board design files, device drivers, and firmware. Nevertheless, our goal is to reduce the commercial closed source IPs for each successive release of PicoRio, with the long term goal of having a version that is as open as practical.
* **Low-Power and Low-Cost**: The target metrics of PicoRio are long battery life and low cost, which is a better match to RISC-V today, instead of high performance and large memory. In contrast, Raspberry Pi uses more power hungry ARM processors. For example, the idle power consumption has risen from 0.4 Watts to 2.7 Watts in the latest version of Raspberry Pi.
What is PicoRio
PicoRio is an open-source project stewarded by the RISC-V International Open Source (RIOS) laboratory —— —— a nonprofit research lab at Tsinghua-Berkeley Shenzhen Institute (TBSI). The RIOS Lab uses collaborative engineering from both academia and industry to elevate the RISC-V software and hardware ecosystem. In PicoRio, we create an open, affordable, Linux-capable RISC-V hardware platform to aid software developers in porting many modern programs that require Javascript or GPUs. PicoRio will build upon high-quality IPs and software components from expert industry engineers and academic researchers. PicoRio is not proprietary to any specific vendor and platform, and will have complete documentation that can help people to build quality products in a short amount of time.
Need more than processors to build a system
* Large cost to license other IPs in SoC: cache, interconnect, graphics, camera ISP, etc
* Need an attractive open-source platform to try new Hardware ideas
* Security and trusted execution are not complete without a full-system support
* RISC-V hardware extensions: JIT runtime, vector, etc
The community lacks affordable RISC-V hardware platforms that run a variety of software
* Few software-capable boards for the long tail of developers
* Developers won't spend a thousand dollar for a new hardware just for software development
* **Independently Maintained**: The RIOS Lab will be the solo nonprofit organization that governs the architecture development, ensures compliance, and will publish the design. The RIOS Lab will be the gatekeeper for both hardware and software, from SoC and firmware/drivers to high-level software and documentation. PicoRio will be vendor agnostic and not proprietary, and the RIOS Lab will work with academic and commercial organizations that will commit to its expansion and volume manufacturing.
* **Open Source**: PicoRio will open source as many components as possible, including the CPU and main SoC design, chip package and board design files, device drivers, and firmware. The exceptions are foundry related IPs (e.g., TSMC SRAM configurations), commercial high-speed interfaces, and complex commercial IP blocks like GPU. Nevertheless, our goal is to reduce the commercial closed source IPs for each successive release of PicoRio, with the long term goal of having a version that is as open as practical.
* **High-Quality IPs**: A major goal of the RIOS lab is to develop open source, industrial strength hardware IP to help the RISC-V ecosystem catch up with those of the older, proprietary ISAs. Thus, PicoRio aims at a high-quality silicon release using open-source IP. The IPs will have gone through rigorous real tapeout verifications that meet industry quality. The openness of PicoRio will not come at the cost of lower quality IP blocks. In addition, we will open source our verification process, which will help to improve transparency and trustworthiness.
* **Modern Software Stack Support**: PicoRio utilizes a heterogeneous multicore architecture and is Linux-capable (RV64GC). We also designed PicoRio hardware to run modern managed languages such as JavaScript/WebAssembly as well as graphical applications like the Chrome web browser. At the RIOS Lab, PicoRio is also the hardware platform for several other open-source software projects, like the RISC-V ports for the V8 Javascript engine and the Chromium OS.
* **Low-Power and Low-Cost**: The target metrics of PicoRio are long battery life and low cost, which is a better match to RISC-V today, instead of high performance and large memory.
Project Roadmap
Three Phases of the PicoRio Development
This section tells some concrete targets. We aim to release a new PicoRio version step by step. We divide the development of PicoRio into three phases:
* **First Phase (PicoRio 1.0)**: We include a basic 64-bit quad-core cache-coherent design (RV64GC) that runs full Linux. We have already booted a Chromium OS kernel in command line mode. A standalone version of Chrome V8 Javascript engine will run directly on the kernel. We expect an early beta release late this year. This “headless” version of PicoRio should be fine for software development.
* **Second Phase (PicoRio 2.0)**: In addition to improving the v1.0 hardware, we are working with Imagination to include a complete display pipeline (including a GPU) with video encode/decode capabilities to run graphics intensive applications like web browsers.
* **Third Phase (PicoRio 3.0)**: Building upon the v2.0 hardware, we plan to further improve the CPU performance to bring PicoRio to the level of a pad computer / laptop
\ No newline at end of file
.. rios_pi_doc documentation master file, created by
sphinx-quickstart on Fri May 29 14:12:33 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
PicoRio User Manual
Software Projects
This section describes the software projects supported by PicoRio. We put all the subprojects in a dashboard, and list out our current developing status of them.
.. toctree::
:maxdepth: 2
| Projects | Development State | Project Description | Link |
| `V8`_ | | V8 is a commonly used JavaScript engine in | |
| | | popular web browsers. PicoRio provides | |
| | | support for RISC-V V8. | |
| Chromium OS | | Chromium OS is a open-source web browser | |
| | | with strong web application support and rich | |
| | | software ecosystem. This project is RISC-V | |
| | | port of Chromium OS, and is in development. | |
.. _V8: ./software/v8.html
\ No newline at end of file
This is an on-going project to develop the RISC-V backend for the V8 JavaScript Engine. After a few months of intensive development, we have built a sufficient MVP (Minimal Viable Product) for the RISC-V64-bit port, which currently passes over 90% (10,000+) standard V8 test cases using v8-riscv64 simulated build. We have also established a sustainable porting methodology and development best practices that we feel confident invite a broader community participation. We welcome you joining our development effort. Plenty of supports are still needed for a complete and high-performing V8 on RISC-V.
This repo will be the community home for some time before the code-base is upstream to the V8 community. For general V8 information, see `V8 Dev`_. The rest of the wiki is specific to the RISC-V V8 backend.
ISC-V ISA specification is found `here`_, and RISC-V standard ABI can be found `here.`_
.. _V8 Dev:
.. _here:
.. _here.:
.. toctree::
:maxdepth: 2
:caption: Contents:
.. _Join our Slack:
\ No newline at end of file
Community Operations
`Join our Slack`_
Attend developer meetings
.. _Join our Slack:
\ No newline at end of file
RISC-V Backend Design Documentation
.. toctree::
:maxdepth: 2
:caption: Contents:
\ No newline at end of file
How to Add a New Instruction
For an evolving ISA like RISC-V, it is common that we will have support for new instructions or new ISA extensions to the backend. In this post, we explain the steps to add a new instruction to an existing backend. In this case, we use the riscv64 backend as an example, but the process is similar to other backends as well.
1. Add constants (``src/codegen/riscv64/constants-riscv64.h``)
``constants-riscv64.h`` defines constants that are related to instruction classes and encodings that are shared by the ``Assembler``, ``Disasm``, and ``Simulator``. You will need to add new opcode to ``enum Opcode_t`` and other constants if it uses a new instruction format. Sometimes, a new instruction uses a new class of registers. Then one needs to add new register classes to ``register-riscv64.h``.
2. Add to the assembler (``src/codegen/riscv64/assembler-riscv64.h/cc``)
Add a new ``Assembler`` API to ```` and ``assembler-riscv64.h`` as the generator for the new instruction. These ``Assembler`` APIs are typically named after the instruction name unless there is a naming conflict, such as ``and`` is named as ``and_``::
// assembler-riscv64.h
void add(Register rd, Register rs1, Register rs2);
void Assembler::add(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b000, rd, rs1, rs2);
If the instruction uses a new instruction format, one needs to add a new generator function for this new instruction format (e.g., ``GenInstrALU_rr``).
3. Add to the simulator (``src/codegen/riscv64/simulator-riscv64.h/cc``)
Implement the behavior of the instruction in the simulator as shown blow::
void Simulator::DecodeRVRType() {
switch (instr_.InstructionBits() & kRTypeMask) {
case RO_ADD: {
set_rd(sext_xlen(rs1() + rs2()));
Note that constants like ``kRTypeMask`` is defined in ``constants-riscv64.h`` and is shared by both ``Assembler``, ``Simulator``, and ``Disasm``.
4. Test the instruction
Once an instruction is added to the ``Assembler`` and the ``Simulator``, it can be tested under the `simulator build`_ run. The new instruction needs to be added ``test/cctest/``::
.. _simulator build: ../getstart/simulator.html
which is a macro that specifies two input operands to add ``and`` compare it against the expected result computing by ``+`` the two operands.
5. Add to the disassembler (``src/diagnostics/riscv64/disasm-riscv64.h/cc``)
Add the disassembler for the new instruction, as shown below::
void Decoder::DecodeRType(Instruction* instr) {
switch (instr->InstructionBits() & kRTypeMask) {
case RO_ADD:
Format(instr, "add 'rd, 'rs1, 'rs2");
6. Test disassembler
Add a test for disassembly the new instruction in ``test/cctest/`` as shown below::
COMPARE(add(s6, t0, t4), "01d28b33 add s6, t0, t4");
7. Use the new instruction
Simply adding a new instruction to the ``Assembler`` does not mean that the instruction is generated during code-gen. You have to use these "assembler" APIs in the code-gen routines such as in ``TurboAssembler`` (``src/codegen/riscv64/``), in ASM built-in functions (``src/builtins/riscv64/``), during the lowering from TF machine-node IR to target-specific codes (``src/compiler/backend/riscv64/``), in the lowering from WASM IR to target-specific codes in the liftoff-compiler (``src/wasm/riscv64/liftoff-assembler-riscv64.h``), in regexp assembler (``src/regexp/riscv64/``).
Sometimes a sequence of TF machine-node IRs may be represented by the new instruction being added. In this case, you need to introduce a new architecture-specific machine-node IR and add the new instruction to the instruction selector (``src/compiler/backend/riscv64/``), and a test case for the instruction selection (``test/unittests/riscv64/``).
\ No newline at end of file
This diff is collapsed.
How to Develop a New Backend
\ No newline at end of file
For Developers
.. toctree::
:maxdepth: 2
:caption: Contents:
\ No newline at end of file
As we hope to eventually get this code upstreamed, we will generally follow all policies from the `official v8 project`_.
.. _official v8 project:
In general, all changes should be based on an `issue`_. If you would like to work on an existing issue, first check if anyone is already assigned and if so, discuss with that person before beginning work. If you would like to work on a new problem or enhancement, first create an issue for it and discuss with the community. The best way to do this will be to `join us in Slack`_.
.. _issue:
.. _join us in Slack:
When creating a new issue, please be descriptive and include all relevant details, enough that someone completely unfamiliar with the problem or proposal can understand. Be sure to label your issue with the appropriate category (bug, enhancement, documentation, etc.). If you plan to work on the issue yourself, feel free to self-assign, otherwise, you can leave it unassigned for someone else to pick up.
If you plan to begin work on an issue, first verify that it is not already assigned to someone else. If it is already assigned, but you have some special reason to work on this issue, be sure to communicate with the assigned person. If it is unassigned, assign it to yourself before beginning work so that others know you are working on it. Use the issues comments to update your status regularly and communicate any important information to the community.
Submitting your Changes
This project uses the standard GitHub mechanism for pull requests. See `GitHub. Contributing to a Project`_ for the basic information on how to fork the repository, create a pull request, etc.
As mentioned above, we will follow the `guidelines`_ for the upstream v8 project. The relevant part for submitting code is::
\\ The source code of V8 follows the Google C++ Style Guide so you should familiarize yourself with those guidelines. Before submitting code you must pass all our tests, and have to successfully run the presubmit checks:
git cl presubmit
\\ The presubmit script uses a linter from Google, It is part of depot_tools, and it must be in your PATH — so if you have depot_tools in your PATH, everything should just work.
.. _guidelines:
.. _GitHub. Contributing to a Project:
Our CI job will run tests as well. These tests must all pass in order for your pull request to be considered. The CI job runs the following command to test a build::
tools/ --outdir=out/riscv64.sim cctest \
unittests \
wasm-api-tests \
wasm-js \
wasm-spec-tests \
mjsunit \
intl \
message \
debugger \
inspector \
Please run this same suite of tests locally before opening your PR to avoid wasting any one's time.
All pull requests must be reviewed and approved by at least one owner before being accepted. Please also review "Using Git" and ensure that your commit messages follow the guidelines laid out there.
Contributing to the Documentation
The wiki is editable by all team members. Others may open issues against documentation, in the same way you would do for issues with the code. It seems that GitHub does not support PRs for the wiki, but we welcome contributors to add your changes into an issue for the team to review.
\ No newline at end of file
How to debug V8
Overall strategy
* Simplify the test cases
* Identify the ground truth
* Find the lead
* Map execution trace back to V8 source code
Build options for debugging
When running ``d8`` or ``cctest`` in ``gdb``, it will be useful to add the flag ``v8_optimized_debug = false`` to the GN arguments and rebuild. Without this, the code is optimized by default and will be difficult to debug.
Useful flags for debugging
* ``--single-threaded``: disable background threads
* ``--jitless``: disable JIT code generation
Debugging under simulated build run
Use simulator trace (``--trace-sim``)
V8's simulated build is not only convenient for developing the backend for a new ISA on a host machine, but also helpful for debugging target binary on the host machine. The latter is enabled by ``--trace-sim``, which dumps out all instructions executed using V8's built-in simulator as well as the register states::
cctest test-bytecode-generator/StaticClassFields --trace-sim > trace.log
A typical trace looks like the following. The number in ``()`` (e.g., ``(49)``) indicates the instruction count. And the hex number before the instruction count is the value in the target register (e.g., ``s3`` in this instruction) in hex. And the ``type:value`` pair following the instruction count is the value of target register in decimal (for integer types) or floating-point (for float)::
0x55b90866a9e0 00200993 li s3, 2 0000000000000002 (49) int64:2 uint64:2
0x55b90866a9e4 00000463 beq zero_reg, zero_reg, 8
0x55b90866a9ec ff810113 addi sp, sp, -8 00007fe83b181ee0 (51) int64:140635400576736 uint64:140635400576736
0x55b90866a9f0 01313023 sd s3, 0(sp) (52) int64:2 uint64:2 --> [addr: 7fe83b181ee0]
0x55b90866a9f4 01c0006f j 28 0000000000000000 (53) int64:0 uint64:0
0x55b90866aa10 00000e13 mv t3, zero_reg 0000000000000000 (54) int64:0 uint64:0
Use simulator debugger (``--stop-at-sim``)
The simulator embedded in V8 has a built-in debugger. The debugger can be invoked by ``--stop-sim-at <n>``. For instance, the following command will enter the simulator mode after executing 100 RISCV instructions in the simulator (as shown by the ``sim>`` prompt)::
cctest test-bytecode-generator/StaticClassFields --stop-sim-at 100
0x000055937ba80000 009784b3 add s1, a5, s1
sim> disasm
0x55937ba80000 009784b3 add s1, a5, s1
0x55937ba80004 00000c63 beq zero_reg, zero_reg, 24
0x55937ba80008 0007b903 ld s2, 0(a5)
0x55937ba8000c 00878793 addi a5, a5, 8
0x55937ba80010 00093903 ld s2, 0(s2)
0x55937ba80014 ff810113 addi sp, sp, -8
0x55937ba80018 01213023 sd s2, 0(sp)
0x55937ba8001c fe9796e3 bne a5, s1, -20
0x55937ba80020 fa0b3703 ld a4, -96(s6)
0x55937ba80024 00070793 mv a5, a4
One can type ``help`` under the prompt to get a list of commands supported by the debugger::
sim> help
continue execution (alias 'c')
step one instruction (alias 'si')
print <register> (e.g., `print a0`)
print register content (alias 'p')
use register name 'all' to print all GPRs
use register name 'allf' to print all GPRs and FPRs
printobject <register>
print an object from a register (alias 'po')
stack [<words>] (e.g., `stack 5`)
dump stack content, default dump 10 words)
mem <address> [<words>] (`mem 0x234567 5`)
dump memory content, default dump 10 words)
disasm [<instructions>] (e.g., disasm 30)
disasm [<address/register>] (e.g., disasm pc)
disasm [[<address/register>] <instructions>]
disassemble code, default is 10 instructions
from pc (alias 'di')
Note: commands ``break``, ``stop``, and ``gdb`` are not yet supported.
Generate debugging code in generated codes
Sometimes we want to see if an execution follows a particular code path. For instance, in the following example, a ``Trap`` instruction is inserted to the code path following the label ``stack_overflow``. If the execution does reach this path, it will enter the simulator debugger (i.e., entering prompt ``sim>``)::
__ bind(&stack_overflow);
__ Trap(); // trap if execution reaches here
// Restore the context from the frame.
__ Ld(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
__ CallRuntime(Runtime::kThrowStackOverflow);
Other debugging APIs from ``TurboAssembler`` are::
void TurboAssembler::Trap();
void TurboAssembler::Assert(Condition cc, AbortReason reason, Register rs, Operand rt);
void TurboAssembler::Check(Condition cc, AbortReason reason, Register rs, Operand rt);
void TurboAssembler::Abort(AbortReason reason);
Flags summary
``d8`` flags needed:
* ``--trace-sim``: print out disasm of instructions and content of target register after each simulated instruction
* ``--debug-riscv``: Print instructions as they are emitted; print other debug info from assemblers
* ``--stop-sim-at <n>``: enter debugger embedded inside the simulator after <n> instructions
Connect simulated trace to generated code
Use ``print-all-code``
This is a very useful flag when debugging built-in functions. It dumps all codes generated by the compiler including built-in functions and user-level codes. Since there are a couple of thousands of built-in functions, it is recommended to redirect output to a file when using the flag (otherwise your VSCode remote window may freeze over too much stdout output)::
cctest test-bytecode-generator/StaticClassFields --print-all-code > t.all-code
Here are some useful flags for tracing V8 internals (complete flags use ``d8 --help``):
* ``--print-bytecode``: print Ignition interpreter bytecode
* ``--print-code`` and ``--code-comments``: printout generated final code (w/ additional comments)
* ``--print-all-code``: will printout all generated codes (incl. builtins) w/ all verbose options, a lot of output so better redirect to a file
* ``--use-verbose-printer`` (combined w/ ``print-code``, ``print-builtin-code``): print out
* ``--print-wasm-code``, ``--print-wasm-stub-code``, ``--code-coments``: printout wasm code generated and wasm native code gen
* ``--print-builtin-code`` and ``--print-builtin-size``: print out disasm of generated builtin functions or their instruction sizes
Use code comments
Code comments may be useful to identify the locations where specific assembly code came from. When code comments are enabled, comments inserted at the high level will translate into comments in the output with --print-all-code. For example, if I want to see the code coming from CollectionsBuiltinsAssembler::SameValueZeroHeapNumber (, I may insert the Comment shown below at the beginning of the functions definition::
void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber(
TNode<Float64T> key_float, TNode<Object> candidate_key, Label* if_same,
Label* if_not_same) {
Label if_smi(this), if_keyisnan(this);
GotoIf(TaggedIsSmi(candidate_key), &if_smi);
GotoIfNot(IsHeapNumber(CAST(candidate_key)), if_not_same);
The code comments will not appear unless the appropriate flag is used. For code compiled at run-time, use the flag ``--code-comments``. For code that is pre-compiled in the snapshot, add the following flag to your build configuration (in ````), then rebuild::
v8_enable_snapshot_code_comments = true
Now, when I run my test with ``--print-all-code``, I can search for "SameValueZeroHeapNumber" to identify the PC where this line was generated::
0x563e95e60628 4188 0005169b slliw a3, a0, 0
0x563e95e6062c 418c 0006d69b srliw a3, a3, 0
0x563e95e60630 4190 fad43423 sd a3, -88(fp)
0x563e95e60634 4194 0016f993 andi s3, a3, 0x1
These PCs can then be mapped to the output from ``--trace-sim``, to track the code and identify the bug.
Trace Analyzer
We have developed a tool to help analyze a simulator trace. It is available in the repository at ``_. It is designed to read the output of a simulation run with the flags ``--print-all-code`` and ``--trace-sim``. Write this output to a file, as in this example::
$ ./cctest --print-all-code -trace-sim test-interpreter-intrinsics/Call &> out
The tool takes that file as input and uses it to generate a call tree::
$ ../../tools/riscv/ out
### Start in JSEntry
### Call JSEntryTrampoline 70
### sp=0x7fd46befbed0 fp=0x7fd46befbf00
### Args: 0x55b749fba710 0x2e3f480471 0x6789a9c129 0x2269200121 0x0 0x0 ? ?
### Jump to JSEntryTrampoline 79
### sp=0x7fd46befbed0 fp=0x7fd46befbf00
### Args: 0x55b749fba710 0x2e3f480471 0x6789a9c129 0x2269200121 0x0 0x0 ? ?
### Call Call_ReceiverIsAny 116
### sp=0x7fd46befbea8 fp=0x7fd46befbec0
### Args: 0x0 0x6789a9c129 0x6789a9c129 0x2e3f480471 0x2e3f480471 0x2e3f480471 ? ?
### Jump to Call_ReceiverIsAny 125
### sp=0x7fd46befbea8 fp=0x7fd46befbec0
### Args: 0x0 0x6789a9c129 0x6789a9c129 0x2e3f480471 0x2e3f480471 0x2e3f480471 ? ?
### Jump to CallFunction_ReceiverIsAny 137
### sp=0x7fd46befbea8 fp=0x7fd46befbec0
### Args: 0x0 0x6789a9c129 0x6789a9c129 0x2e3f480471 0x2e3f480471 0x2e3f480471 ? ?
### Jump to CallFunction_ReceiverIsAny 146
### Return from StackCheckHandler 1576
### Returned: 0x2269203f81 0x50
### Return from Call_ReceiverIsAny 1596
### Returned: 0x2269203f81 0xab
### WARNING: Expected stack pointer = 140550320668328, actual = 140550320668336
### Return from JSEntryTrampoline 1600
### Returned: 0x2269203f81 0xab
### Return from JSEntry 1650
### Returned: 0x2269203f81 0x0
As you can see in the example output above, the tool detects calls and jumps to functions and reports the name of the function called, then dumps the stack and frame pointers, and argument registers (a0-a7). a ``?`` indicates that a value has not yet been seen for this register. Upon detecting a return, the comment is printed and the return value registers (a0 and a1) are printed. The following checks are also performed at a return:
* The return address should match the original return address from the call-site
* The stack pointer should be reset to the original stack pointer from the call-site
* The frame pointer should be reset to the original frame pointer from the call-site
You may use the ``-help`` flag to see the current list of available flags::
usage: [-h] [--inline] [--target TARGET] [--print-host-calls]
positional arguments:
optional arguments:
-h, --help show this help message and exit
--inline Print comments inline with trace
--target TARGET Specify the target architecture
--print-host-calls Print info about calls to host functions
--inline is useful to see the comments inline with the original lines of the simulator trace, to use the comments as a starting place to dig deeper.
--target allows users to specify the target architecture, which is riscv by default, but also supports mips. This is useful for comparing the run of RISC-V against MIPS.
--print-host-calls enables tracking calls/returns from host functions. These are ignored by default since we do not have information about the callee.
Dump TF compiler IR via Turbolizer
Turbolizer is a tool to visualize generated TF IR from ``--trace-turbo``.
Generate TF sea-of-nodes
``d8`` flags needed:
* ``--trace-opt``, ``--trace-turbo``: trace Turbofan compiler, dump IR/code after each transformation into a generated ``.json`` or ``.cfg`` file
* ``--trace-turbo-path=xxx`` to dump the generated file to a specified directory
V8 (d8) can generate TF IRs to json files when ``--trace-turbo`` is specified. Each TF compiled function will produce one json file.
For instance, the following command will generate ``turbo-0x591b1bfd0-0.json`` which contains TF IR/nodes generated by different phases of TF compile::
> test-run-jsops/BinopAdd --trace-turbo
Concurrent recompilation has been disabled for tracing.
Begin compiling method using TurboFan
Finished compiling method using TurboFan
To generate turbo-trace for built-in functions, ``--trace-turbo`` and ``--trace-turbo-path=xxx`` need to be specified 'mksnapshot' stage. One can specify a directory for these json files via ``--trace-turbo-path=xxx``. For instance::
mkdir turbo-dump
./mksnapshot -turbo_instruction_scheduling --target_os=linux --target_arch=x64 --embedded_src gen/embedded.S --target_is_simulator --embedded_variant Default --random-seed 314159265 --native-code-counters --verify-heap --trace-turbo --trace-turbo-path=turbo-dump
**NOTE**: if you specify a ``trace-turbo-path``, make sure the specified directory is created, otherwise the JSON files are not generated.
Setup turbolizer
Please follow the instructions `here`_, but in a nutshell, it involves two steps
.. _here:
1. Setup turbolizer::
cd tools/turbolizer
npm I
npm run-script build
Note that I have to do an ``do-release-update`` on my server so that my ``node`` and ``npm`` met the version requirements of ``turbolizer``
2. Start turbolizer as an HTTP server::
cd tools/turbolizer
python -m SimpleHTTPServer
3. Access Turbolizer through your browser, e.g., This will bring up the web interface of the turbolizer. Use 'Ctrl+L' to load the json file from your local directory.
Note: since my V8 environment is on a remote server, the turbolizer is running on the server, but the json file needs to be loaded from my laptop to the browser, I have to ``scp`` the generated json file to my local machine, then load it to Turbolizer web interface