今回は、
static std::unique_ptr<MultiIsolatePlatform> Create(
int thread_pool_size,
v8::TracingController* tracing_controller = nullptr,
v8::PageAllocator* page_allocator = nullptr);
};
から見ていきます。
static std::unique_ptr<MultiIsolatePlatform> Create(
int thread_pool_size,
v8::TracingController* tracing_controller = nullptr,
※※※※4
/**
* V8 Tracing controller.
*
* Can be implemented by an embedder to record trace events from V8.
* V8からのトレースイベントを記録するために、エンベッダーによって実装することができる。
*/
class TracingController {
public:
virtual ~TracingController() = default;
// In Perfetto mode, trace events are written using Perfetto's Track Event
// API directly without going through the embedder. However, it is still
// possible to observe tracing being enabled and disabled.
// Perfettoモードでは、トレースイベントはPerfettoのトラック種目アプリケーションプログラミングインターフェイスを使用して、エンベッダーを経由せずに直接書き込まれる。ただし、トレースが有効になっているか無効になっているかを確認することは可能である。
#if !defined(V8_USE_PERFETTO)
/**
* Called by TRACE_EVENT* macros, don't call this directly.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
* TRACE_EVENT*マクロによって呼び出されますが、これを直接呼び出さないでください。nameパラメータはカテゴリグループです。例:TRACE_EVENT0("v8,parse","v8.Parse")返されるポインタは、CategoryGroupEnabledFlagsで定義された0以上のビットを持つ値を指します。
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}
※※※※4-
v8::PageAllocator* page_allocator = nullptr);
※※※※4
/**
* A V8 memory page allocator. V8メモリページアロケータ。
*
* Can be implemented by an embedder to manage large host OS allocations.
* 大規模なホストOSの割り当てを管理するために、埋め込み器によって実装することができる。
*/
class PageAllocator {
public:
virtual ~PageAllocator() = default;
/**
* Gets the page granularity for AllocatePages and FreePages. Addresses and
* lengths for those calls should be multiples of AllocatePageSize().
* AllocatePagesとFreePagesのページ粒度を取得します。これらの呼び出しのアドレスと長さは、AllocatePageSize()の倍数である必要があります。
*/
virtual size_t AllocatePageSize() = 0;
/**
* Gets the page granularity for SetPermissions and ReleasePages. Addresses
* and lengths for those calls should be multiples of CommitPageSize().
* SetPermissionsとReleasePagesのページ粒度を取得します。これらの呼び出しのアドレスと長さは、CommitPageSize()の倍数である必要があります。
*/
virtual size_t CommitPageSize() = 0;
/**
* Sets the random seed so that GetRandomMmapAddr() will generate repeatable
* sequences of random mmap addresses.
* GetRandomMmapAddr()がランダムなmmapアドレスの繰り返し可能なシーケンスを生成するように、ランダムシードを設定する。
*/
virtual void SetRandomMmapSeed(int64_t seed) = 0;
/**
* Returns a randomized address, suitable for memory allocation under ASLR.
* The address will be aligned to AllocatePageSize.
* ASLRの下でのメモリ割り当てに適したランダム化されたアドレスを返します。アドレスはAllocatePageSizeに揃えられます。
*/
virtual void* GetRandomMmapAddr() = 0;
/**
* Memory permissions.
*/
enum Permission {
kNoAccess,
kRead,
kReadWrite,
kReadWriteExecute,
kReadExecute,
// Set this when reserving memory that will later require kReadWriteExecute
// permissions. The resulting behavior is platform-specific, currently
// this is used to set the MAP_JIT flag on Apple Silicon.
// TODO(jkummerow): Remove this when Wasm has a platform-independent
// w^x implementation.
// TODO(saelo): Remove this once all JIT pages are allocated through the
// VirtualAddressSpace API.
// これは、後でkReadWriteExecute権限を必要とするメモリを予約するときに設定します。結果として生じる動作はプラットフォーム固有であり、現在はApple SiliconでMAP_JITフラグを設定するために使用されています。TODO(jkummerow):Wasmがプラットフォームに依存しないw^x実装を持っている場合は、これを削除します。TODO(saelo):すべてのJITページがVirtualAddressSpaceのAPIを通じて割り当てられたら、これを削除します。
kNoAccessWillJitLater
};
/**
* Allocates memory in range with the given alignment and permission.
* 指定されたアラインメントとパーミッションで範囲内のメモリを割り当てます。
*/
virtual void* AllocatePages(void* address, size_t length, size_t alignment,
Permission permissions) = 0;
/**
* Frees memory in a range that was allocated by a call to AllocatePages.
* AllocatePagesへの呼び出しによって割り当てられた範囲内のメモリを解放する。
*/
virtual bool FreePages(void* address, size_t length) = 0;
/**
* Releases memory in a range that was allocated by a call to AllocatePages.
* AllocatePagesの呼び出しによって割り当てられた範囲内のメモリーを解放します。
*/
virtual bool ReleasePages(void* address, size_t length,
size_t new_length) = 0;
/**
* Sets permissions on pages in an allocated range.
* 割り当てられた範囲内のページにアクセス権を設定します。
*/
virtual bool SetPermissions(void* address, size_t length,
Permission permissions) = 0;
/**
* Frees memory in the given [address, address + size) range. address and size
* should be operating system page-aligned. The next write to this
* memory area brings the memory transparently back. This should be treated as
* a hint to the OS that the pages are no longer needed. It does not guarantee
* that the pages will be discarded immediately or at all.
* 指定された[アドレス,アドレス+サイズ]の範囲のメモリを解放します。アドレスとサイズは、オペレーティングシステムのページ単位で指定する必要があります。次にこのメモリ領域に書き込むと、メモリは透過的に元に戻ります。これは、ページが不要になったことをOSに知らせるヒントとして扱う必要があります。ページがすぐに破棄されることや、まったく破棄されないことを保証するものではありません。
*/
virtual bool DiscardSystemPages(void* address, size_t size) { return true; }
/**
* Decommits any wired memory pages in the given range, allowing the OS to
* reclaim them, and marks the region as inacessible (kNoAccess). The address
* range stays reserved and can be accessed again later by changing its
* permissions. However, in that case the memory content is guaranteed to be
* zero-initialized again. The memory must have been previously allocated by a
* call to AllocatePages. Returns true on success, false otherwise.
* 指定された範囲内のすべてのワイヤード・メモリー・ページをコミット解除し、オペレーティング・システムがそれらを再要求できるようにして、その領域をアクセス不可(kNoAccess)としてマークします。アドレス範囲は予約されたままになり、後でその権限を変更することによって再度アクセスできます。ただし、その場合、メモリーの内容は再度ゼロ初期化されることが保証されます。メモリーは、AllocatePagesへのコールによって事前に割り当てられている必要があります。成功した場合はtrue、それ以外の場合はfalseを返します。
*/
virtual bool DecommitPages(void* address, size_t size) = 0;
/**
* INTERNAL ONLY: This interface has not been stabilised and may change
* without notice from one release to another without being deprecated first.
* 内部のみ:このインタフェースは安定しておらず、最初に非推奨にすることなく、あるリリースから別のリリースへと予告なしに変更される可能性がある。
*/
class SharedMemoryMapping {
public:
// Implementations are expected to free the shared memory mapping in the
// destructor.
// 実装は、デストラクタ内の共有メモリマッピングを解放することが期待される。
virtual ~SharedMemoryMapping() = default;
virtual void* GetMemory() const = 0;
};
/**
* INTERNAL ONLY: This interface has not been stabilised and may change
* without notice from one release to another without being deprecated first.
* 内部のみ:このインタフェースは安定しておらず、最初に非推奨にすることなく、あるリリースから別のリリースへと予告なしに変更される可能性がある。
*/
class SharedMemory {
public:
// Implementations are expected to free the shared memory in the destructor.
//実装はデストラクタ内の共有メモリを解放することが期待される。
virtual ~SharedMemory() = default;
virtual std::unique_ptr<SharedMemoryMapping> RemapTo(
void* new_address) const = 0;
virtual void* GetMemory() const = 0;
virtual size_t GetSize() const = 0;
};
/**
* INTERNAL ONLY: This interface has not been stabilised and may change
* without notice from one release to another without being deprecated first.
* 内部のみ:このインタフェースは安定しておらず、最初に非推奨にすることなく、あるリリースから別のリリースへと予告なしに変更される可能性がある。
*
* Reserve pages at a fixed address returning whether the reservation is
* possible. The reserved memory is detached from the PageAllocator and so
* should not be freed by it. It's intended for use with
* SharedMemory::RemapTo, where ~SharedMemoryMapping would free the memory.
* 予約が可能かどうかを返す固定アドレスでページを予約する。予約されたメモリはPageAllocatorから切り離されているため、予約によって解放されるべきではない。これはSharedMemory::RemapToで使用することを意図しており、~SharedMemoryMappingはメモリを解放する。
*/
virtual bool ReserveForSharedMemoryMapping(void* address, size_t size) {
return false;
}
/**
* INTERNAL ONLY: This interface has not been stabilised and may change
* without notice from one release to another without being deprecated first.
* 内部のみ:このインタフェースは安定しておらず、最初に非推奨にすることなく、あるリリースから別のリリースへと予告なしに変更される可能性がある。
*
* Allocates shared memory pages. Not all PageAllocators need support this and
* so this method need not be overridden.
* Allocates a new read-only shared memory region of size |length| and copies
* the memory at |original_address| into it.
* 共有メモリページを割り当てます。すべてのPageAllocatorsがこれをサポートする必要はないので、このメソッドをオーバーライドする必要はありません。size lengthの新しい読み取り専用共有メモリ領域を割り当て、original_addressのメモリをその領域にコピーします。
*/
virtual std::unique_ptr<SharedMemory> AllocateSharedPages(
size_t length, const void* original_address) {
return {};
}
/**
* INTERNAL ONLY: This interface has not been stabilised and may change
* without notice from one release to another without being deprecated first.
* 内部のみ:このインタフェースは安定しておらず、最初に非推奨にすることなく、あるリリースから別のリリースへと予告なしに変更される可能性がある。
*
* If not overridden and changed to return true, V8 will not attempt to call
* AllocateSharedPages or RemapSharedPages. If overridden, AllocateSharedPages
* and RemapSharedPages must also be overridden.
* オーバーライドされず、trueを返すように変更された場合、V8はAllocateSharedPagesまたはRemapSharedPagesを呼び出そうとしません。オーバーライドされた場合、AllocateSharedPagesおよびRemapSharedPagesもオーバーライドする必要があります。
*/
virtual bool CanAllocateSharedPages() { return false; }
};
※※※※4-
};
※※※3-
private:
InitializationResult() = default;
friend class InitializationResultImpl;
※※2
class InitializationResultImpl final : public InitializationResult {
public:
~InitializationResultImpl();
int exit_code() const { return exit_code_; }
bool early_return() const { return early_return_; }
const std::vector<std::string>& args() const { return args_; }
const std::vector<std::string>& exec_args() const { return exec_args_; }
const std::vector<std::string>& errors() const { return errors_; }
MultiIsolatePlatform* platform() const { return platform_; }
int exit_code_ = 0;
std::vector<std::string> args_;
std::vector<std::string> exec_args_;
std::vector<std::string> errors_;
bool early_return_ = false;
MultiIsolatePlatform* platform_ = nullptr;
};
※※2-
};
※1-
int exit_code = result->exit_code();
// nullptr indicates there's no snapshot data.
//nullptrは、スナップショットデータがないことを示します。
DCHECK_NULL(*snapshot_data_ptr);
// --snapshot-blob indicates that we are reading a customized snapshot.
// --snapshot-blobは、カスタマイズされたスナップショットを読み取っていることを示します。
if (!per_process::cli_options->snapshot_blob.empty()) {
std::string filename = per_process::cli_options->snapshot_blob;
FILE* fp = fopen(filename.c_str(), "rb");
※1
fopen
ファイルを開きます。 より多くのパラメーター検証を実行し、エラー コードを返す、より安全なバージョンのこれらの関数を使用できます。を_wfopen_s参照してくださいfopen_s。
FILE *fopen(
const char *filename,
const char *mode
);
パラメーター
filename ファイル名。
mode 有効なアクセス種類。
戻り値
これらの各関数は、開いているファイルへのポインターを返します。 エラーが発生すると、NULL のポインター値を返します。
"r" 読み取り用に開きます。 ファイルが存在しないか、見つからない場合、呼び出しは fopen 失敗します。
b ファイルをバイナリ (無変換) モードで開きます。復帰文字と改行文字の変換は行われません。
※1-
if (fp == nullptr) {
fprintf(stderr, "Cannot open %s", filename.c_str());
exit_code = 1;
return exit_code;
}
std::unique_ptr<SnapshotData> read_data = std::make_unique<SnapshotData>();
bool ok = SnapshotData::FromBlob(read_data.get(), fp);
fclose(fp);
if (!ok) {
// If we fail to read the customized snapshot, simply exit with 1.
//カスタマイズされたスナップショットの読み取りに失敗した場合は、1で終了します。
exit_code = 1;
return exit_code;
}
*snapshot_data_ptr = read_data.release();
} else if (per_process::cli_options->node_snapshot) {
// If --snapshot-blob is not specified, we are reading the embedded
// snapshot, but we will skip it if --no-node-snapshot is specified.
// --snapshot-blobが指定されていない場合、埋め込まれたスナップショットを読み込んでいるが、--no-node-snapshotが指定されている場合はスキップする。
const node::SnapshotData* read_data =
SnapshotBuilder::GetEmbeddedSnapshotData();
if (read_data != nullptr && read_data->Check()) {
// If we fail to read the embedded snapshot, treat it as if Node.js
// was built without one.
// 埋め込まれたスナップショットの読み取りに失敗した場合は、Node.jsがスナップショットなしで構築されたかのように扱ってください。
*snapshot_data_ptr = read_data;
}
}
if ((*snapshot_data_ptr) != nullptr) {
BuiltinLoader::RefreshCodeCache((*snapshot_data_ptr)->code_cache);
※1
// Handles compilation and caching of built-in JavaScript modules and
// bootstrap scripts, whose source are bundled into the binary as static data.
// ソースが静的データとしてバイナリにバンドルされている、組み込みのJavaScriptモジュールとブートストラップスクリプトのコンパイルとキャッシュを処理します。
class NODE_EXTERN_PRIVATE BuiltinLoader {
public:
BuiltinLoader(const BuiltinLoader&) = delete;
BuiltinLoader& operator=(const BuiltinLoader&) = delete;
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
※1
// This class manages the external references from the V8 heap
// to the C++ addresses in Node.js.
// このクラスは、V8ヒープからNode.jsのC++アドレスへの外部参照を管理する。
class ExternalReferenceRegistry {
public:
ExternalReferenceRegistry();
#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \
V(CFunctionCallback) \
V(const v8::CFunctionInfo*) \
V(v8::FunctionCallback) \
V(v8::AccessorGetterCallback) \
V(v8::AccessorSetterCallback) \
V(v8::AccessorNameGetterCallback) \
V(v8::AccessorNameSetterCallback) \
V(v8::GenericNamedPropertyDefinerCallback) \
V(v8::GenericNamedPropertyDeleterCallback) \
V(v8::GenericNamedPropertyEnumeratorCallback) \
V(v8::GenericNamedPropertyQueryCallback) \
V(v8::GenericNamedPropertySetterCallback) \
V(v8::IndexedPropertySetterCallback) \
V(v8::IndexedPropertyDefinerCallback) \
V(v8::IndexedPropertyDeleterCallback) \
V(v8::IndexedPropertyQueryCallback) \
V(v8::IndexedPropertyDescriptorCallback)
#define V(ExternalReferenceType) \
void Register(ExternalReferenceType addr) { RegisterT(addr); }
ALLOWED_EXTERNAL_REFERENCE_TYPES(V)
#undef V
// This can be called only once.
// これは1回だけ呼び出すことができます。
const std::vector<intptr_t>& external_references();
bool is_empty() { return external_references_.empty(); }
private:
template <typename T>
void RegisterT(T* address) {
external_references_.push_back(reinterpret_cast<intptr_t>(address));
}
bool is_finalized_ = false;
std::vector<intptr_t> external_references_;
};
※1-
次回
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
から見ていきます。