diff --git a/lib/luajit/src/lib_jit.c b/lib/luajit/src/lib_jit.c index 1e29d79e05..a6ba770c9a 100644 --- a/lib/luajit/src/lib_jit.c +++ b/lib/luajit/src/lib_jit.c @@ -141,6 +141,12 @@ LJLIB_CF(jit_attach) return 0; } +/* Calling this forces a trace stitch. */ +LJLIB_CF(jit_tracebarrier) +{ + return 0; +} + LJLIB_PUSH(top-5) LJLIB_SET(os) LJLIB_PUSH(top-4) LJLIB_SET(arch) LJLIB_PUSH(top-3) LJLIB_SET(version_num) diff --git a/lib/luajit/src/lj_jit.h b/lib/luajit/src/lj_jit.h index 92054e3df6..ff3aee2de0 100644 --- a/lib/luajit/src/lj_jit.h +++ b/lib/luajit/src/lj_jit.h @@ -97,11 +97,11 @@ /* Optimization parameters and their defaults. Length is a char in octal! */ #define JIT_PARAMDEF(_) \ - _(\010, maxtrace, 1000) /* Max. # of traces in cache. */ \ - _(\011, maxrecord, 4000) /* Max. # of recorded IR instructions. */ \ + _(\010, maxtrace, 2000) /* Max. # of traces in cache. */ \ + _(\011, maxrecord, 6000) /* 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. */ \ - _(\007, maxsnap, 500) /* Max. # of snapshots for a trace. */ \ + _(\007, maxside, 200) /* Max. # of side traces of a root trace. */ \ + _(\007, maxsnap, 1000) /* Max. # of snapshots for a trace. */ \ _(\011, minstitch, 0) /* Min. # of IR ins for a stitched trace. */ \ \ _(\007, hotloop, 56) /* # of iter. to detect a hot loop/call. */ \ @@ -116,7 +116,7 @@ /* Size of each machine code area (in KBytes). */ \ _(\011, sizemcode, JIT_P_sizemcode_DEFAULT) \ /* Max. total size of all machine code areas (in KBytes). */ \ - _(\010, maxmcode, 512) \ + _(\010, maxmcode, 4096) \ /* End of list. */ enum { @@ -277,13 +277,13 @@ static LJ_AINLINE MSize snap_nextofs(GCtrace *T, SnapShot *snap) /* Round-robin penalty cache for bytecodes leading to aborted traces. */ typedef struct HotPenalty { MRef pc; /* Starting bytecode PC. */ - uint16_t val; /* Penalty value, i.e. hotcount start. */ + uint32_t val; /* Penalty value, i.e. hotcount start. */ uint16_t reason; /* Abort reason (really TraceErr). */ } HotPenalty; #define PENALTY_SLOTS 64 /* Penalty cache slot. Must be a power of 2. */ #define PENALTY_MIN (36*2) /* Minimum penalty value. */ -#define PENALTY_MAX 60000 /* Maximum penalty value. */ +#define PENALTY_MAX 6000000 /* Maximum penalty value. */ #define PENALTY_RNDBITS 4 /* # of random bits to add to penalty value. */ /* Round-robin backpropagation cache for narrowing conversions. */ diff --git a/lib/luajit/src/lj_record.c b/lib/luajit/src/lj_record.c index b2abed08f0..2d2510a736 100644 --- a/lib/luajit/src/lj_record.c +++ b/lib/luajit/src/lj_record.c @@ -595,7 +595,8 @@ static void rec_loop_interp(jit_State *J, const BCIns *pc, LoopEvent ev) /* Handle the case when an already compiled loop op is hit. */ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev) { - if (J->parent == 0 && J->exitno == 0) { /* Root trace hit an inner loop. */ + /* Root trace hit an inner loop. */ + if (J->parent == 0 && J->exitno == 0 && !innerloopleft(J, J->startpc)) { /* Better let the inner loop spawn a side trace back here. */ lj_trace_err(J, LJ_TRERR_LINNER); } else if (ev != LOOPEV_LEAVE) { /* Side trace enters a compiled loop. */ diff --git a/lib/luajit/src/lj_trace.c b/lib/luajit/src/lj_trace.c index 80a7f024af..e4a10aa5c3 100644 --- a/lib/luajit/src/lj_trace.c +++ b/lib/luajit/src/lj_trace.c @@ -293,6 +293,8 @@ int lj_trace_flushall(lua_State *L) J->freetrace = 0; /* Clear penalty cache. */ memset(J->penalty, 0, sizeof(J->penalty)); + /* Reset hotcounts. */ + lj_dispatch_init_hotcount(J2G(J)); /* Free the whole machine code and invalidate all exit stub groups. */ lj_mcode_free(J); memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); @@ -392,7 +394,7 @@ static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e) J->penaltyslot = (J->penaltyslot + 1) & (PENALTY_SLOTS-1); setmref(J->penalty[i].pc, pc); setpenalty: - J->penalty[i].val = (uint16_t)val; + J->penalty[i].val = val; J->penalty[i].reason = e; hotcount_set(J2GG(J), pc+1, val); } @@ -473,6 +475,7 @@ static void trace_stop(jit_State *J) TraceNo traceno = J->cur.traceno; GCtrace *T = J->curfinal; lua_State *L; + int i; switch (op) { case BC_FORL: @@ -524,6 +527,11 @@ static void trace_stop(jit_State *J) J->postproc = LJ_POST_NONE; trace_save(J, T); + /* Clear any penalty after successful recording. */ + for (i = 0; i < PENALTY_SLOTS; i++) + if (mref(J->penalty[i].pc, const BCIns) == pc) + J->penalty[i].val = PENALTY_MIN; + L = J->L; lj_vmevent_send(L, TRACE, setstrV(L, L->top++, lj_str_newlit(L, "stop")); diff --git a/src/apps/jit_loop/ipv4_apps.lua b/src/apps/jit_loop/ipv4_apps.lua new file mode 100644 index 0000000000..abf05b4e53 --- /dev/null +++ b/src/apps/jit_loop/ipv4_apps.lua @@ -0,0 +1,84 @@ +module(..., package.seeall) + +local ethernet = require("lib.protocol.ethernet") +local receive, transmit = link.receive, link.transmit +local lpm4 = require("lib.lpm.lpm4_trie").LPM4_trie +local ipv4 = require("lib.protocol.ipv4") + +ChangeMAC = {} + +function ChangeMAC:new(conf) + local o = setmetatable({}, {__index=ChangeMAC}) + o.conf = conf + o.src_eth = ethernet:pton(conf.src_eth) + o.dst_eth = ethernet:pton(conf.dst_eth) + o.eth_pkt = ethernet:new({}) + return o +end + +function ChangeMAC:push() + local i, o = self.input.input, self.output.output + for _ = 1, link.nreadable(i) do + local p = receive(i) + local data, length = p.data, p.length + if length > 0 then + local eth_pkt = self.eth_pkt:new_from_mem(data, length) + eth_pkt:src(self.src_eth) + eth_pkt:dst(self.dst_eth) + transmit(o, p) + else + packet.free(p) + end + end +end + +RouteNorth = {} +local IP_TYPE = 0x0800 +local ARP_TYPE = 0x0806 +local IPICMP_TYPE = 0x01 +local ETH_SIZE = ethernet:sizeof() + +function RouteNorth:new (conf) + local o = {lpm_hash = lpm4:new(), + arp_table = {}, + src_eth = ethernet:pton(conf.src_eth), + eth_pkt = ethernet:new({}), + ippkt = ipv4:new({})} + o.lpm_hash:add_string("16.0.0.1/24", 1) + o.lpm_hash:build() + o.arp_table[1] = ethernet:pton("08:35:71:00:97:14") + return setmetatable(o, {__index = self}) +end + +function RouteNorth:push() + local i = assert(self.input.input, "input port not found") + local o = assert(self.output.output, "output port not found") + + while not link.empty(i) do + local p = link.receive(i) + local result = self:process_packet(p, o) + end +end + +function RouteNorth:process_packet(p, o) + local eth_pkt = self.eth_pkt:new_from_mem(p.data, p.length) + if eth_pkt:type() == IP_TYPE then + local ippkt = self.ippkt:new_from_mem(p.data+ETH_SIZE, ipv4:sizeof()) + if ippkt:protocol() == IPICMP_TYPE then + packet.free(p) + end + local client_ip = ippkt:dst() + local gw_idx = self.lpm_hash:search_string(ipv4:ntop(client_ip)) + if gw_idx == nil then + logger:log("Freeing a packet as index is nil") + packet.free(p) + else + local lookedup_mac = self.arp_table[gw_idx] + eth_pkt:src(self.src_eth) + eth_pkt:dst(lookedup_mac) + link.transmit(o,p) + end + else + packet.free(p) + end +end diff --git a/src/core/app.lua b/src/core/app.lua index 9ea416797c..893e251036 100644 --- a/src/core/app.lua +++ b/src/core/app.lua @@ -82,6 +82,7 @@ end -- Run app:methodname() in protected mode (pcall). If it throws an -- error app will be marked as dead and restarted eventually. function with_restart (app, method) + jit.tracebarrier() -- don't mix engine and apps in traces local status, result if use_restart then -- Run fn in protected mode using pcall. @@ -95,6 +96,7 @@ function with_restart (app, method) else status, result = true, method(app) end + jit.tracebarrier() return status, result end diff --git a/src/program/jit_loop/jit_loop.lua b/src/program/jit_loop/jit_loop.lua new file mode 100644 index 0000000000..22aa76f62e --- /dev/null +++ b/src/program/jit_loop/jit_loop.lua @@ -0,0 +1,40 @@ +module(..., package.seeall) + +local lib = require("core.lib") +local logger = lib.logger_new({ rate = 32, module = 'minapp' }); +local intel = require("apps.intel_mp.intel_mp") +local ipv4_apps = require("apps.jit_loop.ipv4_apps") + +function run (parameters) + local north_pci_address = "0000:01:00.1" + local south_pci_address = "0000:01:00.0" + local north_mac = "08:35:71:02:6a:63" + local south_mac = "08:35:71:02:6a:62" + local north_next_hop_mac = "08:35:71:00:97:15" + local south_next_hop_mac = "08:35:71:00:97:14" + + local south_if_config = {pciaddr=south_pci_address, rxq = 0, txq = 0} + local north_if_config = {pciaddr=north_pci_address, rxq = 0, txq = 0} + + local north_mac_config = {src_eth = north_mac, dst_eth = north_next_hop_mac} + local south_mac_config = {src_eth = south_mac, dst_eth = south_next_hop_mac} + + local south_rt_config = {src_eth = south_mac} + + local c = config.new() + config.app(c, "south_if", intel.Intel, south_if_config) + config.app(c, "north_if", intel.Intel, north_if_config) + config.app(c, "north_setmac", ipv4_apps.ChangeMAC, north_mac_config) + config.app(c, "south_setmac", ipv4_apps.ChangeMAC, south_mac_config) + config.app(c, "south_rt", ipv4_apps.RouteNorth, south_rt_config) + + config.link(c, "south_if.output -> north_setmac.input") + config.link(c, "north_setmac.output -> north_if.input") + + config.link(c, "north_if.output -> south_rt.input") + config.link(c, "south_rt.output -> south_if.input") + + engine.configure(c) + logger:log ("Engine ready to start processing") + engine.main({report = {showlinks=true, showapps=true}}) +end