I am intrigued by how the V8 areas work.
How does a scope object on the stack find other objects and object contexts further down the stack?
Delving into the work of HandleScopes, I found that they rely on flow locators. This made me wonder how it works in C ++, I found an implementation, but still I donβt feel that I understand what is happening.
api.cc - HandleScope searches for the current isolator
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 - the static method looks for the current isolate as a local stream
// 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 - calls a low-level method to get a local stream
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 - magic happens
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)); }
- How exactly does this last method work?
- How to find out where to look?
- What is the structure of the stack?
source share