Skip to content

Commit 4944ab5

Browse files
committed
doc: add v8 fast api contribution guidelines
1 parent f5dc92c commit 4944ab5

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Adding V8 Fast API
2+
3+
Node.js uses [v8](https://github.com/v8/v8) as the JavaScript engine.
4+
In order to provide fast paths for functions that are called quiet often,
5+
v8 proposes the usage of `fast api calls` that does not use any of the v8
6+
internals, but uses internal C functions.
7+
8+
## Limitations
9+
10+
- Fast api calls can not use `v8` internals inside the fast path.
11+
- Not all parameter and return types are supported in fast api calls.
12+
For a full list, please look into `v8-fast-api-calls.h` file.
13+
14+
## Requirements
15+
- Each unique fast path function signature should be defined inside
16+
`node_external_reference.h` file.
17+
- In order to test fast paths, make sure to run the tests in a loop
18+
with more than 1000 iterations to force v8 to optimize and prefer the
19+
fast api over slow path.
20+
21+
## Fallback to slow path
22+
23+
Fast apis support fallback to slow path (implementation that uses v8 internals)
24+
in case logically it is wise to do so. Fallback mechanism can be enabled, and changed
25+
from both caller JavaScript function or from the fast api function declaration.
26+
27+
Every fast api function accessible from JavaScript side, can pass an object
28+
consisting of fallback key, with a boolean value as the last parameter
29+
(or the first parameter, if no parameters of the function exist).
30+
31+
In v8 the options fallback is defined as `FastApiCallbackOptions` inside
32+
`v8-fast-api-calls.h` file.
33+
34+
- JavaScript land
35+
36+
Example of a JavaScript:
37+
38+
```javascript
39+
// Let calculateX be a function that provides fast api calls.
40+
const { calculateX } = internalBinding('custom_namespace');
41+
42+
function conditionallyGetX(useSlowPath) {
43+
return calculateX({ fallback: useSlowPath })
44+
}
45+
```
46+
47+
- C++ land
48+
49+
Example of a conditional fast path on C++
50+
51+
```c++
52+
// Anywhere in the execution flow, you can set fallback and stop the execution.
53+
static void FastCalculateX(const v8::FastApiCallbackOptions& options) {
54+
if (true) {
55+
options.fallback = true;
56+
}
57+
}
58+
```
59+
60+
## Example
61+
62+
A typical function that communicates between JavaScript and C++ is as follows.
63+
64+
- On the JavaScript side:
65+
66+
```javascript
67+
const { calculateX } = internalBinding('custom_namespace');
68+
```
69+
70+
- On the C++ side:
71+
72+
```c++
73+
namespace node {
74+
namespace custom_namespace {
75+
76+
#define PREFER_FALLBACK = false;
77+
78+
static void CalculateX(const FunctionCallbackInfo<Value>& args) {
79+
int calculated_x = 5;
80+
args.GetReturnValue().Set(calculated_x);
81+
}
82+
83+
static int FastCalculateX(const v8::FastApiCallbackOptions& options) {
84+
if (PREFER_FALLBACK) {
85+
options.fallback = true;
86+
return;
87+
}
88+
return 5;
89+
}
90+
91+
CFunction fast_calculate_x_(CFunction::Make(FastCalculateX));
92+
93+
static void Initialize(Local<Object> target, Local<Value> unused, Local<Context> context, void* priv) {
94+
SetFastMethod(context, target, "calculateX", CalculateX, &calculate_x_);
95+
}
96+
97+
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
98+
registry->Register(CalculateX);
99+
registry->Register(FastCalculateX);
100+
registry->Register(fast_calculate_x_.GetTypeInfo());
101+
}
102+
103+
} // namespace custom_namespace
104+
} // namespace node
105+
106+
NODE_BINDING_CONTEXT_AWARE_INTERNAL(custom_namespace, node::custom_namespace::Initialize)
107+
NODE_BINDING_EXTERNAL_REFERENCE(custom_namespace, node::custom_namespace::RegisterExternalReferences)
108+
```
109+
110+
- Update external references (`node_external_reference.h`)
111+
112+
Since our implementation used `int(const v8::FastApiCallbackOptions& options)` signature,
113+
we need to add it to external references.
114+
115+
Example declaration:
116+
117+
```c++
118+
using CFunctionCallbackReturningInt = int (*)(const v8::FastApiCallbackOptions& options);
119+
```

0 commit comments

Comments
 (0)