上一篇其實想講初始化的第二步,但是內容比較無聊,所以換了一個話題,談了談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的追蹤,全是巨集,太麻煩了,有興趣的自己去研究吧。