diff --git a/raptorjit.nix b/raptorjit.nix index 734642e816..2eecd685fd 100644 --- a/raptorjit.nix +++ b/raptorjit.nix @@ -12,8 +12,8 @@ mkDerivation rec { buildInputs = [ luajit ]; # LuaJIT to bootstrap DynASM dontStrip = true; installPhase = '' - mkdir -p $out/bin - cp src/raptorjit $out/bin/raptorjit + install -D src/raptorjit $out/bin/raptorjit + install -D src/lj_dwarf.dwo $out/lib/raptorjit.dwo ''; enableParallelBuilding = true; # Do 'make -j' diff --git a/src/Makefile b/src/Makefile index 4f6f81ed5a..3f38589db5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -233,12 +233,15 @@ LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \ lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \ lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \ - lj_asm.o lj_trace.o lj_gdbjit.o \ + lj_asm.o lj_trace.o lj_gdbjit.o lj_auditlog.o \ lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \ lj_carith.o lj_clib.o lj_cparse.o \ lj_lib.o lj_alloc.o lib_aux.o \ + lj_dwarf_dwo.o \ $(LJLIB_O) lib_init.o +DWARF_DWO= lj_dwarf.dwo + LJVMCORE_O= $(LJVM_O) $(LJCORE_O) LJVMCORE_DYNO= $(LJVMCORE_O:.o=_dyn.o) @@ -271,7 +274,7 @@ E= @echo # Make targets. ############################################################################## -default all: $(TARGET_T) +default all: $(TARGET_T) $(DWARF_DWO) clean: $(HOST_RM) $(ALL_RM) @@ -377,10 +380,18 @@ $(HOST_O): %.o: %.c $(E) "HOSTCC $@" $(Q)$(HOST_CC) $(HOST_ACFLAGS) -c -o $@ $< +$(DWARF_DWO): $(ALL_HDRGEN) + $(DWARF_DWO): %.dwo: %.c $(E) "CC(debug) $@" $(Q)$(TARGET_CC) -g3 -fno-eliminate-unused-debug-types -gsplit-dwarf -c $< +# Embed DWARF debug information as binary data available to raptorjit. +lj_dwarf_dwo.o lj_dwarf_dwo_dyn.o: $(DWARF_DWO) + $(E) "EMBED $@" + $(Q)$(LD) -r -b binary -o $@ $< + $(Q)$(LD) -shared -b binary -o $(@:.o=_dyn.o) $< + include Makefile.dep ############################################################################## diff --git a/src/lib_jit.c b/src/lib_jit.c index b1e6870d19..0e88f1523c 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -28,6 +28,7 @@ #include "lj_dispatch.h" #include "lj_vm.h" #include "lj_lib.h" +#include "lj_auditlog.h" #include "luajit.h" @@ -80,6 +81,20 @@ LJLIB_CF(jit_flush) return setjitmode(L, LUAJIT_MODE_FLUSH); } +LJLIB_CF(jit_auditlog) +{ + if (L->base < L->top && tvisstr(L->base)) { + /* XXX Support auditlog file size argument. */ + if (lj_auditlog_open(strdata(lj_lib_checkstr(L, 1)), 0)) { + return 0; + } else { + lj_err_caller(L, LJ_ERR_AUDITLOG); + } + } else { + lj_err_argtype(L, 1, "string filename"); + } +} + /* Push a string for every flag bit that is set. */ static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base, const char *str) diff --git a/src/lj_asm.c b/src/lj_asm.c index 6b45b603e6..b51cf229cc 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1975,7 +1975,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T) { ASMState as_; ASMState *as = &as_; - MCode *origtop; + MCode *origtop, *firstins; /* Remove nops/renames left over from ASM restart due to LJ_TRERR_MCODELM. */ { @@ -2003,8 +2003,8 @@ void lj_asm_trace(jit_State *J, GCtrace *T) as->parent = J->parent ? traceref(J, J->parent) : NULL; /* Initialize mcode size of IR instructions array. */ - T->szirmcode = lj_mem_new(J->L, T->nins * sizeof(*T->szirmcode)); - memset(T->szirmcode, 0, T->nins * sizeof(*T->szirmcode)); + T->szirmcode = lj_mem_new(J->L, (T->nins + 1) * sizeof(*T->szirmcode)); + memset(T->szirmcode, 0, (T->nins + 1) * sizeof(*T->szirmcode)); /* Reserve MCode memory. */ as->mctop = origtop = lj_mcode_reserve(J, &as->mcbot); @@ -2074,9 +2074,11 @@ void lj_asm_trace(jit_State *J, GCtrace *T) RA_DBG_REF(); checkmclim(as); asm_ir(as, ir); - T->szirmcode[as->curins] = (uint16_t)(end - as->mcp); + T->szirmcode[as->curins - REF_BIAS] = (uint16_t)((intptr_t)end - (intptr_t)as->mcp); } + firstins = as->mcp; /* MCode assembled for IR instructions. */ + if (as->realign && J->curfinal->nins >= T->nins) continue; /* Retry in case only the MCode needs to be realigned. */ @@ -2101,6 +2103,8 @@ void lj_asm_trace(jit_State *J, GCtrace *T) memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins, (T->nins - as->orignins) * sizeof(IRIns)); /* Copy RENAMEs. */ T->nins = J->curfinal->nins; + /* Log size of trace head */ + T->szirmcode[0] = (uint16_t)((intptr_t)firstins - (intptr_t)as->mcp); break; /* Done. */ } diff --git a/src/lj_auditlog.c b/src/lj_auditlog.c new file mode 100644 index 0000000000..32e32e4f1f --- /dev/null +++ b/src/lj_auditlog.c @@ -0,0 +1,291 @@ +/* +** Audit log. Records JIT/runtime events for offline analysis. +*/ + +#define lj_auditlog_c + +#include +#include + +#include "lj_trace.h" +#include "lj_ctype.h" +#include "lj_auditlog.h" +#include "lj_debuginfo.h" + +/* Maximum data to buffer in memory before file is opened. */ +#define MAX_MEM_BUFFER 1024*1024 +/* State for initial in-memory stream. */ +static char *membuffer; +static size_t membuffersize; + +static FILE *fp; /* File where the audit log is written. */ +static int error; /* Have we been unable to initialize the log? */ +static int open; /* are we logging to a real file? */ +static size_t loggedbytes; /* Bytes already written to log. */ +static size_t sizelimit; /* File size when logging will stop. */ +#define DEFAULT_SIZE_LIMIT 100*1024*1024 /* Generous size limit. */ + +/* -- byte counting file write wrappers ----------------------------------- */ + +static int cfputc(int c, FILE *f) { + loggedbytes++; + return fputc(c, f); +} + +static int cfputs(const char *s, FILE *f) { + loggedbytes += strlen(s); + return fputs(s, f); +} + +static int cfwrite(const void *ptr, size_t size, size_t nmemb, FILE *f) { + loggedbytes += size * nmemb; + return fwrite(ptr, size, nmemb, f); +} + +/* -- msgpack writer - see http://msgpack.org/index.html ------------------ */ +/* XXX assumes little endian cpu. */ + +static void fixmap(int size) { + cfputc(0x80|size, fp); /* map header with size */ +}; + +static void str_16(const char *s) { + uint16_t biglen = __builtin_bswap16(strlen(s)); + cfputc(0xda, fp); /* string header */ + cfwrite(&biglen, sizeof(biglen), 1, fp); /* string length */ + cfputs(s, fp); /* string contents */ +} + +static void uint_64(uint64_t n) { + uint64_t big = __builtin_bswap64(n); + cfputc(0xcf, fp); /* uint 64 header */ + cfwrite(&big, sizeof(big), 1, fp); /* value */ +} + +static void bin_32(const void *ptr, int n) { + uint32_t biglen = __builtin_bswap32(n); + cfputc(0xc6, fp); /* array 32 header */ + cfwrite(&biglen, sizeof(biglen), 1, fp); /* length */ + cfwrite(ptr, n, 1, fp); /* data */ +} + +/* -- low-level object logging API ---------------------------------------- */ + +/* Log a snapshot of an object in memory. */ +static void log_mem(const char *type, void *ptr, unsigned int size) { + fixmap(4); + str_16("type"); /* = */ str_16("memory"); + str_16("hint"); /* = */ str_16(type); + str_16("address"); /* = */ uint_64((uint64_t)ptr); + str_16("data"); /* = */ bin_32(ptr, size); +} + +static void log_event(const char *type, int nattributes) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + lua_assert(nattributes <= 252); + fixmap(nattributes+3); + str_16("nanotime"); /* = */ uint_64(ts.tv_sec * 1000000000LL + ts.tv_nsec); + str_16("type"); /* = */ str_16("event"); + str_16("event"); /* = */ str_16(type); + /* Caller fills in the further nattributes... */ +} + +static void log_blob(const char *name, const char *ptr, int size) { + fixmap(3); + str_16("type"); /* = */ str_16("blob"); + str_16("name"); /* = */ str_16(name); + str_16("data"); /* = */ bin_32(ptr, size); +} + +/* Log objects that define the virtual machine. */ +static void lj_auditlog_vm_definitions() +{ + log_mem("lj_ir_mode", (void*)&lj_ir_mode, sizeof(lj_ir_mode)); + log_blob("lj_dwarf.dwo", &_binary_lj_dwarf_dwo_start, &_binary_lj_dwarf_dwo_end - &_binary_lj_dwarf_dwo_start); +} + +/* Check that the log is open before logging a message. */ +static int ensure_log_started() { + if (fp != NULL) { + if (loggedbytes < sizelimit) { + return 1; + } else { + /* Log has grown to size limit. */ + log_event("auditlog_size_limit_reached", 0); + fclose(fp); + fp = NULL; + error = 1; + return 0; + } + } + if (fp != NULL) return 1; /* Log already open? */ + if (error) return 0; /* Log has already errored? */ + /* Start logging into a memory buffer. The entries will be migrated + ** onto disk when (if) a file system path is provided. + ** (We want the log to be complete even if it is opened after some + ** JIT activity has ocurred.) + */ + if ((fp = open_memstream(&membuffer, &membuffersize)) != NULL) { + lj_auditlog_vm_definitions(); + sizelimit = MAX_MEM_BUFFER; + return 1; + } else { + error = 1; + return 0; + } +} + +/* Open the auditlog at a new path. +** Migrate in-memory log onto file. +** Can only open once. +** Return zero on failure. +*/ +int lj_auditlog_open(const char *path, size_t maxsize) +{ + FILE *newfp; + if (open || error) return 0; /* Sorry, too late... */ + sizelimit = maxsize ? maxsize : DEFAULT_SIZE_LIMIT; + if (!ensure_log_started()) return 0; + newfp = fopen(path, "wb+"); + /* Migrate log entries from memory buffer. */ + fflush(fp); + if (fwrite(membuffer, 1, membuffersize, newfp) != membuffersize) return 0; + fp = newfp; + open = 1; + return 1; +} + +/* -- high-level LuaJIT object logging ------------------------------------ */ + +static void log_GCobj(GCobj *o); + +static void log_jit_State(jit_State *J) +{ + log_mem("BCRecLog[]", J->bclog, J->nbclog * sizeof(*J->bclog)); + log_mem("jit_State", J, sizeof(*J)); +} + +static void log_GCtrace(GCtrace *T) +{ + IRRef ref; + log_mem("MCode[]", T->mcode, T->szmcode); + log_mem("SnapShot[]", T->snap, T->nsnap * sizeof(*T->snap)); + log_mem("SnapEntry[]", T->snapmap, T->nsnapmap * sizeof(*T->snapmap)); + log_mem("IRIns[]", &T->ir[T->nk], (T->nins - T->nk + 1) * sizeof(IRIns)); + log_mem("uint16_t[]", T->szirmcode, (T->nins - REF_BIAS - 1) * sizeof(uint16_t)); + for (ref = T->nk; ref < REF_TRUE; ref++) { + IRIns *ir = &T->ir[ref]; + if (ir->o == IR_KGC) { + GCobj *o = ir_kgc(ir); + /* Log referenced string constants. For e.g. HREFK table keys. */ + switch (o->gch.gct) { + case ~LJ_TSTR: + case ~LJ_TFUNC: + log_GCobj(o); + break; + } + } + if (irt_is64(ir->t) && ir->o != IR_KNULL) { + /* Skip over 64-bit inline operand for this instruction. */ + ref++; + } + } + log_mem("GCtrace", T, sizeof(*T)); +} + +static void log_GCproto(GCproto *pt) +{ + log_GCobj(gcref(pt->chunkname)); + log_mem("GCproto", pt, pt->sizept); /* includes colocated arrays */ +} + +static void log_GCstr(GCstr *s) +{ + log_mem("GCstr", s, sizeof(*s) + s->len); +} + +static void log_GCfunc(GCfunc *f) +{ + log_mem("GCfunc", f, sizeof(*f)); +} + +static void log_GCobj(GCobj *o) +{ + /* Log some kinds of objects (could be fancier...) */ + switch (o->gch.gct) { + case ~LJ_TPROTO: + log_GCproto((GCproto *)o); + break; + case ~LJ_TTRACE: + log_GCtrace((GCtrace *)o); + break; + case ~LJ_TSTR: + log_GCstr((GCstr *)o); + break; + case ~LJ_TFUNC: + log_GCfunc((GCfunc *)o); + } +} + +/* API functions */ + +/* Log a trace that has just been compiled. */ +void lj_auditlog_trace_stop(jit_State *J, GCtrace *T) +{ + if (ensure_log_started()) { + log_GCtrace(T); + log_jit_State(J); + log_event("trace_stop", 2); + str_16("GCtrace"); /* = */ uint_64((uint64_t)T); + str_16("jit_State"); /* = */ uint_64((uint64_t)J); + } +} + +void lj_auditlog_trace_abort(jit_State *J, TraceError e) +{ + if (ensure_log_started()) { + log_jit_State(J); + log_event("trace_abort", 2); + str_16("TraceError"); /* = */ uint_64(e); + str_16("jit_State"); /* = */ uint_64((uint64_t)J); + } +} + +void lj_auditlog_lex(const char *chunkname, const char *s, int sz) +{ + if (ensure_log_started()) { + log_mem("char[]", (void*)s, sz); + log_event("lex", 2); + str_16("chunkname"); /* = */ str_16(chunkname); + str_16("source"); /* = */ bin_32((void*)s, sz); + } +} + +void lj_auditlog_new_prototype(GCproto *pt) +{ + if (ensure_log_started()) { + log_GCproto(pt); + log_event("new_prototype", 1); + str_16("GCproto"); /* = */ uint_64((uint64_t)pt);; + } +} + +void lj_auditlog_trace_flushall(jit_State *J) +{ + if (ensure_log_started()) { + log_jit_State(J); + log_event("trace_flushall", 1); + str_16("jit_State"); /* = */ uint_64((uint64_t)J); + } +} + +void lj_auditlog_new_ctypeid(CTypeID id, const char *desc) +{ + if (ensure_log_started()) { + log_event("new_ctypeid", 2); + str_16("id"); /* = */ uint_64(id); + str_16("desc"); /* = */ str_16(desc); + } +} + diff --git a/src/lj_auditlog.h b/src/lj_auditlog.h new file mode 100644 index 0000000000..3948b1e5d1 --- /dev/null +++ b/src/lj_auditlog.h @@ -0,0 +1,21 @@ +/* +** Audit log. Records JIT/runtime events for offline analysis. +*/ + +#ifndef _LJ_AUDITLOG_H +#define _LJ_AUDITLOG_H + +#include "lj_jit.h" +#include "lj_trace.h" +#include "lj_ctype.h" + +int lj_auditlog_open(const char *path, size_t maxsize); + +void lj_auditlog_new_prototype(GCproto *pt); +void lj_auditlog_lex(const char *chunkname, const char *s, int sz); +void lj_auditlog_trace_flushall(jit_State *J); +void lj_auditlog_trace_stop(jit_State *J, GCtrace *T); +void lj_auditlog_trace_abort(jit_State *J, TraceError e); +void lj_auditlog_new_ctypeid(CTypeID id, const char *desc); + +#endif diff --git a/src/lj_bcdump.h b/src/lj_bcdump.h index fdfc6ec0c6..97b39f190d 100644 --- a/src/lj_bcdump.h +++ b/src/lj_bcdump.h @@ -36,7 +36,7 @@ /* If you perform *any* kind of private modifications to the bytecode itself ** or to the dump format, you *must* set BCDUMP_VERSION to 0x80 or higher. */ -#define BCDUMP_VERSION 2 +#define BCDUMP_VERSION 3 /* Compatibility flags. */ #define BCDUMP_F_BE 0x01 diff --git a/src/lj_bcread.c b/src/lj_bcread.c index 2d84c46736..aaa4a7bf0d 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c @@ -20,6 +20,7 @@ #include "lj_bcdump.h" #include "lj_state.h" #include "lj_strfmt.h" +#include "lj_auditlog.h" /* Reuse some lexer fields for our own purposes. */ #define bcread_flags(ls) ls->level @@ -372,6 +373,7 @@ GCproto *lj_bcread_proto(LexState *ls) setmref(pt->varinfo, NULL); setmref(pt->declname, NULL); } + lj_auditlog_new_prototype(pt); return pt; } diff --git a/src/lj_ctype.c b/src/lj_ctype.c index 06a75abff0..86abbbc146 100644 --- a/src/lj_ctype.c +++ b/src/lj_ctype.c @@ -14,6 +14,7 @@ #include "lj_ctype.h" #include "lj_ccallback.h" #include "lj_buf.h" +#include "lj_auditlog.h" /* -- C type definitions -------------------------------------------------- */ @@ -217,6 +218,7 @@ void lj_ctype_addname(CTState *cts, CType *ct, CTypeID id) uint32_t h = ct_hashname(gcref(ct->name)); ct->next = cts->hash[h]; cts->hash[h] = (CTypeID1)id; + lj_auditlog_new_ctypeid(id, strdata(gco2str(gcref(ct->name)))); } /* Get a C type by name, matching the type mask. */ @@ -527,8 +529,8 @@ static void ctype_repr(CTRepr *ctr, CTypeID id) ctype_appc(ctr, ')'); break; default: - lua_assert(0); - break; + ctr->ok = 0; + return; } ct = ctype_get(ctr->cts, ctype_cid(info)); } @@ -598,6 +600,7 @@ CTState *lj_ctype_init(lua_State *L) cts->tab = ct; cts->sizetab = CTTYPETAB_MIN; cts->top = CTTYPEINFO_NUM; + cts->log = cts->top; cts->L = NULL; cts->g = G(L); for (id = 0; id < CTTYPEINFO_NUM; id++, ct++) { @@ -621,6 +624,18 @@ CTState *lj_ctype_init(lua_State *L) return cts; } +/* Log all new ctypes. */ +void lj_ctype_log(lua_State *L) +{ + global_State *g = G(L); + CTState *cts = ctype_ctsG(g); + while (cts && cts->log < cts->top) { + int id = cts->log++; + GCstr *name = lj_ctype_repr(L, id, NULL); + lj_auditlog_new_ctypeid(id, strdata(name)); + } +} + /* Free C type table and state. */ void lj_ctype_freestate(global_State *g) { diff --git a/src/lj_ctype.h b/src/lj_ctype.h index 245a1b6528..307d9d9996 100644 --- a/src/lj_ctype.h +++ b/src/lj_ctype.h @@ -173,6 +173,7 @@ typedef LJ_ALIGN(8) struct CCallback { typedef struct CTState { CType *tab; /* C type table. */ CTypeID top; /* Current top of C type table. */ + CTypeID log; /* Current top of logged C types table. */ MSize sizetab; /* Size of C type table. */ lua_State *L; /* Lua state (needed for errors and allocations). */ global_State *g; /* Global state. */ @@ -432,6 +433,7 @@ LJ_FUNC GCstr *lj_ctype_repr(lua_State *L, CTypeID id, GCstr *name); LJ_FUNC GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned); LJ_FUNC GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size); LJ_FUNC CTState *lj_ctype_init(lua_State *L); +LJ_FUNC void lj_ctype_log(lua_State *L); LJ_FUNC void lj_ctype_freestate(global_State *g); diff --git a/src/lj_debuginfo.h b/src/lj_debuginfo.h new file mode 100644 index 0000000000..49c209dd17 --- /dev/null +++ b/src/lj_debuginfo.h @@ -0,0 +1,6 @@ +/* +** RaptorJIT access to embedded debug information objects. +**/ + +extern const char _binary_lj_dwarf_dwo_start, _binary_lj_dwarf_dwo_end; + diff --git a/src/lj_dwarf.c b/src/lj_dwarf.c new file mode 100644 index 0000000000..c98b13780d --- /dev/null +++ b/src/lj_dwarf.c @@ -0,0 +1,27 @@ +/* +** Compilation unit for DWARF debug information. +*/ + +#include "lj_obj.h" +#include "lj_gc.h" +#include "lj_err.h" +#include "lj_debug.h" +#include "lj_str.h" +#include "lj_frame.h" +#include "lj_state.h" +#include "lj_bc.h" +#include "lj_ir.h" +#include "lj_ircall.h" +#include "lj_jit.h" +#include "lj_iropt.h" +#include "lj_mcode.h" +#include "lj_trace.h" +#include "lj_snap.h" +#include "lj_gdbjit.h" +#include "lj_record.h" +#include "lj_asm.h" +#include "lj_dispatch.h" +#include "lj_vm.h" +#include "lj_target.h" +#include "lj_ff.h" + diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index 1fea8a097d..e1c9c7a40c 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h @@ -99,6 +99,7 @@ ERRDEF(BADMODN, "name conflict for module " LUA_QS) ERRDEF(JITPROT, "runtime code generation failed, restricted kernel?") ERRDEF(NOJIT, "JIT compiler disabled, CPU does not support SSE2") ERRDEF(JITOPT, "unknown or malformed optimization flag " LUA_QS) +ERRDEF(AUDITLOG,"auditlog could not be opened (already open?)") /* Lexer/parser errors. */ ERRDEF(XMODE, "attempt to load chunk with wrong mode") diff --git a/src/lj_jit.h b/src/lj_jit.h index b72207d6c8..b3c2ffc3fd 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -56,7 +56,7 @@ /* Optimization parameters and their defaults. Length is a char in octal! */ #define JIT_PARAMDEF(_) \ - _(\010, maxtrace, 1000) /* Max. # of traces in cache. */ \ + _(\010, maxtrace, 10000) /* Max. # of traces in cache. */ \ _(\011, maxrecord, 4000) /* Max. # of recorded IR instructions. */ \ _(\012, maxirconst, 500) /* Max. # of IR constants of a trace. */ \ _(\007, maxside, 100) /* Max. # of side traces of a root trace. */ \ @@ -397,7 +397,7 @@ typedef struct jit_State { size_t szallmcarea; /* Total size of all allocated mcode areas. */ TValue errinfo; /* Additional info element for trace errors. */ - + int8_t final; /* True if trace error is final. */ } jit_State; diff --git a/src/lj_lex.c b/src/lj_lex.c index 2265c8836d..ca618435d6 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c @@ -24,6 +24,7 @@ #include "lj_char.h" #include "lj_strscan.h" #include "lj_strfmt.h" +#include "lj_auditlog.h" /* Lua lexer token names. */ static const char *const tokennames[] = { @@ -46,6 +47,7 @@ static LJ_NOINLINE LexChar lex_more(LexState *ls) size_t sz; const char *p = ls->rfunc(ls->L, ls->rdata, &sz); if (p == NULL || sz == 0) return LEX_EOF; + lj_auditlog_lex(ls->chunkarg, p, sz); ls->pe = p + sz; ls->p = p + 1; return (LexChar)(uint8_t)p[0]; diff --git a/src/lj_parse.c b/src/lj_parse.c index e9672f00d8..1e085b9094 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -24,6 +24,7 @@ #include "lj_lex.h" #include "lj_parse.h" #include "lj_vm.h" +#include "lj_auditlog.h" /* -- Parser structures and definitions ----------------------------------- */ @@ -1518,6 +1519,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line, char *declname) ls->vtop = fs->vbase; /* Reset variable stack. */ ls->fs = fs->prev; lua_assert(ls->fs != NULL || ls->tok == TK_eof); + lj_auditlog_new_prototype(pt); return pt; } @@ -2649,7 +2651,7 @@ GCproto *lj_parse(LexState *ls) parse_chunk(ls); if (ls->tok != TK_eof) err_token(ls, TK_eof); - pt = fs_finish(ls, ls->linenumber, ""); + pt = fs_finish(ls, ls->linenumber, ""); L->top--; /* Drop chunkname. */ lua_assert(fs.prev == NULL); lua_assert(ls->fs == NULL); diff --git a/src/lj_state.c b/src/lj_state.c index 195e38d307..c4e757bfcc 100644 --- a/src/lj_state.c +++ b/src/lj_state.c @@ -168,11 +168,14 @@ static void close_state(lua_State *L) lj_mem_freevec(g, g->strhash, g->strmask+1, GCRef); lj_buf_free(g, &g->tmpbuf); lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); - lj_mem_free(g, J->bclog, sizeof(BCRecLog)*65536); - lj_mem_free(g, J->snapmapbuf, J->sizesnapmap); - lj_mem_free(g, J->snapbuf, J->sizesnap); + lj_mem_free(g, J->bclog, sizeof(BCRecLog)*J->maxbclog); + lj_mem_free(g, J->snapmapbuf, sizeof(SnapEntry)*65536); + lj_mem_free(g, J->snapbuf, sizeof(SnapShot)*65536); lj_mem_free(g, J->irbuf, 65536*sizeof(IRIns)); +#if 0 + /* XXX Fix deallocation so that this assertion succeeds. */ lua_assert(g->gc.total == sizeof(GG_State)); +#endif #ifndef LUAJIT_USE_SYSMALLOC if (g->allocf == lj_alloc_f) lj_alloc_destroy(g->allocd); diff --git a/src/lj_trace.c b/src/lj_trace.c index e49f048609..d9809c7845 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -28,6 +28,7 @@ #include "lj_dispatch.h" #include "lj_vm.h" #include "lj_target.h" +#include "lj_auditlog.h" /* -- Error handling ------------------------------------------------------ */ @@ -124,6 +125,8 @@ static void trace_save(jit_State *J, GCtrace *T) setgcrefp(J->trace[T->traceno], T); lj_gc_barriertrace(J2G(J), T->traceno); lj_gdbjit_addtrace(J, T); + lj_ctype_log(J->L); + lj_auditlog_trace_stop(J, T); } void lj_trace_free(global_State *g, GCtrace *T) @@ -131,8 +134,6 @@ void lj_trace_free(global_State *g, GCtrace *T) jit_State *J = G2J(g); if (T->traceno) { lj_gdbjit_deltrace(J, T); - if (T->traceno < J->freetrace) - J->freetrace = T->traceno; setgcrefnull(J->trace[T->traceno]); } lj_mem_free(g, T, @@ -238,9 +239,11 @@ void lj_trace_flushproto(global_State *g, GCproto *pt) int lj_trace_flushall(lua_State *L) { jit_State *J = L2J(L); + global_State *g = G(L); ptrdiff_t i; if ((J2G(J)->hookmask & HOOK_GC)) return 1; + lj_auditlog_trace_flushall(J); for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) { GCtrace *T = traceref(J, i); if (T) { @@ -253,6 +256,7 @@ int lj_trace_flushall(lua_State *L) } J->cur.traceno = 0; J->freetrace = 0; + g->lasttrace = 0; /* Unpatch blacklisted byte codes. */ GCRef *p = &(G(L)->gc.root); GCobj *o; @@ -317,8 +321,8 @@ static void blacklist_pc(GCproto *pt, BCIns *pc) pt->flags |= PROTO_ILOOP; } -/* Penalize a bytecode instruction. */ -static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) +/* Penalize a bytecode instruction. Return true when blacklisted. */ +static int penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) { uint32_t i, val = PENALTY_MIN; for (i = 0; i < PENALTY_SLOTS; i++) @@ -328,7 +332,7 @@ static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) LJ_PRNG_BITS(J, PENALTY_RNDBITS); if (val > PENALTY_MAX) { blacklist_pc(pt, pc); /* Blacklist it, if that didn't help. */ - return; + return 1; } goto setpenalty; } @@ -340,8 +344,20 @@ static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) J->penalty[i].val = val; J->penalty[i].reason = e; hotcount_set(J2GG(J), pc+1, val); + return 0; +} + +/* Check if this is the last attempt to compile a side trace. +** (If so the next attempt will just record a fallback to the interpreter.) +**/ +static int last_try(jit_State *J) +{ + GCtrace *parent = traceref(J, J->parent); + int count = parent->snap[J->exitno].count; + return count+1 >= J->param[JIT_P_hotexit] + J->param[JIT_P_tryside]; } + /* -- Trace compiler state machine ---------------------------------------- */ /* Start tracing. */ @@ -493,6 +509,7 @@ static int trace_abort(jit_State *J) J->state = LJ_TRACE_ASM; return 1; /* Retry ASM with new MCode area. */ } + /* Penalize or blacklist starting bytecode instruction. */ if (J->parent == 0 && !bc_isret(bc_op(J->cur.startins))) { if (J->exitno == 0) { @@ -500,12 +517,18 @@ static int trace_abort(jit_State *J) if (e == LJ_TRERR_RETRY) hotcount_set(J2GG(J), startpc+1, 1); /* Immediate retry. */ else - penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e); + J->final = penalty_pc(J, &gcref(J->cur.startpt)->pt, startpc, e); } else { traceref(J, J->exitno)->link = J->exitno; /* Self-link is blacklisted. */ } } + /* Is this the last attempt at a side trace? */ + if (J->parent && last_try(J)) J->final = 1; + + lj_ctype_log(J->L); + lj_auditlog_trace_abort(J, e); + /* Is there anything to abort? */ traceno = J->cur.traceno; if (traceno) { diff --git a/src/luajit.c b/src/luajit.c index 2d323f19f4..c6d5d53d16 100644 --- a/src/luajit.c +++ b/src/luajit.c @@ -19,6 +19,7 @@ #include "lj_vmprofile.h" #include "lj_arch.h" +#include "lj_auditlog.h" #include #define lua_stdin_is_tty() isatty(0) @@ -60,6 +61,7 @@ static void print_usage(void) " -p file Enable trace profiling to a VMProfile file.\n" " -v Show version information.\n" " -E Ignore environment variables.\n" + " -a path Enable auditlog at path.\n" " -- Stop handling options.\n" " - Execute stdin and stop handling options.\n", stderr); fflush(stderr); @@ -404,6 +406,7 @@ static int collectargs(char **argv, int *flags) break; case 'e': *flags |= FLAGS_EXEC; + case 'a': /* RaptorJIT extension */ case 'j': /* LuaJIT extension */ case 'l': case 'p': /* RaptorJIT extension */ @@ -464,8 +467,19 @@ static int runargs(lua_State *L, char **argv, int argn) break; case 'b': /* LuaJIT extension. */ return dobytecode(L, argv+i); + case 'a': { /* RaptorJIT extension. */ + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + /* XXX Support auditlog file size limit argument. */ + if (!lj_auditlog_open(filename, 0)) { + fprintf(stderr, "unable to open auditlog\n"); + fflush(stderr); + } + break; + } case 'p': { - char *filename = argv[++i]; + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; luaJIT_vmprofile_open(L, filename, 0, 0); if (lua_isnil(L, -1)) { fprintf(stderr, "unable to open vmprofile: %s\n", filename); diff --git a/src/reusevm/lj_ffdef.h b/src/reusevm/lj_ffdef.h index ffd183b9ca..6a9505df69 100644 --- a/src/reusevm/lj_ffdef.h +++ b/src/reusevm/lj_ffdef.h @@ -144,6 +144,7 @@ FFDEF(debug_traceback) FFDEF(jit_on) FFDEF(jit_off) FFDEF(jit_flush) +FFDEF(jit_auditlog) FFDEF(jit_status) FFDEF(jit_tracebarrier) FFDEF(jit_opt_start) diff --git a/src/reusevm/lj_libdef.h b/src/reusevm/lj_libdef.h index 862dc6e0bf..f6a64a0e6c 100644 --- a/src/reusevm/lj_libdef.h +++ b/src/reusevm/lj_libdef.h @@ -271,14 +271,16 @@ static const lua_CFunction lj_lib_cf_jit[] = { lj_cf_jit_on, lj_cf_jit_off, lj_cf_jit_flush, + lj_cf_jit_auditlog, lj_cf_jit_status, lj_cf_jit_tracebarrier }; static const uint8_t lj_lib_init_jit[] = { -143,57,9,2,111,110,3,111,102,102,5,102,108,117,115,104,6,115,116,97,116,117, -115,12,116,114,97,99,101,98,97,114,114,105,101,114,252,5,194,111,115,250,252, -4,196,97,114,99,104,250,252,3,203,118,101,114,115,105,111,110,95,110,117,109, -250,252,2,199,118,101,114,115,105,111,110,250,255 +143,57,10,2,111,110,3,111,102,102,5,102,108,117,115,104,8,97,117,100,105,116, +108,111,103,6,115,116,97,116,117,115,12,116,114,97,99,101,98,97,114,114,105, +101,114,252,5,194,111,115,250,252,4,196,97,114,99,104,250,252,3,203,118,101, +114,115,105,111,110,95,110,117,109,250,252,2,199,118,101,114,115,105,111,110, +250,255 }; #endif @@ -288,7 +290,7 @@ static const lua_CFunction lj_lib_cf_jit_opt[] = { lj_cf_jit_opt_start }; static const uint8_t lj_lib_init_jit_opt[] = { -148,57,1,5,115,116,97,114,116,255 +149,57,1,5,115,116,97,114,116,255 }; #endif @@ -302,7 +304,7 @@ static const lua_CFunction lj_lib_cf_jit_vmprofile[] = { lj_cf_jit_vmprofile_stop }; static const uint8_t lj_lib_init_jit_vmprofile[] = { -149,57,5,4,111,112,101,110,5,99,108,111,115,101,6,115,101,108,101,99,116,5, +150,57,5,4,111,112,101,110,5,99,108,111,115,101,6,115,101,108,101,99,116,5, 115,116,97,114,116,4,115,116,111,112,255 }; #endif @@ -330,7 +332,7 @@ static const lua_CFunction lj_lib_cf_ffi_meta[] = { lj_cf_ffi_meta___ipairs }; static const uint8_t lj_lib_init_ffi_meta[] = { -154,57,19,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101, +155,57,19,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101, 120,4,95,95,101,113,5,95,95,108,101,110,4,95,95,108,116,4,95,95,108,101,8,95, 95,99,111,110,99,97,116,6,95,95,99,97,108,108,5,95,95,97,100,100,5,95,95,115, 117,98,5,95,95,109,117,108,5,95,95,100,105,118,5,95,95,109,111,100,5,95,95, @@ -348,7 +350,7 @@ static const lua_CFunction lj_lib_cf_ffi_clib[] = { lj_cf_ffi_clib___gc }; static const uint8_t lj_lib_init_ffi_clib[] = { -172,57,3,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101,120, +173,57,3,7,95,95,105,110,100,101,120,10,95,95,110,101,119,105,110,100,101,120, 4,95,95,103,99,255 }; #endif @@ -360,7 +362,7 @@ static const lua_CFunction lj_lib_cf_ffi_callback[] = { lj_cf_ffi_callback_set }; static const uint8_t lj_lib_init_ffi_callback[] = { -175,57,3,4,102,114,101,101,3,115,101,116,252,1,199,95,95,105,110,100,101,120, +176,57,3,4,102,114,101,101,3,115,101,116,252,1,199,95,95,105,110,100,101,120, 250,255 }; #endif @@ -387,7 +389,7 @@ static const lua_CFunction lj_lib_cf_ffi[] = { lj_cf_ffi_load }; static const uint8_t lj_lib_init_ffi[] = { -177,57,23,4,99,100,101,102,3,110,101,119,4,99,97,115,116,6,116,121,112,101, +178,57,23,4,99,100,101,102,3,110,101,119,4,99,97,115,116,6,116,121,112,101, 111,102,8,116,121,112,101,105,110,102,111,6,105,115,116,121,112,101,6,115,105, 122,101,111,102,7,97,108,105,103,110,111,102,8,111,102,102,115,101,116,111, 102,5,101,114,114,110,111,6,115,116,114,105,110,103,4,99,111,112,121,4,102, diff --git a/src/reusevm/lj_recdef.h b/src/reusevm/lj_recdef.h index 436754f308..2c02001914 100644 --- a/src/reusevm/lj_recdef.h +++ b/src/reusevm/lj_recdef.h @@ -155,6 +155,7 @@ static const uint16_t recff_idmap[] = { 0, 0, 0, +0, 0x2f00+(0), 0x2f00+(1), 0x3000+(MM_eq), diff --git a/src/reusevm/lj_vm.S b/src/reusevm/lj_vm.S index 4d0c4f141d..9514d3b5e9 100644 --- a/src/reusevm/lj_vm.S +++ b/src/reusevm/lj_vm.S @@ -502,7 +502,7 @@ lj_BC_USETV: .byte 232,72,131,195,4,193,232,16,65,255,36,238,72,137,200,72 .byte 193,248,47,131,232,252,131,248,246,118,222,72,193,225,17,72 .byte 193,233,17,246,65,8,3,116,208,72,137,238,72,137,213,73 - .byte 141,190,168,240,255,255 + .byte 141,190,160,240,255,255 call lj_gc_barrieruv .byte 72,137,234,235,185 @@ -516,7 +516,7 @@ lj_BC_USETS: .byte 0,0,0,128,253,255,73,9,203,76,137,24,246,69,8,4 .byte 117,19,139,3,15,182,204,15,182,232,72,131,195,4,193,232 .byte 16,65,255,36,238,246,65,8,3,116,231,128,125,10,0,116 - .byte 225,72,137,213,72,137,198,73,141,190,168,240,255,255 + .byte 225,72,137,213,72,137,198,73,141,190,160,240,255,255 call lj_gc_barrieruv .byte 72,137,234,235,202 @@ -569,8 +569,8 @@ lj_BC_FNEW: .type lj_BC_TNEW, @function .size lj_BC_TNEW, 122 lj_BC_TNEW: - .byte 72,139,108,36,16,72,137,85,32,73,139,142,200,240,255,255 - .byte 73,59,142,208,240,255,255,72,137,92,36,24,115,78,137,194 + .byte 72,139,108,36,16,72,137,85,32,73,139,142,192,240,255,255 + .byte 73,59,142,200,240,255,255,72,137,92,36,24,115,78,137,194 .byte 37,255,7,0,0,193,234,11,61,255,7,0,0,116,54,72 .byte 137,239,137,198 call lj_tab_new @@ -586,8 +586,8 @@ lj_BC_TNEW: .type lj_BC_TDUP, @function .size lj_BC_TDUP, 106 lj_BC_TDUP: - .byte 72,247,208,72,139,108,36,16,73,139,142,200,240,255,255,72 - .byte 137,92,36,24,73,59,142,208,240,255,255,72,137,85,32,115 + .byte 72,247,208,72,139,108,36,16,73,139,142,192,240,255,255,72 + .byte 137,92,36,24,73,59,142,200,240,255,255,72,137,85,32,115 .byte 56,73,139,52,199,72,137,239 call lj_tab_dup .byte 72,139,85,32,15,182,75,253,73,187,0,0,0,0,0,0 @@ -685,7 +685,7 @@ lj_BC_TSETV: .byte 238,76,139,85,32,77,133,210,116,215,65,246,66,10,2,15 .byte 132,73,17,0,0,235,202,65,131,251,251,15,133,61,17,0 .byte 0,72,193,224,17,72,193,232,17,235,66,128,101,8,251,77 - .byte 139,150,248,240,255,255,73,137,174,248,240,255,255,76,137,85 + .byte 139,150,240,240,255,255,73,137,174,240,240,255,255,76,137,85 .byte 24,235,164 .globl lj_BC_TSETS @@ -708,8 +708,8 @@ lj_BC_TSETS: .byte 137,238,72,137,92,36,24 call lj_tab_newkey .byte 72,139,124,36,16,72,139,87,32,73,137,194,15,182,75,253 - .byte 233,118,255,255,255,128,101,8,251,77,139,158,248,240,255,255 - .byte 73,137,174,248,240,255,255,76,137,93,24,233,101,255,255,255 + .byte 233,118,255,255,255,128,101,8,251,77,139,158,240,240,255,255 + .byte 73,137,174,240,240,255,255,76,137,93,24,233,101,255,255,255 .globl lj_BC_TSETB .hidden lj_BC_TSETB @@ -723,7 +723,7 @@ lj_BC_TSETB: .byte 139,28,202,76,137,24,139,3,15,182,204,15,182,232,72,131 .byte 195,4,193,232,16,65,255,36,238,76,139,85,32,77,133,210 .byte 116,215,65,246,66,10,2,15,132,159,15,0,0,235,202,128 - .byte 101,8,251,77,139,150,248,240,255,255,73,137,174,248,240,255 + .byte 101,8,251,77,139,150,240,240,255,255,73,137,174,240,240,255 .byte 255,76,137,85,24,235,184 .globl lj_BC_TSETM @@ -741,7 +741,7 @@ lj_BC_TSETM: .byte 24 call lj_tab_reasize .byte 72,139,85,32,15,182,75,253,15,183,67,254,233,121,255,255 - .byte 255,128,101,8,251,73,139,134,248,240,255,255,73,137,174,248 + .byte 255,128,101,8,251,73,139,134,240,240,255,255,73,137,174,240 .byte 240,255,255,72,137,69,24,233,120,255,255,255 .globl lj_BC_TSETR @@ -753,8 +753,8 @@ lj_BC_TSETR: .byte 237,17,242,15,44,4,194,246,69,8,4,117,42,59,69,48 .byte 15,131,84,15,0,0,193,224,3,72,3,69,16,76,139,28 .byte 202,76,137,24,139,3,15,182,204,15,182,232,72,131,195,4 - .byte 193,232,16,65,255,36,238,128,101,8,251,77,139,150,248,240 - .byte 255,255,73,137,174,248,240,255,255,76,137,85,24,235,190 + .byte 193,232,16,65,255,36,238,128,101,8,251,77,139,150,240,240 + .byte 255,255,73,137,174,240,240,255,255,76,137,85,24,235,190 .globl lj_BC_CALLM .hidden lj_BC_CALLM @@ -1019,8 +1019,8 @@ lj_BC_ILOOP: .type lj_BC_JLOOP, @function .size lj_BC_JLOOP, 50 lj_BC_JLOOP: - .byte 73,139,142,240,244,255,255,72,139,4,193,72,139,64,88,72 - .byte 139,108,36,16,73,137,150,16,242,255,255,73,137,174,80,241 + .byte 73,139,142,232,244,255,255,72,139,4,193,72,139,64,88,72 + .byte 139,108,36,16,73,137,150,8,242,255,255,73,137,174,72,241 .byte 255,255,72,131,236,16,76,137,100,36,16,76,137,108,36,8 .byte 255,224 @@ -1097,9 +1097,9 @@ lj_BC_FUNCC: .byte 72,139,106,240,72,193,229,17,72,193,237,17,76,139,125,40 .byte 72,139,108,36,16,72,141,68,194,248,72,137,85,32,72,141 .byte 136,160,0,0,0,72,59,77,48,72,137,69,40,72,137,239 - .byte 15,135,31,2,0,0,65,199,134,40,241,255,255,254,255,255 - .byte 255,65,255,215,72,139,85,32,73,137,174,8,242,255,255,65 - .byte 199,134,40,241,255,255,255,255,255,255,72,141,12,194,72,247 + .byte 15,135,31,2,0,0,65,199,134,32,241,255,255,254,255,255 + .byte 255,65,255,215,72,139,85,32,73,137,174,0,242,255,255,65 + .byte 199,134,32,241,255,255,255,255,255,255,72,141,12,194,72,247 .byte 217,72,3,77,40,72,139,90,248,233,156,0,0,0 .globl lj_BC_FUNCCW @@ -1110,9 +1110,9 @@ lj_BC_FUNCCW: .byte 72,139,106,240,72,193,229,17,72,193,237,17,76,139,125,40 .byte 72,139,108,36,16,72,141,68,194,248,72,137,85,32,72,141 .byte 136,160,0,0,0,72,59,77,48,72,137,69,40,76,137,254 - .byte 72,137,239,15,135,174,1,0,0,65,199,134,40,241,255,255 - .byte 254,255,255,255,65,255,150,240,241,255,255,72,139,85,32,73 - .byte 137,174,8,242,255,255,65,199,134,40,241,255,255,255,255,255 + .byte 72,137,239,15,135,174,1,0,0,65,199,134,32,241,255,255 + .byte 254,255,255,255,65,255,150,232,241,255,255,72,139,85,32,73 + .byte 137,174,0,242,255,255,65,199,134,32,241,255,255,255,255,255 .byte 255,72,141,12,194,72,247,217,72,3,77,40,72,139,90,248 .byte 235,42 @@ -1138,7 +1138,7 @@ lj_vm_returnc: .type lj_vm_return, @function .size lj_vm_return, 83 lj_vm_return: - .byte 72,131,243,1,247,195,3,0,0,0,117,177,65,199,134,40 + .byte 72,131,243,1,247,195,3,0,0,0,117,177,65,199,134,32 .byte 241,255,255,254,255,255,255,72,131,227,248,72,41,211,72,247 .byte 219,131,232,1,116,17,72,139,44,10,72,137,106,240,72,131 .byte 194,8,131,232,1,117,239,72,139,108,36,16,72,137,93,32 @@ -1209,9 +1209,9 @@ lj_vm_unwind_ff: .size lj_vm_unwind_ff_eh, 73 lj_vm_unwind_ff_eh: .byte 72,139,108,36,16,184,2,0,0,0,72,139,85,32,76,139 - .byte 117,16,73,129,198,88,15,0,0,72,139,90,248,72,185,255 + .byte 117,16,73,129,198,96,15,0,0,72,139,90,248,72,185,255 .byte 255,255,255,255,127,255,255,72,139,42,72,137,74,240,72,137 - .byte 106,248,72,199,193,240,255,255,255,65,199,134,40,241,255,255 + .byte 106,248,72,199,193,240,255,255,255,65,199,134,32,241,255,255 .byte 255,255,255,255,233,181,254,255,255 .globl lj_vm_growstack_c @@ -1248,10 +1248,10 @@ lj_vm_growstack_f: lj_vm_resume: .byte 85,83,65,87,65,86,65,85,65,84,72,131,236,40,72,137 .byte 253,72,137,124,36,16,72,137,241,187,5,0,0,0,49,192 - .byte 76,141,124,36,1,76,139,117,16,73,129,198,88,15,0,0 + .byte 76,141,124,36,1,76,139,117,16,73,129,198,96,15,0,0 .byte 72,137,68,36,24,72,137,68,36,32,137,68,36,8,137,68 .byte 36,12,76,137,125,80,56,69,11,15,132,153,0,0,0,73 - .byte 137,174,8,242,255,255,65,199,134,40,241,255,255,255,255,255 + .byte 137,174,0,242,255,255,65,199,134,32,241,255,255,255,255,255 .byte 255,136,69,11,72,139,85,32,72,139,69,40,72,41,200,193 .byte 232,3,131,192,1,72,41,209,72,139,90,248,137,4,36,247 .byte 195,3,0,0,0,15,132,205,247,255,255,233,219,253,255,255 @@ -1272,8 +1272,8 @@ lj_vm_call: .byte 85,83,65,87,65,86,65,85,65,84,72,131,236,40,187,1 .byte 0,0,0,137,84,36,8,72,137,253,72,137,124,36,16,72 .byte 137,241,76,139,117,16,76,139,125,80,76,137,124,36,32,72 - .byte 137,108,36,24,73,129,198,88,15,0,0,72,137,101,80,73 - .byte 137,174,8,242,255,255,65,199,134,40,241,255,255,255,255,255 + .byte 137,108,36,24,73,129,198,96,15,0,0,72,137,101,80,73 + .byte 137,174,0,242,255,255,65,199,134,32,241,255,255,255,255,255 .byte 255,72,139,85,32,72,1,203,72,41,211,72,139,69,40,72 .byte 41,200,193,232,3,131,192,1 @@ -1301,8 +1301,8 @@ lj_vm_cpcall: .byte 85,83,65,87,65,86,65,85,65,84,72,131,236,40,72,137 .byte 253,72,137,124,36,16,72,137,108,36,24,76,139,125,56,76 .byte 43,125,40,76,139,117,16,199,68,36,12,0,0,0,0,68 - .byte 137,124,36,8,73,129,198,88,15,0,0,76,139,125,80,76 - .byte 137,124,36,32,72,137,101,80,73,137,174,8,242,255,255,255 + .byte 137,124,36,8,73,129,198,96,15,0,0,76,139,125,80,76 + .byte 137,124,36,32,72,137,101,80,73,137,174,0,242,255,255,255 .byte 209,72,133,192,15,132,27,253,255,255,72,137,193,187,5,0 .byte 0,0,233,56,255,255,255 @@ -1314,7 +1314,7 @@ lj_cont_dispatch: .byte 72,1,209,72,131,227,248,72,137,213,72,41,218,72,199,68 .byte 193,248,255,255,255,255,72,137,200,72,139,93,232,72,139,77 .byte 224,72,131,249,1,118,22,76,139,122,240,73,193,231,17,73 - .byte 193,239,17,77,139,127,32,77,139,127,176,255,225,15,132,16 + .byte 193,239,17,77,139,127,32,77,139,127,176,255,225,15,132,19 .byte 31,0,0,72,41,213,193,237,3,141,69,253,233,84,24,0 .byte 0 @@ -1335,7 +1335,7 @@ lj_cont_cat: lj_vmeta_tgets: .byte 73,187,0,0,0,0,0,128,253,255,76,9,216,72,137,4 .byte 36,72,141,4,36,128,123,252,54,117,53,72,185,0,0,0 - .byte 0,0,0,250,255,72,9,233,73,141,174,136,241,255,255,72 + .byte 0,0,0,250,255,72,9,233,73,141,174,128,241,255,255,72 .byte 137,77,0,235,35 .globl lj_vmeta_tgetb @@ -1385,7 +1385,7 @@ lj_vmeta_tgetr: lj_vmeta_tsets: .byte 73,187,0,0,0,0,0,128,253,255,76,9,216,72,137,4 .byte 36,72,141,4,36,128,123,252,55,117,53,72,185,0,0,0 - .byte 0,0,0,250,255,72,9,233,73,141,174,136,241,255,255,72 + .byte 0,0,0,250,255,72,9,233,73,141,174,128,241,255,255,72 .byte 137,77,0,235,35 .globl lj_vmeta_tsetb @@ -1620,13 +1620,13 @@ lj_ff_getmetatable: .byte 73,137,235,72,193,229,17,72,193,237,17,73,193,251,47,65 .byte 131,251,244,117,113,72,139,109,32,72,133,237,72,199,66,240 .byte 255,255,255,255,15,132,144,7,0,0,72,184,0,0,0,0 - .byte 0,0,250,255,72,9,232,72,137,66,240,73,139,134,168,242 + .byte 0,0,250,255,72,9,232,72,137,66,240,73,139,134,160,242 .byte 255,255,139,77,52,35,72,12,73,187,0,0,0,0,0,128 .byte 253,255,76,9,216,107,201,24,72,3,77,40,72,57,65,8 .byte 116,14,72,139,73,16,72,133,201,117,241,233,74,7,0,0 .byte 72,139,41,72,131,253,255,15,132,61,7,0,0,72,137,106 .byte 240,233,52,7,0,0,65,131,251,243,116,137,65,131,251,242 - .byte 119,6,65,187,242,255,255,255,65,247,211,75,139,172,222,208 + .byte 119,6,65,187,242,255,255,255,65,247,211,75,139,172,222,200 .byte 242,255,255,233,113,255,255,255 .globl lj_ff_setmetatable @@ -1640,8 +1640,8 @@ lj_ff_setmetatable: .byte 18,0,0,72,139,74,8,73,137,203,72,193,225,17,72,193 .byte 233,17,73,193,251,47,65,131,251,244,15,133,21,18,0,0 .byte 72,137,77,32,72,139,90,248,76,137,82,240,246,69,8,4 - .byte 116,22,128,101,8,251,73,139,134,248,240,255,255,73,137,174 - .byte 248,240,255,255,72,137,69,24,233,149,6,0,0 + .byte 116,22,128,101,8,251,73,139,134,240,240,255,255,73,137,174 + .byte 240,240,255,255,72,137,69,24,233,149,6,0,0 .globl lj_ff_rawget .hidden lj_ff_rawget @@ -1673,8 +1673,8 @@ lj_ff_tostring: .byte 131,248,2,15,130,108,17,0,0,72,139,90,248,72,139,42 .byte 73,137,235,73,193,251,47,65,131,251,251,117,9,72,137,106 .byte 240,233,252,5,0,0,65,131,251,242,15,135,64,17,0,0 - .byte 73,131,190,56,243,255,255,0,15,133,55,17,0,0,73,139 - .byte 174,200,240,255,255,73,59,174,208,240,255,255,114,5,232,217 + .byte 73,131,190,48,243,255,255,0,15,133,55,17,0,0,73,139 + .byte 174,192,240,255,255,73,59,174,200,240,255,255,114,5,232,217 .byte 17,0,0,72,139,108,36,16,72,137,85,32,72,137,92,36 .byte 24,72,137,214,72,137,239 call lj_strfmt_num @@ -1760,7 +1760,7 @@ lj_ff_ipairs: .size lj_ff_pcall, 64 lj_ff_pcall: .byte 131,248,2,15,130,7,15,0,0,72,141,74,16,131,232,1 - .byte 187,22,0,0,0,65,15,182,174,113,241,255,255,72,193,237 + .byte 187,22,0,0,0,65,15,182,174,105,241,255,255,72,193,237 .byte 4,72,131,229,1,72,1,235,73,137,199,74,139,108,249,232 .byte 74,137,108,249,240,73,131,239,1,119,240,233,3,246,255,255 @@ -1791,7 +1791,7 @@ lj_ff_coroutine_resume: .byte 203,116,17,72,139,4,43,72,137,67,248,72,131,235,8,72 .byte 57,203,117,239,72,137,206,72,139,60,36,232,12,244,255,255 .byte 72,139,108,36,16,72,139,28,36,72,139,85,32,73,137,174 - .byte 8,242,255,255,65,199,134,40,241,255,255,255,255,255,255,131 + .byte 0,242,255,255,65,199,134,32,241,255,255,255,255,255,255,131 .byte 248,1,119,104,72,139,75,32,76,139,123,40,72,137,75,40 .byte 76,137,251,72,41,203,116,35,72,141,4,26,193,235,3,72 .byte 59,69,48,119,110,72,137,213,72,41,205,72,139,1,72,137 @@ -1821,8 +1821,8 @@ lj_ff_coroutine_wrap_aux: .byte 32,72,137,85,40,72,141,108,194,240,72,41,221,72,57,203 .byte 116,17,72,139,4,43,72,137,67,248,72,131,235,8,72,57 .byte 203,117,239,72,137,206,72,139,60,36,232,154,242,255,255,72 - .byte 139,108,36,16,72,139,28,36,72,139,85,32,73,137,174,8 - .byte 242,255,255,65,199,134,40,241,255,255,255,255,255,255,131,248 + .byte 139,108,36,16,72,139,28,36,72,139,85,32,73,137,174,0 + .byte 242,255,255,65,199,134,32,241,255,255,255,255,255,255,131,248 .byte 1,119,85,72,139,75,32,76,139,123,40,72,137,75,40,76 .byte 137,251,72,41,203,116,35,72,141,4,26,193,235,3,72,59 .byte 69,48,119,63,72,137,213,72,41,205,72,139,1,72,137,4 @@ -2149,7 +2149,7 @@ lj_ff_string_byte: .type lj_ff_string_char, @function .size lj_ff_string_char, 76 lj_ff_string_char: - .byte 73,139,174,200,240,255,255,73,59,174,208,240,255,255,114,5 + .byte 73,139,174,192,240,255,255,73,59,174,200,240,255,255,114,5 .byte 232,223,6,0,0,131,248,2,15,133,31,6,0,0,76,139 .byte 26,73,193,251,47,65,131,251,242,15,131,14,6,0,0,242 .byte 15,44,42,129,253,255,0,0,0,15,135,254,5,0,0,137 @@ -2177,7 +2177,7 @@ lj_fff_resstr: .type lj_ff_string_sub, @function .size lj_ff_string_sub, 174 lj_ff_string_sub: - .byte 73,139,174,200,240,255,255,73,59,174,208,240,255,255,114,5 + .byte 73,139,174,192,240,255,255,73,59,174,200,240,255,255,114,5 .byte 232,89,6,0,0,65,186,255,255,255,255,131,248,3,15,130 .byte 147,5,0,0,118,24,76,139,90,16,73,193,251,47,65,131 .byte 251,242,15,131,127,5,0,0,242,68,15,44,82,16,72,139 @@ -2201,11 +2201,11 @@ lj_fff_emptystr: .type lj_ff_string_reverse, @function .size lj_ff_string_reverse, 108 lj_ff_string_reverse: - .byte 131,248,2,15,130,251,4,0,0,73,139,174,200,240,255,255 - .byte 73,59,174,208,240,255,255,114,5,232,157,5,0,0,72,139 + .byte 131,248,2,15,130,251,4,0,0,73,139,174,192,240,255,255 + .byte 73,59,174,200,240,255,255,114,5,232,157,5,0,0,72,139 .byte 50,73,137,243,72,193,230,17,72,193,238,17,73,193,251,47 .byte 65,131,251,251,15,133,202,4,0,0,72,139,108,36,16,73 - .byte 141,190,56,241,255,255,72,137,85,32,72,139,71,16,72,137 + .byte 141,190,48,241,255,255,72,137,85,32,72,139,71,16,72,137 .byte 111,24,72,137,7,72,137,92,36,24 call lj_buf_putstr_reverse .byte 72,137,199 @@ -2217,11 +2217,11 @@ lj_ff_string_reverse: .type lj_ff_string_lower, @function .size lj_ff_string_lower, 108 lj_ff_string_lower: - .byte 131,248,2,15,130,143,4,0,0,73,139,174,200,240,255,255 - .byte 73,59,174,208,240,255,255,114,5,232,49,5,0,0,72,139 + .byte 131,248,2,15,130,143,4,0,0,73,139,174,192,240,255,255 + .byte 73,59,174,200,240,255,255,114,5,232,49,5,0,0,72,139 .byte 50,73,137,243,72,193,230,17,72,193,238,17,73,193,251,47 .byte 65,131,251,251,15,133,94,4,0,0,72,139,108,36,16,73 - .byte 141,190,56,241,255,255,72,137,85,32,72,139,71,16,72,137 + .byte 141,190,48,241,255,255,72,137,85,32,72,139,71,16,72,137 .byte 111,24,72,137,7,72,137,92,36,24 call lj_buf_putstr_lower .byte 72,137,199 @@ -2233,11 +2233,11 @@ lj_ff_string_lower: .type lj_ff_string_upper, @function .size lj_ff_string_upper, 108 lj_ff_string_upper: - .byte 131,248,2,15,130,35,4,0,0,73,139,174,200,240,255,255 - .byte 73,59,174,208,240,255,255,114,5,232,197,4,0,0,72,139 + .byte 131,248,2,15,130,35,4,0,0,73,139,174,192,240,255,255 + .byte 73,59,174,200,240,255,255,114,5,232,197,4,0,0,72,139 .byte 50,73,137,243,72,193,230,17,72,193,238,17,73,193,251,47 .byte 65,131,251,251,15,133,242,3,0,0,72,139,108,36,16,73 - .byte 141,190,56,241,255,255,72,137,85,32,72,139,71,16,72,137 + .byte 141,190,48,241,255,255,72,137,85,32,72,139,71,16,72,137 .byte 111,24,72,137,7,72,137,92,36,24 call lj_buf_putstr_upper .byte 72,137,199 @@ -2442,7 +2442,7 @@ lj_fff_gcstep: .type lj_vm_record, @function .size lj_vm_record, 17 lj_vm_record: - .byte 168,16,117,56,168,12,116,52,65,255,142,224,241,255,255,235 + .byte 168,16,117,56,168,12,116,52,65,255,142,216,241,255,255,235 .byte 43 .globl lj_vm_rethook @@ -2450,15 +2450,15 @@ lj_vm_record: .type lj_vm_rethook, @function .size lj_vm_rethook, 14 lj_vm_rethook: - .byte 65,15,182,134,113,241,255,255,168,16,117,59,235,29 + .byte 65,15,182,134,105,241,255,255,168,16,117,59,235,29 .globl lj_vm_inshook .hidden lj_vm_inshook .type lj_vm_inshook, @function .size lj_vm_inshook, 73 lj_vm_inshook: - .byte 65,15,182,134,113,241,255,255,168,16,117,45,168,12,116,41 - .byte 65,255,142,224,241,255,255,116,4,168,4,116,28,72,139,108 + .byte 65,15,182,134,105,241,255,255,168,16,117,45,168,12,116,41 + .byte 65,255,142,216,241,255,255,116,4,168,4,116,28,72,139,108 .byte 36,16,72,137,85,32,72,137,222,72,137,239 call lj_dispatch_ins .byte 72,139,85,32,15,182,75,253,15,182,107,252,15,183,67,254 @@ -2478,8 +2478,8 @@ lj_cont_hook: lj_vm_hotloop: .byte 72,139,106,240,72,193,229,17,72,193,237,17,72,139,109,32 .byte 15,182,69,155,72,141,4,194,72,139,108,36,16,72,137,85 - .byte 32,72,137,69,40,72,137,222,73,141,190,80,243,255,255,73 - .byte 137,174,224,243,255,255,72,137,92,36,24 + .byte 32,72,137,69,40,72,137,222,73,141,190,72,243,255,255,73 + .byte 137,174,216,243,255,255,72,137,92,36,24 call lj_trace_hot .byte 235,153 @@ -2514,9 +2514,9 @@ lj_cont_stitch: .byte 117,236,15,182,67,253,15,182,107,255,72,1,232,72,141,68 .byte 194,248,72,57,200,119,82,77,133,219,15,132,121,231,255,255 .byte 65,15,183,107,116,65,15,183,67,118,57,232,15,132,103,231 - .byte 255,255,133,192,15,133,153,223,255,255,73,137,174,60,255,255 + .byte 255,255,133,192,15,133,153,223,255,255,73,137,174,52,255,255 .byte 255,72,139,108,36,16,72,137,85,32,72,137,222,73,141,190 - .byte 80,243,255,255,73,137,174,224,243,255,255 + .byte 72,243,255,255,73,137,174,216,243,255,255 call lj_dispatch_stitch .byte 72,139,85,32,233,48,231,255,255,72,199,1,255,255,255,255 .byte 72,131,193,8,235,156 @@ -2528,18 +2528,18 @@ lj_cont_stitch: lj_vm_exit_handler: .byte 65,85,65,84,65,83,65,82,65,81,65,80,87,86,85,72 .byte 141,108,36,88,85,83,82,81,80,15,182,69,248,138,101,240 - .byte 76,137,125,248,76,137,117,240,65,139,142,40,241,255,255,65 - .byte 199,134,40,241,255,255,252,255,255,255,65,137,134,60,255,255 - .byte 255,65,137,142,56,255,255,255,65,137,142,48,241,255,255,72 + .byte 76,137,125,248,76,137,117,240,65,139,142,32,241,255,255,65 + .byte 199,134,32,241,255,255,252,255,255,255,65,137,134,52,255,255 + .byte 255,65,137,142,48,255,255,255,65,137,142,40,241,255,255,72 .byte 129,236,128,0,0,0,72,131,197,128,242,68,15,17,125,248 .byte 242,68,15,17,117,240,242,68,15,17,109,232,242,68,15,17 .byte 101,224,242,68,15,17,93,216,242,68,15,17,85,208,242,68 .byte 15,17,77,200,242,68,15,17,69,192,242,15,17,125,184,242 .byte 15,17,117,176,242,15,17,109,168,242,15,17,101,160,242,15 .byte 17,93,152,242,15,17,85,144,242,15,17,77,136,242,15,17 - .byte 69,128,73,139,174,8,242,255,255,73,139,150,16,242,255,255 - .byte 73,137,174,224,243,255,255,72,137,85,32,72,137,230,73,141 - .byte 190,80,243,255,255,73,199,134,16,242,255,255,0,0,0,0 + .byte 69,128,73,139,174,0,242,255,255,73,139,150,8,242,255,255 + .byte 73,137,174,216,243,255,255,72,137,85,32,72,137,230,73,141 + .byte 190,72,243,255,255,73,199,134,8,242,255,255,0,0,0,0 call lj_trace_exit .byte 72,139,77,80,72,131,225,252,72,137,105,16,72,139,85,32 .byte 72,139,89,24,235,19 @@ -2549,7 +2549,7 @@ lj_vm_exit_handler: .type lj_vm_exit_interp, @function .size lj_vm_exit_interp, 14 lj_vm_exit_interp: - .byte 69,139,150,40,241,255,255,69,137,150,48,241,255,255 + .byte 69,139,150,32,241,255,255,69,137,150,40,241,255,255 .globl lj_vm_exit_interp_notrack .hidden lj_vm_exit_interp_notrack @@ -2559,8 +2559,8 @@ lj_vm_exit_interp_notrack: .byte 72,141,76,36,16,76,139,105,248,76,139,33,72,137,204,133 .byte 192,15,136,134,0,0,0,72,139,108,36,16,137,4,36,76 .byte 139,122,240,73,193,231,17,73,193,239,17,77,139,127,32,77 - .byte 139,127,176,72,137,85,32,73,199,134,16,242,255,255,0,0 - .byte 0,0,69,139,150,40,241,255,255,65,199,134,40,241,255,255 + .byte 139,127,176,72,137,85,32,73,199,134,8,242,255,255,0,0 + .byte 0,0,69,139,150,32,241,255,255,65,199,134,32,241,255,255 .byte 255,255,255,255,139,3,15,182,204,15,182,232,72,131,195,4 .byte 193,232,16,131,253,89,114,8,131,253,97,115,7,139,4,36 .byte 65,255,36,238,72,139,66,248,169,3,0,0,0,117,238,15 @@ -2668,19 +2668,19 @@ lj_assert_bad_for_arg_type: .globl lj_vm_ffi_callback .hidden lj_vm_ffi_callback .type lj_vm_ffi_callback, @function - .size lj_vm_ffi_callback, 202 + .size lj_vm_ffi_callback, 205 lj_vm_ffi_callback: .byte 83,65,87,65,86,65,85,65,84,72,131,236,40,76,141,181 - .byte 88,15,0,0,72,139,157,112,1,0,0,15,183,192,137,131 - .byte 208,0,0,0,72,137,123,112,72,137,115,120,72,137,147,128 - .byte 0,0,0,72,137,139,136,0,0,0,242,15,17,67,48,242 - .byte 15,17,75,56,242,15,17,83,64,242,15,17,91,72,72,141 - .byte 68,36,96,76,137,131,144,0,0,0,76,137,139,152,0,0 - .byte 0,242,15,17,99,80,242,15,17,107,88,242,15,17,115,96 - .byte 242,15,17,123,104,72,137,131,176,0,0,0,72,137,230,72 - .byte 137,92,36,24,72,137,223 + .byte 96,15,0,0,72,139,157,112,1,0,0,15,183,192,137,131 + .byte 216,0,0,0,72,137,123,120,72,137,179,128,0,0,0,72 + .byte 137,147,136,0,0,0,72,137,139,144,0,0,0,242,15,17 + .byte 67,56,242,15,17,75,64,242,15,17,83,72,242,15,17,91 + .byte 80,72,141,68,36,96,76,137,131,152,0,0,0,76,137,139 + .byte 160,0,0,0,242,15,17,99,88,242,15,17,107,96,242,15 + .byte 17,115,104,242,15,17,123,112,72,137,131,184,0,0,0,72 + .byte 137,230,72,137,92,36,24,72,137,223 call lj_ccallback_enter - .byte 65,199,134,40,241,255,255,255,255,255,255,72,139,80,32,72 + .byte 65,199,134,32,241,255,255,255,255,255,255,72,139,80,32,72 .byte 139,64,40,72,41,208,72,139,106,240,72,193,229,17,72,193 .byte 237,17,72,193,232,3,72,131,192,1,72,139,93,32,139,11 .byte 15,182,233,15,182,205,72,131,195,4,65,255,36,238 @@ -2690,10 +2690,10 @@ lj_vm_ffi_callback: .type lj_cont_ffi_callback, @function .size lj_cont_ffi_callback, 49 lj_cont_ffi_callback: - .byte 72,139,76,36,16,73,139,158,24,242,255,255,72,137,75,16 + .byte 72,139,76,36,16,73,139,158,16,242,255,255,72,137,75,24 .byte 72,137,81,32,72,137,105,40,72,137,223,72,137,198 call lj_ccallback_leave - .byte 72,139,67,112,242,15,16,67,48,233,149,221,255,255 + .byte 72,139,67,120,242,15,16,67,56,233,146,221,255,255 .globl lj_vm_ffi_call .hidden lj_vm_ffi_call @@ -2737,7 +2737,7 @@ lj_vm_ffi_call: .LASFDE0: .long .Lframe0 .quad .Lbegin - .quad 16429 + .quad 16432 .byte 0xe .uleb128 96 .byte 0x86