1. 程式人生 > >[WebKit] JavaScriptCore解析--基礎篇(三)從指令碼程式碼到JIT編譯的程式碼實現

[WebKit] JavaScriptCore解析--基礎篇(三)從指令碼程式碼到JIT編譯的程式碼實現

前面說了一些解析、生成ByteCode直至JIT的基本概念,下面是對照JavaScriptCore原始碼來大致瞭解它的實現。

從JS Script到Byte Code

首先說明Lexer, Parser和ByteCode的生成都是由ProgramExecutable初始化過程完成的。先在JSC的API evaluate()中會建立ProgramExecutable並指定指令碼程式碼。然後傳入Interpreter時,再透過CodeCache獲取的UnlinkedProgramCodeBlock就是已經生成ByteCode後的Code Block了。


下圖是CodeCache呼叫Parser和ByteCodeGenerator的序列圖:


而Lexer則是在Parser過程中呼叫的,如下圖:


再從類圖來觀察所涉及的幾個類之間的關係:


關於CodeBlock、UnlinkedCodeBlock和ScriptExecutable

CodeBlock可以理解為程式碼管理的類,按型別分為GlobalCodeBlock, ProgramCodeBlock, FunctionCodeBlock及EvalCodeBlock, 與之對應的UnlinkedCodeBlock和ScriptExecutable也有相似的繼承體系,如下所示:


UnlinkedCodeBlock儲存的是編譯後的ByteCode,而CodeBlock則會用於LLint和JIT。

ProgramExecutable則可以理解為當前所執行指令碼的大總管,從其名字上可以看出來是代表一個可執行程式。

它們的作用也很容易理解。

關於LLint的slow path

前面說過了LLint是基於offlineasm的組合語言,這裡只是介紹一下它的slow path. 為了處理一些操作,需要在LLint執行指令時呼叫一些C函式進行擴充套件處理,比如後面要說明的JIT統計功能,LLint提供一個呼叫C函式的介面,並將所有會被呼叫的C函式稱為slow path,如下圖所示:


程式碼可以在LowLevelInterpreterXXX.asm中看到。所以可以C函式宣告看到帶有SLOW_PATH的巨集。

關於JIT優化的觸發

首先JSC使用的是基於計數器的熱點探測方法。前面提到函式或迴圈體被執行若干次後會觸發JIT, 首先這個次數是可以通過JSC::Options中的thresholdForOptimizeSoon來設定的。然後在LLint在執行迴圈的ByteCode指令loop_hint和函式返回指令ret時會呼叫slow path中的C函式,進行次數統計和判斷,過程如下:


  其中會根據checkIfJITThresholdReached()返回結果來決定是否進行jitCompile.一旦要進行JIT編譯時,也是根據當前CodeBlock的型別,而執行鍼對不同函式或程式碼段的優化。下面顯示的是對一個頻繁使用的函式進行JIT編譯的操作:


其中計數的功能並非由CodeBlock直接實現,而是通過ExecutionCounter來管理的。主要關係如下:

     

系列索引:


相關推薦

[WebKit] JavaScriptCore解析--基礎()指令碼程式碼JIT編譯程式碼實現

前面說了一些解析、生成ByteCode直至JIT的基本概念,下面是對照JavaScriptCore原始碼來大致瞭解它的實現。 從JS Script到Byte Code 首先說明Lexer, Parser和ByteCode的生成都是由ProgramExecutable初始化

[WebKit] JavaScriptCore解析--基礎(四) 頁面解析與JavaScript元素的執行

很多地方都已經介紹了JavaScript在瀏覽器是如何被執行的,這裡介紹一下WebKit是如何實現的。主要涉及JS的async,defer及普通指令碼的解析與執行過程的程式碼實現。 1. 概要說明 先概要說明一下瀏覽器如何執行JavaScript的。 首先瀏覽器的頁面解析

[WebKit] JavaScriptCore解析--高階() Register Allocation & Trampoline

Register Allocation對於一個JIT而言,暫存器分配對系統的消耗通常是一個瓶徑。之前有Graph Coloring Allocators, Chaitin style等分配方式,現在要介紹的是DFG JIT使用的Linear Scan演算法。其基本工作方式是將

[WebKit] JavaScriptCore解析--基礎(二)直譯器基礎與JSC核心元件

這一篇主要說明直譯器的基本工作過程和JSC的核心元件的實現。 作為一個語言,就像人在的平時交流時一樣,當接收到資訊後,包含兩個過程:先理解再行動。理解的過程就是語言解析的過程,行動就是根據解析的結果執行對應的行為。在計算機領域,理解就是編譯或解釋,這個已經被研究的很透徹了

[WebKit] JavaScriptCore解析--高階(二) 型別推導(Type Inference)

型別推導是DFG JIT最重要的一個基礎,WebKit官網對此做了一點解釋,翻譯如下做為學習參考。 Type inference通過profiling values來做到的,先是預測對哪些型別操作進行分析,再新增型別檢查,最後基於型別檢查的結果建立型別統計資料。 用下面

[WebKit] JavaScriptCore解析--高階(一) SSA (static single assignment)

在編譯器優化領域,資料結構的選擇會直接影響程式優化的有效性。SSA是一種編譯器使用的中間語言(intermediate language), 作為編譯優化的基礎(也是DFG JIT的基礎),它和Control Dependence Graph一起被用來表示程式的資料流和控制

[WebKit核心] JavaScriptCore深度解析--基礎(一)位元組碼生成及語法樹的構建詳情分析

     看到HorkeyChen寫的文章《[WebKit] JavaScriptCore解析--基礎篇(三)從指令碼程式碼到JIT編譯的程式碼實現》,寫的很好,深受啟發。想補充一些Horkey沒有寫到的細節比如位元組碼是如何生成的等等,為此成文。       JS

機器學習讀書筆記()決策樹基礎相親說起

方法 事務 家裏 分類 筆記 判斷 都是 rom tro 一、決策樹 決策樹是什麽?決策樹(decision tree)是一種基本的分類與回歸方法。舉個通俗易懂的例子,如下圖所示的流程圖就是一個決策樹,長方形代表判斷模塊(decision block),橢圓形成代

[WebKit核心] JavaScript引擎深度解析--基礎(一)位元組碼生成及語法樹的構建詳情分析

      看到HorkeyChen寫的文章《[WebKit] JavaScriptCore解析--基礎篇(三)從指令碼程式碼到JIT編譯的程式碼實現》,寫的很好,深受啟發。想補充一些Horkey沒有寫到的細節比如位元組碼是如何生成的等等,為此成文。       JSC對

JAVA常用集合框架用法詳解基礎之Colletion子介面Set

這一篇我們來介紹Collection介面的另一個子介面,Set介面。Set是個介面,元素不可以重複,是無序的。Set介面中的方法和Collection的一致。 A、Set的子類: 1、HashSet:此類實現的Set介面,由雜湊表(實際上是一個HashMap)例項支援,它不保證Set的迭代順

PE檔案解析 基礎

PE檔案解析 基礎篇 來源 https://bbs.pediy.com/thread-247114.htm 前言 之前學習了PE格式,為了更好的理解,決定寫一個類似LoadPE的小工具。 編譯器是VS2015,採用MFC框架。 此係列文章採用邊介紹知識點,邊寫程式碼的

SpringBoot基礎()啟動載入資料CommandLineRunner詳解

        SpringBoot應用程式在啟動時,會遍歷CommandLineRunner介面的例項並執行他們的run()方法。也可以利用@Order註解或者Order介面來規定所有CommandLineRunner例項的執行順序。 /** * 伺服

Spring 基礎() Spring 模組概述

Spring 主要模組 從上面可以看出Spring主要分成六個模組: 1.Spring核心容器:核心容器是Spring框架的重要組成部分,也可以說是Spring框架的基礎。他在整個框架中的作用是負責管理物件的建立,管理,配置等等的操作。其主要包含spring-

002java面試筆記——【java基礎團800失敗面試總結的java面試題

6、java io流      1)java io流相關概念 輸出流:   輸入流: 因此輸入和輸出都是從程式的角度來說的。 位元組流:一次讀入或讀出是8位二進位制。 字元流:一次讀入或讀出是16位二進位制。 位元組流和字元流的原理是相同的,只不過處

【Redis詳解基礎(持久化)】

前言 什麼是持久化 因為redis是存放在記憶體中的,所以我們的資料很可能會丟失。所以得讓他持久化的保留起來就肯定需要硬碟,也就是放到裝置上進行儲存 使用場景 如果你想用redis暫時性的存放一些資料,只是存放之後設定一個超時的時間,那麼你可以不需要redi

手機玩轉區塊鏈基礎款挖礦主流APP

這兩年區塊鏈很火,除了傳統的電腦礦機挖礦,現在APP市場流行大量參差不齊的手機挖礦APP。相較於礦機挖礦,“手機挖礦”的優勢是顯而易見的,因為這種挖礦方式看上去屬於“零投入”,而且還能夠隨時隨地“挖”。簡言之,就是便宜、方便。”手機挖礦”,就是用手機版的挖礦平臺APP來進行同

Android基礎()——Android中的Activity簡單介紹

一、Activity的基本介紹 Android應用中通常由一個或者多個基本元件組成,我們平時看到的Andrid應用中最常用的元件就是Activity。Activity、BroadcastReceiver、ContentProvider和Service合稱Android的四大

【redis 基礎】set集合常用命令

     在使用集合的過程中,我們都明白他是通過Key-value的形式來儲存的,在存入資料的時候將值賦值給一個key值,去出的時候,我不管你那個value值跑到了什麼位置,我只要通過這個key值就可

C語言----選擇結構(基礎

運算符和 優先級 rom 表達 main idt 兩個 sco times 大家好,忙裏抽空更新一下自己的博客,算是自己的一個進步,C語言視頻啟蒙我早就看完啦,只是覺得這個視頻真不錯,所以給大家分享一下,同時自己還有很多沒有理解透徹,寫寫博客算是一個筆記更是對自己所學的知識

Java面試題-基礎(乾貨)

這些JAVA基礎題確定都會了嗎? 31、String s = new String("xyz");建立了幾個StringObject?是否可以繼承String類?         兩個或一個都有可能,”xyz&rd