我对V8的范围如何工作很感兴趣。
堆栈上的作用域对象如何在堆栈中找到其他作用域对象和上下文?
深入研究HandleScope的工作原理我发现他们依赖于线程本地人。这让我想知道这些是如何在C ++中工作的,我已经找到了实现,但仍然觉得我不明白发生了什么。
api.cc - HandleScope查找当前的隔离
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 - 静态方法查找当前隔离为线程本地
// 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));
}
答案 0 :(得分:3)
您可以将InternalGetExistingThreadLocal
视为TlsGetValue
WinAPI调用的内联版本。
在用户模式的Windows上fs
段寄存器允许代码访问包含线程特定信息的线程信息块(TIB),例如线程本地存储结构。
TIB的布局和TLS存储在TIB中的方式在DDK中公开(有关TIB布局的快速概述,请参阅http://en.wikipedia.org/wiki/Win32_Thread_Information_Block)。
鉴于这种知识和能力通过__readfsdword(offs)
从TIB读取数据(相当于阅读dword ptr fs:[offs]
),可以直接有效地访问TLS而无需调用TlsGetValue
。