V8 のスコープの仕組みに興味があります。
スタック上のスコープ オブジェクトは、他のスコープ オブジェクトとコンテキストをスタックのさらに上にどのように見つけることができますか?
HandleScopes がどのように機能するかを調べたところ、それらはスレッド ローカルに依存していることがわかりました。これにより、これらが C++ でどのように機能するのか疑問に思いました。実装を見つけましたが、何が起こっているのかまだ理解していません。
api.cc -- HandleScope は現在の Isolate を探します
HandleScope::HandleScope() {
i::Isolate* isolate = i::Isolate::Current();
API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
v8::ImplementationUtilities::HandleScopeData* current =
isolate->handle_scope_data();
isolate_ = isolate;
prev_next_ = current->next;
prev_limit_ = current->limit;
is_closed_ = false;
current->level++;
}
isolate.cc -- 静的メソッドは現在の isolate をスレッド ローカルとして検索します
// Returns the isolate inside which the current thread is running.
INLINE(static Isolate* Current()) {
const Thread::LocalStorageKey key = isolate_key();
Isolate* isolate = reinterpret_cast<Isolate*>(
Thread::GetExistingThreadLocal(key));
if (!isolate) {
EnsureDefaultIsolate();
isolate = reinterpret_cast<Isolate*>(
Thread::GetExistingThreadLocal(key));
}
ASSERT(isolate != NULL);
return isolate;
}
platform.h -- 低レベルのメソッドを呼び出して、スレッド ローカルを取得します。
static inline void* GetExistingThreadLocal(LocalStorageKey key) {
void* result = reinterpret_cast<void*>(
InternalGetExistingThreadLocal(static_cast<intptr_t>(key)));
ASSERT(result == GetThreadLocal(key));
return result;
}
platform-tls-win32.h -- 魔法が起こる
inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
const intptr_t kTibInlineTlsOffset = 0xE10;
const intptr_t kTibExtraTlsOffset = 0xF94;
const intptr_t kMaxInlineSlots = 64;
const intptr_t kMaxSlots = kMaxInlineSlots + 1024;
ASSERT(0 <= index && index < kMaxSlots);
if (index < kMaxInlineSlots) {
return static_cast<intptr_t>(__readfsdword(kTibInlineTlsOffset +
kPointerSize * index));
}
intptr_t extra = static_cast<intptr_t>(__readfsdword(kTibExtraTlsOffset));
ASSERT(extra != 0);
return *reinterpret_cast<intptr_t*>(extra +
kPointerSize * (index - kMaxInlineSlots));
}
- この最後の方法はどのくらい正確に機能していますか?
- どこを見るべきかをどのように知っていますか?
- スタックの構造は何ですか?