深入V8引擎-初始化之InitPlatform


上一篇其實想講初始化的第二步,但是內容比較無聊,所以換了一個話題,談了談v8的命名空間和宏,稍微輕松一下。

在這里還是接着說說初始化過程,畢竟寫博客的初衷是對自己努力的記錄,不是為了吸粉,這篇沒圖,對代碼本身沒有興趣的可以跳過了。

 

再多說幾句,講一下我怎么看的源碼吧。源碼的一些方法涉及很多類和文件,所以我都會統一標注在弄到一個文件里,這樣后期復盤可以比較方便,就像圖中這樣。

文件名代表源碼的方法、類別、邏輯等等,就像vue的源碼也被分割為diff、virtual-dom、parse等等模塊一樣。不過v8可不會給你搞這些,所以就需要自己去整理了。內容里,每一個方法、類構造的跳轉都會進行標記,前面貼代碼也能看到,就是1-1、1-2這些,后期考慮有沒有別的更好方法。

就像上面這樣,基本上每一個小點也會進行注釋,畢竟C++平時工作不會用上,語法什么的容易忘。而且C++的類型是真的很隨意,到處都是using、typedef,有可能這只是一個整數類型,但是為了語義化類型搞得跟類一樣,比較典型的就是win的DWORD,實際上就是unsigned long,第一次見還以為是個多復雜的結構體,標注之后會視覺上的復雜性會減少很多。

目前先用這個來整理思路和學習,感覺還不錯。最近是因為比較閑所以才寫的多,如果比較繁忙,碎片時間看源碼就會凸顯一個很嚴重的問題,就是思路斷檔。之前嘗試分析v8對JS代碼的compile的時候就發現了,其過程十分的長,第一天看了一半,第二天忘了一部分后就接不上了。后面就暫時放棄過於繁瑣的部分,並且開始尋找一個好方法可以整理源碼。

 

開始貼代碼環節,上一篇說過第二步的嵌入,實際上只是命名空間的轉移,也就是將生成的platform賦值到另一個namespace中。

v8::Platform* V8::platform_ = nullptr;

void V8::InitializePlatform(v8::Platform* platform) {
  CHECK(!platform_);
  CHECK(platform);
  // 將普通的platform對象轉移到v8::platform命名空間下
  platform_ = platform;
  // 1-1
  v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter());
  // 1-2
  v8::tracing::TracingCategoryObserver::SetUp();
}

如上所示,v8::Platform的命名空間下聲明了一個platform類型的變量,這里只是簡單的進行賦值。但肯定不僅僅這么一點,后面還有兩步內容,分別是設置調用棧打印方法和調用棧追蹤類的初始化。

第一個設置也是很簡單的命名空間轉移,函數已經在默認Platform上定義好了,如下。

// v8::platform
// 預定義
void PrintStackTrace() {
  v8::base::debug::StackTrace trace;
  trace.Print();
  // Avoid dumping duplicate stack trace on abort signal.
  v8::base::debug::DisableSignalStackDump();
}
Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
  return PrintStackTrace;
}

// v8::base
void (*g_print_stack_trace)() = nullptr;
void SetPrintStackTrace(void (*print_stack_trace)()) {
  g_print_stack_trace = print_stack_trace;
}

這個方法后面專門來講,初始化時候只是賦值,並沒有調用。

第二步的初始化也比較簡單。

// v8::tracing
TracingCategoryObserver* TracingCategoryObserver::instance_ = nullptr;
void TracingCategoryObserver::SetUp() {// 生成一個新的Observer 這個類構造函數沒什么特殊
  TracingCategoryObserver::instance_ = new TracingCategoryObserver();// v8::platform::tracing
  i::V8::GetCurrentPlatform()->GetTracingController()->AddTraceStateObserver(TracingCategoryObserver::instance_);
}

void TracingController::AddTraceStateObserver(v8::TracingController::TraceStateObserver* observer) {
  {
    base::MutexGuard lock(mutex_.get());
    // TracingController的屬性std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
    // insert是unordered_set的插入方法
    observers_.insert(observer);
    if (!recording_.load(std::memory_order_acquire)) return;
  }// Fire the observer if recording is already in progress.
  observer->OnTraceEnabled();
}

在前面的platform屬性介紹里講過,除了線程相關,還有兩個工具類,一個就是這里的TracingController。這里生成了一個調用棧的觀察者對象,並將其加入類的一個無序SET屬性中。

最后一步是根據默認參數來啟動Observer對不同狀態runtime的追蹤,全是宏,太麻煩了,有興趣的自己去研究吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM