我对 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++;
}
隔离.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));
}
- 最后一种方法到底是如何工作的?
- 它怎么知道去哪里看?
- 栈的结构是什么?