mirror of
https://github.com/nodejs/node.git
synced 2026-10-10 18:59:49 -04:00
With V8_ENABLE_SANDBOX every ArrayBuffer backing store has to be allocated inside the sandbox, so memory that Node.js or a library allocated itself cannot be wrapped and has to be copied in. Several places already special-cased this, each with its own #ifdef, but a build with the sandbox enabled still failed to compile (`kMaxSafeBufferSizeForSandbox`), aborted in `crypto.randomUUID()` (`SecureBuffer` was UNREACHABLE) and threw from every caller of the malloc-owning `Buffer::New()` (v8.serialize, string transcoding, IPC, the public `Buffer::New(isolate, data, length)`), and trace_events, SEA assets and FFI still wrapped outside memory unconditionally. Add `AdoptIntoBackingStore()`, which wraps the memory as before in regular builds and copies it into an isolate-allocated backing store, running the deleter right away, when the sandbox is enabled, and use it at all of those sites so the #ifdef lives in one place. The trace category flag cannot be copied since JS polls it, so under the sandbox `getCategoryEnabledBuffer()` returns nothing and lib falls back to `isTraceCategoryEnabled()`; FFI zero-copy views throw ERR_OPERATION_FAILED there for the same reason. Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com> PR-URL: https://github.com/nodejs/node/pull/62237 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
72 lines
2.2 KiB
JavaScript
72 lines
2.2 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
getCategoryEnabledBuffer,
|
|
isTraceCategoryEnabled,
|
|
trace,
|
|
usePerfetto,
|
|
} = internalBinding('trace_events');
|
|
const {
|
|
CHAR_UPPERCASE_B,
|
|
CHAR_LOWERCASE_B,
|
|
CHAR_UPPERCASE_C,
|
|
CHAR_LOWERCASE_E,
|
|
CHAR_UPPERCASE_E,
|
|
CHAR_LOWERCASE_N,
|
|
} = require('internal/constants');
|
|
|
|
let nodeTraceEventCategory;
|
|
if (usePerfetto) {
|
|
nodeTraceEventCategory = (category) => `${category}`;
|
|
} else {
|
|
nodeTraceEventCategory = (category) => `node,${category}`;
|
|
}
|
|
|
|
// The returned function reads the category's enabled flag directly when the
|
|
// binding can expose it to JS, and asks the tracing controller otherwise.
|
|
function categoryEnabledChecker(category) {
|
|
const buffer = getCategoryEnabledBuffer(category);
|
|
if (buffer === undefined) {
|
|
return () => isTraceCategoryEnabled(category);
|
|
}
|
|
return () => buffer[0] > 0;
|
|
}
|
|
|
|
// The async events describe the execution of a single asynchronous operation, and are
|
|
// used to measure the time spent in a single asynchronous operation.
|
|
// Async events may overlap with each other. Different events do not have
|
|
// to be nested, or FILO (first in last out).
|
|
// TODO(legendecas): V8 `trace` API does not support async marks in perfetto yet.
|
|
const kAsyncBegin = usePerfetto ? CHAR_UPPERCASE_B : CHAR_LOWERCASE_B;
|
|
const kAsyncEnd = usePerfetto ? CHAR_UPPERCASE_E : CHAR_LOWERCASE_E;
|
|
|
|
// The sync events describe the execution of a single thread, and are
|
|
// used to measure the time spent in a function.
|
|
// Sync events must be nested, and are FILO (first in last out), in a stack
|
|
// manner.
|
|
const kSyncBegin = CHAR_UPPERCASE_B;
|
|
const kSyncEnd = CHAR_UPPERCASE_E;
|
|
|
|
// Counter events track a named numeric value as it changes over time. Each
|
|
// event records the value at a point in time, and the trace viewer renders the
|
|
// series as a graph.
|
|
// TODO(legendecas): V8 `trace` API does not support count marks in perfetto yet.
|
|
const kTraceCount = usePerfetto ? CHAR_LOWERCASE_N : CHAR_UPPERCASE_C;
|
|
|
|
// Instant events mark a single moment in time. They have no duration and do
|
|
// not need to be paired or nested.
|
|
const kTraceInstant = CHAR_LOWERCASE_N;
|
|
|
|
module.exports = {
|
|
usePerfetto,
|
|
categoryEnabledChecker,
|
|
trace,
|
|
nodeTraceEventCategory,
|
|
kAsyncBegin,
|
|
kAsyncEnd,
|
|
kSyncBegin,
|
|
kSyncEnd,
|
|
kTraceCount,
|
|
kTraceInstant,
|
|
};
|