nodejs c++啓動過程1

在main文件中調用以下代碼

// 創建一個句柄作用域 ( 在棧上 ) 
HandleScope handle_scope; 

// 創建一個新的上下文對象
Persistent<Context> 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<Context> v8::Context::New(
    v8::ExtensionConfiguration* extensions,
    v8::Handle<ObjectTemplate> global_template,
    v8::Handle<Value> 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>());

// 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()

若依賴的項目是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,告訴可以使用的內存範圍







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章