javascript代码实例教程-nodejs c++启动过程1

发布时间:2019-02-17 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-nodejs c++启动过程1脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

在main文件中调用以下代码

// 创建一个句柄作用域 ( 在栈上 )
HandleScoPE handle_scope;

// 创建一个新的上下文对象
Persistent context = Context::New();

// 进入上一步创建的上下文,用于编译执行 helloworld
Context::Scope context_scope(context);


Isolate

在main文件之前,会首先实例化一个引擎,在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();


Persistent v8::Context::New(
v8::Extensionconfiguration* extensions,
v8::Handle global_template,
v8::Handle global_object) {
i::Isolate::EnsureDefaultIsolate();
i::Isolate* isolate = i::Isolate::Current(); // 会调用初始化快照函数i::Snapshot::Initialize(),迅速初始化引擎,具体见2-1
EnsureinitializeDForIsolate(isolate, "v8::Context::New()");
LOG_API(isolate, "Context::New");
ON_BAILOUT(isolate, "v8::Context::New()", return Persistent());

// context的初始化见博客3
// Enter V8 via an ENTER_V8 scope.
i::Handle env;
{
ENTER_V8(isolate);
v8::Handle Proxy_template = global_template;
i::Handle proxy_constructor;
i::Handle 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();
}
return Persistent(Utils::ToLocal(env));
}


2-1 i::Snapshot::Initialize()

若依赖的项目是v8_snapshot则引擎会从快照中直接初始化,执行以下逻辑 // 快照数据二进制格式 SnapshotByteSource source(raw_data_, raw_size_); //反序列号读取数据
Deserializer deserializer(&source); // 设置数据
ReserveSpaceForLinkedInSnapshot(&deserializer); // V8::Initialize(&deserializer); 见2-1-1 return V8::Initialize(&deserializer);


2-1-1V8::Initialize(&deserializer);

bool V8::Initialize(Deserializer* des) {
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) { // 会调用引擎的Enter函数见2-1-1-1
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; // 首次进入的时候,data不存在
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. // 多次进入,只需要count加1
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. // 设置当前引擎的线程id
set_thread_id(data->thread_id());
}

2-2 InitializeOncePerProcess();


void V8::InitializeOncePerProcess() {
// 调用InitializeOncePerProcessImpl 见2-3 CallOnce(&init_once, &InitializeOncePerProcessImpl); }

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

创建类的时候初始化一个内存地址ReserveRegion(size),调用RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);,设置这段地址内存为保留和不允许访问
然后再调用提交内存,CommitRegion(void* base, size_t size, bool is_executable) ,即调用VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE),使得申请的内存是是可执行可读写的,然后调用UpdateAllocatedSpaceLimits,告诉可以使用的内存范围






觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-nodejs c++启动过程1全部内容,希望文章能够帮你解决javascript代码实例教程-nodejs c++启动过程1所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。