immunio 0.15.4 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +0 -27
- data/ext/immunio/Rakefile +9 -0
- data/lib/immunio/plugins/active_record.rb +1 -1
- data/lib/immunio/plugins/active_record_relation.rb +1 -1
- data/lib/immunio/plugins/environment_reporter.rb +20 -0
- data/lib/immunio/rufus_lua_ext/ref.rb +1 -3
- data/lib/immunio/version.rb +1 -1
- data/lib/immunio/vm.rb +1 -2
- data/lua-hooks/Makefile +97 -0
- data/lua-hooks/ext/all.c +41 -52
- data/lua-hooks/ext/all.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_html5.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_xss.o +0 -0
- data/lua-hooks/ext/libinjection/lualib.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.o +0 -0
- data/lua-hooks/ext/lpeg/lpcode.c +2 -2
- data/lua-hooks/ext/lpeg/lpcode.h +1 -1
- data/lua-hooks/ext/lpeg/lpcode.o +0 -0
- data/lua-hooks/ext/lpeg/lpprint.o +0 -0
- data/lua-hooks/ext/lpeg/lptree.c +2 -2
- data/lua-hooks/ext/lpeg/lptypes.h +1 -1
- data/lua-hooks/ext/lpeg/lpvm.c +2 -2
- data/lua-hooks/ext/lpeg/lpvm.o +0 -0
- data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +16 -3
- data/lua-hooks/ext/lua-snapshot/snapshot.c +14 -7
- data/lua-hooks/ext/luajit/COPYRIGHT +56 -0
- data/lua-hooks/ext/luajit/Makefile +159 -0
- data/lua-hooks/ext/luajit/README +16 -0
- data/lua-hooks/ext/luajit/doc/bluequad-print.css +166 -0
- data/lua-hooks/ext/luajit/doc/bluequad.css +325 -0
- data/lua-hooks/ext/luajit/doc/changes.html +804 -0
- data/lua-hooks/ext/luajit/doc/contact.html +104 -0
- data/lua-hooks/ext/luajit/doc/ext_c_api.html +189 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi.html +332 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +570 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +1261 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +603 -0
- data/lua-hooks/ext/luajit/doc/ext_jit.html +201 -0
- data/lua-hooks/ext/luajit/doc/ext_profiler.html +365 -0
- data/lua-hooks/ext/luajit/doc/extensions.html +448 -0
- data/lua-hooks/ext/luajit/doc/faq.html +186 -0
- data/lua-hooks/ext/luajit/doc/img/contact.png +0 -0
- data/lua-hooks/ext/luajit/doc/install.html +659 -0
- data/lua-hooks/ext/luajit/doc/luajit.html +236 -0
- data/lua-hooks/ext/luajit/doc/running.html +309 -0
- data/lua-hooks/ext/luajit/doc/status.html +118 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +456 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1125 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +518 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1166 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +416 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +953 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +419 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1919 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +83 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +12 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +471 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +1945 -0
- data/lua-hooks/ext/luajit/dynasm/dynasm.lua +1094 -0
- data/lua-hooks/ext/luajit/etc/luajit.1 +88 -0
- data/lua-hooks/ext/luajit/etc/luajit.pc +25 -0
- data/lua-hooks/ext/luajit/src/Makefile +697 -0
- data/lua-hooks/ext/luajit/src/Makefile.dep +244 -0
- data/lua-hooks/ext/luajit/src/host/README +4 -0
- data/lua-hooks/ext/luajit/src/host/buildvm +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.c +518 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.h +105 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_arch.h +7449 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +345 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +229 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +457 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +45 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +368 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.o +0 -0
- data/lua-hooks/ext/luajit/src/host/genlibbc.lua +197 -0
- data/lua-hooks/ext/luajit/src/host/genminilua.lua +428 -0
- data/lua-hooks/ext/luajit/src/host/minilua +0 -0
- data/lua-hooks/ext/luajit/src/host/minilua.c +7770 -0
- data/lua-hooks/ext/luajit/src/host/minilua.o +0 -0
- data/lua-hooks/ext/luajit/src/jit/bc.lua +190 -0
- data/lua-hooks/ext/luajit/src/jit/bcsave.lua +661 -0
- data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +689 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +428 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +591 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +838 -0
- data/lua-hooks/ext/luajit/src/jit/dump.lua +706 -0
- data/lua-hooks/ext/luajit/src/jit/p.lua +310 -0
- data/lua-hooks/ext/luajit/src/jit/v.lua +170 -0
- data/lua-hooks/ext/luajit/src/jit/vmdef.lua +362 -0
- data/lua-hooks/ext/luajit/src/jit/zone.lua +45 -0
- data/lua-hooks/ext/{lua → luajit/src}/lauxlib.h +10 -17
- data/lua-hooks/ext/luajit/src/lib_aux.c +356 -0
- data/lua-hooks/ext/luajit/src/lib_aux.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_aux_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base.c +664 -0
- data/lua-hooks/ext/luajit/src/lib_base.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit.c +180 -0
- data/lua-hooks/ext/luajit/src/lib_bit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug.c +405 -0
- data/lua-hooks/ext/luajit/src/lib_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.c +872 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init.c +55 -0
- data/lua-hooks/ext/luajit/src/lib_init.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io.c +541 -0
- data/lua-hooks/ext/luajit/src/lib_io.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit.c +767 -0
- data/lua-hooks/ext/luajit/src/lib_jit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math.c +230 -0
- data/lua-hooks/ext/luajit/src/lib_math.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os.c +292 -0
- data/lua-hooks/ext/luajit/src/lib_os.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package.c +610 -0
- data/lua-hooks/ext/luajit/src/lib_package.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string.c +752 -0
- data/lua-hooks/ext/luajit/src/lib_string.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table.c +307 -0
- data/lua-hooks/ext/luajit/src/lib_table.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.a +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.so +0 -0
- data/lua-hooks/ext/luajit/src/lj.supp +26 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.c +1398 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_alloc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api.c +1210 -0
- data/lua-hooks/ext/luajit/src/lj_api.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_arch.h +509 -0
- data/lua-hooks/ext/luajit/src/lj_asm.c +2278 -0
- data/lua-hooks/ext/luajit/src/lj_asm.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_arm.h +2217 -0
- data/lua-hooks/ext/luajit/src/lj_asm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_mips.h +1833 -0
- data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2015 -0
- data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2634 -0
- data/lua-hooks/ext/luajit/src/lj_bc.c +14 -0
- data/lua-hooks/ext/luajit/src/lj_bc.h +265 -0
- data/lua-hooks/ext/luajit/src/lj_bc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcdef.h +220 -0
- data/lua-hooks/ext/luajit/src/lj_bcdump.h +68 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.c +457 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcread_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.c +361 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf.c +234 -0
- data/lua-hooks/ext/luajit/src/lj_buf.h +105 -0
- data/lua-hooks/ext/luajit/src/lj_buf.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith.c +429 -0
- data/lua-hooks/ext/luajit/src/lj_carith.h +37 -0
- data/lua-hooks/ext/luajit/src/lj_carith.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.c +984 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.h +178 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.c +712 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.h +25 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.c +752 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.h +70 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.c +288 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.h +76 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char.c +43 -0
- data/lua-hooks/ext/luajit/src/lj_char.h +42 -0
- data/lua-hooks/ext/luajit/src/lj_char.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib.c +418 -0
- data/lua-hooks/ext/luajit/src/lj_clib.h +29 -0
- data/lua-hooks/ext/luajit/src/lj_clib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.c +1862 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.c +1834 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.c +635 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.h +461 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug.c +699 -0
- data/lua-hooks/ext/luajit/src/lj_debug.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_def.h +365 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.c +557 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.h +138 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_emit_arm.h +356 -0
- data/lua-hooks/ext/luajit/src/lj_emit_mips.h +211 -0
- data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +238 -0
- data/lua-hooks/ext/luajit/src/lj_emit_x86.h +462 -0
- data/lua-hooks/ext/luajit/src/lj_err.c +794 -0
- data/lua-hooks/ext/luajit/src/lj_err.h +41 -0
- data/lua-hooks/ext/luajit/src/lj_err.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_err_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_errmsg.h +190 -0
- data/lua-hooks/ext/luajit/src/lj_ff.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_ffdef.h +209 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.c +1247 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_folddef.h +1138 -0
- data/lua-hooks/ext/luajit/src/lj_frame.h +259 -0
- data/lua-hooks/ext/luajit/src/lj_func.c +185 -0
- data/lua-hooks/ext/luajit/src/lj_func.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_func.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_func_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc.c +845 -0
- data/lua-hooks/ext/luajit/src/lj_gc.h +134 -0
- data/lua-hooks/ext/luajit/src/lj_gc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.c +787 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.h +22 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir.c +505 -0
- data/lua-hooks/ext/luajit/src/lj_ir.h +577 -0
- data/lua-hooks/ext/luajit/src/lj_ir.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ircall.h +321 -0
- data/lua-hooks/ext/luajit/src/lj_iropt.h +161 -0
- data/lua-hooks/ext/luajit/src/lj_jit.h +440 -0
- data/lua-hooks/ext/luajit/src/lj_lex.c +482 -0
- data/lua-hooks/ext/luajit/src/lj_lex.h +86 -0
- data/lua-hooks/ext/luajit/src/lj_lex.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lex_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib.c +303 -0
- data/lua-hooks/ext/luajit/src/lj_lib.h +115 -0
- data/lua-hooks/ext/luajit/src/lj_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_libdef.h +414 -0
- data/lua-hooks/ext/luajit/src/lj_load.c +168 -0
- data/lua-hooks/ext/luajit/src/lj_load.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_load_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.c +386 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.h +30 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta.c +477 -0
- data/lua-hooks/ext/luajit/src/lj_meta.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_meta.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj.c +50 -0
- data/lua-hooks/ext/luajit/src/lj_obj.h +976 -0
- data/lua-hooks/ext/luajit/src/lj_obj.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.c +78 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.c +2488 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.c +449 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.c +935 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +652 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.c +245 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.c +856 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse.c +2725 -0
- data/lua-hooks/ext/luajit/src/lj_parse.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_parse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile.c +368 -0
- data/lua-hooks/ext/luajit/src/lj_profile.h +21 -0
- data/lua-hooks/ext/luajit/src/lj_profile.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_recdef.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_record.c +2554 -0
- data/lua-hooks/ext/luajit/src/lj_record.h +45 -0
- data/lua-hooks/ext/luajit/src/lj_record.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_record_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap.c +870 -0
- data/lua-hooks/ext/luajit/src/lj_snap.h +34 -0
- data/lua-hooks/ext/luajit/src/lj_snap.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state.c +300 -0
- data/lua-hooks/ext/luajit/src/lj_state.h +35 -0
- data/lua-hooks/ext/luajit/src/lj_state.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str.c +197 -0
- data/lua-hooks/ext/luajit/src/lj_str.h +27 -0
- data/lua-hooks/ext/luajit/src/lj_str.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.c +554 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.h +125 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.c +547 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.h +39 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab.c +666 -0
- data/lua-hooks/ext/luajit/src/lj_tab.h +73 -0
- data/lua-hooks/ext/luajit/src/lj_tab.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_target.h +164 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm64.h +97 -0
- data/lua-hooks/ext/luajit/src/lj_target_mips.h +260 -0
- data/lua-hooks/ext/luajit/src/lj_target_ppc.h +280 -0
- data/lua-hooks/ext/luajit/src/lj_target_x86.h +345 -0
- data/lua-hooks/ext/luajit/src/lj_trace.c +859 -0
- data/lua-hooks/ext/luajit/src/lj_trace.h +54 -0
- data/lua-hooks/ext/luajit/src/lj_trace.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_trace_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_traceerr.h +63 -0
- data/lua-hooks/ext/luajit/src/lj_udata.c +34 -0
- data/lua-hooks/ext/luajit/src/lj_udata.h +14 -0
- data/lua-hooks/ext/luajit/src/lj_udata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_udata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm.S +2730 -0
- data/lua-hooks/ext/luajit/src/lj_vm.h +114 -0
- data/lua-hooks/ext/luajit/src/lj_vm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.c +58 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.h +59 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.c +152 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/ljamalg.c +96 -0
- data/lua-hooks/ext/{lua → luajit/src}/lua.h +12 -7
- data/lua-hooks/ext/luajit/src/lua.hpp +9 -0
- data/lua-hooks/ext/luajit/src/luaconf.h +156 -0
- data/lua-hooks/ext/luajit/src/luajit +0 -0
- data/lua-hooks/ext/luajit/src/luajit.c +570 -0
- data/lua-hooks/ext/luajit/src/luajit.h +79 -0
- data/lua-hooks/ext/luajit/src/luajit.o +0 -0
- data/lua-hooks/ext/luajit/src/lualib.h +43 -0
- data/lua-hooks/ext/luajit/src/msvcbuild.bat +114 -0
- data/lua-hooks/ext/luajit/src/ps4build.bat +103 -0
- data/lua-hooks/ext/luajit/src/psvitabuild.bat +93 -0
- data/lua-hooks/ext/luajit/src/vm_arm.dasc +4585 -0
- data/lua-hooks/ext/luajit/src/vm_arm64.dasc +3764 -0
- data/lua-hooks/ext/luajit/src/vm_mips.dasc +4355 -0
- data/lua-hooks/ext/luajit/src/vm_ppc.dasc +5252 -0
- data/lua-hooks/ext/luajit/src/vm_x64.dasc +4902 -0
- data/lua-hooks/ext/luajit/src/vm_x86.dasc +5710 -0
- data/lua-hooks/ext/luajit/src/xb1build.bat +101 -0
- data/lua-hooks/ext/luajit/src/xedkbuild.bat +92 -0
- data/lua-hooks/ext/luautf8/lutf8lib.c +3 -3
- data/lua-hooks/lib/boot.lua +37 -2
- metadata +372 -69
- data/lua-hooks/ext/bitop/README +0 -22
- data/lua-hooks/ext/bitop/bit.c +0 -189
- data/lua-hooks/ext/extconf.rb +0 -38
- data/lua-hooks/ext/lua/COPYRIGHT +0 -34
- data/lua-hooks/ext/lua/lapi.c +0 -1087
- data/lua-hooks/ext/lua/lapi.h +0 -16
- data/lua-hooks/ext/lua/lauxlib.c +0 -652
- data/lua-hooks/ext/lua/lbaselib.c +0 -659
- data/lua-hooks/ext/lua/lcode.c +0 -831
- data/lua-hooks/ext/lua/lcode.h +0 -76
- data/lua-hooks/ext/lua/ldblib.c +0 -398
- data/lua-hooks/ext/lua/ldebug.c +0 -638
- data/lua-hooks/ext/lua/ldebug.h +0 -33
- data/lua-hooks/ext/lua/ldo.c +0 -519
- data/lua-hooks/ext/lua/ldo.h +0 -57
- data/lua-hooks/ext/lua/ldump.c +0 -164
- data/lua-hooks/ext/lua/lfunc.c +0 -174
- data/lua-hooks/ext/lua/lfunc.h +0 -34
- data/lua-hooks/ext/lua/lgc.c +0 -710
- data/lua-hooks/ext/lua/lgc.h +0 -110
- data/lua-hooks/ext/lua/linit.c +0 -38
- data/lua-hooks/ext/lua/liolib.c +0 -556
- data/lua-hooks/ext/lua/llex.c +0 -463
- data/lua-hooks/ext/lua/llex.h +0 -81
- data/lua-hooks/ext/lua/llimits.h +0 -128
- data/lua-hooks/ext/lua/lmathlib.c +0 -263
- data/lua-hooks/ext/lua/lmem.c +0 -86
- data/lua-hooks/ext/lua/lmem.h +0 -49
- data/lua-hooks/ext/lua/loadlib.c +0 -705
- data/lua-hooks/ext/lua/loadlib_rel.c +0 -760
- data/lua-hooks/ext/lua/lobject.c +0 -214
- data/lua-hooks/ext/lua/lobject.h +0 -381
- data/lua-hooks/ext/lua/lopcodes.c +0 -102
- data/lua-hooks/ext/lua/lopcodes.h +0 -268
- data/lua-hooks/ext/lua/loslib.c +0 -243
- data/lua-hooks/ext/lua/lparser.c +0 -1339
- data/lua-hooks/ext/lua/lparser.h +0 -82
- data/lua-hooks/ext/lua/lstate.c +0 -214
- data/lua-hooks/ext/lua/lstate.h +0 -169
- data/lua-hooks/ext/lua/lstring.c +0 -111
- data/lua-hooks/ext/lua/lstring.h +0 -31
- data/lua-hooks/ext/lua/lstrlib.c +0 -871
- data/lua-hooks/ext/lua/ltable.c +0 -588
- data/lua-hooks/ext/lua/ltable.h +0 -40
- data/lua-hooks/ext/lua/ltablib.c +0 -287
- data/lua-hooks/ext/lua/ltm.c +0 -75
- data/lua-hooks/ext/lua/ltm.h +0 -54
- data/lua-hooks/ext/lua/lua.c +0 -392
- data/lua-hooks/ext/lua/lua.def +0 -131
- data/lua-hooks/ext/lua/lua.rc +0 -28
- data/lua-hooks/ext/lua/lua_dll.rc +0 -26
- data/lua-hooks/ext/lua/luac.c +0 -200
- data/lua-hooks/ext/lua/luac.rc +0 -1
- data/lua-hooks/ext/lua/luaconf.h +0 -763
- data/lua-hooks/ext/lua/luaconf.h.in +0 -724
- data/lua-hooks/ext/lua/luaconf.h.orig +0 -763
- data/lua-hooks/ext/lua/lualib.h +0 -53
- data/lua-hooks/ext/lua/lundump.c +0 -227
- data/lua-hooks/ext/lua/lundump.h +0 -36
- data/lua-hooks/ext/lua/lvm.c +0 -767
- data/lua-hooks/ext/lua/lvm.h +0 -36
- data/lua-hooks/ext/lua/lzio.c +0 -82
- data/lua-hooks/ext/lua/lzio.h +0 -67
- data/lua-hooks/ext/lua/print.c +0 -227
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/*
|
|
2
|
+
** Definitions for x86 and x64 CPUs.
|
|
3
|
+
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#ifndef _LJ_TARGET_X86_H
|
|
7
|
+
#define _LJ_TARGET_X86_H
|
|
8
|
+
|
|
9
|
+
/* -- Registers IDs ------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
#if LJ_64
|
|
12
|
+
#define GPRDEF(_) \
|
|
13
|
+
_(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI) \
|
|
14
|
+
_(R8D) _(R9D) _(R10D) _(R11D) _(R12D) _(R13D) _(R14D) _(R15D)
|
|
15
|
+
#define FPRDEF(_) \
|
|
16
|
+
_(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) \
|
|
17
|
+
_(XMM8) _(XMM9) _(XMM10) _(XMM11) _(XMM12) _(XMM13) _(XMM14) _(XMM15)
|
|
18
|
+
#else
|
|
19
|
+
#define GPRDEF(_) \
|
|
20
|
+
_(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI)
|
|
21
|
+
#define FPRDEF(_) \
|
|
22
|
+
_(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7)
|
|
23
|
+
#endif
|
|
24
|
+
#define VRIDDEF(_) \
|
|
25
|
+
_(MRM)
|
|
26
|
+
|
|
27
|
+
#define RIDENUM(name) RID_##name,
|
|
28
|
+
|
|
29
|
+
enum {
|
|
30
|
+
GPRDEF(RIDENUM) /* General-purpose registers (GPRs). */
|
|
31
|
+
FPRDEF(RIDENUM) /* Floating-point registers (FPRs). */
|
|
32
|
+
RID_MAX,
|
|
33
|
+
RID_MRM = RID_MAX, /* Pseudo-id for ModRM operand. */
|
|
34
|
+
|
|
35
|
+
/* Calling conventions. */
|
|
36
|
+
RID_SP = RID_ESP,
|
|
37
|
+
RID_RET = RID_EAX,
|
|
38
|
+
#if LJ_64
|
|
39
|
+
RID_FPRET = RID_XMM0,
|
|
40
|
+
#else
|
|
41
|
+
RID_RETLO = RID_EAX,
|
|
42
|
+
RID_RETHI = RID_EDX,
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
/* These definitions must match with the *.dasc file(s): */
|
|
46
|
+
RID_BASE = RID_EDX, /* Interpreter BASE. */
|
|
47
|
+
#if LJ_64 && !LJ_ABI_WIN
|
|
48
|
+
RID_LPC = RID_EBX, /* Interpreter PC. */
|
|
49
|
+
RID_DISPATCH = RID_R14D, /* Interpreter DISPATCH table. */
|
|
50
|
+
#else
|
|
51
|
+
RID_LPC = RID_ESI, /* Interpreter PC. */
|
|
52
|
+
RID_DISPATCH = RID_EBX, /* Interpreter DISPATCH table. */
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
/* Register ranges [min, max) and number of registers. */
|
|
56
|
+
RID_MIN_GPR = RID_EAX,
|
|
57
|
+
RID_MIN_FPR = RID_XMM0,
|
|
58
|
+
RID_MAX_GPR = RID_MIN_FPR,
|
|
59
|
+
RID_MAX_FPR = RID_MAX,
|
|
60
|
+
RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
|
|
61
|
+
RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/* -- Register sets ------------------------------------------------------- */
|
|
65
|
+
|
|
66
|
+
/* Make use of all registers, except the stack pointer. */
|
|
67
|
+
#define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP))
|
|
68
|
+
#define RSET_FPR (RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
|
|
69
|
+
#define RSET_ALL (RSET_GPR|RSET_FPR)
|
|
70
|
+
#define RSET_INIT RSET_ALL
|
|
71
|
+
|
|
72
|
+
#if LJ_64
|
|
73
|
+
/* Note: this requires the use of FORCE_REX! */
|
|
74
|
+
#define RSET_GPR8 RSET_GPR
|
|
75
|
+
#else
|
|
76
|
+
#define RSET_GPR8 (RSET_RANGE(RID_EAX, RID_EBX+1))
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
/* ABI-specific register sets. */
|
|
80
|
+
#define RSET_ACD (RID2RSET(RID_EAX)|RID2RSET(RID_ECX)|RID2RSET(RID_EDX))
|
|
81
|
+
#if LJ_64
|
|
82
|
+
#if LJ_ABI_WIN
|
|
83
|
+
/* Windows x64 ABI. */
|
|
84
|
+
#define RSET_SCRATCH \
|
|
85
|
+
(RSET_ACD|RSET_RANGE(RID_R8D, RID_R11D+1)|RSET_RANGE(RID_XMM0, RID_XMM5+1))
|
|
86
|
+
#define REGARG_GPRS \
|
|
87
|
+
(RID_ECX|((RID_EDX|((RID_R8D|(RID_R9D<<5))<<5))<<5))
|
|
88
|
+
#define REGARG_NUMGPR 4
|
|
89
|
+
#define REGARG_NUMFPR 4
|
|
90
|
+
#define REGARG_FIRSTFPR RID_XMM0
|
|
91
|
+
#define REGARG_LASTFPR RID_XMM3
|
|
92
|
+
#define STACKARG_OFS (4*8)
|
|
93
|
+
#else
|
|
94
|
+
/* The rest of the civilized x64 world has a common ABI. */
|
|
95
|
+
#define RSET_SCRATCH \
|
|
96
|
+
(RSET_ACD|RSET_RANGE(RID_ESI, RID_R11D+1)|RSET_FPR)
|
|
97
|
+
#define REGARG_GPRS \
|
|
98
|
+
(RID_EDI|((RID_ESI|((RID_EDX|((RID_ECX|((RID_R8D|(RID_R9D \
|
|
99
|
+
<<5))<<5))<<5))<<5))<<5))
|
|
100
|
+
#define REGARG_NUMGPR 6
|
|
101
|
+
#define REGARG_NUMFPR 8
|
|
102
|
+
#define REGARG_FIRSTFPR RID_XMM0
|
|
103
|
+
#define REGARG_LASTFPR RID_XMM7
|
|
104
|
+
#define STACKARG_OFS 0
|
|
105
|
+
#endif
|
|
106
|
+
#else
|
|
107
|
+
/* Common x86 ABI. */
|
|
108
|
+
#define RSET_SCRATCH (RSET_ACD|RSET_FPR)
|
|
109
|
+
#define REGARG_GPRS (RID_ECX|(RID_EDX<<5)) /* Fastcall only. */
|
|
110
|
+
#define REGARG_NUMGPR 2 /* Fastcall only. */
|
|
111
|
+
#define REGARG_NUMFPR 0
|
|
112
|
+
#define STACKARG_OFS 0
|
|
113
|
+
#endif
|
|
114
|
+
|
|
115
|
+
#if LJ_64
|
|
116
|
+
/* Prefer the low 8 regs of each type to reduce REX prefixes. */
|
|
117
|
+
#undef rset_picktop
|
|
118
|
+
#define rset_picktop(rs) (lj_fls(lj_bswap(rs)) ^ 0x18)
|
|
119
|
+
#endif
|
|
120
|
+
|
|
121
|
+
/* -- Spill slots --------------------------------------------------------- */
|
|
122
|
+
|
|
123
|
+
/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
|
|
124
|
+
**
|
|
125
|
+
** SPS_FIXED: Available fixed spill slots in interpreter frame.
|
|
126
|
+
** This definition must match with the *.dasc file(s).
|
|
127
|
+
**
|
|
128
|
+
** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
|
|
129
|
+
*/
|
|
130
|
+
#if LJ_64
|
|
131
|
+
#if LJ_ABI_WIN
|
|
132
|
+
#define SPS_FIXED (4*2)
|
|
133
|
+
#define SPS_FIRST (4*2) /* Don't use callee register save area. */
|
|
134
|
+
#else
|
|
135
|
+
#if LJ_GC64
|
|
136
|
+
#define SPS_FIXED 2
|
|
137
|
+
#else
|
|
138
|
+
#define SPS_FIXED 4
|
|
139
|
+
#endif
|
|
140
|
+
#define SPS_FIRST 2
|
|
141
|
+
#endif
|
|
142
|
+
#else
|
|
143
|
+
#define SPS_FIXED 6
|
|
144
|
+
#define SPS_FIRST 2
|
|
145
|
+
#endif
|
|
146
|
+
|
|
147
|
+
#define SPOFS_TMP 0
|
|
148
|
+
|
|
149
|
+
#define sps_scale(slot) (4 * (int32_t)(slot))
|
|
150
|
+
#define sps_align(slot) (((slot) - SPS_FIXED + 3) & ~3)
|
|
151
|
+
|
|
152
|
+
/* -- Exit state ---------------------------------------------------------- */
|
|
153
|
+
|
|
154
|
+
/* This definition must match with the *.dasc file(s). */
|
|
155
|
+
typedef struct {
|
|
156
|
+
lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */
|
|
157
|
+
intptr_t gpr[RID_NUM_GPR]; /* General-purpose registers. */
|
|
158
|
+
int32_t spill[256]; /* Spill slots. */
|
|
159
|
+
} ExitState;
|
|
160
|
+
|
|
161
|
+
/* Limited by the range of a short fwd jump (127): (2+2)*(32-1)-2 = 122. */
|
|
162
|
+
#define EXITSTUB_SPACING (2+2)
|
|
163
|
+
#define EXITSTUBS_PER_GROUP 32
|
|
164
|
+
|
|
165
|
+
/* -- x86 ModRM operand encoding ------------------------------------------ */
|
|
166
|
+
|
|
167
|
+
typedef enum {
|
|
168
|
+
XM_OFS0 = 0x00, XM_OFS8 = 0x40, XM_OFS32 = 0x80, XM_REG = 0xc0,
|
|
169
|
+
XM_SCALE1 = 0x00, XM_SCALE2 = 0x40, XM_SCALE4 = 0x80, XM_SCALE8 = 0xc0,
|
|
170
|
+
XM_MASK = 0xc0
|
|
171
|
+
} x86Mode;
|
|
172
|
+
|
|
173
|
+
/* Structure to hold variable ModRM operand. */
|
|
174
|
+
typedef struct {
|
|
175
|
+
int32_t ofs; /* Offset. */
|
|
176
|
+
uint8_t base; /* Base register or RID_NONE. */
|
|
177
|
+
uint8_t idx; /* Index register or RID_NONE. */
|
|
178
|
+
uint8_t scale; /* Index scale (XM_SCALE1 .. XM_SCALE8). */
|
|
179
|
+
} x86ModRM;
|
|
180
|
+
|
|
181
|
+
/* -- Opcodes ------------------------------------------------------------- */
|
|
182
|
+
|
|
183
|
+
/* Macros to construct variable-length x86 opcodes. -(len+1) is in LSB. */
|
|
184
|
+
#define XO_(o) ((uint32_t)(0x0000fe + (0x##o<<24)))
|
|
185
|
+
#define XO_FPU(a,b) ((uint32_t)(0x00fd + (0x##a<<16)+(0x##b<<24)))
|
|
186
|
+
#define XO_0f(o) ((uint32_t)(0x0f00fd + (0x##o<<24)))
|
|
187
|
+
#define XO_66(o) ((uint32_t)(0x6600fd + (0x##o<<24)))
|
|
188
|
+
#define XO_660f(o) ((uint32_t)(0x0f66fc + (0x##o<<24)))
|
|
189
|
+
#define XO_f20f(o) ((uint32_t)(0x0ff2fc + (0x##o<<24)))
|
|
190
|
+
#define XO_f30f(o) ((uint32_t)(0x0ff3fc + (0x##o<<24)))
|
|
191
|
+
|
|
192
|
+
/* This list of x86 opcodes is not intended to be complete. Opcodes are only
|
|
193
|
+
** included when needed. Take a look at DynASM or jit.dis_x86 to see the
|
|
194
|
+
** whole mess.
|
|
195
|
+
*/
|
|
196
|
+
typedef enum {
|
|
197
|
+
/* Fixed length opcodes. XI_* prefix. */
|
|
198
|
+
XI_NOP = 0x90,
|
|
199
|
+
XI_XCHGa = 0x90,
|
|
200
|
+
XI_CALL = 0xe8,
|
|
201
|
+
XI_JMP = 0xe9,
|
|
202
|
+
XI_JMPs = 0xeb,
|
|
203
|
+
XI_PUSH = 0x50, /* Really 50+r. */
|
|
204
|
+
XI_JCCs = 0x70, /* Really 7x. */
|
|
205
|
+
XI_JCCn = 0x80, /* Really 0f8x. */
|
|
206
|
+
XI_LEA = 0x8d,
|
|
207
|
+
XI_MOVrib = 0xb0, /* Really b0+r. */
|
|
208
|
+
XI_MOVri = 0xb8, /* Really b8+r. */
|
|
209
|
+
XI_ARITHib = 0x80,
|
|
210
|
+
XI_ARITHi = 0x81,
|
|
211
|
+
XI_ARITHi8 = 0x83,
|
|
212
|
+
XI_PUSHi8 = 0x6a,
|
|
213
|
+
XI_TESTb = 0x84,
|
|
214
|
+
XI_TEST = 0x85,
|
|
215
|
+
XI_MOVmi = 0xc7,
|
|
216
|
+
XI_GROUP5 = 0xff,
|
|
217
|
+
|
|
218
|
+
/* Note: little-endian byte-order! */
|
|
219
|
+
XI_FLDZ = 0xeed9,
|
|
220
|
+
XI_FLD1 = 0xe8d9,
|
|
221
|
+
XI_FLDLG2 = 0xecd9,
|
|
222
|
+
XI_FLDLN2 = 0xedd9,
|
|
223
|
+
XI_FDUP = 0xc0d9, /* Really fld st0. */
|
|
224
|
+
XI_FPOP = 0xd8dd, /* Really fstp st0. */
|
|
225
|
+
XI_FPOP1 = 0xd9dd, /* Really fstp st1. */
|
|
226
|
+
XI_FRNDINT = 0xfcd9,
|
|
227
|
+
XI_FSIN = 0xfed9,
|
|
228
|
+
XI_FCOS = 0xffd9,
|
|
229
|
+
XI_FPTAN = 0xf2d9,
|
|
230
|
+
XI_FPATAN = 0xf3d9,
|
|
231
|
+
XI_FSCALE = 0xfdd9,
|
|
232
|
+
XI_FYL2X = 0xf1d9,
|
|
233
|
+
|
|
234
|
+
/* Variable-length opcodes. XO_* prefix. */
|
|
235
|
+
XO_MOV = XO_(8b),
|
|
236
|
+
XO_MOVto = XO_(89),
|
|
237
|
+
XO_MOVtow = XO_66(89),
|
|
238
|
+
XO_MOVtob = XO_(88),
|
|
239
|
+
XO_MOVmi = XO_(c7),
|
|
240
|
+
XO_MOVmib = XO_(c6),
|
|
241
|
+
XO_LEA = XO_(8d),
|
|
242
|
+
XO_ARITHib = XO_(80),
|
|
243
|
+
XO_ARITHi = XO_(81),
|
|
244
|
+
XO_ARITHi8 = XO_(83),
|
|
245
|
+
XO_ARITHiw8 = XO_66(83),
|
|
246
|
+
XO_SHIFTi = XO_(c1),
|
|
247
|
+
XO_SHIFT1 = XO_(d1),
|
|
248
|
+
XO_SHIFTcl = XO_(d3),
|
|
249
|
+
XO_IMUL = XO_0f(af),
|
|
250
|
+
XO_IMULi = XO_(69),
|
|
251
|
+
XO_IMULi8 = XO_(6b),
|
|
252
|
+
XO_CMP = XO_(3b),
|
|
253
|
+
XO_TESTb = XO_(84),
|
|
254
|
+
XO_TEST = XO_(85),
|
|
255
|
+
XO_GROUP3b = XO_(f6),
|
|
256
|
+
XO_GROUP3 = XO_(f7),
|
|
257
|
+
XO_GROUP5b = XO_(fe),
|
|
258
|
+
XO_GROUP5 = XO_(ff),
|
|
259
|
+
XO_MOVZXb = XO_0f(b6),
|
|
260
|
+
XO_MOVZXw = XO_0f(b7),
|
|
261
|
+
XO_MOVSXb = XO_0f(be),
|
|
262
|
+
XO_MOVSXw = XO_0f(bf),
|
|
263
|
+
XO_MOVSXd = XO_(63),
|
|
264
|
+
XO_BSWAP = XO_0f(c8),
|
|
265
|
+
XO_CMOV = XO_0f(40),
|
|
266
|
+
|
|
267
|
+
XO_MOVSD = XO_f20f(10),
|
|
268
|
+
XO_MOVSDto = XO_f20f(11),
|
|
269
|
+
XO_MOVSS = XO_f30f(10),
|
|
270
|
+
XO_MOVSSto = XO_f30f(11),
|
|
271
|
+
XO_MOVLPD = XO_660f(12),
|
|
272
|
+
XO_MOVAPS = XO_0f(28),
|
|
273
|
+
XO_XORPS = XO_0f(57),
|
|
274
|
+
XO_ANDPS = XO_0f(54),
|
|
275
|
+
XO_ADDSD = XO_f20f(58),
|
|
276
|
+
XO_SUBSD = XO_f20f(5c),
|
|
277
|
+
XO_MULSD = XO_f20f(59),
|
|
278
|
+
XO_DIVSD = XO_f20f(5e),
|
|
279
|
+
XO_SQRTSD = XO_f20f(51),
|
|
280
|
+
XO_MINSD = XO_f20f(5d),
|
|
281
|
+
XO_MAXSD = XO_f20f(5f),
|
|
282
|
+
XO_ROUNDSD = 0x0b3a0ffc, /* Really 66 0f 3a 0b. See asm_fpmath. */
|
|
283
|
+
XO_UCOMISD = XO_660f(2e),
|
|
284
|
+
XO_CVTSI2SD = XO_f20f(2a),
|
|
285
|
+
XO_CVTTSD2SI= XO_f20f(2c),
|
|
286
|
+
XO_CVTSI2SS = XO_f30f(2a),
|
|
287
|
+
XO_CVTTSS2SI= XO_f30f(2c),
|
|
288
|
+
XO_CVTSS2SD = XO_f30f(5a),
|
|
289
|
+
XO_CVTSD2SS = XO_f20f(5a),
|
|
290
|
+
XO_ADDSS = XO_f30f(58),
|
|
291
|
+
XO_MOVD = XO_660f(6e),
|
|
292
|
+
XO_MOVDto = XO_660f(7e),
|
|
293
|
+
|
|
294
|
+
XO_FLDd = XO_(d9), XOg_FLDd = 0,
|
|
295
|
+
XO_FLDq = XO_(dd), XOg_FLDq = 0,
|
|
296
|
+
XO_FILDd = XO_(db), XOg_FILDd = 0,
|
|
297
|
+
XO_FILDq = XO_(df), XOg_FILDq = 5,
|
|
298
|
+
XO_FSTPd = XO_(d9), XOg_FSTPd = 3,
|
|
299
|
+
XO_FSTPq = XO_(dd), XOg_FSTPq = 3,
|
|
300
|
+
XO_FISTPq = XO_(df), XOg_FISTPq = 7,
|
|
301
|
+
XO_FISTTPq = XO_(dd), XOg_FISTTPq = 1,
|
|
302
|
+
XO_FADDq = XO_(dc), XOg_FADDq = 0,
|
|
303
|
+
XO_FLDCW = XO_(d9), XOg_FLDCW = 5,
|
|
304
|
+
XO_FNSTCW = XO_(d9), XOg_FNSTCW = 7
|
|
305
|
+
} x86Op;
|
|
306
|
+
|
|
307
|
+
/* x86 opcode groups. */
|
|
308
|
+
typedef uint32_t x86Group;
|
|
309
|
+
|
|
310
|
+
#define XG_(i8, i, g) ((x86Group)(((i8) << 16) + ((i) << 8) + (g)))
|
|
311
|
+
#define XG_ARITHi(g) XG_(XI_ARITHi8, XI_ARITHi, g)
|
|
312
|
+
#define XG_TOXOi(xg) ((x86Op)(0x000000fe + (((xg)<<16) & 0xff000000)))
|
|
313
|
+
#define XG_TOXOi8(xg) ((x86Op)(0x000000fe + (((xg)<<8) & 0xff000000)))
|
|
314
|
+
|
|
315
|
+
#define XO_ARITH(a) ((x86Op)(0x030000fe + ((a)<<27)))
|
|
316
|
+
#define XO_ARITHw(a) ((x86Op)(0x036600fd + ((a)<<27)))
|
|
317
|
+
|
|
318
|
+
typedef enum {
|
|
319
|
+
XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
|
|
320
|
+
XOg_X_IMUL
|
|
321
|
+
} x86Arith;
|
|
322
|
+
|
|
323
|
+
typedef enum {
|
|
324
|
+
XOg_ROL, XOg_ROR, XOg_RCL, XOg_RCR, XOg_SHL, XOg_SHR, XOg_SAL, XOg_SAR
|
|
325
|
+
} x86Shift;
|
|
326
|
+
|
|
327
|
+
typedef enum {
|
|
328
|
+
XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
|
|
329
|
+
} x86Group3;
|
|
330
|
+
|
|
331
|
+
typedef enum {
|
|
332
|
+
XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH
|
|
333
|
+
} x86Group5;
|
|
334
|
+
|
|
335
|
+
/* x86 condition codes. */
|
|
336
|
+
typedef enum {
|
|
337
|
+
CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
|
|
338
|
+
CC_S, CC_NS, CC_P, CC_NP, CC_L, CC_NL, CC_LE, CC_NLE,
|
|
339
|
+
CC_C = CC_B, CC_NAE = CC_C, CC_NC = CC_NB, CC_AE = CC_NB,
|
|
340
|
+
CC_Z = CC_E, CC_NZ = CC_NE, CC_NA = CC_BE, CC_A = CC_NBE,
|
|
341
|
+
CC_PE = CC_P, CC_PO = CC_NP, CC_NGE = CC_L, CC_GE = CC_NL,
|
|
342
|
+
CC_NG = CC_LE, CC_G = CC_NLE
|
|
343
|
+
} x86CC;
|
|
344
|
+
|
|
345
|
+
#endif
|
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
/*
|
|
2
|
+
** Trace management.
|
|
3
|
+
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#define lj_trace_c
|
|
7
|
+
#define LUA_CORE
|
|
8
|
+
|
|
9
|
+
#include "lj_obj.h"
|
|
10
|
+
|
|
11
|
+
#if LJ_HASJIT
|
|
12
|
+
|
|
13
|
+
#include "lj_gc.h"
|
|
14
|
+
#include "lj_err.h"
|
|
15
|
+
#include "lj_debug.h"
|
|
16
|
+
#include "lj_str.h"
|
|
17
|
+
#include "lj_frame.h"
|
|
18
|
+
#include "lj_state.h"
|
|
19
|
+
#include "lj_bc.h"
|
|
20
|
+
#include "lj_ir.h"
|
|
21
|
+
#include "lj_jit.h"
|
|
22
|
+
#include "lj_iropt.h"
|
|
23
|
+
#include "lj_mcode.h"
|
|
24
|
+
#include "lj_trace.h"
|
|
25
|
+
#include "lj_snap.h"
|
|
26
|
+
#include "lj_gdbjit.h"
|
|
27
|
+
#include "lj_record.h"
|
|
28
|
+
#include "lj_asm.h"
|
|
29
|
+
#include "lj_dispatch.h"
|
|
30
|
+
#include "lj_vm.h"
|
|
31
|
+
#include "lj_vmevent.h"
|
|
32
|
+
#include "lj_target.h"
|
|
33
|
+
|
|
34
|
+
/* -- Error handling ------------------------------------------------------ */
|
|
35
|
+
|
|
36
|
+
/* Synchronous abort with error message. */
|
|
37
|
+
void lj_trace_err(jit_State *J, TraceError e)
|
|
38
|
+
{
|
|
39
|
+
setnilV(&J->errinfo); /* No error info. */
|
|
40
|
+
setintV(J->L->top++, (int32_t)e);
|
|
41
|
+
lj_err_throw(J->L, LUA_ERRRUN);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Synchronous abort with error message and error info. */
|
|
45
|
+
void lj_trace_err_info(jit_State *J, TraceError e)
|
|
46
|
+
{
|
|
47
|
+
setintV(J->L->top++, (int32_t)e);
|
|
48
|
+
lj_err_throw(J->L, LUA_ERRRUN);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* -- Trace management ---------------------------------------------------- */
|
|
52
|
+
|
|
53
|
+
/* The current trace is first assembled in J->cur. The variable length
|
|
54
|
+
** arrays point to shared, growable buffers (J->irbuf etc.). When trace
|
|
55
|
+
** recording ends successfully, the current trace and its data structures
|
|
56
|
+
** are copied to a new (compact) GCtrace object.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/* Find a free trace number. */
|
|
60
|
+
static TraceNo trace_findfree(jit_State *J)
|
|
61
|
+
{
|
|
62
|
+
MSize osz, lim;
|
|
63
|
+
if (J->freetrace == 0)
|
|
64
|
+
J->freetrace = 1;
|
|
65
|
+
for (; J->freetrace < J->sizetrace; J->freetrace++)
|
|
66
|
+
if (traceref(J, J->freetrace) == NULL)
|
|
67
|
+
return J->freetrace++;
|
|
68
|
+
/* Need to grow trace array. */
|
|
69
|
+
lim = (MSize)J->param[JIT_P_maxtrace] + 1;
|
|
70
|
+
if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
|
|
71
|
+
osz = J->sizetrace;
|
|
72
|
+
if (osz >= lim)
|
|
73
|
+
return 0; /* Too many traces. */
|
|
74
|
+
lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
|
|
75
|
+
for (; osz < J->sizetrace; osz++)
|
|
76
|
+
setgcrefnull(J->trace[osz]);
|
|
77
|
+
return J->freetrace;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
#define TRACE_APPENDVEC(field, szfield, tp) \
|
|
81
|
+
T->field = (tp *)p; \
|
|
82
|
+
memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \
|
|
83
|
+
p += J->cur.szfield*sizeof(tp);
|
|
84
|
+
|
|
85
|
+
#ifdef LUAJIT_USE_PERFTOOLS
|
|
86
|
+
/*
|
|
87
|
+
** Create symbol table of JIT-compiled code. For use with Linux perf tools.
|
|
88
|
+
** Example usage:
|
|
89
|
+
** perf record -f -e cycles luajit test.lua
|
|
90
|
+
** perf report -s symbol
|
|
91
|
+
** rm perf.data /tmp/perf-*.map
|
|
92
|
+
*/
|
|
93
|
+
#include <stdio.h>
|
|
94
|
+
#include <unistd.h>
|
|
95
|
+
|
|
96
|
+
static void perftools_addtrace(GCtrace *T)
|
|
97
|
+
{
|
|
98
|
+
static FILE *fp;
|
|
99
|
+
GCproto *pt = &gcref(T->startpt)->pt;
|
|
100
|
+
const BCIns *startpc = mref(T->startpc, const BCIns);
|
|
101
|
+
const char *name = proto_chunknamestr(pt);
|
|
102
|
+
BCLine lineno;
|
|
103
|
+
if (name[0] == '@' || name[0] == '=')
|
|
104
|
+
name++;
|
|
105
|
+
else
|
|
106
|
+
name = "(string)";
|
|
107
|
+
lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
|
|
108
|
+
lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
|
|
109
|
+
if (!fp) {
|
|
110
|
+
char fname[40];
|
|
111
|
+
sprintf(fname, "/tmp/perf-%d.map", getpid());
|
|
112
|
+
if (!(fp = fopen(fname, "w"))) return;
|
|
113
|
+
setlinebuf(fp);
|
|
114
|
+
}
|
|
115
|
+
fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
|
|
116
|
+
(long)T->mcode, T->szmcode, T->traceno, name, lineno);
|
|
117
|
+
}
|
|
118
|
+
#endif
|
|
119
|
+
|
|
120
|
+
/* Allocate space for copy of trace. */
|
|
121
|
+
static GCtrace *trace_save_alloc(jit_State *J)
|
|
122
|
+
{
|
|
123
|
+
size_t sztr = ((sizeof(GCtrace)+7)&~7);
|
|
124
|
+
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
|
|
125
|
+
size_t sz = sztr + szins +
|
|
126
|
+
J->cur.nsnap*sizeof(SnapShot) +
|
|
127
|
+
J->cur.nsnapmap*sizeof(SnapEntry);
|
|
128
|
+
return lj_mem_newt(J->L, (MSize)sz, GCtrace);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* Save current trace by copying and compacting it. */
|
|
132
|
+
static void trace_save(jit_State *J, GCtrace *T)
|
|
133
|
+
{
|
|
134
|
+
size_t sztr = ((sizeof(GCtrace)+7)&~7);
|
|
135
|
+
size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
|
|
136
|
+
char *p = (char *)T + sztr;
|
|
137
|
+
memcpy(T, &J->cur, sizeof(GCtrace));
|
|
138
|
+
setgcrefr(T->nextgc, J2G(J)->gc.root);
|
|
139
|
+
setgcrefp(J2G(J)->gc.root, T);
|
|
140
|
+
newwhite(J2G(J), T);
|
|
141
|
+
T->gct = ~LJ_TTRACE;
|
|
142
|
+
T->ir = (IRIns *)p - J->cur.nk;
|
|
143
|
+
memcpy(p, J->cur.ir+J->cur.nk, szins);
|
|
144
|
+
p += szins;
|
|
145
|
+
TRACE_APPENDVEC(snap, nsnap, SnapShot)
|
|
146
|
+
TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
|
|
147
|
+
J->cur.traceno = 0;
|
|
148
|
+
setgcrefp(J->trace[T->traceno], T);
|
|
149
|
+
lj_gc_barriertrace(J2G(J), T->traceno);
|
|
150
|
+
lj_gdbjit_addtrace(J, T);
|
|
151
|
+
#ifdef LUAJIT_USE_PERFTOOLS
|
|
152
|
+
perftools_addtrace(T);
|
|
153
|
+
#endif
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T)
|
|
157
|
+
{
|
|
158
|
+
jit_State *J = G2J(g);
|
|
159
|
+
if (T->traceno) {
|
|
160
|
+
lj_gdbjit_deltrace(J, T);
|
|
161
|
+
if (T->traceno < J->freetrace)
|
|
162
|
+
J->freetrace = T->traceno;
|
|
163
|
+
setgcrefnull(J->trace[T->traceno]);
|
|
164
|
+
}
|
|
165
|
+
lj_mem_free(g, T,
|
|
166
|
+
((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
|
|
167
|
+
T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Re-enable compiling a prototype by unpatching any modified bytecode. */
|
|
171
|
+
void lj_trace_reenableproto(GCproto *pt)
|
|
172
|
+
{
|
|
173
|
+
if ((pt->flags & PROTO_ILOOP)) {
|
|
174
|
+
BCIns *bc = proto_bc(pt);
|
|
175
|
+
BCPos i, sizebc = pt->sizebc;;
|
|
176
|
+
pt->flags &= ~PROTO_ILOOP;
|
|
177
|
+
if (bc_op(bc[0]) == BC_IFUNCF)
|
|
178
|
+
setbc_op(&bc[0], BC_FUNCF);
|
|
179
|
+
for (i = 1; i < sizebc; i++) {
|
|
180
|
+
BCOp op = bc_op(bc[i]);
|
|
181
|
+
if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP)
|
|
182
|
+
setbc_op(&bc[i], (int)op+(int)BC_LOOP-(int)BC_ILOOP);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Unpatch the bytecode modified by a root trace. */
|
|
188
|
+
static void trace_unpatch(jit_State *J, GCtrace *T)
|
|
189
|
+
{
|
|
190
|
+
BCOp op = bc_op(T->startins);
|
|
191
|
+
BCIns *pc = mref(T->startpc, BCIns);
|
|
192
|
+
UNUSED(J);
|
|
193
|
+
if (op == BC_JMP)
|
|
194
|
+
return; /* No need to unpatch branches in parent traces (yet). */
|
|
195
|
+
switch (bc_op(*pc)) {
|
|
196
|
+
case BC_JFORL:
|
|
197
|
+
lua_assert(traceref(J, bc_d(*pc)) == T);
|
|
198
|
+
*pc = T->startins;
|
|
199
|
+
pc += bc_j(T->startins);
|
|
200
|
+
lua_assert(bc_op(*pc) == BC_JFORI);
|
|
201
|
+
setbc_op(pc, BC_FORI);
|
|
202
|
+
break;
|
|
203
|
+
case BC_JITERL:
|
|
204
|
+
case BC_JLOOP:
|
|
205
|
+
lua_assert(op == BC_ITERL || op == BC_LOOP || bc_isret(op));
|
|
206
|
+
*pc = T->startins;
|
|
207
|
+
break;
|
|
208
|
+
case BC_JMP:
|
|
209
|
+
lua_assert(op == BC_ITERL);
|
|
210
|
+
pc += bc_j(*pc)+2;
|
|
211
|
+
if (bc_op(*pc) == BC_JITERL) {
|
|
212
|
+
lua_assert(traceref(J, bc_d(*pc)) == T);
|
|
213
|
+
*pc = T->startins;
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
case BC_JFUNCF:
|
|
217
|
+
lua_assert(op == BC_FUNCF);
|
|
218
|
+
*pc = T->startins;
|
|
219
|
+
break;
|
|
220
|
+
default: /* Already unpatched. */
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Flush a root trace. */
|
|
226
|
+
static void trace_flushroot(jit_State *J, GCtrace *T)
|
|
227
|
+
{
|
|
228
|
+
GCproto *pt = &gcref(T->startpt)->pt;
|
|
229
|
+
lua_assert(T->root == 0 && pt != NULL);
|
|
230
|
+
/* First unpatch any modified bytecode. */
|
|
231
|
+
trace_unpatch(J, T);
|
|
232
|
+
/* Unlink root trace from chain anchored in prototype. */
|
|
233
|
+
if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
|
|
234
|
+
pt->trace = T->nextroot;
|
|
235
|
+
} else if (pt->trace) { /* Otherwise search in chain of root traces. */
|
|
236
|
+
GCtrace *T2 = traceref(J, pt->trace);
|
|
237
|
+
if (T2) {
|
|
238
|
+
for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
|
|
239
|
+
if (T2->nextroot == T->traceno) {
|
|
240
|
+
T2->nextroot = T->nextroot; /* Unlink from chain. */
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Flush a trace. Only root traces are considered. */
|
|
248
|
+
void lj_trace_flush(jit_State *J, TraceNo traceno)
|
|
249
|
+
{
|
|
250
|
+
if (traceno > 0 && traceno < J->sizetrace) {
|
|
251
|
+
GCtrace *T = traceref(J, traceno);
|
|
252
|
+
if (T && T->root == 0)
|
|
253
|
+
trace_flushroot(J, T);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/* Flush all traces associated with a prototype. */
|
|
258
|
+
void lj_trace_flushproto(global_State *g, GCproto *pt)
|
|
259
|
+
{
|
|
260
|
+
while (pt->trace != 0)
|
|
261
|
+
trace_flushroot(G2J(g), traceref(G2J(g), pt->trace));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Flush all traces. */
|
|
265
|
+
int lj_trace_flushall(lua_State *L)
|
|
266
|
+
{
|
|
267
|
+
jit_State *J = L2J(L);
|
|
268
|
+
ptrdiff_t i;
|
|
269
|
+
if ((J2G(J)->hookmask & HOOK_GC))
|
|
270
|
+
return 1;
|
|
271
|
+
for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
|
|
272
|
+
GCtrace *T = traceref(J, i);
|
|
273
|
+
if (T) {
|
|
274
|
+
if (T->root == 0)
|
|
275
|
+
trace_flushroot(J, T);
|
|
276
|
+
lj_gdbjit_deltrace(J, T);
|
|
277
|
+
T->traceno = 0;
|
|
278
|
+
setgcrefnull(J->trace[i]);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
J->cur.traceno = 0;
|
|
282
|
+
J->freetrace = 0;
|
|
283
|
+
/* Clear penalty cache. */
|
|
284
|
+
memset(J->penalty, 0, sizeof(J->penalty));
|
|
285
|
+
/* Free the whole machine code and invalidate all exit stub groups. */
|
|
286
|
+
lj_mcode_free(J);
|
|
287
|
+
memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
|
|
288
|
+
lj_vmevent_send(L, TRACE,
|
|
289
|
+
setstrV(L, L->top++, lj_str_newlit(L, "flush"));
|
|
290
|
+
);
|
|
291
|
+
return 0;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Initialize JIT compiler state. */
|
|
295
|
+
void lj_trace_initstate(global_State *g)
|
|
296
|
+
{
|
|
297
|
+
jit_State *J = G2J(g);
|
|
298
|
+
TValue *tv;
|
|
299
|
+
/* Initialize SIMD constants. */
|
|
300
|
+
tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
|
|
301
|
+
tv[0].u64 = U64x(7fffffff,ffffffff);
|
|
302
|
+
tv[1].u64 = U64x(7fffffff,ffffffff);
|
|
303
|
+
tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
|
|
304
|
+
tv[0].u64 = U64x(80000000,00000000);
|
|
305
|
+
tv[1].u64 = U64x(80000000,00000000);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* Free everything associated with the JIT compiler state. */
|
|
309
|
+
void lj_trace_freestate(global_State *g)
|
|
310
|
+
{
|
|
311
|
+
jit_State *J = G2J(g);
|
|
312
|
+
#ifdef LUA_USE_ASSERT
|
|
313
|
+
{ /* This assumes all traces have already been freed. */
|
|
314
|
+
ptrdiff_t i;
|
|
315
|
+
for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
|
|
316
|
+
lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL);
|
|
317
|
+
}
|
|
318
|
+
#endif
|
|
319
|
+
lj_mcode_free(J);
|
|
320
|
+
lj_ir_k64_freeall(J);
|
|
321
|
+
lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
|
|
322
|
+
lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
|
|
323
|
+
lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
|
|
324
|
+
lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* -- Penalties and blacklisting ------------------------------------------ */
|
|
328
|
+
|
|
329
|
+
/* Blacklist a bytecode instruction. */
|
|
330
|
+
static void blacklist_pc(GCproto *pt, BCIns *pc)
|
|
331
|
+
{
|
|
332
|
+
setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
|
|
333
|
+
pt->flags |= PROTO_ILOOP;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* Penalize a bytecode instruction. */
|
|
337
|
+
static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
|
|
338
|
+
{
|
|
339
|
+
uint32_t i, val = PENALTY_MIN;
|
|
340
|
+
for (i = 0; i < PENALTY_SLOTS; i++)
|
|
341
|
+
if (mref(J->penalty[i].pc, const BCIns) == pc) { /* Cache slot found? */
|
|
342
|
+
/* First try to bump its hotcount several times. */
|
|
343
|
+
val = ((uint32_t)J->penalty[i].val << 1) +
|
|
344
|
+
LJ_PRNG_BITS(J, PENALTY_RNDBITS);
|
|
345
|
+
if (val > PENALTY_MAX) {
|
|
346
|
+
blacklist_pc(pt, pc); /* Blacklist it, if that didn't help. */
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
goto setpenalty;
|
|
350
|
+
}
|
|
351
|
+
/* Assign a new penalty cache slot. */
|
|
352
|
+
i = J->penaltyslot;
|
|
353
|
+
J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1);
|
|
354
|
+
setmref(J->penalty[i].pc, pc);
|
|
355
|
+
setpenalty:
|
|
356
|
+
J->penalty[i].val = (uint16_t)val;
|
|
357
|
+
J->penalty[i].reason = e;
|
|
358
|
+
hotcount_set(J2GG(J), pc+1, val);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* -- Trace compiler state machine ---------------------------------------- */
|
|
362
|
+
|
|
363
|
+
/* Start tracing. */
|
|
364
|
+
static void trace_start(jit_State *J)
|
|
365
|
+
{
|
|
366
|
+
lua_State *L;
|
|
367
|
+
TraceNo traceno;
|
|
368
|
+
|
|
369
|
+
if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */
|
|
370
|
+
if (J->parent == 0 && J->exitno == 0) {
|
|
371
|
+
/* Lazy bytecode patching to disable hotcount events. */
|
|
372
|
+
lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
|
|
373
|
+
bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
|
|
374
|
+
setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
|
|
375
|
+
J->pt->flags |= PROTO_ILOOP;
|
|
376
|
+
}
|
|
377
|
+
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* Get a new trace number. */
|
|
382
|
+
traceno = trace_findfree(J);
|
|
383
|
+
if (LJ_UNLIKELY(traceno == 0)) { /* No free trace? */
|
|
384
|
+
lua_assert((J2G(J)->hookmask & HOOK_GC) == 0);
|
|
385
|
+
lj_trace_flushall(J->L);
|
|
386
|
+
J->state = LJ_TRACE_IDLE; /* Silently ignored. */
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
setgcrefp(J->trace[traceno], &J->cur);
|
|
390
|
+
|
|
391
|
+
/* Setup enough of the current trace to be able to send the vmevent. */
|
|
392
|
+
memset(&J->cur, 0, sizeof(GCtrace));
|
|
393
|
+
J->cur.traceno = traceno;
|
|
394
|
+
J->cur.nins = J->cur.nk = REF_BASE;
|
|
395
|
+
J->cur.ir = J->irbuf;
|
|
396
|
+
J->cur.snap = J->snapbuf;
|
|
397
|
+
J->cur.snapmap = J->snapmapbuf;
|
|
398
|
+
J->mergesnap = 0;
|
|
399
|
+
J->needsnap = 0;
|
|
400
|
+
J->bcskip = 0;
|
|
401
|
+
J->guardemit.irt = 0;
|
|
402
|
+
J->postproc = LJ_POST_NONE;
|
|
403
|
+
lj_resetsplit(J);
|
|
404
|
+
J->retryrec = 0;
|
|
405
|
+
setgcref(J->cur.startpt, obj2gco(J->pt));
|
|
406
|
+
|
|
407
|
+
L = J->L;
|
|
408
|
+
lj_vmevent_send(L, TRACE,
|
|
409
|
+
setstrV(L, L->top++, lj_str_newlit(L, "start"));
|
|
410
|
+
setintV(L->top++, traceno);
|
|
411
|
+
setfuncV(L, L->top++, J->fn);
|
|
412
|
+
setintV(L->top++, proto_bcpos(J->pt, J->pc));
|
|
413
|
+
if (J->parent) {
|
|
414
|
+
setintV(L->top++, J->parent);
|
|
415
|
+
setintV(L->top++, J->exitno);
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
lj_record_setup(J);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* Stop tracing. */
|
|
422
|
+
static void trace_stop(jit_State *J)
|
|
423
|
+
{
|
|
424
|
+
BCIns *pc = mref(J->cur.startpc, BCIns);
|
|
425
|
+
BCOp op = bc_op(J->cur.startins);
|
|
426
|
+
GCproto *pt = &gcref(J->cur.startpt)->pt;
|
|
427
|
+
TraceNo traceno = J->cur.traceno;
|
|
428
|
+
GCtrace *T = trace_save_alloc(J); /* Do this first. May throw OOM. */
|
|
429
|
+
lua_State *L;
|
|
430
|
+
|
|
431
|
+
switch (op) {
|
|
432
|
+
case BC_FORL:
|
|
433
|
+
setbc_op(pc+bc_j(J->cur.startins), BC_JFORI); /* Patch FORI, too. */
|
|
434
|
+
/* fallthrough */
|
|
435
|
+
case BC_LOOP:
|
|
436
|
+
case BC_ITERL:
|
|
437
|
+
case BC_FUNCF:
|
|
438
|
+
/* Patch bytecode of starting instruction in root trace. */
|
|
439
|
+
setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP);
|
|
440
|
+
setbc_d(pc, traceno);
|
|
441
|
+
addroot:
|
|
442
|
+
/* Add to root trace chain in prototype. */
|
|
443
|
+
J->cur.nextroot = pt->trace;
|
|
444
|
+
pt->trace = (TraceNo1)traceno;
|
|
445
|
+
break;
|
|
446
|
+
case BC_RET:
|
|
447
|
+
case BC_RET0:
|
|
448
|
+
case BC_RET1:
|
|
449
|
+
*pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno);
|
|
450
|
+
goto addroot;
|
|
451
|
+
case BC_JMP:
|
|
452
|
+
/* Patch exit branch in parent to side trace entry. */
|
|
453
|
+
lua_assert(J->parent != 0 && J->cur.root != 0);
|
|
454
|
+
lj_asm_patchexit(J, traceref(J, J->parent), J->exitno, J->cur.mcode);
|
|
455
|
+
/* Avoid compiling a side trace twice (stack resizing uses parent exit). */
|
|
456
|
+
traceref(J, J->parent)->snap[J->exitno].count = SNAPCOUNT_DONE;
|
|
457
|
+
/* Add to side trace chain in root trace. */
|
|
458
|
+
{
|
|
459
|
+
GCtrace *root = traceref(J, J->cur.root);
|
|
460
|
+
root->nchild++;
|
|
461
|
+
J->cur.nextside = root->nextside;
|
|
462
|
+
root->nextside = (TraceNo1)traceno;
|
|
463
|
+
}
|
|
464
|
+
break;
|
|
465
|
+
case BC_CALLM:
|
|
466
|
+
case BC_CALL:
|
|
467
|
+
case BC_ITERC:
|
|
468
|
+
/* Trace stitching: patch link of previous trace. */
|
|
469
|
+
traceref(J, J->exitno)->link = traceno;
|
|
470
|
+
break;
|
|
471
|
+
default:
|
|
472
|
+
lua_assert(0);
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* Commit new mcode only after all patching is done. */
|
|
477
|
+
lj_mcode_commit(J, J->cur.mcode);
|
|
478
|
+
J->postproc = LJ_POST_NONE;
|
|
479
|
+
trace_save(J, T);
|
|
480
|
+
|
|
481
|
+
L = J->L;
|
|
482
|
+
lj_vmevent_send(L, TRACE,
|
|
483
|
+
setstrV(L, L->top++, lj_str_newlit(L, "stop"));
|
|
484
|
+
setintV(L->top++, traceno);
|
|
485
|
+
setfuncV(L, L->top++, J->fn);
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/* Start a new root trace for down-recursion. */
|
|
490
|
+
static int trace_downrec(jit_State *J)
|
|
491
|
+
{
|
|
492
|
+
/* Restart recording at the return instruction. */
|
|
493
|
+
lua_assert(J->pt != NULL);
|
|
494
|
+
lua_assert(bc_isret(bc_op(*J->pc)));
|
|
495
|
+
if (bc_op(*J->pc) == BC_RETM)
|
|
496
|
+
return 0; /* NYI: down-recursion with RETM. */
|
|
497
|
+
J->parent = 0;
|
|
498
|
+
J->exitno = 0;
|
|
499
|
+
J->state = LJ_TRACE_RECORD;
|
|
500
|
+
trace_start(J);
|
|
501
|
+
return 1;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/* Abort tracing. */
|
|
505
|
+
static int trace_abort(jit_State *J)
|
|
506
|
+
{
|
|
507
|
+
lua_State *L = J->L;
|
|
508
|
+
TraceError e = LJ_TRERR_RECERR;
|
|
509
|
+
TraceNo traceno;
|
|
510
|
+
|
|
511
|
+
J->postproc = LJ_POST_NONE;
|
|
512
|
+
lj_mcode_abort(J);
|
|
513
|
+
if (tvisnumber(L->top-1))
|
|
514
|
+
e = (TraceError)numberVint(L->top-1);
|
|
515
|
+
if (e == LJ_TRERR_MCODELM) {
|
|
516
|
+
L->top--; /* Remove error object */
|
|
517
|
+
J->state = LJ_TRACE_ASM;
|
|
518
|
+
return 1; /* Retry ASM with new MCode area. */
|
|
519
|
+
}
|
|
520
|
+
/* Penalize or blacklist starting bytecode instruction. */
|
|
521
|
+
if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) {
|
|
522
|
+
if (J->exitno == 0) {
|
|
523
|
+
BCIns *startpc = mref(J->cur.startpc, BCIns);
|
|
524
|
+
if (e == LJ_TRERR_RETRY)
|
|
525
|
+
hotcount_set(J2GG(J), startpc+1, 1); /* Immediate retry. */
|
|
526
|
+
else
|
|
527
|
+
penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e);
|
|
528
|
+
} else {
|
|
529
|
+
traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/* Is there anything to abort? */
|
|
534
|
+
traceno = J->cur.traceno;
|
|
535
|
+
if (traceno) {
|
|
536
|
+
ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */
|
|
537
|
+
J->cur.link = 0;
|
|
538
|
+
J->cur.linktype = LJ_TRLINK_NONE;
|
|
539
|
+
lj_vmevent_send(L, TRACE,
|
|
540
|
+
TValue *frame;
|
|
541
|
+
const BCIns *pc;
|
|
542
|
+
GCfunc *fn;
|
|
543
|
+
setstrV(L, L->top++, lj_str_newlit(L, "abort"));
|
|
544
|
+
setintV(L->top++, traceno);
|
|
545
|
+
/* Find original Lua function call to generate a better error message. */
|
|
546
|
+
frame = J->L->base-1;
|
|
547
|
+
pc = J->pc;
|
|
548
|
+
while (!isluafunc(frame_func(frame))) {
|
|
549
|
+
pc = (frame_iscont(frame) ? frame_contpc(frame) : frame_pc(frame)) - 1;
|
|
550
|
+
frame = frame_prev(frame);
|
|
551
|
+
}
|
|
552
|
+
fn = frame_func(frame);
|
|
553
|
+
setfuncV(L, L->top++, fn);
|
|
554
|
+
setintV(L->top++, proto_bcpos(funcproto(fn), pc));
|
|
555
|
+
copyTV(L, L->top++, restorestack(L, errobj));
|
|
556
|
+
copyTV(L, L->top++, &J->errinfo);
|
|
557
|
+
);
|
|
558
|
+
/* Drop aborted trace after the vmevent (which may still access it). */
|
|
559
|
+
setgcrefnull(J->trace[traceno]);
|
|
560
|
+
if (traceno < J->freetrace)
|
|
561
|
+
J->freetrace = traceno;
|
|
562
|
+
J->cur.traceno = 0;
|
|
563
|
+
}
|
|
564
|
+
L->top--; /* Remove error object */
|
|
565
|
+
if (e == LJ_TRERR_DOWNREC)
|
|
566
|
+
return trace_downrec(J);
|
|
567
|
+
else if (e == LJ_TRERR_MCODEAL)
|
|
568
|
+
lj_trace_flushall(L);
|
|
569
|
+
return 0;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/* Perform pending re-patch of a bytecode instruction. */
|
|
573
|
+
static LJ_AINLINE void trace_pendpatch(jit_State *J, int force)
|
|
574
|
+
{
|
|
575
|
+
if (LJ_UNLIKELY(J->patchpc)) {
|
|
576
|
+
if (force || J->bcskip == 0) {
|
|
577
|
+
*J->patchpc = J->patchins;
|
|
578
|
+
J->patchpc = NULL;
|
|
579
|
+
} else {
|
|
580
|
+
J->bcskip = 0;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/* State machine for the trace compiler. Protected callback. */
|
|
586
|
+
static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
|
|
587
|
+
{
|
|
588
|
+
jit_State *J = (jit_State *)ud;
|
|
589
|
+
UNUSED(dummy);
|
|
590
|
+
do {
|
|
591
|
+
retry:
|
|
592
|
+
switch (J->state) {
|
|
593
|
+
case LJ_TRACE_START:
|
|
594
|
+
J->state = LJ_TRACE_RECORD; /* trace_start() may change state. */
|
|
595
|
+
trace_start(J);
|
|
596
|
+
lj_dispatch_update(J2G(J));
|
|
597
|
+
break;
|
|
598
|
+
|
|
599
|
+
case LJ_TRACE_RECORD:
|
|
600
|
+
trace_pendpatch(J, 0);
|
|
601
|
+
setvmstate(J2G(J), RECORD);
|
|
602
|
+
lj_vmevent_send_(L, RECORD,
|
|
603
|
+
/* Save/restore tmptv state for trace recorder. */
|
|
604
|
+
TValue savetv = J2G(J)->tmptv;
|
|
605
|
+
TValue savetv2 = J2G(J)->tmptv2;
|
|
606
|
+
setintV(L->top++, J->cur.traceno);
|
|
607
|
+
setfuncV(L, L->top++, J->fn);
|
|
608
|
+
setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
|
|
609
|
+
setintV(L->top++, J->framedepth);
|
|
610
|
+
,
|
|
611
|
+
J2G(J)->tmptv = savetv;
|
|
612
|
+
J2G(J)->tmptv2 = savetv2;
|
|
613
|
+
);
|
|
614
|
+
lj_record_ins(J);
|
|
615
|
+
break;
|
|
616
|
+
|
|
617
|
+
case LJ_TRACE_END:
|
|
618
|
+
trace_pendpatch(J, 1);
|
|
619
|
+
J->loopref = 0;
|
|
620
|
+
if ((J->flags & JIT_F_OPT_LOOP) &&
|
|
621
|
+
J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
|
|
622
|
+
setvmstate(J2G(J), OPT);
|
|
623
|
+
lj_opt_dce(J);
|
|
624
|
+
if (lj_opt_loop(J)) { /* Loop optimization failed? */
|
|
625
|
+
J->cur.link = 0;
|
|
626
|
+
J->cur.linktype = LJ_TRLINK_NONE;
|
|
627
|
+
J->loopref = J->cur.nins;
|
|
628
|
+
J->state = LJ_TRACE_RECORD; /* Try to continue recording. */
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
J->loopref = J->chain[IR_LOOP]; /* Needed by assembler. */
|
|
632
|
+
}
|
|
633
|
+
lj_opt_split(J);
|
|
634
|
+
lj_opt_sink(J);
|
|
635
|
+
if (!J->loopref) J->cur.snap[J->cur.nsnap-1].count = SNAPCOUNT_DONE;
|
|
636
|
+
J->state = LJ_TRACE_ASM;
|
|
637
|
+
break;
|
|
638
|
+
|
|
639
|
+
case LJ_TRACE_ASM:
|
|
640
|
+
setvmstate(J2G(J), ASM);
|
|
641
|
+
lj_asm_trace(J, &J->cur);
|
|
642
|
+
trace_stop(J);
|
|
643
|
+
setvmstate(J2G(J), INTERP);
|
|
644
|
+
J->state = LJ_TRACE_IDLE;
|
|
645
|
+
lj_dispatch_update(J2G(J));
|
|
646
|
+
return NULL;
|
|
647
|
+
|
|
648
|
+
default: /* Trace aborted asynchronously. */
|
|
649
|
+
setintV(L->top++, (int32_t)LJ_TRERR_RECERR);
|
|
650
|
+
/* fallthrough */
|
|
651
|
+
case LJ_TRACE_ERR:
|
|
652
|
+
trace_pendpatch(J, 1);
|
|
653
|
+
if (trace_abort(J))
|
|
654
|
+
goto retry;
|
|
655
|
+
setvmstate(J2G(J), INTERP);
|
|
656
|
+
J->state = LJ_TRACE_IDLE;
|
|
657
|
+
lj_dispatch_update(J2G(J));
|
|
658
|
+
return NULL;
|
|
659
|
+
}
|
|
660
|
+
} while (J->state > LJ_TRACE_RECORD);
|
|
661
|
+
return NULL;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/* -- Event handling ------------------------------------------------------ */
|
|
665
|
+
|
|
666
|
+
/* A bytecode instruction is about to be executed. Record it. */
|
|
667
|
+
void lj_trace_ins(jit_State *J, const BCIns *pc)
|
|
668
|
+
{
|
|
669
|
+
/* Note: J->L must already be set. pc is the true bytecode PC here. */
|
|
670
|
+
J->pc = pc;
|
|
671
|
+
J->fn = curr_func(J->L);
|
|
672
|
+
J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL;
|
|
673
|
+
while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0)
|
|
674
|
+
J->state = LJ_TRACE_ERR;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/* A hotcount triggered. Start recording a root trace. */
|
|
678
|
+
void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc)
|
|
679
|
+
{
|
|
680
|
+
/* Note: pc is the interpreter bytecode PC here. It's offset by 1. */
|
|
681
|
+
ERRNO_SAVE
|
|
682
|
+
/* Reset hotcount. */
|
|
683
|
+
hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]*HOTCOUNT_LOOP);
|
|
684
|
+
/* Only start a new trace if not recording or inside __gc call or vmevent. */
|
|
685
|
+
if (J->state == LJ_TRACE_IDLE &&
|
|
686
|
+
!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
|
|
687
|
+
J->parent = 0; /* Root trace. */
|
|
688
|
+
J->exitno = 0;
|
|
689
|
+
J->state = LJ_TRACE_START;
|
|
690
|
+
lj_trace_ins(J, pc-1);
|
|
691
|
+
}
|
|
692
|
+
ERRNO_RESTORE
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/* Check for a hot side exit. If yes, start recording a side trace. */
|
|
696
|
+
static void trace_hotside(jit_State *J, const BCIns *pc)
|
|
697
|
+
{
|
|
698
|
+
SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
|
|
699
|
+
if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
|
|
700
|
+
isluafunc(curr_func(J->L)) &&
|
|
701
|
+
snap->count != SNAPCOUNT_DONE &&
|
|
702
|
+
++snap->count >= J->param[JIT_P_hotexit]) {
|
|
703
|
+
lua_assert(J->state == LJ_TRACE_IDLE);
|
|
704
|
+
/* J->parent is non-zero for a side trace. */
|
|
705
|
+
J->state = LJ_TRACE_START;
|
|
706
|
+
lj_trace_ins(J, pc);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* Stitch a new trace to the previous trace. */
|
|
711
|
+
void LJ_FASTCALL lj_trace_stitch(jit_State *J, const BCIns *pc)
|
|
712
|
+
{
|
|
713
|
+
/* Only start a new trace if not recording or inside __gc call or vmevent. */
|
|
714
|
+
if (J->state == LJ_TRACE_IDLE &&
|
|
715
|
+
!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
|
|
716
|
+
J->parent = 0; /* Have to treat it like a root trace. */
|
|
717
|
+
/* J->exitno is set to the invoking trace. */
|
|
718
|
+
J->state = LJ_TRACE_START;
|
|
719
|
+
lj_trace_ins(J, pc);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
/* Tiny struct to pass data to protected call. */
|
|
725
|
+
typedef struct ExitDataCP {
|
|
726
|
+
jit_State *J;
|
|
727
|
+
void *exptr; /* Pointer to exit state. */
|
|
728
|
+
const BCIns *pc; /* Restart interpreter at this PC. */
|
|
729
|
+
} ExitDataCP;
|
|
730
|
+
|
|
731
|
+
/* Need to protect lj_snap_restore because it may throw. */
|
|
732
|
+
static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|
733
|
+
{
|
|
734
|
+
ExitDataCP *exd = (ExitDataCP *)ud;
|
|
735
|
+
cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
|
|
736
|
+
exd->pc = lj_snap_restore(exd->J, exd->exptr);
|
|
737
|
+
UNUSED(dummy);
|
|
738
|
+
return NULL;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
#ifndef LUAJIT_DISABLE_VMEVENT
|
|
742
|
+
/* Push all registers from exit state. */
|
|
743
|
+
static void trace_exit_regs(lua_State *L, ExitState *ex)
|
|
744
|
+
{
|
|
745
|
+
int32_t i;
|
|
746
|
+
setintV(L->top++, RID_NUM_GPR);
|
|
747
|
+
setintV(L->top++, RID_NUM_FPR);
|
|
748
|
+
for (i = 0; i < RID_NUM_GPR; i++) {
|
|
749
|
+
if (sizeof(ex->gpr[i]) == sizeof(int32_t))
|
|
750
|
+
setintV(L->top++, (int32_t)ex->gpr[i]);
|
|
751
|
+
else
|
|
752
|
+
setnumV(L->top++, (lua_Number)ex->gpr[i]);
|
|
753
|
+
}
|
|
754
|
+
#if !LJ_SOFTFP
|
|
755
|
+
for (i = 0; i < RID_NUM_FPR; i++) {
|
|
756
|
+
setnumV(L->top, ex->fpr[i]);
|
|
757
|
+
if (LJ_UNLIKELY(tvisnan(L->top)))
|
|
758
|
+
setnanV(L->top);
|
|
759
|
+
L->top++;
|
|
760
|
+
}
|
|
761
|
+
#endif
|
|
762
|
+
}
|
|
763
|
+
#endif
|
|
764
|
+
|
|
765
|
+
#ifdef EXITSTATE_PCREG
|
|
766
|
+
/* Determine trace number from pc of exit instruction. */
|
|
767
|
+
static TraceNo trace_exit_find(jit_State *J, MCode *pc)
|
|
768
|
+
{
|
|
769
|
+
TraceNo traceno;
|
|
770
|
+
for (traceno = 1; traceno < J->sizetrace; traceno++) {
|
|
771
|
+
GCtrace *T = traceref(J, traceno);
|
|
772
|
+
if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
|
|
773
|
+
return traceno;
|
|
774
|
+
}
|
|
775
|
+
lua_assert(0);
|
|
776
|
+
return 0;
|
|
777
|
+
}
|
|
778
|
+
#endif
|
|
779
|
+
|
|
780
|
+
/* A trace exited. Restore interpreter state. */
|
|
781
|
+
int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
|
|
782
|
+
{
|
|
783
|
+
ERRNO_SAVE
|
|
784
|
+
lua_State *L = J->L;
|
|
785
|
+
ExitState *ex = (ExitState *)exptr;
|
|
786
|
+
ExitDataCP exd;
|
|
787
|
+
int errcode;
|
|
788
|
+
const BCIns *pc;
|
|
789
|
+
void *cf;
|
|
790
|
+
GCtrace *T;
|
|
791
|
+
#ifdef EXITSTATE_PCREG
|
|
792
|
+
J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
|
|
793
|
+
#endif
|
|
794
|
+
T = traceref(J, J->parent); UNUSED(T);
|
|
795
|
+
#ifdef EXITSTATE_CHECKEXIT
|
|
796
|
+
if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */
|
|
797
|
+
lua_assert(T->root != 0);
|
|
798
|
+
J->exitno = T->ir[REF_BASE].op2;
|
|
799
|
+
J->parent = T->ir[REF_BASE].op1;
|
|
800
|
+
T = traceref(J, J->parent);
|
|
801
|
+
}
|
|
802
|
+
#endif
|
|
803
|
+
lua_assert(T != NULL && J->exitno < T->nsnap);
|
|
804
|
+
exd.J = J;
|
|
805
|
+
exd.exptr = exptr;
|
|
806
|
+
errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
|
|
807
|
+
if (errcode)
|
|
808
|
+
return -errcode; /* Return negated error code. */
|
|
809
|
+
|
|
810
|
+
if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)))
|
|
811
|
+
lj_vmevent_send(L, TEXIT,
|
|
812
|
+
lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
|
|
813
|
+
setintV(L->top++, J->parent);
|
|
814
|
+
setintV(L->top++, J->exitno);
|
|
815
|
+
trace_exit_regs(L, ex);
|
|
816
|
+
);
|
|
817
|
+
|
|
818
|
+
pc = exd.pc;
|
|
819
|
+
cf = cframe_raw(L->cframe);
|
|
820
|
+
setcframe_pc(cf, pc);
|
|
821
|
+
if (LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE)) {
|
|
822
|
+
/* Just exit to interpreter. */
|
|
823
|
+
} else if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
|
|
824
|
+
if (!(G(L)->hookmask & HOOK_GC))
|
|
825
|
+
lj_gc_step(L); /* Exited because of GC: drive GC forward. */
|
|
826
|
+
} else {
|
|
827
|
+
trace_hotside(J, pc);
|
|
828
|
+
}
|
|
829
|
+
if (bc_op(*pc) == BC_JLOOP) {
|
|
830
|
+
BCIns *retpc = &traceref(J, bc_d(*pc))->startins;
|
|
831
|
+
if (bc_isret(bc_op(*retpc))) {
|
|
832
|
+
if (J->state == LJ_TRACE_RECORD) {
|
|
833
|
+
J->patchins = *pc;
|
|
834
|
+
J->patchpc = (BCIns *)pc;
|
|
835
|
+
*J->patchpc = *retpc;
|
|
836
|
+
J->bcskip = 1;
|
|
837
|
+
} else {
|
|
838
|
+
pc = retpc;
|
|
839
|
+
setcframe_pc(cf, pc);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
/* Return MULTRES or 0. */
|
|
844
|
+
ERRNO_RESTORE
|
|
845
|
+
switch (bc_op(*pc)) {
|
|
846
|
+
case BC_CALLM: case BC_CALLMT:
|
|
847
|
+
return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) + LJ_FR2);
|
|
848
|
+
case BC_RETM:
|
|
849
|
+
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
|
|
850
|
+
case BC_TSETM:
|
|
851
|
+
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
|
|
852
|
+
default:
|
|
853
|
+
if (bc_op(*pc) >= BC_FUNCF)
|
|
854
|
+
return (int)((BCReg)(L->top - L->base) + 1);
|
|
855
|
+
return 0;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
#endif
|