• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 9,  comments - 19,  trackbacks - 0
            本人博客地址:http://m.shnenglu.com/pwq1989/

            第一篇對Luajit做一個大概的介紹,我目前也正在慢慢的讀通源碼中,以后發(fā)現(xiàn)了新東西就補充在這里。

            大家可以從官網(wǎng)下載到源碼(http://luajit.org/),也可以從Github(https://github.com/LuaDist/luajit)down下來,順便還可以看下commit記錄。

            大家對著luajit的wiki結(jié)合源碼看的話會更好些,因為。。文檔太特么少了!!

            目錄結(jié)構(gòu):
            -- src
                -- host
                -- jit
                *.c
                *.h
                *.dasc
            等等,別的不是很重要

            最開始我是從main函數(shù)開始看的,然后。。碰了一鼻子灰,后來研究下他的makefile,發(fā)現(xiàn)他是這樣子的編譯的,貼一下關(guān)鍵的msvcbuild.bat的代碼(這個更容易看懂)
             1 :X64
             2 minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc
             3 @if errorlevel 1 goto :BAD
             4 
             5 %LJCOMPILE% /I "." /I %DASMDIR% host\buildvm*.c
             6 @if errorlevel 1 goto :BAD
             7 %LJLINK% /out:buildvm.exe buildvm*.obj
             8 @if errorlevel 1 goto :BAD
             9 if exist buildvm.exe.manifest^
            10   %LJMT% -manifest buildvm.exe.manifest -outputresource:buildvm.exe
            11 
            12 buildvm -m peobj -o lj_vm.obj
            13 @if errorlevel 1 goto :BAD
            14 buildvm -m bcdef -o lj_bcdef.h %ALL_LIB%
            15 @if errorlevel 1 goto :BAD
            16 buildvm -m ffdef -o lj_ffdef.h %ALL_LIB%
            17 @if errorlevel 1 goto :BAD
            18 buildvm -m libdef -o lj_libdef.h %ALL_LIB%
            19 @if errorlevel 1 goto :BAD
            20 buildvm -m recdef -o lj_recdef.h %ALL_LIB%
            21 @if errorlevel 1 goto :BAD
            22 buildvm -m vmdef -o jit\vmdef.lua %ALL_LIB%
            23 @if errorlevel 1 goto :BAD
            24 buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
            25 @if errorlevel 1 goto :BAD

            先創(chuàng)建了一個buildvm.exe的中間工具,來自動生成代碼,分別生成了lj_vm.obj,lj_bcdef.h,lj_ffdef.h ,lj_recdef.h ,jit\vmdef.lua,lj_folddef.h, lj_libdef.h

            其中l(wèi)v_vm.obj是依賴于host\buildvm_arch.h的,這個是用DynASM預處理vm_x86.dasc生成的,這個工具的具體分析會在下一篇博客提及。

            先來看下上面自動生成的代碼:
            lj_bcdef.h:
             1 LJ_DATADEF const uint16_t lj_bc_ofs[] = {
             2 0,
             3 71,
             4 142,
             5 213,
             6 284,
             7 
             8 };
             9 
            10 LJ_DATADEF const uint16_t lj_bc_mode[] = {
            11 BCDEF(BCMODE)
            12 BCMODE_FF,
            13 BCMODE_FF,
            14 BCMODE_FF,
            15 BCMODE_FF,
            16 BCMODE_FF,
            17 
            18 };

            lj_bc_ofs[]可能是bc在vm代碼段中的偏移量(這個我還沒深入進去調(diào)試一下),vm的一部分是用DynASM直接擼匯編擼出來的,wiki中也有提到下一步j(luò)it化的opcode等等。
            lj_bc_mode[]的用來根據(jù)壓縮后的bytecode構(gòu)造,分離出操作數(shù),第一行的兩個宏的定義是
            #define BCMODE(name, ma, mb, mc, mm) \
              (BCM##ma|(BCM##mb<<3)|(BCM##mc<<7)|(MM_##mm<<11)),
            #define BCMODE_FF 0

            #define BCDEF(_) \
              /* Comparison ops. ORDER OPR. */ \
              _(ISLT, var, ___, var, lt) \
              _(ISGE, var, ___, var, lt) \
              _(ISLE, var, ___, var, le) \
              _(ISGT, var, ___, var, le) \
            ...
            總之就是充斥著各種拼接起來的宏

            lj_ffdef.h:
            1 FFDEF(assert)
            2 FFDEF(type)
            3 FFDEF(next)
            4 FFDEF(pairs)
            5 FFDEF(ipairs_aux)
            6 
            FFDEF的定義是在
            1 /* Fast function ID. */
            2 typedef enum {
            3   FF_LUA_ = FF_LUA,    /* Lua function (must be 0). */
            4   FF_C_ = FF_C,        /* Regular C function (must be 1). */
            5 #define FFDEF(name)    FF_##name,
            6 #include "lj_ffdef.h"
            7   FF__MAX
            8 } FastFunc;
            差不多就是用FF_##name把上面的名字拼接起來,然后生成在enum里面,這樣就能當成是數(shù)字,在數(shù)組中迅速找到入口了

            vmdef.lua:
            這個里面內(nèi)容就不貼了,包括bcname,irname,irfpm,irfield,ircall 的定義,在jit文件夾下面,用于調(diào)試等,比如在dump.lua中就有用到
            local jit = require("jit")
            assert(jit.version_num == 20002, "LuaJIT core/library version mismatch")
            local jutil = require("jit.util")
            local vmdef = require("jit.vmdef")  // ← ← ← ←

            當你用luajit -jdump的時候,就是調(diào)用的lua的jit庫里面的lua函數(shù)

            lj_recdef.h:
             1 static const uint16_t recff_idmap[] = {
             2 0,
             3 0x0100,
             4 0x0200,
             5 0x0300,
             6 0,
             7 0,
             8 0x0400,
             9 
            10 };
            11 
            12 static const RecordFunc recff_func[] = {
            13 recff_nyi,
            14 recff_c,
            15 recff_assert,
            16 recff_type,
            17 recff_ipairs_aux,
            18 
            19 };
            其中recff_func[]是被注冊的被traced jit 跟蹤的函數(shù),具體可是在lj_ffrecord.c里面看到
            recff_idmap[]被用在lj_ffrecord_func這個函數(shù)中,有一個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)RecordFFData,用來記錄在trace過程中被調(diào)用函數(shù)的參數(shù)和返回值個數(shù),和一些輔助數(shù)據(jù),opcode,literal等等。通過recff_idmap[]保存的值來區(qū)分函數(shù)(待仔細研究)


            lj_folddef.h:
             1 static const FoldFunc fold_func[] = {
             2   fold_kfold_numarith,
             3   fold_kfold_ldexp,
             4   fold_kfold_fpmath,
             5   fold_kfold_numpow,
             6 
             7 };
             8 
             9 static const uint32_t fold_hash[916] = {
            10 0xffffffff,
            11 0xffffffff,
            12 0x5b4c8016,
            13 
            14 };
            用在FOLD optimization中,見lj_opt_fold.c,主要在
            1 if ((fh & 0xffffff) == k || (fh = fold_hash[h+1], (fh & 0xffffff) == k)) {
            2       ref = (IRRef)tref_ref(fold_func[fh >> 24](J));
            3       if (ref != NEXTFOLD)
            4     break;
            5     }
            是根據(jù)數(shù)組偏移獲取函數(shù),直接執(zhí)行。
            (這個Optimation略復雜,以后的博文中再說)

            ----------------------------------------分割線-------------------------------------------

            以上就是buildvm生成代碼,在很多.c的文件中,他加入了一些無意義的MARCO,目的是為了能被buildvm識別出

            下面說說src根目錄下面的文件:

            lauxlib.h:
            用戶開發(fā)擴展和與C交互的時候的頭文件

            lib_*.h /.c:
            顧名思義,就是利用LuaAPI寫的內(nèi)部標準庫,會在方法上表明是否會被trace ( LJLIB_REC(.) )。

            ljamalg.c:
            文件的合并

            lj_alloc.h /.c:
            定制的Memory Allocator

            lj_api.c:
            Public Lua/C API.

            lj_arch.h:
            Target architecture selection

            lj_jit.h:
            jit編譯器里面數(shù)據(jù)結(jié)構(gòu)的定義

            lj_asm.h/ .c  lj_asm_*.c lj_emit_*.h lj_target_*.h/.c :
            將IR編譯成Machine Code,關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)ASMState,線性掃描的O(n2)分配算法

            lj_bc.h/ .c:
            Luajit字節(jié)碼的定義和內(nèi)存布局

            lj_bcdump.c lj_bcread.c  lj_bcwrite.c:
            圍繞著字節(jié)碼的操作

            lj_carith.c:
            C實現(xiàn)的一些數(shù)字運算

            lj_ccall.h/ .c  lj_ccallback.h / .c :
            FFI C語言函數(shù)調(diào)用和回調(diào)綁定

            lj_debug.h/.c :
            調(diào)試與自省用

            lj_def.h:
            這個很重要,重要的類型和一些宏定義在這里

            lj_c*.h/ .c:
            和C語言先關(guān)的,比如類型轉(zhuǎn)化,char管理,數(shù)據(jù)管理

            lj_frame.h:
            Luajit的棧幀管理

            lj_func.h/.c:
            Function handle和閉包有關(guān)的upvalue數(shù)據(jù)結(jié)構(gòu)

            lj_gc.h/.c:
            GC相關(guān),GC可以看下luajit的wiki,里面涉及不少增量式GC的paper和作者的看法

            lj_gdbjit.h/.c :
            對gdb的支持

            lj_ir*.h/.c:
            SSA,IR相關(guān)(這個和bytecode還是不一樣的)操作和優(yōu)化

            lj_lex.h/.c  lj_parse.h/.c:
            lexer和parser

            lj_mcode.h/.c:
            Machine Code管理

            lj_opt_*.h:
            各種bytecode層面上的優(yōu)化

            lj_snap.h/.c:
            快照支持

            lj_state.h/.c:
            LuaState和Stack的操作

            lj_str*.h/.c  lj_tab.h/.c:
            原生類型string和table操作

            lj_udata.h/.c:
            類型user data的操作

            lj_vm.h/.c  lj_vmevent.h/.c:
            vm的API和事件注冊(lj_vmevent_send)

            lj_vmmath.h/.c:
            對vm支持的math庫

            lua.h:
            luaState等基本的Lua結(jié)構(gòu)

            lualib.h:
            和Lua一樣,標準庫的API

            luajit.h:
            luajit 的public API

            vm_*.dasc:
            編譯期被DynASM預處理的源文件,下一篇講DynASM時候介紹dasc文件

            wmain.c:
            windows下面的main入口

            和Trace相關(guān)的:
            lj_crecord.h/.c  : C操作的trace record
            lj_dispatch.h/.c :  指令分發(fā),調(diào)用ASMFuction,處理指令前的hook和記錄trace用的hot count,有一個重要的數(shù)據(jù)結(jié)構(gòu) GG_State
            lj_ff*.h/.c: 上面講lj_ffdef.h的時候提過,trace的時候 記錄Fast Function的調(diào)用記數(shù)
            lj_trace.h/.c: trace的具體過程
            lj_traceerr.h : trace error
            posted on 2013-11-28 19:23 右席 閱讀(12610) 評論(4)  編輯 收藏 引用 所屬分類: Luajit
            亚洲精品高清一二区久久| 久久久久久曰本AV免费免费| 国产精品视频久久久| 久久99精品综合国产首页| 日本久久久久久中文字幕| 久久久久97国产精华液好用吗| 99久久做夜夜爱天天做精品| 青青草国产成人久久91网| 97视频久久久| 99久久精品国产毛片| 亚洲精品国产字幕久久不卡| 久久久久亚洲精品中文字幕| 亚洲中文精品久久久久久不卡| 国产免费福利体检区久久 | 91视频国产91久久久| 久久久久97国产精华液好用吗| 久久国产免费观看精品3| 亚洲欧美国产日韩综合久久| 久久精品国内一区二区三区| 热re99久久精品国99热| 99久久免费只有精品国产| 国内精品久久久久影院优| 亚洲国产婷婷香蕉久久久久久| 欧美精品一本久久男人的天堂| 天堂久久天堂AV色综合| 无码八A片人妻少妇久久| 国产激情久久久久影院| 精品亚洲综合久久中文字幕| 热re99久久6国产精品免费| 久久免费看黄a级毛片| 综合久久一区二区三区| 午夜精品久久久久久久无码| 久久se精品一区精品二区国产 | 午夜人妻久久久久久久久| 亚洲国产精品综合久久一线| 欧美亚洲另类久久综合婷婷| 欧美午夜精品久久久久久浪潮| 精品多毛少妇人妻AV免费久久| 99久久亚洲综合精品网站| 久久成人影院精品777| 97精品伊人久久久大香线蕉|