4

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

1 回答 1

3

您可以将其视为WinAPI 调用InternalGetExistingThreadLocal的内联版本。TlsGetValue

在 Windows 上,用户模式fs段寄存器允许代码访问包含线程特定信息的线程信息块 (TIB),例如线程本地存储结构。

TIB 的布局和 TLS 在 TIB 中的存储方式在 DDK 中公开(请参阅http://en.wikipedia.org/wiki/Win32_Thread_Information_Block以快速了解 TIB 布局)。

__readfsdword(offs)鉴于这种通过(相当于读取)从 TIB 读取数据的知识和能力,dword ptr fs:[offs]人们可以直接有效地访问 TLS 而无需调用TlsGetValue.

于 2012-03-28T09:25:17.247 回答