在main文件中调用以下代码
// 创建一个句柄作用域 ( 在栈上 )
HandleScope handle_scope;
// 创建一个新的上下文对象
Persistent<Context> context = Context::New();
// 进入上一步创建的上下文,用于编译执行 helloworld
Context::Scope context_scope(context);
Isolate
struct StaticInitializer {
StaticInitializer() {
Isolate::EnsureDefaultIsolate();
}
} static_initializer;
默认初始化了一个引擎实例,进入函数EnsureDefaultIsolate
void Isolate::EnsureDefaultIsolate() {
// 初始化一个锁,Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();在文件中已经被初始化过了
// lock是一个scopedLock,在执行完成EnsureDefaultIsolate的时候,析构lock会离开临界区
ScopedLock lock(process_wide_mutex_);
// 默认没有引擎实例
if (default_isolate_ == NULL) {
// 创建局部存储,存储各个线程的引擎实例地址
isolate_key_ = Thread::CreateThreadLocalKey();
// 创建存储threadid
thread_id_key_ = Thread::CreateThreadLocalKey();
// 创建储存开辟的数据块位置
per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
// 存储数据块表
thread_data_table_ = new Isolate::ThreadDataTable();
// 定义默认的引擎
default_isolate_ = new Isolate();
}
// Can't use SetIsolateThreadLocals(default_isolate_, NULL) here
// because a non-null thread data may be already set.
if (Thread::GetThreadLocal(isolate_key_) == NULL) {
// 存储当前引擎
Thread::SetThreadLocal(isolate_key_, default_isolate_);
}
}
然后再main文件中:
第一步:HandleScope初始化
// 获取当前线程的引擎实例
i::Isolate* isolate = i::Isolate::Current();
API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
// Introduce an alias for the handle scope data to allow non-friends
// to access the HandleScope data.
v8::ImplementationUtilities::HandleScopeData* current =
isolate->handle_scope_data();
isolate_ = isolate;
prev_next_ = current->next;
prev_limit_ = current->limit;
is_closed_ = false;
current->level++;
第二部:Context::New();
v8::ExtensionConfiguration* extensions,
v8::Handle<ObjectTemplate> global_template,
v8::Handle<Value> global_object) {
i::Isolate::EnsureDefaultIsolate();
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Context::New()");
LOG_API(isolate, "Context::New");
ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
// context的初始化见 博客3
// Enter V8 via an ENTER_V8 scope.
i::Handle<i::Context> env;
{
ENTER_V8(isolate);
v8::Handle<ObjectTemplate> proxy_template = global_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
if (!global_template.IsEmpty()) {
// Make sure that the global_template has a constructor.
global_constructor =
EnsureConstructor(Utils::OpenHandle(*global_template));
// Create a fresh template for the global proxy object.
proxy_template = ObjectTemplate::New();
proxy_constructor =
EnsureConstructor(Utils::OpenHandle(*proxy_template));
// Set the global template to be the prototype template of
// global proxy template.
proxy_constructor->set_prototype_template(
*Utils::OpenHandle(*global_template));
// Migrate security handlers from global_template to
// proxy_template. Temporarily removing access check
// information from the global template.
if (!global_constructor->access_check_info()->IsUndefined()) {
proxy_constructor->set_access_check_info(
global_constructor->access_check_info());
proxy_constructor->set_needs_access_check(
global_constructor->needs_access_check());
global_constructor->set_needs_access_check(false);
global_constructor->set_access_check_info(
isolate->heap()->undefined_value());
}
}
// Create the environment.
env = isolate->bootstrapper()->CreateEnvironment(
isolate,
Utils::OpenHandle(*global_object, true),
proxy_template,
extensions);
// Restore the access check info on the global template.
if (!global_template.IsEmpty()) {
ASSERT(!global_constructor.is_null());
ASSERT(!proxy_constructor.is_null());
global_constructor->set_access_check_info(
proxy_constructor->access_check_info());
global_constructor->set_needs_access_check(
proxy_constructor->needs_access_check());
}
isolate->runtime_profiler()->Reset();
}
// Leave V8.
if (env.is_null()) {
return Persistent<Context>();
}
return Persistent<Context>(Utils::ToLocal(env));
}
2-1 i::Snapshot::Initialize()
Deserializer deserializer(&source);
ReserveSpaceForLinkedInSnapshot(&deserializer);
2-1-1V8::Initialize(&deserializer);
FlagList::EnforceFlagImplications();
//初始化,会调用InitializeOncePerProcess();初始化一次一次的函数,见2-2
InitializeOncePerProcess();
// The current thread may not yet had entered an isolate to run.
// Note the Isolate::Current() may be non-null because for various
// initialization purposes an initializing thread may be assigned an isolate
// but not actually enter it.
if (i::Isolate::CurrentPerIsolateThreadData() == NULL) {
i::Isolate::EnterDefaultIsolate();
}
ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
i::ThreadId::Current()));
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
i::Isolate::Current());
if (IsDead()) return false;
Isolate* isolate = Isolate::Current();
if (isolate->IsInitialized()) return true;
is_running_ = true;
has_been_set_up_ = true;
has_fatal_error_ = false;
has_been_disposed_ = false;
// 引擎又一个初始化,见下一篇博客
return isolate->Init(des);
}
2-1-1-1 Isolate::Enter()
void Isolate::Enter() {Isolate* current_isolate = NULL;
PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
if (current_data != NULL) {
current_isolate = current_data->isolate_;
ASSERT(current_isolate != NULL);
if (current_isolate == this) {
ASSERT(Current() == this);
ASSERT(entry_stack_ != NULL);
ASSERT(entry_stack_->previous_thread_data == NULL ||
entry_stack_->previous_thread_data->thread_id().Equals(
ThreadId::Current()));
// Same thread re-enters the isolate, no need to re-init anything.
entry_stack_->entry_count++;
return;
}
}
// Threads can have default isolate set into TLS as Current but not yet have
// PerIsolateThreadData for it, as it requires more advanced phase of the
// initialization. For example, a thread might be the one that system used for
// static initializers - in this case the default isolate is set in TLS but
// the thread did not yet Enter the isolate. If PerisolateThreadData is not
// there, use the isolate set in TLS.
if (current_isolate == NULL) {
current_isolate = Isolate::UncheckedCurrent();
}
// 创建一段PerIsolateThreadData
PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
ASSERT(data != NULL);
ASSERT(data->isolate_ == this);
// 进入引擎线程
EntryStackItem* item = new EntryStackItem(current_data,
current_isolate,
entry_stack_);
entry_stack_ = item;
// 设置PerIsolateThreadData到TLS中
SetIsolateThreadLocals(this, data);
// In case it's the first time some thread enters the isolate.
set_thread_id(data->thread_id());
}
2-2 InitializeOncePerProcess();
// 调用InitializeOncePerProcessImpl 见2-3
2-3 InitializeOncePerProcessImpl
void V8::InitializeOncePerProcessImpl() {
// 有v8类调到os类的初始化,初始化随机数种子,sampler等等
OS::SetUp();use_crankshaft_ = FLAG_crankshaft;
if (Serializer::enabled()) {
use_crankshaft_ = false;
}
// 会调用void CpuFeatures::Probe() ,里面有个VirtualMemory类,是自己分配的内存2-4
//这里会创建类Assembler,对js的二进制执行码进行优化
CPU::SetUp();if (!CPU::SupportsCrankshaft()) {
use_crankshaft_ = false;
}
// 在cpu二进制执行码初始化后,调用这个后续初始化
// 一些数学函数的优化,需要二进制码优化
OS::PostSetUp();// TODO:下面的还没读
RuntimeProfiler::GlobalSetUp();
ElementsAccessor::InitializeOncePerProcess();
if (FLAG_stress_compaction) {
FLAG_force_marking_deque_overflows = true;
FLAG_gc_global = true;
FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
}
LOperand::SetUpCaches();
SetUpJSCallerSavedCodeData();
SamplerRegistry::SetUp();
ExternalReference::SetUp();
}
2-4 VirtualMemory