You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2015/07/23 13:14:06 UTC

[09/43] trafficserver git commit: TS-3783 TS-3030 Add luajit v2.0.4 as a subtree

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_tab.c
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_tab.c b/lib/luajit/src/lj_tab.c
new file mode 100644
index 0000000..a8062db
--- /dev/null
+++ b/lib/luajit/src/lj_tab.c
@@ -0,0 +1,631 @@
+/*
+** Table handling.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+**
+** Major portions taken verbatim or adapted from the Lua interpreter.
+** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
+*/
+
+#define lj_tab_c
+#define LUA_CORE
+
+#include "lj_obj.h"
+#include "lj_gc.h"
+#include "lj_err.h"
+#include "lj_tab.h"
+
+/* -- Object hashing ------------------------------------------------------ */
+
+/* Hash values are masked with the table hash mask and used as an index. */
+static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
+{
+  Node *n = noderef(t->node);
+  return &n[hash & t->hmask];
+}
+
+/* String hashes are precomputed when they are interned. */
+#define hashstr(t, s)		hashmask(t, (s)->hash)
+
+#define hashlohi(t, lo, hi)	hashmask((t), hashrot((lo), (hi)))
+#define hashnum(t, o)		hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
+#define hashptr(t, p)		hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS)
+#define hashgcref(t, r)		hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
+
+/* Hash an arbitrary key and return its anchor position in the hash table. */
+static Node *hashkey(const GCtab *t, cTValue *key)
+{
+  lua_assert(!tvisint(key));
+  if (tvisstr(key))
+    return hashstr(t, strV(key));
+  else if (tvisnum(key))
+    return hashnum(t, key);
+  else if (tvisbool(key))
+    return hashmask(t, boolV(key));
+  else
+    return hashgcref(t, key->gcr);
+  /* Only hash 32 bits of lightuserdata on a 64 bit CPU. Good enough? */
+}
+
+/* -- Table creation and destruction -------------------------------------- */
+
+/* Create new hash part for table. */
+static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
+{
+  uint32_t hsize;
+  Node *node;
+  lua_assert(hbits != 0);
+  if (hbits > LJ_MAX_HBITS)
+    lj_err_msg(L, LJ_ERR_TABOV);
+  hsize = 1u << hbits;
+  node = lj_mem_newvec(L, hsize, Node);
+  setmref(node->freetop, &node[hsize]);
+  setmref(t->node, node);
+  t->hmask = hsize-1;
+}
+
+/*
+** Q: Why all of these copies of t->hmask, t->node etc. to local variables?
+** A: Because alias analysis for C is _really_ tough.
+**    Even state-of-the-art C compilers won't produce good code without this.
+*/
+
+/* Clear hash part of table. */
+static LJ_AINLINE void clearhpart(GCtab *t)
+{
+  uint32_t i, hmask = t->hmask;
+  Node *node = noderef(t->node);
+  lua_assert(t->hmask != 0);
+  for (i = 0; i <= hmask; i++) {
+    Node *n = &node[i];
+    setmref(n->next, NULL);
+    setnilV(&n->key);
+    setnilV(&n->val);
+  }
+}
+
+/* Clear array part of table. */
+static LJ_AINLINE void clearapart(GCtab *t)
+{
+  uint32_t i, asize = t->asize;
+  TValue *array = tvref(t->array);
+  for (i = 0; i < asize; i++)
+    setnilV(&array[i]);
+}
+
+/* Create a new table. Note: the slots are not initialized (yet). */
+static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
+{
+  GCtab *t;
+  /* First try to colocate the array part. */
+  if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) {
+    lua_assert((sizeof(GCtab) & 7) == 0);
+    t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
+    t->gct = ~LJ_TTAB;
+    t->nomm = (uint8_t)~0;
+    t->colo = (int8_t)asize;
+    setmref(t->array, (TValue *)((char *)t + sizeof(GCtab)));
+    setgcrefnull(t->metatable);
+    t->asize = asize;
+    t->hmask = 0;
+    setmref(t->node, &G(L)->nilnode);
+  } else {  /* Otherwise separately allocate the array part. */
+    t = lj_mem_newobj(L, GCtab);
+    t->gct = ~LJ_TTAB;
+    t->nomm = (uint8_t)~0;
+    t->colo = 0;
+    setmref(t->array, NULL);
+    setgcrefnull(t->metatable);
+    t->asize = 0;  /* In case the array allocation fails. */
+    t->hmask = 0;
+    setmref(t->node, &G(L)->nilnode);
+    if (asize > 0) {
+      if (asize > LJ_MAX_ASIZE)
+	lj_err_msg(L, LJ_ERR_TABOV);
+      setmref(t->array, lj_mem_newvec(L, asize, TValue));
+      t->asize = asize;
+    }
+  }
+  if (hbits)
+    newhpart(L, t, hbits);
+  return t;
+}
+
+/* Create a new table.
+**
+** IMPORTANT NOTE: The API differs from lua_createtable()!
+**
+** The array size is non-inclusive. E.g. asize=128 creates array slots
+** for 0..127, but not for 128. If you need slots 1..128, pass asize=129
+** (slot 0 is wasted in this case).
+**
+** The hash size is given in hash bits. hbits=0 means no hash part.
+** hbits=1 creates 2 hash slots, hbits=2 creates 4 hash slots and so on.
+*/
+GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits)
+{
+  GCtab *t = newtab(L, asize, hbits);
+  clearapart(t);
+  if (t->hmask > 0) clearhpart(t);
+  return t;
+}
+
+#if LJ_HASJIT
+GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize)
+{
+  GCtab *t = newtab(L, ahsize & 0xffffff, ahsize >> 24);
+  clearapart(t);
+  if (t->hmask > 0) clearhpart(t);
+  return t;
+}
+#endif
+
+/* Duplicate a table. */
+GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
+{
+  GCtab *t;
+  uint32_t asize, hmask;
+  t = newtab(L, kt->asize, kt->hmask > 0 ? lj_fls(kt->hmask)+1 : 0);
+  lua_assert(kt->asize == t->asize && kt->hmask == t->hmask);
+  t->nomm = 0;  /* Keys with metamethod names may be present. */
+  asize = kt->asize;
+  if (asize > 0) {
+    TValue *array = tvref(t->array);
+    TValue *karray = tvref(kt->array);
+    if (asize < 64) {  /* An inlined loop beats memcpy for < 512 bytes. */
+      uint32_t i;
+      for (i = 0; i < asize; i++)
+	copyTV(L, &array[i], &karray[i]);
+    } else {
+      memcpy(array, karray, asize*sizeof(TValue));
+    }
+  }
+  hmask = kt->hmask;
+  if (hmask > 0) {
+    uint32_t i;
+    Node *node = noderef(t->node);
+    Node *knode = noderef(kt->node);
+    ptrdiff_t d = (char *)node - (char *)knode;
+    setmref(node->freetop, (Node *)((char *)noderef(knode->freetop) + d));
+    for (i = 0; i <= hmask; i++) {
+      Node *kn = &knode[i];
+      Node *n = &node[i];
+      Node *next = nextnode(kn);
+      /* Don't use copyTV here, since it asserts on a copy of a dead key. */
+      n->val = kn->val; n->key = kn->key;
+      setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
+    }
+  }
+  return t;
+}
+
+/* Free a table. */
+void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
+{
+  if (t->hmask > 0)
+    lj_mem_freevec(g, noderef(t->node), t->hmask+1, Node);
+  if (t->asize > 0 && LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
+    lj_mem_freevec(g, tvref(t->array), t->asize, TValue);
+  if (LJ_MAX_COLOSIZE != 0 && t->colo)
+    lj_mem_free(g, t, sizetabcolo((uint32_t)t->colo & 0x7f));
+  else
+    lj_mem_freet(g, t);
+}
+
+/* -- Table resizing ------------------------------------------------------ */
+
+/* Resize a table to fit the new array/hash part sizes. */
+static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
+{
+  Node *oldnode = noderef(t->node);
+  uint32_t oldasize = t->asize;
+  uint32_t oldhmask = t->hmask;
+  if (asize > oldasize) {  /* Array part grows? */
+    TValue *array;
+    uint32_t i;
+    if (asize > LJ_MAX_ASIZE)
+      lj_err_msg(L, LJ_ERR_TABOV);
+    if (LJ_MAX_COLOSIZE != 0 && t->colo > 0) {
+      /* A colocated array must be separated and copied. */
+      TValue *oarray = tvref(t->array);
+      array = lj_mem_newvec(L, asize, TValue);
+      t->colo = (int8_t)(t->colo | 0x80);  /* Mark as separated (colo < 0). */
+      for (i = 0; i < oldasize; i++)
+	copyTV(L, &array[i], &oarray[i]);
+    } else {
+      array = (TValue *)lj_mem_realloc(L, tvref(t->array),
+			  oldasize*sizeof(TValue), asize*sizeof(TValue));
+    }
+    setmref(t->array, array);
+    t->asize = asize;
+    for (i = oldasize; i < asize; i++)  /* Clear newly allocated slots. */
+      setnilV(&array[i]);
+  }
+  /* Create new (empty) hash part. */
+  if (hbits) {
+    newhpart(L, t, hbits);
+    clearhpart(t);
+  } else {
+    global_State *g = G(L);
+    setmref(t->node, &g->nilnode);
+    t->hmask = 0;
+  }
+  if (asize < oldasize) {  /* Array part shrinks? */
+    TValue *array = tvref(t->array);
+    uint32_t i;
+    t->asize = asize;  /* Note: This 'shrinks' even colocated arrays. */
+    for (i = asize; i < oldasize; i++)  /* Reinsert old array values. */
+      if (!tvisnil(&array[i]))
+	copyTV(L, lj_tab_setinth(L, t, (int32_t)i), &array[i]);
+    /* Physically shrink only separated arrays. */
+    if (LJ_MAX_COLOSIZE != 0 && t->colo <= 0)
+      setmref(t->array, lj_mem_realloc(L, array,
+	      oldasize*sizeof(TValue), asize*sizeof(TValue)));
+  }
+  if (oldhmask > 0) {  /* Reinsert pairs from old hash part. */
+    global_State *g;
+    uint32_t i;
+    for (i = 0; i <= oldhmask; i++) {
+      Node *n = &oldnode[i];
+      if (!tvisnil(&n->val))
+	copyTV(L, lj_tab_set(L, t, &n->key), &n->val);
+    }
+    g = G(L);
+    lj_mem_freevec(g, oldnode, oldhmask+1, Node);
+  }
+}
+
+static uint32_t countint(cTValue *key, uint32_t *bins)
+{
+  lua_assert(!tvisint(key));
+  if (tvisnum(key)) {
+    lua_Number nk = numV(key);
+    int32_t k = lj_num2int(nk);
+    if ((uint32_t)k < LJ_MAX_ASIZE && nk == (lua_Number)k) {
+      bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static uint32_t countarray(const GCtab *t, uint32_t *bins)
+{
+  uint32_t na, b, i;
+  if (t->asize == 0) return 0;
+  for (na = i = b = 0; b < LJ_MAX_ABITS; b++) {
+    uint32_t n, top = 2u << b;
+    TValue *array;
+    if (top >= t->asize) {
+      top = t->asize-1;
+      if (i > top)
+	break;
+    }
+    array = tvref(t->array);
+    for (n = 0; i <= top; i++)
+      if (!tvisnil(&array[i]))
+	n++;
+    bins[b] += n;
+    na += n;
+  }
+  return na;
+}
+
+static uint32_t counthash(const GCtab *t, uint32_t *bins, uint32_t *narray)
+{
+  uint32_t total, na, i, hmask = t->hmask;
+  Node *node = noderef(t->node);
+  for (total = na = 0, i = 0; i <= hmask; i++) {
+    Node *n = &node[i];
+    if (!tvisnil(&n->val)) {
+      na += countint(&n->key, bins);
+      total++;
+    }
+  }
+  *narray += na;
+  return total;
+}
+
+static uint32_t bestasize(uint32_t bins[], uint32_t *narray)
+{
+  uint32_t b, sum, na = 0, sz = 0, nn = *narray;
+  for (b = 0, sum = 0; 2*nn > (1u<<b) && sum != nn; b++)
+    if (bins[b] > 0 && 2*(sum += bins[b]) > (1u<<b)) {
+      sz = (2u<<b)+1;
+      na = sum;
+    }
+  *narray = sz;
+  return na;
+}
+
+static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
+{
+  uint32_t bins[LJ_MAX_ABITS];
+  uint32_t total, asize, na, i;
+  for (i = 0; i < LJ_MAX_ABITS; i++) bins[i] = 0;
+  asize = countarray(t, bins);
+  total = 1 + asize;
+  total += counthash(t, bins, &asize);
+  asize += countint(ek, bins);
+  na = bestasize(bins, &asize);
+  total -= na;
+  resizetab(L, t, asize, hsize2hbits(total));
+}
+
+#if LJ_HASFFI
+void lj_tab_rehash(lua_State *L, GCtab *t)
+{
+  rehashtab(L, t, niltv(L));
+}
+#endif
+
+void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
+{
+  resizetab(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
+}
+
+/* -- Table getters ------------------------------------------------------- */
+
+cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key)
+{
+  TValue k;
+  Node *n;
+  k.n = (lua_Number)key;
+  n = hashnum(t, &k);
+  do {
+    if (tvisnum(&n->key) && n->key.n == k.n)
+      return &n->val;
+  } while ((n = nextnode(n)));
+  return NULL;
+}
+
+cTValue *lj_tab_getstr(GCtab *t, GCstr *key)
+{
+  Node *n = hashstr(t, key);
+  do {
+    if (tvisstr(&n->key) && strV(&n->key) == key)
+      return &n->val;
+  } while ((n = nextnode(n)));
+  return NULL;
+}
+
+cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key)
+{
+  if (tvisstr(key)) {
+    cTValue *tv = lj_tab_getstr(t, strV(key));
+    if (tv)
+      return tv;
+  } else if (tvisint(key)) {
+    cTValue *tv = lj_tab_getint(t, intV(key));
+    if (tv)
+      return tv;
+  } else if (tvisnum(key)) {
+    lua_Number nk = numV(key);
+    int32_t k = lj_num2int(nk);
+    if (nk == (lua_Number)k) {
+      cTValue *tv = lj_tab_getint(t, k);
+      if (tv)
+	return tv;
+    } else {
+      goto genlookup;  /* Else use the generic lookup. */
+    }
+  } else if (!tvisnil(key)) {
+    Node *n;
+  genlookup:
+    n = hashkey(t, key);
+    do {
+      if (lj_obj_equal(&n->key, key))
+	return &n->val;
+    } while ((n = nextnode(n)));
+  }
+  return niltv(L);
+}
+
+/* -- Table setters ------------------------------------------------------- */
+
+/* Insert new key. Use Brent's variation to optimize the chain length. */
+TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
+{
+  Node *n = hashkey(t, key);
+  if (!tvisnil(&n->val) || t->hmask == 0) {
+    Node *nodebase = noderef(t->node);
+    Node *collide, *freenode = noderef(nodebase->freetop);
+    lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1);
+    do {
+      if (freenode == nodebase) {  /* No free node found? */
+	rehashtab(L, t, key);  /* Rehash table. */
+	return lj_tab_set(L, t, key);  /* Retry key insertion. */
+      }
+    } while (!tvisnil(&(--freenode)->key));
+    setmref(nodebase->freetop, freenode);
+    lua_assert(freenode != &G(L)->nilnode);
+    collide = hashkey(t, &n->key);
+    if (collide != n) {  /* Colliding node not the main node? */
+      while (noderef(collide->next) != n)  /* Find predecessor. */
+	collide = nextnode(collide);
+      setmref(collide->next, freenode);  /* Relink chain. */
+      /* Copy colliding node into free node and free main node. */
+      freenode->val = n->val;
+      freenode->key = n->key;
+      freenode->next = n->next;
+      setmref(n->next, NULL);
+      setnilV(&n->val);
+      /* Rechain pseudo-resurrected string keys with colliding hashes. */
+      while (nextnode(freenode)) {
+	Node *nn = nextnode(freenode);
+	if (tvisstr(&nn->key) && !tvisnil(&nn->val) &&
+	    hashstr(t, strV(&nn->key)) == n) {
+	  freenode->next = nn->next;
+	  nn->next = n->next;
+	  setmref(n->next, nn);
+	} else {
+	  freenode = nn;
+	}
+      }
+    } else {  /* Otherwise use free node. */
+      setmrefr(freenode->next, n->next);  /* Insert into chain. */
+      setmref(n->next, freenode);
+      n = freenode;
+    }
+  }
+  n->key.u64 = key->u64;
+  if (LJ_UNLIKELY(tvismzero(&n->key)))
+    n->key.u64 = 0;
+  lj_gc_anybarriert(L, t);
+  lua_assert(tvisnil(&n->val));
+  return &n->val;
+}
+
+TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key)
+{
+  TValue k;
+  Node *n;
+  k.n = (lua_Number)key;
+  n = hashnum(t, &k);
+  do {
+    if (tvisnum(&n->key) && n->key.n == k.n)
+      return &n->val;
+  } while ((n = nextnode(n)));
+  return lj_tab_newkey(L, t, &k);
+}
+
+TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key)
+{
+  TValue k;
+  Node *n = hashstr(t, key);
+  do {
+    if (tvisstr(&n->key) && strV(&n->key) == key)
+      return &n->val;
+  } while ((n = nextnode(n)));
+  setstrV(L, &k, key);
+  return lj_tab_newkey(L, t, &k);
+}
+
+TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key)
+{
+  Node *n;
+  t->nomm = 0;  /* Invalidate negative metamethod cache. */
+  if (tvisstr(key)) {
+    return lj_tab_setstr(L, t, strV(key));
+  } else if (tvisint(key)) {
+    return lj_tab_setint(L, t, intV(key));
+  } else if (tvisnum(key)) {
+    lua_Number nk = numV(key);
+    int32_t k = lj_num2int(nk);
+    if (nk == (lua_Number)k)
+      return lj_tab_setint(L, t, k);
+    if (tvisnan(key))
+      lj_err_msg(L, LJ_ERR_NANIDX);
+    /* Else use the generic lookup. */
+  } else if (tvisnil(key)) {
+    lj_err_msg(L, LJ_ERR_NILIDX);
+  }
+  n = hashkey(t, key);
+  do {
+    if (lj_obj_equal(&n->key, key))
+      return &n->val;
+  } while ((n = nextnode(n)));
+  return lj_tab_newkey(L, t, key);
+}
+
+/* -- Table traversal ----------------------------------------------------- */
+
+/* Get the traversal index of a key. */
+static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key)
+{
+  TValue tmp;
+  if (tvisint(key)) {
+    int32_t k = intV(key);
+    if ((uint32_t)k < t->asize)
+      return (uint32_t)k;  /* Array key indexes: [0..t->asize-1] */
+    setnumV(&tmp, (lua_Number)k);
+    key = &tmp;
+  } else if (tvisnum(key)) {
+    lua_Number nk = numV(key);
+    int32_t k = lj_num2int(nk);
+    if ((uint32_t)k < t->asize && nk == (lua_Number)k)
+      return (uint32_t)k;  /* Array key indexes: [0..t->asize-1] */
+  }
+  if (!tvisnil(key)) {
+    Node *n = hashkey(t, key);
+    do {
+      if (lj_obj_equal(&n->key, key))
+	return t->asize + (uint32_t)(n - noderef(t->node));
+	/* Hash key indexes: [t->asize..t->asize+t->nmask] */
+    } while ((n = nextnode(n)));
+    if (key->u32.hi == 0xfffe7fff)  /* ITERN was despecialized while running. */
+      return key->u32.lo - 1;
+    lj_err_msg(L, LJ_ERR_NEXTIDX);
+    return 0;  /* unreachable */
+  }
+  return ~0u;  /* A nil key starts the traversal. */
+}
+
+/* Advance to the next step in a table traversal. */
+int lj_tab_next(lua_State *L, GCtab *t, TValue *key)
+{
+  uint32_t i = keyindex(L, t, key);  /* Find predecessor key index. */
+  for (i++; i < t->asize; i++)  /* First traverse the array keys. */
+    if (!tvisnil(arrayslot(t, i))) {
+      setintV(key, i);
+      copyTV(L, key+1, arrayslot(t, i));
+      return 1;
+    }
+  for (i -= t->asize; i <= t->hmask; i++) {  /* Then traverse the hash keys. */
+    Node *n = &noderef(t->node)[i];
+    if (!tvisnil(&n->val)) {
+      copyTV(L, key, &n->key);
+      copyTV(L, key+1, &n->val);
+      return 1;
+    }
+  }
+  return 0;  /* End of traversal. */
+}
+
+/* -- Table length calculation -------------------------------------------- */
+
+static MSize unbound_search(GCtab *t, MSize j)
+{
+  cTValue *tv;
+  MSize i = j;  /* i is zero or a present index */
+  j++;
+  /* find `i' and `j' such that i is present and j is not */
+  while ((tv = lj_tab_getint(t, (int32_t)j)) && !tvisnil(tv)) {
+    i = j;
+    j *= 2;
+    if (j > (MSize)(INT_MAX-2)) {  /* overflow? */
+      /* table was built with bad purposes: resort to linear search */
+      i = 1;
+      while ((tv = lj_tab_getint(t, (int32_t)i)) && !tvisnil(tv)) i++;
+      return i - 1;
+    }
+  }
+  /* now do a binary search between them */
+  while (j - i > 1) {
+    MSize m = (i+j)/2;
+    cTValue *tvb = lj_tab_getint(t, (int32_t)m);
+    if (tvb && !tvisnil(tvb)) i = m; else j = m;
+  }
+  return i;
+}
+
+/*
+** Try to find a boundary in table `t'. A `boundary' is an integer index
+** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
+*/
+MSize LJ_FASTCALL lj_tab_len(GCtab *t)
+{
+  MSize j = (MSize)t->asize;
+  if (j > 1 && tvisnil(arrayslot(t, j-1))) {
+    MSize i = 1;
+    while (j - i > 1) {
+      MSize m = (i+j)/2;
+      if (tvisnil(arrayslot(t, m-1))) j = m; else i = m;
+    }
+    return i-1;
+  }
+  if (j) j--;
+  if (t->hmask <= 0)
+    return j;
+  return unbound_search(t, j);
+}
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_tab.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_tab.h b/lib/luajit/src/lj_tab.h
new file mode 100644
index 0000000..f0d228e
--- /dev/null
+++ b/lib/luajit/src/lj_tab.h
@@ -0,0 +1,70 @@
+/*
+** Table handling.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TAB_H
+#define _LJ_TAB_H
+
+#include "lj_obj.h"
+
+/* Hash constants. Tuned using a brute force search. */
+#define HASH_BIAS	(-0x04c11db7)
+#define HASH_ROT1	14
+#define HASH_ROT2	5
+#define HASH_ROT3	13
+
+/* Scramble the bits of numbers and pointers. */
+static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
+{
+#if LJ_TARGET_X86ORX64
+  /* Prefer variant that compiles well for a 2-operand CPU. */
+  lo ^= hi; hi = lj_rol(hi, HASH_ROT1);
+  lo -= hi; hi = lj_rol(hi, HASH_ROT2);
+  hi ^= lo; hi -= lj_rol(lo, HASH_ROT3);
+#else
+  lo ^= hi;
+  lo = lo - lj_rol(hi, HASH_ROT1);
+  hi = lo ^ lj_rol(hi, HASH_ROT1 + HASH_ROT2);
+  hi = hi - lj_rol(lo, HASH_ROT3);
+#endif
+  return hi;
+}
+
+#define hsize2hbits(s)	((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
+
+LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);
+#if LJ_HASJIT
+LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize);
+#endif
+LJ_FUNCA GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt);
+LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
+#if LJ_HASFFI
+LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
+#endif
+LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);
+
+/* Caveat: all getters except lj_tab_get() can return NULL! */
+
+LJ_FUNCA cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key);
+LJ_FUNC cTValue *lj_tab_getstr(GCtab *t, GCstr *key);
+LJ_FUNCA cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key);
+
+/* Caveat: all setters require a write barrier for the stored value. */
+
+LJ_FUNCA TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key);
+LJ_FUNC TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key);
+LJ_FUNC TValue *lj_tab_setstr(lua_State *L, GCtab *t, GCstr *key);
+LJ_FUNC TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key);
+
+#define inarray(t, key)		((MSize)(key) < (MSize)(t)->asize)
+#define arrayslot(t, i)		(&tvref((t)->array)[(i)])
+#define lj_tab_getint(t, key) \
+  (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_getinth((t), (key)))
+#define lj_tab_setint(L, t, key) \
+  (inarray((t), (key)) ? arrayslot((t), (key)) : lj_tab_setinth(L, (t), (key)))
+
+LJ_FUNCA int lj_tab_next(lua_State *L, GCtab *t, TValue *key);
+LJ_FUNCA MSize LJ_FASTCALL lj_tab_len(GCtab *t);
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_target.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_target.h b/lib/luajit/src/lj_target.h
new file mode 100644
index 0000000..1a24232
--- /dev/null
+++ b/lib/luajit/src/lj_target.h
@@ -0,0 +1,162 @@
+/*
+** Definitions for target CPU.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TARGET_H
+#define _LJ_TARGET_H
+
+#include "lj_def.h"
+#include "lj_arch.h"
+
+/* -- Registers and spill slots ------------------------------------------- */
+
+/* Register type (uint8_t in ir->r). */
+typedef uint32_t Reg;
+
+/* The hi-bit is NOT set for an allocated register. This means the value
+** can be directly used without masking. The hi-bit is set for a register
+** allocation hint or for RID_INIT, RID_SINK or RID_SUNK.
+*/
+#define RID_NONE		0x80
+#define RID_MASK		0x7f
+#define RID_INIT		(RID_NONE|RID_MASK)
+#define RID_SINK		(RID_INIT-1)
+#define RID_SUNK		(RID_INIT-2)
+
+#define ra_noreg(r)		((r) & RID_NONE)
+#define ra_hasreg(r)		(!((r) & RID_NONE))
+
+/* The ra_hashint() macro assumes a previous test for ra_noreg(). */
+#define ra_hashint(r)		((r) < RID_SUNK)
+#define ra_gethint(r)		((Reg)((r) & RID_MASK))
+#define ra_sethint(rr, r)	rr = (uint8_t)((r)|RID_NONE)
+#define ra_samehint(r1, r2)	(ra_gethint((r1)^(r2)) == 0)
+
+/* Spill slot 0 means no spill slot has been allocated. */
+#define SPS_NONE		0
+
+#define ra_hasspill(s)		((s) != SPS_NONE)
+
+/* Combined register and spill slot (uint16_t in ir->prev). */
+typedef uint32_t RegSP;
+
+#define REGSP(r, s)		((r) + ((s) << 8))
+#define REGSP_HINT(r)		((r)|RID_NONE)
+#define REGSP_INIT		REGSP(RID_INIT, 0)
+
+#define regsp_reg(rs)		((rs) & 255)
+#define regsp_spill(rs)		((rs) >> 8)
+#define regsp_used(rs) \
+  (((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0))
+
+/* -- Register sets ------------------------------------------------------- */
+
+/* Bitset for registers. 32 registers suffice for most architectures.
+** Note that one set holds bits for both GPRs and FPRs.
+*/
+#if LJ_TARGET_PPC || LJ_TARGET_MIPS
+typedef uint64_t RegSet;
+#else
+typedef uint32_t RegSet;
+#endif
+
+#define RID2RSET(r)		(((RegSet)1) << (r))
+#define RSET_EMPTY		((RegSet)0)
+#define RSET_RANGE(lo, hi)	((RID2RSET((hi)-(lo))-1) << (lo))
+
+#define rset_test(rs, r)	((int)((rs) >> (r)) & 1)
+#define rset_set(rs, r)		(rs |= RID2RSET(r))
+#define rset_clear(rs, r)	(rs &= ~RID2RSET(r))
+#define rset_exclude(rs, r)	(rs & ~RID2RSET(r))
+#if LJ_TARGET_PPC || LJ_TARGET_MIPS
+#define rset_picktop(rs)	((Reg)(__builtin_clzll(rs)^63))
+#define rset_pickbot(rs)	((Reg)__builtin_ctzll(rs))
+#else
+#define rset_picktop(rs)	((Reg)lj_fls(rs))
+#define rset_pickbot(rs)	((Reg)lj_ffs(rs))
+#endif
+
+/* -- Register allocation cost -------------------------------------------- */
+
+/* The register allocation heuristic keeps track of the cost for allocating
+** a specific register:
+**
+** A free register (obviously) has a cost of 0 and a 1-bit in the free mask.
+**
+** An already allocated register has the (non-zero) IR reference in the lowest
+** bits and the result of a blended cost-model in the higher bits.
+**
+** The allocator first checks the free mask for a hit. Otherwise an (unrolled)
+** linear search for the minimum cost is used. The search doesn't need to
+** keep track of the position of the minimum, which makes it very fast.
+** The lowest bits of the minimum cost show the desired IR reference whose
+** register is the one to evict.
+**
+** Without the cost-model this degenerates to the standard heuristics for
+** (reverse) linear-scan register allocation. Since code generation is done
+** in reverse, a live interval extends from the last use to the first def.
+** For an SSA IR the IR reference is the first (and only) def and thus
+** trivially marks the end of the interval. The LSRA heuristics says to pick
+** the register whose live interval has the furthest extent, i.e. the lowest
+** IR reference in our case.
+**
+** A cost-model should take into account other factors, like spill-cost and
+** restore- or rematerialization-cost, which depend on the kind of instruction.
+** E.g. constants have zero spill costs, variant instructions have higher
+** costs than invariants and PHIs should preferably never be spilled.
+**
+** Here's a first cut at simple, but effective blended cost-model for R-LSRA:
+** - Due to careful design of the IR, constants already have lower IR
+**   references than invariants and invariants have lower IR references
+**   than variants.
+** - The cost in the upper 16 bits is the sum of the IR reference and a
+**   weighted score. The score currently only takes into account whether
+**   the IRT_ISPHI bit is set in the instruction type.
+** - The PHI weight is the minimum distance (in IR instructions) a PHI
+**   reference has to be further apart from a non-PHI reference to be spilled.
+** - It should be a power of two (for speed) and must be between 2 and 32768.
+**   Good values for the PHI weight seem to be between 40 and 150.
+** - Further study is required.
+*/
+#define REGCOST_PHI_WEIGHT	64
+
+/* Cost for allocating a specific register. */
+typedef uint32_t RegCost;
+
+/* Note: assumes 16 bit IRRef1. */
+#define REGCOST(cost, ref)	((RegCost)(ref) + ((RegCost)(cost) << 16))
+#define regcost_ref(rc)		((IRRef1)(rc))
+
+#define REGCOST_T(t) \
+  ((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI))
+#define REGCOST_REF_T(ref, t)	(REGCOST((ref), (ref)) + REGCOST_T((t)))
+
+/* -- Target-specific definitions ----------------------------------------- */
+
+#if LJ_TARGET_X86ORX64
+#include "lj_target_x86.h"
+#elif LJ_TARGET_ARM
+#include "lj_target_arm.h"
+#elif LJ_TARGET_PPC
+#include "lj_target_ppc.h"
+#elif LJ_TARGET_MIPS
+#include "lj_target_mips.h"
+#else
+#error "Missing include for target CPU"
+#endif
+
+#ifdef EXITSTUBS_PER_GROUP
+/* Return the address of an exit stub. */
+static LJ_AINLINE char *exitstub_addr_(char **group, uint32_t exitno)
+{
+  lua_assert(group[exitno / EXITSTUBS_PER_GROUP] != NULL);
+  return (char *)group[exitno / EXITSTUBS_PER_GROUP] +
+	 EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP);
+}
+/* Avoid dependence on lj_jit.h if only including lj_target.h. */
+#define exitstub_addr(J, exitno) \
+  ((MCode *)exitstub_addr_((char **)((J)->exitstubgroup), (exitno)))
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_target_arm.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_target_arm.h b/lib/luajit/src/lj_target_arm.h
new file mode 100644
index 0000000..6d4d0ae
--- /dev/null
+++ b/lib/luajit/src/lj_target_arm.h
@@ -0,0 +1,274 @@
+/*
+** Definitions for ARM CPUs.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TARGET_ARM_H
+#define _LJ_TARGET_ARM_H
+
+/* -- Registers IDs ------------------------------------------------------- */
+
+#define GPRDEF(_) \
+  _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
+  _(R8) _(R9) _(R10) _(R11) _(R12) _(SP) _(LR) _(PC)
+#if LJ_SOFTFP
+#define FPRDEF(_)
+#else
+#define FPRDEF(_) \
+  _(D0) _(D1) _(D2) _(D3) _(D4) _(D5) _(D6) _(D7) \
+  _(D8) _(D9) _(D10) _(D11) _(D12) _(D13) _(D14) _(D15)
+#endif
+#define VRIDDEF(_)
+
+#define RIDENUM(name)	RID_##name,
+
+enum {
+  GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
+  FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
+  RID_MAX,
+  RID_TMP = RID_LR,
+
+  /* Calling conventions. */
+  RID_RET = RID_R0,
+  RID_RETLO = RID_R0,
+  RID_RETHI = RID_R1,
+#if LJ_SOFTFP
+  RID_FPRET = RID_R0,
+#else
+  RID_FPRET = RID_D0,
+#endif
+
+  /* These definitions must match with the *.dasc file(s): */
+  RID_BASE = RID_R9,		/* Interpreter BASE. */
+  RID_LPC = RID_R6,		/* Interpreter PC. */
+  RID_DISPATCH = RID_R7,	/* Interpreter DISPATCH table. */
+  RID_LREG = RID_R8,		/* Interpreter L. */
+
+  /* Register ranges [min, max) and number of registers. */
+  RID_MIN_GPR = RID_R0,
+  RID_MAX_GPR = RID_PC+1,
+  RID_MIN_FPR = RID_MAX_GPR,
+#if LJ_SOFTFP
+  RID_MAX_FPR = RID_MIN_FPR,
+#else
+  RID_MAX_FPR = RID_D15+1,
+#endif
+  RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
+  RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR
+};
+
+#define RID_NUM_KREF		RID_NUM_GPR
+#define RID_MIN_KREF		RID_R0
+
+/* -- Register sets ------------------------------------------------------- */
+
+/* Make use of all registers, except sp, lr and pc. */
+#define RSET_GPR		(RSET_RANGE(RID_MIN_GPR, RID_R12+1))
+#define RSET_GPREVEN \
+  (RID2RSET(RID_R0)|RID2RSET(RID_R2)|RID2RSET(RID_R4)|RID2RSET(RID_R6)| \
+   RID2RSET(RID_R8)|RID2RSET(RID_R10))
+#define RSET_GPRODD \
+  (RID2RSET(RID_R1)|RID2RSET(RID_R3)|RID2RSET(RID_R5)|RID2RSET(RID_R7)| \
+   RID2RSET(RID_R9)|RID2RSET(RID_R11))
+#if LJ_SOFTFP
+#define RSET_FPR		0
+#else
+#define RSET_FPR		(RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
+#endif
+#define RSET_ALL		(RSET_GPR|RSET_FPR)
+#define RSET_INIT		RSET_ALL
+
+/* ABI-specific register sets. lr is an implicit scratch register. */
+#define RSET_SCRATCH_GPR_	(RSET_RANGE(RID_R0, RID_R3+1)|RID2RSET(RID_R12))
+#ifdef __APPLE__
+#define RSET_SCRATCH_GPR	(RSET_SCRATCH_GPR_|RID2RSET(RID_R9))
+#else
+#define RSET_SCRATCH_GPR	RSET_SCRATCH_GPR_
+#endif
+#if LJ_SOFTFP
+#define RSET_SCRATCH_FPR	0
+#else
+#define RSET_SCRATCH_FPR	(RSET_RANGE(RID_D0, RID_D7+1))
+#endif
+#define RSET_SCRATCH		(RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
+#define REGARG_FIRSTGPR		RID_R0
+#define REGARG_LASTGPR		RID_R3
+#define REGARG_NUMGPR		4
+#if LJ_ABI_SOFTFP
+#define REGARG_FIRSTFPR		0
+#define REGARG_LASTFPR		0
+#define REGARG_NUMFPR		0
+#else
+#define REGARG_FIRSTFPR		RID_D0
+#define REGARG_LASTFPR		RID_D7
+#define REGARG_NUMFPR		8
+#endif
+
+/* -- Spill slots --------------------------------------------------------- */
+
+/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
+**
+** SPS_FIXED: Available fixed spill slots in interpreter frame.
+** This definition must match with the *.dasc file(s).
+**
+** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
+*/
+#define SPS_FIXED	2
+#define SPS_FIRST	2
+
+#define SPOFS_TMP	0
+
+#define sps_scale(slot)		(4 * (int32_t)(slot))
+#define sps_align(slot)		(((slot) - SPS_FIXED + 1) & ~1)
+
+/* -- Exit state ---------------------------------------------------------- */
+
+/* This definition must match with the *.dasc file(s). */
+typedef struct {
+#if !LJ_SOFTFP
+  lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
+#endif
+  int32_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
+  int32_t spill[256];		/* Spill slots. */
+} ExitState;
+
+/* PC after instruction that caused an exit. Used to find the trace number. */
+#define EXITSTATE_PCREG		RID_PC
+/* Highest exit + 1 indicates stack check. */
+#define EXITSTATE_CHECKEXIT	1
+
+#define EXITSTUB_SPACING        4
+#define EXITSTUBS_PER_GROUP     32
+
+/* -- Instructions -------------------------------------------------------- */
+
+/* Instruction fields. */
+#define ARMF_CC(ai, cc)	(((ai) ^ ARMI_CCAL) | ((cc) << 28))
+#define ARMF_N(r)	((r) << 16)
+#define ARMF_D(r)	((r) << 12)
+#define ARMF_S(r)	((r) << 8)
+#define ARMF_M(r)	(r)
+#define ARMF_SH(sh, n)	(((sh) << 5) | ((n) << 7))
+#define ARMF_RSH(sh, r)	(0x10 | ((sh) << 5) | ARMF_S(r))
+
+typedef enum ARMIns {
+  ARMI_CCAL = 0xe0000000,
+  ARMI_S = 0x000100000,
+  ARMI_K12 = 0x02000000,
+  ARMI_KNEG = 0x00200000,
+  ARMI_LS_W = 0x00200000,
+  ARMI_LS_U = 0x00800000,
+  ARMI_LS_P = 0x01000000,
+  ARMI_LS_R = 0x02000000,
+  ARMI_LSX_I = 0x00400000,
+
+  ARMI_AND = 0xe0000000,
+  ARMI_EOR = 0xe0200000,
+  ARMI_SUB = 0xe0400000,
+  ARMI_RSB = 0xe0600000,
+  ARMI_ADD = 0xe0800000,
+  ARMI_ADC = 0xe0a00000,
+  ARMI_SBC = 0xe0c00000,
+  ARMI_RSC = 0xe0e00000,
+  ARMI_TST = 0xe1100000,
+  ARMI_TEQ = 0xe1300000,
+  ARMI_CMP = 0xe1500000,
+  ARMI_CMN = 0xe1700000,
+  ARMI_ORR = 0xe1800000,
+  ARMI_MOV = 0xe1a00000,
+  ARMI_BIC = 0xe1c00000,
+  ARMI_MVN = 0xe1e00000,
+
+  ARMI_NOP = 0xe1a00000,
+
+  ARMI_MUL = 0xe0000090,
+  ARMI_SMULL = 0xe0c00090,
+
+  ARMI_LDR = 0xe4100000,
+  ARMI_LDRB = 0xe4500000,
+  ARMI_LDRH = 0xe01000b0,
+  ARMI_LDRSB = 0xe01000d0,
+  ARMI_LDRSH = 0xe01000f0,
+  ARMI_LDRD = 0xe00000d0,
+  ARMI_STR = 0xe4000000,
+  ARMI_STRB = 0xe4400000,
+  ARMI_STRH = 0xe00000b0,
+  ARMI_STRD = 0xe00000f0,
+  ARMI_PUSH = 0xe92d0000,
+
+  ARMI_B = 0xea000000,
+  ARMI_BL = 0xeb000000,
+  ARMI_BLX = 0xfa000000,
+  ARMI_BLXr = 0xe12fff30,
+
+  /* ARMv6 */
+  ARMI_REV = 0xe6bf0f30,
+  ARMI_SXTB = 0xe6af0070,
+  ARMI_SXTH = 0xe6bf0070,
+  ARMI_UXTB = 0xe6ef0070,
+  ARMI_UXTH = 0xe6ff0070,
+
+  /* ARMv6T2 */
+  ARMI_MOVW = 0xe3000000,
+  ARMI_MOVT = 0xe3400000,
+
+  /* VFP */
+  ARMI_VMOV_D = 0xeeb00b40,
+  ARMI_VMOV_S = 0xeeb00a40,
+  ARMI_VMOVI_D = 0xeeb00b00,
+
+  ARMI_VMOV_R_S = 0xee100a10,
+  ARMI_VMOV_S_R = 0xee000a10,
+  ARMI_VMOV_RR_D = 0xec500b10,
+  ARMI_VMOV_D_RR = 0xec400b10,
+
+  ARMI_VADD_D = 0xee300b00,
+  ARMI_VSUB_D = 0xee300b40,
+  ARMI_VMUL_D = 0xee200b00,
+  ARMI_VMLA_D = 0xee000b00,
+  ARMI_VMLS_D = 0xee000b40,
+  ARMI_VNMLS_D = 0xee100b00,
+  ARMI_VDIV_D = 0xee800b00,
+
+  ARMI_VABS_D = 0xeeb00bc0,
+  ARMI_VNEG_D = 0xeeb10b40,
+  ARMI_VSQRT_D = 0xeeb10bc0,
+
+  ARMI_VCMP_D = 0xeeb40b40,
+  ARMI_VCMPZ_D = 0xeeb50b40,
+
+  ARMI_VMRS = 0xeef1fa10,
+
+  ARMI_VCVT_S32_F32 = 0xeebd0ac0,
+  ARMI_VCVT_S32_F64 = 0xeebd0bc0,
+  ARMI_VCVT_U32_F32 = 0xeebc0ac0,
+  ARMI_VCVT_U32_F64 = 0xeebc0bc0,
+  ARMI_VCVTR_S32_F32 = 0xeebd0a40,
+  ARMI_VCVTR_S32_F64 = 0xeebd0b40,
+  ARMI_VCVTR_U32_F32 = 0xeebc0a40,
+  ARMI_VCVTR_U32_F64 = 0xeebc0b40,
+  ARMI_VCVT_F32_S32 = 0xeeb80ac0,
+  ARMI_VCVT_F64_S32 = 0xeeb80bc0,
+  ARMI_VCVT_F32_U32 = 0xeeb80a40,
+  ARMI_VCVT_F64_U32 = 0xeeb80b40,
+  ARMI_VCVT_F32_F64 = 0xeeb70bc0,
+  ARMI_VCVT_F64_F32 = 0xeeb70ac0,
+
+  ARMI_VLDR_S = 0xed100a00,
+  ARMI_VLDR_D = 0xed100b00,
+  ARMI_VSTR_S = 0xed000a00,
+  ARMI_VSTR_D = 0xed000b00,
+} ARMIns;
+
+typedef enum ARMShift {
+  ARMSH_LSL, ARMSH_LSR, ARMSH_ASR, ARMSH_ROR
+} ARMShift;
+
+/* ARM condition codes. */
+typedef enum ARMCC {
+  CC_EQ, CC_NE, CC_CS, CC_CC, CC_MI, CC_PL, CC_VS, CC_VC,
+  CC_HI, CC_LS, CC_GE, CC_LT, CC_GT, CC_LE, CC_AL,
+  CC_HS = CC_CS, CC_LO = CC_CC
+} ARMCC;
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_target_mips.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_target_mips.h b/lib/luajit/src/lj_target_mips.h
new file mode 100644
index 0000000..0ab140b
--- /dev/null
+++ b/lib/luajit/src/lj_target_mips.h
@@ -0,0 +1,257 @@
+/*
+** Definitions for MIPS CPUs.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TARGET_MIPS_H
+#define _LJ_TARGET_MIPS_H
+
+/* -- Registers IDs ------------------------------------------------------- */
+
+#define GPRDEF(_) \
+  _(R0) _(R1) _(R2) _(R3) _(R4) _(R5) _(R6) _(R7) \
+  _(R8) _(R9) _(R10) _(R11) _(R12) _(R13) _(R14) _(R15) \
+  _(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \
+  _(R24) _(R25) _(SYS1) _(SYS2) _(R28) _(SP) _(R30) _(RA)
+#define FPRDEF(_) \
+  _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
+  _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
+  _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
+  _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
+#define VRIDDEF(_)
+
+#define RIDENUM(name)	RID_##name,
+
+enum {
+  GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
+  FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
+  RID_MAX,
+  RID_ZERO = RID_R0,
+  RID_TMP = RID_RA,
+
+  /* Calling conventions. */
+  RID_RET = RID_R2,
+#if LJ_LE
+  RID_RETHI = RID_R3,
+  RID_RETLO = RID_R2,
+#else
+  RID_RETHI = RID_R2,
+  RID_RETLO = RID_R3,
+#endif
+  RID_FPRET = RID_F0,
+  RID_CFUNCADDR = RID_R25,
+
+  /* These definitions must match with the *.dasc file(s): */
+  RID_BASE = RID_R16,		/* Interpreter BASE. */
+  RID_LPC = RID_R18,		/* Interpreter PC. */
+  RID_DISPATCH = RID_R19,	/* Interpreter DISPATCH table. */
+  RID_LREG = RID_R20,		/* Interpreter L. */
+  RID_JGL = RID_R30,		/* On-trace: global_State + 32768. */
+
+  /* Register ranges [min, max) and number of registers. */
+  RID_MIN_GPR = RID_R0,
+  RID_MAX_GPR = RID_RA+1,
+  RID_MIN_FPR = RID_F0,
+  RID_MAX_FPR = RID_F31+1,
+  RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
+  RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR	/* Only even regs are used. */
+};
+
+#define RID_NUM_KREF		RID_NUM_GPR
+#define RID_MIN_KREF		RID_R0
+
+/* -- Register sets ------------------------------------------------------- */
+
+/* Make use of all registers, except ZERO, TMP, SP, SYS1, SYS2 and JGL. */
+#define RSET_FIXED \
+  (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\
+   RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL))
+#define RSET_GPR	(RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
+#define RSET_FPR \
+  (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
+   RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
+   RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\
+   RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30))
+#define RSET_ALL	(RSET_GPR|RSET_FPR)
+#define RSET_INIT	RSET_ALL
+
+#define RSET_SCRATCH_GPR \
+  (RSET_RANGE(RID_R1, RID_R15+1)|\
+   RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_R28))
+#define RSET_SCRATCH_FPR \
+  (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\
+   RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\
+   RID2RSET(RID_F16)|RID2RSET(RID_F18))
+#define RSET_SCRATCH		(RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
+#define REGARG_FIRSTGPR		RID_R4
+#define REGARG_LASTGPR		RID_R7
+#define REGARG_NUMGPR		4
+#define REGARG_FIRSTFPR		RID_F12
+#define REGARG_LASTFPR		RID_F14
+#define REGARG_NUMFPR		2
+
+/* -- Spill slots --------------------------------------------------------- */
+
+/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
+**
+** SPS_FIXED: Available fixed spill slots in interpreter frame.
+** This definition must match with the *.dasc file(s).
+**
+** SPS_FIRST: First spill slot for general use.
+*/
+#define SPS_FIXED	5
+#define SPS_FIRST	4
+
+#define SPOFS_TMP	0
+
+#define sps_scale(slot)		(4 * (int32_t)(slot))
+#define sps_align(slot)		(((slot) - SPS_FIXED + 1) & ~1)
+
+/* -- Exit state ---------------------------------------------------------- */
+
+/* This definition must match with the *.dasc file(s). */
+typedef struct {
+  lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
+  int32_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
+  int32_t spill[256];		/* Spill slots. */
+} ExitState;
+
+/* Highest exit + 1 indicates stack check. */
+#define EXITSTATE_CHECKEXIT	1
+
+/* Return the address of a per-trace exit stub. */
+static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p)
+{
+  while (*p == 0x00000000) p++;  /* Skip MIPSI_NOP. */
+  return p;
+}
+/* Avoid dependence on lj_jit.h if only including lj_target.h. */
+#define exitstub_trace_addr(T, exitno) \
+  exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode))
+
+/* -- Instructions -------------------------------------------------------- */
+
+/* Instruction fields. */
+#define MIPSF_S(r)	((r) << 21)
+#define MIPSF_T(r)	((r) << 16)
+#define MIPSF_D(r)	((r) << 11)
+#define MIPSF_R(r)	((r) << 21)
+#define MIPSF_H(r)	((r) << 16)
+#define MIPSF_G(r)	((r) << 11)
+#define MIPSF_F(r)	((r) << 6)
+#define MIPSF_A(n)	((n) << 6)
+#define MIPSF_M(n)	((n) << 11)
+
+typedef enum MIPSIns {
+  /* Integer instructions. */
+  MIPSI_MOVE = 0x00000021,
+  MIPSI_NOP = 0x00000000,
+
+  MIPSI_LI = 0x24000000,
+  MIPSI_LU = 0x34000000,
+  MIPSI_LUI = 0x3c000000,
+
+  MIPSI_ADDIU = 0x24000000,
+  MIPSI_ANDI = 0x30000000,
+  MIPSI_ORI = 0x34000000,
+  MIPSI_XORI = 0x38000000,
+  MIPSI_SLTI = 0x28000000,
+  MIPSI_SLTIU = 0x2c000000,
+
+  MIPSI_ADDU = 0x00000021,
+  MIPSI_SUBU = 0x00000023,
+  MIPSI_MUL = 0x70000002,
+  MIPSI_AND = 0x00000024,
+  MIPSI_OR = 0x00000025,
+  MIPSI_XOR = 0x00000026,
+  MIPSI_NOR = 0x00000027,
+  MIPSI_SLT = 0x0000002a,
+  MIPSI_SLTU = 0x0000002b,
+  MIPSI_MOVZ = 0x0000000a,
+  MIPSI_MOVN = 0x0000000b,
+
+  MIPSI_SLL = 0x00000000,
+  MIPSI_SRL = 0x00000002,
+  MIPSI_SRA = 0x00000003,
+  MIPSI_ROTR = 0x00200002,	/* MIPS32R2 */
+  MIPSI_SLLV = 0x00000004,
+  MIPSI_SRLV = 0x00000006,
+  MIPSI_SRAV = 0x00000007,
+  MIPSI_ROTRV = 0x00000046,	/* MIPS32R2 */
+
+  MIPSI_SEB = 0x7c000420,	/* MIPS32R2 */
+  MIPSI_SEH = 0x7c000620,	/* MIPS32R2 */
+  MIPSI_WSBH = 0x7c0000a0,	/* MIPS32R2 */
+
+  MIPSI_B = 0x10000000,
+  MIPSI_J = 0x08000000,
+  MIPSI_JAL = 0x0c000000,
+  MIPSI_JR = 0x00000008,
+  MIPSI_JALR = 0x0000f809,
+
+  MIPSI_BEQ = 0x10000000,
+  MIPSI_BNE = 0x14000000,
+  MIPSI_BLEZ = 0x18000000,
+  MIPSI_BGTZ = 0x1c000000,
+  MIPSI_BLTZ = 0x04000000,
+  MIPSI_BGEZ = 0x04010000,
+
+  /* Load/store instructions. */
+  MIPSI_LW = 0x8c000000,
+  MIPSI_SW = 0xac000000,
+  MIPSI_LB = 0x80000000,
+  MIPSI_SB = 0xa0000000,
+  MIPSI_LH = 0x84000000,
+  MIPSI_SH = 0xa4000000,
+  MIPSI_LBU = 0x90000000,
+  MIPSI_LHU = 0x94000000,
+  MIPSI_LWC1 = 0xc4000000,
+  MIPSI_SWC1 = 0xe4000000,
+  MIPSI_LDC1 = 0xd4000000,
+  MIPSI_SDC1 = 0xf4000000,
+
+  /* FP instructions. */
+  MIPSI_MOV_S = 0x46000006,
+  MIPSI_MOV_D = 0x46200006,
+  MIPSI_MOVT_D = 0x46210011,
+  MIPSI_MOVF_D = 0x46200011,
+
+  MIPSI_ABS_D = 0x46200005,
+  MIPSI_NEG_D = 0x46200007,
+
+  MIPSI_ADD_D = 0x46200000,
+  MIPSI_SUB_D = 0x46200001,
+  MIPSI_MUL_D = 0x46200002,
+  MIPSI_DIV_D = 0x46200003,
+  MIPSI_SQRT_D = 0x46200004,
+
+  MIPSI_ADD_S = 0x46000000,
+  MIPSI_SUB_S = 0x46000001,
+
+  MIPSI_CVT_D_S = 0x46000021,
+  MIPSI_CVT_W_S = 0x46000024,
+  MIPSI_CVT_S_D = 0x46200020,
+  MIPSI_CVT_W_D = 0x46200024,
+  MIPSI_CVT_S_W = 0x46800020,
+  MIPSI_CVT_D_W = 0x46800021,
+
+  MIPSI_TRUNC_W_S = 0x4600000d,
+  MIPSI_TRUNC_W_D = 0x4620000d,
+  MIPSI_FLOOR_W_S = 0x4600000f,
+  MIPSI_FLOOR_W_D = 0x4620000f,
+
+  MIPSI_MFC1 = 0x44000000,
+  MIPSI_MTC1 = 0x44800000,
+
+  MIPSI_BC1F = 0x45000000,
+  MIPSI_BC1T = 0x45010000,
+
+  MIPSI_C_EQ_D = 0x46200032,
+  MIPSI_C_OLT_D = 0x46200034,
+  MIPSI_C_ULT_D = 0x46200035,
+  MIPSI_C_OLE_D = 0x46200036,
+  MIPSI_C_ULE_D = 0x46200037,
+
+} MIPSIns;
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_target_ppc.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_target_ppc.h b/lib/luajit/src/lj_target_ppc.h
new file mode 100644
index 0000000..2caeeb0
--- /dev/null
+++ b/lib/luajit/src/lj_target_ppc.h
@@ -0,0 +1,280 @@
+/*
+** Definitions for PPC CPUs.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TARGET_PPC_H
+#define _LJ_TARGET_PPC_H
+
+/* -- Registers IDs ------------------------------------------------------- */
+
+#define GPRDEF(_) \
+  _(R0) _(SP) _(SYS1) _(R3) _(R4) _(R5) _(R6) _(R7) \
+  _(R8) _(R9) _(R10) _(R11) _(R12) _(SYS2) _(R14) _(R15) \
+  _(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \
+  _(R24) _(R25) _(R26) _(R27) _(R28) _(R29) _(R30) _(R31)
+#define FPRDEF(_) \
+  _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \
+  _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \
+  _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \
+  _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31)
+#define VRIDDEF(_)
+
+#define RIDENUM(name)	RID_##name,
+
+enum {
+  GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
+  FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
+  RID_MAX,
+  RID_TMP = RID_R0,
+
+  /* Calling conventions. */
+  RID_RET = RID_R3,
+  RID_RETHI = RID_R3,
+  RID_RETLO = RID_R4,
+  RID_FPRET = RID_F1,
+
+  /* These definitions must match with the *.dasc file(s): */
+  RID_BASE = RID_R14,		/* Interpreter BASE. */
+  RID_LPC = RID_R16,		/* Interpreter PC. */
+  RID_DISPATCH = RID_R17,	/* Interpreter DISPATCH table. */
+  RID_LREG = RID_R18,		/* Interpreter L. */
+  RID_JGL = RID_R31,		/* On-trace: global_State + 32768. */
+
+  /* Register ranges [min, max) and number of registers. */
+  RID_MIN_GPR = RID_R0,
+  RID_MAX_GPR = RID_R31+1,
+  RID_MIN_FPR = RID_F0,
+  RID_MAX_FPR = RID_F31+1,
+  RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
+  RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR
+};
+
+#define RID_NUM_KREF		RID_NUM_GPR
+#define RID_MIN_KREF		RID_R0
+
+/* -- Register sets ------------------------------------------------------- */
+
+/* Make use of all registers, except TMP, SP, SYS1, SYS2 and JGL. */
+#define RSET_FIXED \
+  (RID2RSET(RID_TMP)|RID2RSET(RID_SP)|RID2RSET(RID_SYS1)|\
+   RID2RSET(RID_SYS2)|RID2RSET(RID_JGL))
+#define RSET_GPR	(RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED)
+#define RSET_FPR	RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR)
+#define RSET_ALL	(RSET_GPR|RSET_FPR)
+#define RSET_INIT	RSET_ALL
+
+#define RSET_SCRATCH_GPR	(RSET_RANGE(RID_R3, RID_R12+1))
+#define RSET_SCRATCH_FPR	(RSET_RANGE(RID_F0, RID_F13+1))
+#define RSET_SCRATCH		(RSET_SCRATCH_GPR|RSET_SCRATCH_FPR)
+#define REGARG_FIRSTGPR		RID_R3
+#define REGARG_LASTGPR		RID_R10
+#define REGARG_NUMGPR		8
+#define REGARG_FIRSTFPR		RID_F1
+#define REGARG_LASTFPR		RID_F8
+#define REGARG_NUMFPR		8
+
+/* -- Spill slots --------------------------------------------------------- */
+
+/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
+**
+** SPS_FIXED: Available fixed spill slots in interpreter frame.
+** This definition must match with the *.dasc file(s).
+**
+** SPS_FIRST: First spill slot for general use.
+** [sp+12] tmplo word \
+** [sp+ 8] tmphi word / tmp dword, parameter area for callee
+** [sp+ 4] tmpw, LR of callee
+** [sp+ 0] stack chain
+*/
+#define SPS_FIXED	7
+#define SPS_FIRST	4
+
+/* Stack offsets for temporary slots. Used for FP<->int conversions etc. */
+#define SPOFS_TMPW	4
+#define SPOFS_TMP	8
+#define SPOFS_TMPHI	8
+#define SPOFS_TMPLO	12
+
+#define sps_scale(slot)		(4 * (int32_t)(slot))
+#define sps_align(slot)		(((slot) - SPS_FIXED + 3) & ~3)
+
+/* -- Exit state ---------------------------------------------------------- */
+
+/* This definition must match with the *.dasc file(s). */
+typedef struct {
+  lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
+  int32_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
+  int32_t spill[256];		/* Spill slots. */
+} ExitState;
+
+/* Highest exit + 1 indicates stack check. */
+#define EXITSTATE_CHECKEXIT	1
+
+/* Return the address of a per-trace exit stub. */
+static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno)
+{
+  while (*p == 0x60000000) p++;  /* Skip PPCI_NOP. */
+  return p + 3 + exitno;
+}
+/* Avoid dependence on lj_jit.h if only including lj_target.h. */
+#define exitstub_trace_addr(T, exitno) \
+  exitstub_trace_addr_((MCode *)((char *)(T)->mcode + (T)->szmcode), (exitno))
+
+/* -- Instructions -------------------------------------------------------- */
+
+/* Instruction fields. */
+#define PPCF_CC(cc)	((((cc) & 3) << 16) | (((cc) & 4) << 22))
+#define PPCF_T(r)	((r) << 21)
+#define PPCF_A(r)	((r) << 16)
+#define PPCF_B(r)	((r) << 11)
+#define PPCF_C(r)	((r) << 6)
+#define PPCF_MB(n)	((n) << 6)
+#define PPCF_ME(n)	((n) << 1)
+#define PPCF_Y		0x00200000
+#define PPCF_DOT	0x00000001
+
+typedef enum PPCIns {
+  /* Integer instructions. */
+  PPCI_MR = 0x7c000378,
+  PPCI_NOP = 0x60000000,
+
+  PPCI_LI = 0x38000000,
+  PPCI_LIS = 0x3c000000,
+
+  PPCI_ADD = 0x7c000214,
+  PPCI_ADDC = 0x7c000014,
+  PPCI_ADDO = 0x7c000614,
+  PPCI_ADDE = 0x7c000114,
+  PPCI_ADDZE = 0x7c000194,
+  PPCI_ADDME = 0x7c0001d4,
+  PPCI_ADDI = 0x38000000,
+  PPCI_ADDIS = 0x3c000000,
+  PPCI_ADDIC = 0x30000000,
+  PPCI_ADDICDOT = 0x34000000,
+
+  PPCI_SUBF = 0x7c000050,
+  PPCI_SUBFC = 0x7c000010,
+  PPCI_SUBFO = 0x7c000450,
+  PPCI_SUBFE = 0x7c000110,
+  PPCI_SUBFZE = 0x7c000190,
+  PPCI_SUBFME = 0x7c0001d0,
+  PPCI_SUBFIC = 0x20000000,
+
+  PPCI_NEG = 0x7c0000d0,
+
+  PPCI_AND = 0x7c000038,
+  PPCI_ANDC = 0x7c000078,
+  PPCI_NAND = 0x7c0003b8,
+  PPCI_ANDIDOT = 0x70000000,
+  PPCI_ANDISDOT = 0x74000000,
+
+  PPCI_OR = 0x7c000378,
+  PPCI_NOR = 0x7c0000f8,
+  PPCI_ORI = 0x60000000,
+  PPCI_ORIS = 0x64000000,
+
+  PPCI_XOR = 0x7c000278,
+  PPCI_EQV = 0x7c000238,
+  PPCI_XORI = 0x68000000,
+  PPCI_XORIS = 0x6c000000,
+
+  PPCI_CMPW = 0x7c000000,
+  PPCI_CMPLW = 0x7c000040,
+  PPCI_CMPWI = 0x2c000000,
+  PPCI_CMPLWI = 0x28000000,
+
+  PPCI_MULLW = 0x7c0001d6,
+  PPCI_MULLI = 0x1c000000,
+  PPCI_MULLWO = 0x7c0005d6,
+
+  PPCI_EXTSB = 0x7c000774,
+  PPCI_EXTSH = 0x7c000734,
+
+  PPCI_SLW = 0x7c000030,
+  PPCI_SRW = 0x7c000430,
+  PPCI_SRAW = 0x7c000630,
+  PPCI_SRAWI = 0x7c000670,
+
+  PPCI_RLWNM = 0x5c000000,
+  PPCI_RLWINM = 0x54000000,
+  PPCI_RLWIMI = 0x50000000,
+
+  PPCI_B = 0x48000000,
+  PPCI_BL = 0x48000001,
+  PPCI_BC = 0x40800000,
+  PPCI_BCL = 0x40800001,
+  PPCI_BCTR = 0x4e800420,
+  PPCI_BCTRL = 0x4e800421,
+
+  PPCI_CRANDC = 0x4c000102,
+  PPCI_CRXOR = 0x4c000182,
+  PPCI_CRAND = 0x4c000202,
+  PPCI_CREQV = 0x4c000242,
+  PPCI_CRORC = 0x4c000342,
+  PPCI_CROR = 0x4c000382,
+
+  PPCI_MFLR = 0x7c0802a6,
+  PPCI_MTCTR = 0x7c0903a6,
+
+  PPCI_MCRXR = 0x7c000400,
+
+  /* Load/store instructions. */
+  PPCI_LWZ = 0x80000000,
+  PPCI_LBZ = 0x88000000,
+  PPCI_STW = 0x90000000,
+  PPCI_STB = 0x98000000,
+  PPCI_LHZ = 0xa0000000,
+  PPCI_LHA = 0xa8000000,
+  PPCI_STH = 0xb0000000,
+
+  PPCI_STWU = 0x94000000,
+
+  PPCI_LFS = 0xc0000000,
+  PPCI_LFD = 0xc8000000,
+  PPCI_STFS = 0xd0000000,
+  PPCI_STFD = 0xd8000000,
+
+  PPCI_LWZX = 0x7c00002e,
+  PPCI_LBZX = 0x7c0000ae,
+  PPCI_STWX = 0x7c00012e,
+  PPCI_STBX = 0x7c0001ae,
+  PPCI_LHZX = 0x7c00022e,
+  PPCI_LHAX = 0x7c0002ae,
+  PPCI_STHX = 0x7c00032e,
+
+  PPCI_LWBRX = 0x7c00042c,
+  PPCI_STWBRX = 0x7c00052c,
+
+  PPCI_LFSX = 0x7c00042e,
+  PPCI_LFDX = 0x7c0004ae,
+  PPCI_STFSX = 0x7c00052e,
+  PPCI_STFDX = 0x7c0005ae,
+
+  /* FP instructions. */
+  PPCI_FMR = 0xfc000090,
+  PPCI_FNEG = 0xfc000050,
+  PPCI_FABS = 0xfc000210,
+
+  PPCI_FRSP = 0xfc000018,
+  PPCI_FCTIWZ = 0xfc00001e,
+
+  PPCI_FADD = 0xfc00002a,
+  PPCI_FSUB = 0xfc000028,
+  PPCI_FMUL = 0xfc000032,
+  PPCI_FDIV = 0xfc000024,
+  PPCI_FSQRT = 0xfc00002c,
+
+  PPCI_FMADD = 0xfc00003a,
+  PPCI_FMSUB = 0xfc000038,
+  PPCI_FNMSUB = 0xfc00003c,
+
+  PPCI_FCMPU = 0xfc000000,
+  PPCI_FSEL = 0xfc00002e,
+} PPCIns;
+
+typedef enum PPCCC {
+  CC_GE, CC_LE, CC_NE, CC_NS, CC_LT, CC_GT, CC_EQ, CC_SO
+} PPCCC;
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_target_x86.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_target_x86.h b/lib/luajit/src/lj_target_x86.h
new file mode 100644
index 0000000..d12a1b8
--- /dev/null
+++ b/lib/luajit/src/lj_target_x86.h
@@ -0,0 +1,342 @@
+/*
+** Definitions for x86 and x64 CPUs.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TARGET_X86_H
+#define _LJ_TARGET_X86_H
+
+/* -- Registers IDs ------------------------------------------------------- */
+
+#if LJ_64
+#define GPRDEF(_) \
+  _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI) \
+  _(R8D) _(R9D) _(R10D) _(R11D) _(R12D) _(R13D) _(R14D) _(R15D)
+#define FPRDEF(_) \
+  _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7) \
+  _(XMM8) _(XMM9) _(XMM10) _(XMM11) _(XMM12) _(XMM13) _(XMM14) _(XMM15)
+#else
+#define GPRDEF(_) \
+  _(EAX) _(ECX) _(EDX) _(EBX) _(ESP) _(EBP) _(ESI) _(EDI)
+#define FPRDEF(_) \
+  _(XMM0) _(XMM1) _(XMM2) _(XMM3) _(XMM4) _(XMM5) _(XMM6) _(XMM7)
+#endif
+#define VRIDDEF(_) \
+  _(MRM)
+
+#define RIDENUM(name)	RID_##name,
+
+enum {
+  GPRDEF(RIDENUM)		/* General-purpose registers (GPRs). */
+  FPRDEF(RIDENUM)		/* Floating-point registers (FPRs). */
+  RID_MAX,
+  RID_MRM = RID_MAX,		/* Pseudo-id for ModRM operand. */
+
+  /* Calling conventions. */
+  RID_RET = RID_EAX,
+#if LJ_64
+  RID_FPRET = RID_XMM0,
+#else
+  RID_RETLO = RID_EAX,
+  RID_RETHI = RID_EDX,
+#endif
+
+  /* These definitions must match with the *.dasc file(s): */
+  RID_BASE = RID_EDX,		/* Interpreter BASE. */
+#if LJ_64 && !LJ_ABI_WIN
+  RID_LPC = RID_EBX,		/* Interpreter PC. */
+  RID_DISPATCH = RID_R14D,	/* Interpreter DISPATCH table. */
+#else
+  RID_LPC = RID_ESI,		/* Interpreter PC. */
+  RID_DISPATCH = RID_EBX,	/* Interpreter DISPATCH table. */
+#endif
+
+  /* Register ranges [min, max) and number of registers. */
+  RID_MIN_GPR = RID_EAX,
+  RID_MIN_FPR = RID_XMM0,
+  RID_MAX_GPR = RID_MIN_FPR,
+  RID_MAX_FPR = RID_MAX,
+  RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR,
+  RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR,
+};
+
+/* -- Register sets ------------------------------------------------------- */
+
+/* Make use of all registers, except the stack pointer. */
+#define RSET_GPR	(RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR)-RID2RSET(RID_ESP))
+#define RSET_FPR	(RSET_RANGE(RID_MIN_FPR, RID_MAX_FPR))
+#define RSET_ALL	(RSET_GPR|RSET_FPR)
+#define RSET_INIT	RSET_ALL
+
+#if LJ_64
+/* Note: this requires the use of FORCE_REX! */
+#define RSET_GPR8	RSET_GPR
+#else
+#define RSET_GPR8	(RSET_RANGE(RID_EAX, RID_EBX+1))
+#endif
+
+/* ABI-specific register sets. */
+#define RSET_ACD	(RID2RSET(RID_EAX)|RID2RSET(RID_ECX)|RID2RSET(RID_EDX))
+#if LJ_64
+#if LJ_ABI_WIN
+/* Windows x64 ABI. */
+#define RSET_SCRATCH \
+  (RSET_ACD|RSET_RANGE(RID_R8D, RID_R11D+1)|RSET_RANGE(RID_XMM0, RID_XMM5+1))
+#define REGARG_GPRS \
+  (RID_ECX|((RID_EDX|((RID_R8D|(RID_R9D<<5))<<5))<<5))
+#define REGARG_NUMGPR	4
+#define REGARG_NUMFPR	4
+#define REGARG_FIRSTFPR	RID_XMM0
+#define REGARG_LASTFPR	RID_XMM3
+#define STACKARG_OFS	(4*8)
+#else
+/* The rest of the civilized x64 world has a common ABI. */
+#define RSET_SCRATCH \
+  (RSET_ACD|RSET_RANGE(RID_ESI, RID_R11D+1)|RSET_FPR)
+#define REGARG_GPRS \
+  (RID_EDI|((RID_ESI|((RID_EDX|((RID_ECX|((RID_R8D|(RID_R9D \
+   <<5))<<5))<<5))<<5))<<5))
+#define REGARG_NUMGPR	6
+#define REGARG_NUMFPR	8
+#define REGARG_FIRSTFPR	RID_XMM0
+#define REGARG_LASTFPR	RID_XMM7
+#define STACKARG_OFS	0
+#endif
+#else
+/* Common x86 ABI. */
+#define RSET_SCRATCH	(RSET_ACD|RSET_FPR)
+#define REGARG_GPRS	(RID_ECX|(RID_EDX<<5))  /* Fastcall only. */
+#define REGARG_NUMGPR	2  /* Fastcall only. */
+#define REGARG_NUMFPR	0
+#define STACKARG_OFS	0
+#endif
+
+#if LJ_64
+/* Prefer the low 8 regs of each type to reduce REX prefixes. */
+#undef rset_picktop
+#define rset_picktop(rs)	(lj_fls(lj_bswap(rs)) ^ 0x18)
+#endif
+
+/* -- Spill slots --------------------------------------------------------- */
+
+/* Spill slots are 32 bit wide. An even/odd pair is used for FPRs.
+**
+** SPS_FIXED: Available fixed spill slots in interpreter frame.
+** This definition must match with the *.dasc file(s).
+**
+** SPS_FIRST: First spill slot for general use. Reserve min. two 32 bit slots.
+*/
+#if LJ_64
+#if LJ_ABI_WIN
+#define SPS_FIXED	(4*2)
+#define SPS_FIRST	(4*2)	/* Don't use callee register save area. */
+#else
+#define SPS_FIXED	4
+#define SPS_FIRST	2
+#endif
+#else
+#define SPS_FIXED	6
+#define SPS_FIRST	2
+#endif
+
+#define SPOFS_TMP	0
+
+#define sps_scale(slot)		(4 * (int32_t)(slot))
+#define sps_align(slot)		(((slot) - SPS_FIXED + 3) & ~3)
+
+/* -- Exit state ---------------------------------------------------------- */
+
+/* This definition must match with the *.dasc file(s). */
+typedef struct {
+  lua_Number fpr[RID_NUM_FPR];	/* Floating-point registers. */
+  intptr_t gpr[RID_NUM_GPR];	/* General-purpose registers. */
+  int32_t spill[256];		/* Spill slots. */
+} ExitState;
+
+/* Limited by the range of a short fwd jump (127): (2+2)*(32-1)-2 = 122. */
+#define EXITSTUB_SPACING	(2+2)
+#define EXITSTUBS_PER_GROUP	32
+
+/* -- x86 ModRM operand encoding ------------------------------------------ */
+
+typedef enum {
+  XM_OFS0 = 0x00, XM_OFS8 = 0x40, XM_OFS32 = 0x80, XM_REG = 0xc0,
+  XM_SCALE1 = 0x00, XM_SCALE2 = 0x40, XM_SCALE4 = 0x80, XM_SCALE8 = 0xc0,
+  XM_MASK = 0xc0
+} x86Mode;
+
+/* Structure to hold variable ModRM operand. */
+typedef struct {
+  int32_t ofs;		/* Offset. */
+  uint8_t base;		/* Base register or RID_NONE. */
+  uint8_t idx;		/* Index register or RID_NONE. */
+  uint8_t scale;	/* Index scale (XM_SCALE1 .. XM_SCALE8). */
+} x86ModRM;
+
+/* -- Opcodes ------------------------------------------------------------- */
+
+/* Macros to construct variable-length x86 opcodes. -(len+1) is in LSB. */
+#define XO_(o)		((uint32_t)(0x0000fe + (0x##o<<24)))
+#define XO_FPU(a,b)	((uint32_t)(0x00fd + (0x##a<<16)+(0x##b<<24)))
+#define XO_0f(o)	((uint32_t)(0x0f00fd + (0x##o<<24)))
+#define XO_66(o)	((uint32_t)(0x6600fd + (0x##o<<24)))
+#define XO_660f(o)	((uint32_t)(0x0f66fc + (0x##o<<24)))
+#define XO_f20f(o)	((uint32_t)(0x0ff2fc + (0x##o<<24)))
+#define XO_f30f(o)	((uint32_t)(0x0ff3fc + (0x##o<<24)))
+
+/* This list of x86 opcodes is not intended to be complete. Opcodes are only
+** included when needed. Take a look at DynASM or jit.dis_x86 to see the
+** whole mess.
+*/
+typedef enum {
+  /* Fixed length opcodes. XI_* prefix. */
+  XI_NOP =	0x90,
+  XI_XCHGa =	0x90,
+  XI_CALL =	0xe8,
+  XI_JMP =	0xe9,
+  XI_JMPs =	0xeb,
+  XI_PUSH =	0x50, /* Really 50+r. */
+  XI_JCCs =	0x70, /* Really 7x. */
+  XI_JCCn =	0x80, /* Really 0f8x. */
+  XI_LEA =	0x8d,
+  XI_MOVrib =	0xb0, /* Really b0+r. */
+  XI_MOVri =	0xb8, /* Really b8+r. */
+  XI_ARITHib =	0x80,
+  XI_ARITHi =	0x81,
+  XI_ARITHi8 =	0x83,
+  XI_PUSHi8 =	0x6a,
+  XI_TESTb =	0x84,
+  XI_TEST =	0x85,
+  XI_MOVmi =	0xc7,
+  XI_GROUP5 =	0xff,
+
+  /* Note: little-endian byte-order! */
+  XI_FLDZ =	0xeed9,
+  XI_FLD1 =	0xe8d9,
+  XI_FLDLG2 =	0xecd9,
+  XI_FLDLN2 =	0xedd9,
+  XI_FDUP =	0xc0d9,  /* Really fld st0. */
+  XI_FPOP =	0xd8dd,  /* Really fstp st0. */
+  XI_FPOP1 =	0xd9dd,  /* Really fstp st1. */
+  XI_FRNDINT =	0xfcd9,
+  XI_FSIN =	0xfed9,
+  XI_FCOS =	0xffd9,
+  XI_FPTAN =	0xf2d9,
+  XI_FPATAN =	0xf3d9,
+  XI_FSCALE =	0xfdd9,
+  XI_FYL2X =	0xf1d9,
+
+  /* Variable-length opcodes. XO_* prefix. */
+  XO_MOV =	XO_(8b),
+  XO_MOVto =	XO_(89),
+  XO_MOVtow =	XO_66(89),
+  XO_MOVtob =	XO_(88),
+  XO_MOVmi =	XO_(c7),
+  XO_MOVmib =	XO_(c6),
+  XO_LEA =	XO_(8d),
+  XO_ARITHib =	XO_(80),
+  XO_ARITHi =	XO_(81),
+  XO_ARITHi8 =	XO_(83),
+  XO_ARITHiw8 =	XO_66(83),
+  XO_SHIFTi =	XO_(c1),
+  XO_SHIFT1 =	XO_(d1),
+  XO_SHIFTcl =	XO_(d3),
+  XO_IMUL =	XO_0f(af),
+  XO_IMULi =	XO_(69),
+  XO_IMULi8 =	XO_(6b),
+  XO_CMP =	XO_(3b),
+  XO_TESTb =	XO_(84),
+  XO_TEST =	XO_(85),
+  XO_GROUP3b =	XO_(f6),
+  XO_GROUP3 =	XO_(f7),
+  XO_GROUP5b =	XO_(fe),
+  XO_GROUP5 =	XO_(ff),
+  XO_MOVZXb =	XO_0f(b6),
+  XO_MOVZXw =	XO_0f(b7),
+  XO_MOVSXb =	XO_0f(be),
+  XO_MOVSXw =	XO_0f(bf),
+  XO_MOVSXd =	XO_(63),
+  XO_BSWAP =	XO_0f(c8),
+  XO_CMOV =	XO_0f(40),
+
+  XO_MOVSD =	XO_f20f(10),
+  XO_MOVSDto =	XO_f20f(11),
+  XO_MOVSS =	XO_f30f(10),
+  XO_MOVSSto =	XO_f30f(11),
+  XO_MOVLPD =	XO_660f(12),
+  XO_MOVAPS =	XO_0f(28),
+  XO_XORPS =	XO_0f(57),
+  XO_ANDPS =	XO_0f(54),
+  XO_ADDSD =	XO_f20f(58),
+  XO_SUBSD =	XO_f20f(5c),
+  XO_MULSD =	XO_f20f(59),
+  XO_DIVSD =	XO_f20f(5e),
+  XO_SQRTSD =	XO_f20f(51),
+  XO_MINSD =	XO_f20f(5d),
+  XO_MAXSD =	XO_f20f(5f),
+  XO_ROUNDSD =	0x0b3a0ffc,  /* Really 66 0f 3a 0b. See asm_fpmath. */
+  XO_UCOMISD =	XO_660f(2e),
+  XO_CVTSI2SD =	XO_f20f(2a),
+  XO_CVTSD2SI =	XO_f20f(2d),
+  XO_CVTTSD2SI=	XO_f20f(2c),
+  XO_CVTSI2SS =	XO_f30f(2a),
+  XO_CVTSS2SI =	XO_f30f(2d),
+  XO_CVTTSS2SI=	XO_f30f(2c),
+  XO_CVTSS2SD =	XO_f30f(5a),
+  XO_CVTSD2SS =	XO_f20f(5a),
+  XO_ADDSS =	XO_f30f(58),
+  XO_MOVD =	XO_660f(6e),
+  XO_MOVDto =	XO_660f(7e),
+
+  XO_FLDd =	XO_(d9), XOg_FLDd = 0,
+  XO_FLDq =	XO_(dd), XOg_FLDq = 0,
+  XO_FILDd =	XO_(db), XOg_FILDd = 0,
+  XO_FILDq =	XO_(df), XOg_FILDq = 5,
+  XO_FSTPd =	XO_(d9), XOg_FSTPd = 3,
+  XO_FSTPq =	XO_(dd), XOg_FSTPq = 3,
+  XO_FISTPq =	XO_(df), XOg_FISTPq = 7,
+  XO_FISTTPq =	XO_(dd), XOg_FISTTPq = 1,
+  XO_FADDq =	XO_(dc), XOg_FADDq = 0,
+  XO_FLDCW =	XO_(d9), XOg_FLDCW = 5,
+  XO_FNSTCW =	XO_(d9), XOg_FNSTCW = 7
+} x86Op;
+
+/* x86 opcode groups. */
+typedef uint32_t x86Group;
+
+#define XG_(i8, i, g)	((x86Group)(((i8) << 16) + ((i) << 8) + (g)))
+#define XG_ARITHi(g)	XG_(XI_ARITHi8, XI_ARITHi, g)
+#define XG_TOXOi(xg)	((x86Op)(0x000000fe + (((xg)<<16) & 0xff000000)))
+#define XG_TOXOi8(xg)	((x86Op)(0x000000fe + (((xg)<<8) & 0xff000000)))
+
+#define XO_ARITH(a)	((x86Op)(0x030000fe + ((a)<<27)))
+#define XO_ARITHw(a)	((x86Op)(0x036600fd + ((a)<<27)))
+
+typedef enum {
+  XOg_ADD, XOg_OR, XOg_ADC, XOg_SBB, XOg_AND, XOg_SUB, XOg_XOR, XOg_CMP,
+  XOg_X_IMUL
+} x86Arith;
+
+typedef enum {
+  XOg_ROL, XOg_ROR, XOg_RCL, XOg_RCR, XOg_SHL, XOg_SHR, XOg_SAL, XOg_SAR
+} x86Shift;
+
+typedef enum {
+  XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
+} x86Group3;
+
+typedef enum {
+  XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH
+} x86Group5;
+
+/* x86 condition codes. */
+typedef enum {
+  CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
+  CC_S, CC_NS, CC_P, CC_NP, CC_L, CC_NL, CC_LE, CC_NLE,
+  CC_C = CC_B, CC_NAE = CC_C, CC_NC = CC_NB, CC_AE = CC_NB,
+  CC_Z = CC_E, CC_NZ = CC_NE, CC_NA = CC_BE, CC_A = CC_NBE,
+  CC_PE = CC_P, CC_PO = CC_NP, CC_NGE = CC_L, CC_GE = CC_NL,
+  CC_NG = CC_LE, CC_G = CC_NLE
+} x86CC;
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_trace.c
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_trace.c b/lib/luajit/src/lj_trace.c
new file mode 100644
index 0000000..e51ec54
--- /dev/null
+++ b/lib/luajit/src/lj_trace.c
@@ -0,0 +1,816 @@
+/*
+** Trace management.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#define lj_trace_c
+#define LUA_CORE
+
+#include "lj_obj.h"
+
+#if LJ_HASJIT
+
+#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_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_vmevent.h"
+#include "lj_target.h"
+
+/* -- Error handling ------------------------------------------------------ */
+
+/* Synchronous abort with error message. */
+void lj_trace_err(jit_State *J, TraceError e)
+{
+  setnilV(&J->errinfo);  /* No error info. */
+  setintV(J->L->top++, (int32_t)e);
+  lj_err_throw(J->L, LUA_ERRRUN);
+}
+
+/* Synchronous abort with error message and error info. */
+void lj_trace_err_info(jit_State *J, TraceError e)
+{
+  setintV(J->L->top++, (int32_t)e);
+  lj_err_throw(J->L, LUA_ERRRUN);
+}
+
+/* -- Trace management ---------------------------------------------------- */
+
+/* The current trace is first assembled in J->cur. The variable length
+** arrays point to shared, growable buffers (J->irbuf etc.). When trace
+** recording ends successfully, the current trace and its data structures
+** are copied to a new (compact) GCtrace object.
+*/
+
+/* Find a free trace number. */
+static TraceNo trace_findfree(jit_State *J)
+{
+  MSize osz, lim;
+  if (J->freetrace == 0)
+    J->freetrace = 1;
+  for (; J->freetrace < J->sizetrace; J->freetrace++)
+    if (traceref(J, J->freetrace) == NULL)
+      return J->freetrace++;
+  /* Need to grow trace array. */
+  lim = (MSize)J->param[JIT_P_maxtrace] + 1;
+  if (lim < 2) lim = 2; else if (lim > 65535) lim = 65535;
+  osz = J->sizetrace;
+  if (osz >= lim)
+    return 0;  /* Too many traces. */
+  lj_mem_growvec(J->L, J->trace, J->sizetrace, lim, GCRef);
+  for (; osz < J->sizetrace; osz++)
+    setgcrefnull(J->trace[osz]);
+  return J->freetrace;
+}
+
+#define TRACE_APPENDVEC(field, szfield, tp) \
+  T->field = (tp *)p; \
+  memcpy(p, J->cur.field, J->cur.szfield*sizeof(tp)); \
+  p += J->cur.szfield*sizeof(tp);
+
+#ifdef LUAJIT_USE_PERFTOOLS
+/*
+** Create symbol table of JIT-compiled code. For use with Linux perf tools.
+** Example usage:
+**   perf record -f -e cycles luajit test.lua
+**   perf report -s symbol
+**   rm perf.data /tmp/perf-*.map
+*/
+#include <stdio.h>
+#include <unistd.h>
+
+static void perftools_addtrace(GCtrace *T)
+{
+  static FILE *fp;
+  GCproto *pt = &gcref(T->startpt)->pt;
+  const BCIns *startpc = mref(T->startpc, const BCIns);
+  const char *name = proto_chunknamestr(pt);
+  BCLine lineno;
+  if (name[0] == '@' || name[0] == '=')
+    name++;
+  else
+    name = "(string)";
+  lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
+  lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
+  if (!fp) {
+    char fname[40];
+    sprintf(fname, "/tmp/perf-%d.map", getpid());
+    if (!(fp = fopen(fname, "w"))) return;
+    setlinebuf(fp);
+  }
+  fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
+	  (long)T->mcode, T->szmcode, T->traceno, name, lineno);
+}
+#endif
+
+/* Save current trace by copying and compacting it. */
+static void trace_save(jit_State *J)
+{
+  size_t sztr = ((sizeof(GCtrace)+7)&~7);
+  size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns);
+  size_t sz = sztr + szins +
+	      J->cur.nsnap*sizeof(SnapShot) +
+	      J->cur.nsnapmap*sizeof(SnapEntry);
+  GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace);
+  char *p = (char *)T + sztr;
+  memcpy(T, &J->cur, sizeof(GCtrace));
+  setgcrefr(T->nextgc, J2G(J)->gc.root);
+  setgcrefp(J2G(J)->gc.root, T);
+  newwhite(J2G(J), T);
+  T->gct = ~LJ_TTRACE;
+  T->ir = (IRIns *)p - J->cur.nk;
+  memcpy(p, J->cur.ir+J->cur.nk, szins);
+  p += szins;
+  TRACE_APPENDVEC(snap, nsnap, SnapShot)
+  TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry)
+  J->cur.traceno = 0;
+  setgcrefp(J->trace[T->traceno], T);
+  lj_gc_barriertrace(J2G(J), T->traceno);
+  lj_gdbjit_addtrace(J, T);
+#ifdef LUAJIT_USE_PERFTOOLS
+  perftools_addtrace(T);
+#endif
+}
+
+void LJ_FASTCALL 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,
+    ((sizeof(GCtrace)+7)&~7) + (T->nins-T->nk)*sizeof(IRIns) +
+    T->nsnap*sizeof(SnapShot) + T->nsnapmap*sizeof(SnapEntry));
+}
+
+/* Re-enable compiling a prototype by unpatching any modified bytecode. */
+void lj_trace_reenableproto(GCproto *pt)
+{
+  if ((pt->flags & PROTO_ILOOP)) {
+    BCIns *bc = proto_bc(pt);
+    BCPos i, sizebc = pt->sizebc;;
+    pt->flags &= ~PROTO_ILOOP;
+    if (bc_op(bc[0]) == BC_IFUNCF)
+      setbc_op(&bc[0], BC_FUNCF);
+    for (i = 1; i < sizebc; i++) {
+      BCOp op = bc_op(bc[i]);
+      if (op == BC_IFORL || op == BC_IITERL || op == BC_ILOOP)
+	setbc_op(&bc[i], (int)op+(int)BC_LOOP-(int)BC_ILOOP);
+    }
+  }
+}
+
+/* Unpatch the bytecode modified by a root trace. */
+static void trace_unpatch(jit_State *J, GCtrace *T)
+{
+  BCOp op = bc_op(T->startins);
+  BCIns *pc = mref(T->startpc, BCIns);
+  UNUSED(J);
+  if (op == BC_JMP)
+    return;  /* No need to unpatch branches in parent traces (yet). */
+  switch (bc_op(*pc)) {
+  case BC_JFORL:
+    lua_assert(traceref(J, bc_d(*pc)) == T);
+    *pc = T->startins;
+    pc += bc_j(T->startins);
+    lua_assert(bc_op(*pc) == BC_JFORI);
+    setbc_op(pc, BC_FORI);
+    break;
+  case BC_JITERL:
+  case BC_JLOOP:
+    lua_assert(op == BC_ITERL || op == BC_LOOP || bc_isret(op));
+    *pc = T->startins;
+    break;
+  case BC_JMP:
+    lua_assert(op == BC_ITERL);
+    pc += bc_j(*pc)+2;
+    if (bc_op(*pc) == BC_JITERL) {
+      lua_assert(traceref(J, bc_d(*pc)) == T);
+      *pc = T->startins;
+    }
+    break;
+  case BC_JFUNCF:
+    lua_assert(op == BC_FUNCF);
+    *pc = T->startins;
+    break;
+  default:  /* Already unpatched. */
+    break;
+  }
+}
+
+/* Flush a root trace. */
+static void trace_flushroot(jit_State *J, GCtrace *T)
+{
+  GCproto *pt = &gcref(T->startpt)->pt;
+  lua_assert(T->root == 0 && pt != NULL);
+  /* First unpatch any modified bytecode. */
+  trace_unpatch(J, T);
+  /* Unlink root trace from chain anchored in prototype. */
+  if (pt->trace == T->traceno) {  /* Trace is first in chain. Easy. */
+    pt->trace = T->nextroot;
+  } else if (pt->trace) {  /* Otherwise search in chain of root traces. */
+    GCtrace *T2 = traceref(J, pt->trace);
+    if (T2) {
+      for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
+	if (T2->nextroot == T->traceno) {
+	  T2->nextroot = T->nextroot;  /* Unlink from chain. */
+	  break;
+	}
+    }
+  }
+}
+
+/* Flush a trace. Only root traces are considered. */
+void lj_trace_flush(jit_State *J, TraceNo traceno)
+{
+  if (traceno > 0 && traceno < J->sizetrace) {
+    GCtrace *T = traceref(J, traceno);
+    if (T && T->root == 0)
+      trace_flushroot(J, T);
+  }
+}
+
+/* Flush all traces associated with a prototype. */
+void lj_trace_flushproto(global_State *g, GCproto *pt)
+{
+  while (pt->trace != 0)
+    trace_flushroot(G2J(g), traceref(G2J(g), pt->trace));
+}
+
+/* Flush all traces. */
+int lj_trace_flushall(lua_State *L)
+{
+  jit_State *J = L2J(L);
+  ptrdiff_t i;
+  if ((J2G(J)->hookmask & HOOK_GC))
+    return 1;
+  for (i = (ptrdiff_t)J->sizetrace-1; i > 0; i--) {
+    GCtrace *T = traceref(J, i);
+    if (T) {
+      if (T->root == 0)
+	trace_flushroot(J, T);
+      lj_gdbjit_deltrace(J, T);
+      T->traceno = 0;
+      setgcrefnull(J->trace[i]);
+    }
+  }
+  J->cur.traceno = 0;
+  J->freetrace = 0;
+  /* Clear penalty cache. */
+  memset(J->penalty, 0, sizeof(J->penalty));
+  /* Free the whole machine code and invalidate all exit stub groups. */
+  lj_mcode_free(J);
+  memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup));
+  lj_vmevent_send(L, TRACE,
+    setstrV(L, L->top++, lj_str_newlit(L, "flush"));
+  );
+  return 0;
+}
+
+/* Initialize JIT compiler state. */
+void lj_trace_initstate(global_State *g)
+{
+  jit_State *J = G2J(g);
+  TValue *tv;
+  /* Initialize SIMD constants. */
+  tv = LJ_KSIMD(J, LJ_KSIMD_ABS);
+  tv[0].u64 = U64x(7fffffff,ffffffff);
+  tv[1].u64 = U64x(7fffffff,ffffffff);
+  tv = LJ_KSIMD(J, LJ_KSIMD_NEG);
+  tv[0].u64 = U64x(80000000,00000000);
+  tv[1].u64 = U64x(80000000,00000000);
+}
+
+/* Free everything associated with the JIT compiler state. */
+void lj_trace_freestate(global_State *g)
+{
+  jit_State *J = G2J(g);
+#ifdef LUA_USE_ASSERT
+  {  /* This assumes all traces have already been freed. */
+    ptrdiff_t i;
+    for (i = 1; i < (ptrdiff_t)J->sizetrace; i++)
+      lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL);
+  }
+#endif
+  lj_mcode_free(J);
+  lj_ir_k64_freeall(J);
+  lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry);
+  lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot);
+  lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);
+  lj_mem_freevec(g, J->trace, J->sizetrace, GCRef);
+}
+
+/* -- Penalties and blacklisting ------------------------------------------ */
+
+/* Blacklist a bytecode instruction. */
+static void blacklist_pc(GCproto *pt, BCIns *pc)
+{
+  setbc_op(pc, (int)bc_op(*pc)+(int)BC_ILOOP-(int)BC_LOOP);
+  pt->flags |= PROTO_ILOOP;
+}
+
+/* Penalize a bytecode instruction. */
+static void penalty_pc(jit_State *J, GCproto *pt, BCIns *pc, TraceError e)
+{
+  uint32_t i, val = PENALTY_MIN;
+  for (i = 0; i < PENALTY_SLOTS; i++)
+    if (mref(J->penalty[i].pc, const BCIns) == pc) {  /* Cache slot found? */
+      /* First try to bump its hotcount several times. */
+      val = ((uint32_t)J->penalty[i].val << 1) +
+	    LJ_PRNG_BITS(J, PENALTY_RNDBITS);
+      if (val > PENALTY_MAX) {
+	blacklist_pc(pt, pc);  /* Blacklist it, if that didn't help. */
+	return;
+      }
+      goto setpenalty;
+    }
+  /* Assign a new penalty cache slot. */
+  i = J->penaltyslot;
+  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].reason = e;
+  hotcount_set(J2GG(J), pc+1, val);
+}
+
+/* -- Trace compiler state machine ---------------------------------------- */
+
+/* Start tracing. */
+static void trace_start(jit_State *J)
+{
+  lua_State *L;
+  TraceNo traceno;
+
+  if ((J->pt->flags & PROTO_NOJIT)) {  /* JIT disabled for this proto? */
+    if (J->parent == 0) {
+      /* Lazy bytecode patching to disable hotcount events. */
+      lua_assert(bc_op(*J->pc) == BC_FORL || bc_op(*J->pc) == BC_ITERL ||
+		 bc_op(*J->pc) == BC_LOOP || bc_op(*J->pc) == BC_FUNCF);
+      setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
+      J->pt->flags |= PROTO_ILOOP;
+    }
+    J->state = LJ_TRACE_IDLE;  /* Silently ignored. */
+    return;
+  }
+
+  /* Get a new trace number. */
+  traceno = trace_findfree(J);
+  if (LJ_UNLIKELY(traceno == 0)) {  /* No free trace? */
+    lua_assert((J2G(J)->hookmask & HOOK_GC) == 0);
+    lj_trace_flushall(J->L);
+    J->state = LJ_TRACE_IDLE;  /* Silently ignored. */
+    return;
+  }
+  setgcrefp(J->trace[traceno], &J->cur);
+
+  /* Setup enough of the current trace to be able to send the vmevent. */
+  memset(&J->cur, 0, sizeof(GCtrace));
+  J->cur.traceno = traceno;
+  J->cur.nins = J->cur.nk = REF_BASE;
+  J->cur.ir = J->irbuf;
+  J->cur.snap = J->snapbuf;
+  J->cur.snapmap = J->snapmapbuf;
+  J->mergesnap = 0;
+  J->needsnap = 0;
+  J->bcskip = 0;
+  J->guardemit.irt = 0;
+  J->postproc = LJ_POST_NONE;
+  lj_resetsplit(J);
+  setgcref(J->cur.startpt, obj2gco(J->pt));
+
+  L = J->L;
+  lj_vmevent_send(L, TRACE,
+    setstrV(L, L->top++, lj_str_newlit(L, "start"));
+    setintV(L->top++, traceno);
+    setfuncV(L, L->top++, J->fn);
+    setintV(L->top++, proto_bcpos(J->pt, J->pc));
+    if (J->parent) {
+      setintV(L->top++, J->parent);
+      setintV(L->top++, J->exitno);
+    }
+  );
+  lj_record_setup(J);
+}
+
+/* Stop tracing. */
+static void trace_stop(jit_State *J)
+{
+  BCIns *pc = mref(J->cur.startpc, BCIns);
+  BCOp op = bc_op(J->cur.startins);
+  GCproto *pt = &gcref(J->cur.startpt)->pt;
+  TraceNo traceno = J->cur.traceno;
+  lua_State *L;
+
+  switch (op) {
+  case BC_FORL:
+    setbc_op(pc+bc_j(J->cur.startins), BC_JFORI);  /* Patch FORI, too. */
+    /* fallthrough */
+  case BC_LOOP:
+  case BC_ITERL:
+  case BC_FUNCF:
+    /* Patch bytecode of starting instruction in root trace. */
+    setbc_op(pc, (int)op+(int)BC_JLOOP-(int)BC_LOOP);
+    setbc_d(pc, traceno);
+  addroot:
+    /* Add to root trace chain in prototype. */
+    J->cur.nextroot = pt->trace;
+    pt->trace = (TraceNo1)traceno;
+    break;
+  case BC_RET:
+  case BC_RET0:
+  case BC_RET1:
+    *pc = BCINS_AD(BC_JLOOP, J->cur.snap[0].nslots, traceno);
+    goto addroot;
+  case BC_JMP:
+    /* Patch exit branch in parent to side trace entry. */
+    lua_assert(J->parent != 0 && J->cur.root != 0);
+    lj_asm_patchexit(J, traceref(J, J->parent), J->exitno, J->cur.mcode);
+    /* Avoid compiling a side trace twice (stack resizing uses parent exit). */
+    traceref(J, J->parent)->snap[J->exitno].count = SNAPCOUNT_DONE;
+    /* Add to side trace chain in root trace. */
+    {
+      GCtrace *root = traceref(J, J->cur.root);
+      root->nchild++;
+      J->cur.nextside = root->nextside;
+      root->nextside = (TraceNo1)traceno;
+    }
+    break;
+  default:
+    lua_assert(0);
+    break;
+  }
+
+  /* Commit new mcode only after all patching is done. */
+  lj_mcode_commit(J, J->cur.mcode);
+  J->postproc = LJ_POST_NONE;
+  trace_save(J);
+
+  L = J->L;
+  lj_vmevent_send(L, TRACE,
+    setstrV(L, L->top++, lj_str_newlit(L, "stop"));
+    setintV(L->top++, traceno);
+  );
+}
+
+/* Start a new root trace for down-recursion. */
+static int trace_downrec(jit_State *J)
+{
+  /* Restart recording at the return instruction. */
+  lua_assert(J->pt != NULL);
+  lua_assert(bc_isret(bc_op(*J->pc)));
+  if (bc_op(*J->pc) == BC_RETM)
+    return 0;  /* NYI: down-recursion with RETM. */
+  J->parent = 0;
+  J->exitno = 0;
+  J->state = LJ_TRACE_RECORD;
+  trace_start(J);
+  return 1;
+}
+
+/* Abort tracing. */
+static int trace_abort(jit_State *J)
+{
+  lua_State *L = J->L;
+  TraceError e = LJ_TRERR_RECERR;
+  TraceNo traceno;
+
+  J->postproc = LJ_POST_NONE;
+  lj_mcode_abort(J);
+  if (tvisnumber(L->top-1))
+    e = (TraceError)numberVint(L->top-1);
+  if (e == LJ_TRERR_MCODELM) {
+    L->top--;  /* Remove error object */
+    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)))
+    penalty_pc(J, &gcref(J->cur.startpt)->pt, mref(J->cur.startpc, BCIns), e);
+
+  /* Is there anything to abort? */
+  traceno = J->cur.traceno;
+  if (traceno) {
+    ptrdiff_t errobj = savestack(L, L->top-1);  /* Stack may be resized. */
+    J->cur.link = 0;
+    J->cur.linktype = LJ_TRLINK_NONE;
+    lj_vmevent_send(L, TRACE,
+      TValue *frame;
+      const BCIns *pc;
+      GCfunc *fn;
+      setstrV(L, L->top++, lj_str_newlit(L, "abort"));
+      setintV(L->top++, traceno);
+      /* Find original Lua function call to generate a better error message. */
+      frame = J->L->base-1;
+      pc = J->pc;
+      while (!isluafunc(frame_func(frame))) {
+	pc = (frame_iscont(frame) ? frame_contpc(frame) : frame_pc(frame)) - 1;
+	frame = frame_prev(frame);
+      }
+      fn = frame_func(frame);
+      setfuncV(L, L->top++, fn);
+      setintV(L->top++, proto_bcpos(funcproto(fn), pc));
+      copyTV(L, L->top++, restorestack(L, errobj));
+      copyTV(L, L->top++, &J->errinfo);
+    );
+    /* Drop aborted trace after the vmevent (which may still access it). */
+    setgcrefnull(J->trace[traceno]);
+    if (traceno < J->freetrace)
+      J->freetrace = traceno;
+    J->cur.traceno = 0;
+  }
+  L->top--;  /* Remove error object */
+  if (e == LJ_TRERR_DOWNREC)
+    return trace_downrec(J);
+  else if (e == LJ_TRERR_MCODEAL)
+    lj_trace_flushall(L);
+  return 0;
+}
+
+/* Perform pending re-patch of a bytecode instruction. */
+static LJ_AINLINE void trace_pendpatch(jit_State *J, int force)
+{
+  if (LJ_UNLIKELY(J->patchpc)) {
+    if (force || J->bcskip == 0) {
+      *J->patchpc = J->patchins;
+      J->patchpc = NULL;
+    } else {
+      J->bcskip = 0;
+    }
+  }
+}
+
+/* State machine for the trace compiler. Protected callback. */
+static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
+{
+  jit_State *J = (jit_State *)ud;
+  UNUSED(dummy);
+  do {
+  retry:
+    switch (J->state) {
+    case LJ_TRACE_START:
+      J->state = LJ_TRACE_RECORD;  /* trace_start() may change state. */
+      trace_start(J);
+      lj_dispatch_update(J2G(J));
+      break;
+
+    case LJ_TRACE_RECORD:
+      trace_pendpatch(J, 0);
+      setvmstate(J2G(J), RECORD);
+      lj_vmevent_send_(L, RECORD,
+	/* Save/restore tmptv state for trace recorder. */
+	TValue savetv = J2G(J)->tmptv;
+	TValue savetv2 = J2G(J)->tmptv2;
+	setintV(L->top++, J->cur.traceno);
+	setfuncV(L, L->top++, J->fn);
+	setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1);
+	setintV(L->top++, J->framedepth);
+      ,
+	J2G(J)->tmptv = savetv;
+	J2G(J)->tmptv2 = savetv2;
+      );
+      lj_record_ins(J);
+      break;
+
+    case LJ_TRACE_END:
+      trace_pendpatch(J, 1);
+      J->loopref = 0;
+      if ((J->flags & JIT_F_OPT_LOOP) &&
+	  J->cur.link == J->cur.traceno && J->framedepth + J->retdepth == 0) {
+	setvmstate(J2G(J), OPT);
+	lj_opt_dce(J);
+	if (lj_opt_loop(J)) {  /* Loop optimization failed? */
+	  J->cur.link = 0;
+	  J->cur.linktype = LJ_TRLINK_NONE;
+	  J->loopref = J->cur.nins;
+	  J->state = LJ_TRACE_RECORD;  /* Try to continue recording. */
+	  break;
+	}
+	J->loopref = J->chain[IR_LOOP];  /* Needed by assembler. */
+      }
+      lj_opt_split(J);
+      lj_opt_sink(J);
+      if (!J->loopref) J->cur.snap[J->cur.nsnap-1].count = SNAPCOUNT_DONE;
+      J->state = LJ_TRACE_ASM;
+      break;
+
+    case LJ_TRACE_ASM:
+      setvmstate(J2G(J), ASM);
+      lj_asm_trace(J, &J->cur);
+      trace_stop(J);
+      setvmstate(J2G(J), INTERP);
+      J->state = LJ_TRACE_IDLE;
+      lj_dispatch_update(J2G(J));
+      return NULL;
+
+    default:  /* Trace aborted asynchronously. */
+      setintV(L->top++, (int32_t)LJ_TRERR_RECERR);
+      /* fallthrough */
+    case LJ_TRACE_ERR:
+      trace_pendpatch(J, 1);
+      if (trace_abort(J))
+	goto retry;
+      setvmstate(J2G(J), INTERP);
+      J->state = LJ_TRACE_IDLE;
+      lj_dispatch_update(J2G(J));
+      return NULL;
+    }
+  } while (J->state > LJ_TRACE_RECORD);
+  return NULL;
+}
+
+/* -- Event handling ------------------------------------------------------ */
+
+/* A bytecode instruction is about to be executed. Record it. */
+void lj_trace_ins(jit_State *J, const BCIns *pc)
+{
+  /* Note: J->L must already be set. pc is the true bytecode PC here. */
+  J->pc = pc;
+  J->fn = curr_func(J->L);
+  J->pt = isluafunc(J->fn) ? funcproto(J->fn) : NULL;
+  while (lj_vm_cpcall(J->L, NULL, (void *)J, trace_state) != 0)
+    J->state = LJ_TRACE_ERR;
+}
+
+/* A hotcount triggered. Start recording a root trace. */
+void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc)
+{
+  /* Note: pc is the interpreter bytecode PC here. It's offset by 1. */
+  ERRNO_SAVE
+  /* Reset hotcount. */
+  hotcount_set(J2GG(J), pc, J->param[JIT_P_hotloop]*HOTCOUNT_LOOP);
+  /* Only start a new trace if not recording or inside __gc call or vmevent. */
+  if (J->state == LJ_TRACE_IDLE &&
+      !(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
+    J->parent = 0;  /* Root trace. */
+    J->exitno = 0;
+    J->state = LJ_TRACE_START;
+    lj_trace_ins(J, pc-1);
+  }
+  ERRNO_RESTORE
+}
+
+/* Check for a hot side exit. If yes, start recording a side trace. */
+static void trace_hotside(jit_State *J, const BCIns *pc)
+{
+  SnapShot *snap = &traceref(J, J->parent)->snap[J->exitno];
+  if (!(J2G(J)->hookmask & (HOOK_GC|HOOK_VMEVENT)) &&
+      snap->count != SNAPCOUNT_DONE &&
+      ++snap->count >= J->param[JIT_P_hotexit]) {
+    lua_assert(J->state == LJ_TRACE_IDLE);
+    /* J->parent is non-zero for a side trace. */
+    J->state = LJ_TRACE_START;
+    lj_trace_ins(J, pc);
+  }
+}
+
+/* Tiny struct to pass data to protected call. */
+typedef struct ExitDataCP {
+  jit_State *J;
+  void *exptr;		/* Pointer to exit state. */
+  const BCIns *pc;	/* Restart interpreter at this PC. */
+} ExitDataCP;
+
+/* Need to protect lj_snap_restore because it may throw. */
+static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud)
+{
+  ExitDataCP *exd = (ExitDataCP *)ud;
+  cframe_errfunc(L->cframe) = -1;  /* Inherit error function. */
+  exd->pc = lj_snap_restore(exd->J, exd->exptr);
+  UNUSED(dummy);
+  return NULL;
+}
+
+#ifndef LUAJIT_DISABLE_VMEVENT
+/* Push all registers from exit state. */
+static void trace_exit_regs(lua_State *L, ExitState *ex)
+{
+  int32_t i;
+  setintV(L->top++, RID_NUM_GPR);
+  setintV(L->top++, RID_NUM_FPR);
+  for (i = 0; i < RID_NUM_GPR; i++) {
+    if (sizeof(ex->gpr[i]) == sizeof(int32_t))
+      setintV(L->top++, (int32_t)ex->gpr[i]);
+    else
+      setnumV(L->top++, (lua_Number)ex->gpr[i]);
+  }
+#if !LJ_SOFTFP
+  for (i = 0; i < RID_NUM_FPR; i++) {
+    setnumV(L->top, ex->fpr[i]);
+    if (LJ_UNLIKELY(tvisnan(L->top)))
+      setnanV(L->top);
+    L->top++;
+  }
+#endif
+}
+#endif
+
+#ifdef EXITSTATE_PCREG
+/* Determine trace number from pc of exit instruction. */
+static TraceNo trace_exit_find(jit_State *J, MCode *pc)
+{
+  TraceNo traceno;
+  for (traceno = 1; traceno < J->sizetrace; traceno++) {
+    GCtrace *T = traceref(J, traceno);
+    if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode))
+      return traceno;
+  }
+  lua_assert(0);
+  return 0;
+}
+#endif
+
+/* A trace exited. Restore interpreter state. */
+int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
+{
+  ERRNO_SAVE
+  lua_State *L = J->L;
+  ExitState *ex = (ExitState *)exptr;
+  ExitDataCP exd;
+  int errcode;
+  const BCIns *pc;
+  void *cf;
+  GCtrace *T;
+#ifdef EXITSTATE_PCREG
+  J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]);
+#endif
+  T = traceref(J, J->parent); UNUSED(T);
+#ifdef EXITSTATE_CHECKEXIT
+  if (J->exitno == T->nsnap) {  /* Treat stack check like a parent exit. */
+    lua_assert(T->root != 0);
+    J->exitno = T->ir[REF_BASE].op2;
+    J->parent = T->ir[REF_BASE].op1;
+    T = traceref(J, J->parent);
+  }
+#endif
+  lua_assert(T != NULL && J->exitno < T->nsnap);
+  exd.J = J;
+  exd.exptr = exptr;
+  errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp);
+  if (errcode)
+    return -errcode;  /* Return negated error code. */
+
+  lj_vmevent_send(L, TEXIT,
+    lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK);
+    setintV(L->top++, J->parent);
+    setintV(L->top++, J->exitno);
+    trace_exit_regs(L, ex);
+  );
+
+  pc = exd.pc;
+  cf = cframe_raw(L->cframe);
+  setcframe_pc(cf, pc);
+  if (G(L)->gc.state == GCSatomic || G(L)->gc.state == GCSfinalize) {
+    if (!(G(L)->hookmask & HOOK_GC))
+      lj_gc_step(L);  /* Exited because of GC: drive GC forward. */
+  } else {
+    trace_hotside(J, pc);
+  }
+  if (bc_op(*pc) == BC_JLOOP) {
+    BCIns *retpc = &traceref(J, bc_d(*pc))->startins;
+    if (bc_isret(bc_op(*retpc))) {
+      if (J->state == LJ_TRACE_RECORD) {
+	J->patchins = *pc;
+	J->patchpc = (BCIns *)pc;
+	*J->patchpc = *retpc;
+	J->bcskip = 1;
+      } else {
+	pc = retpc;
+	setcframe_pc(cf, pc);
+      }
+    }
+  }
+  /* Return MULTRES or 0. */
+  ERRNO_RESTORE
+  switch (bc_op(*pc)) {
+  case BC_CALLM: case BC_CALLMT:
+    return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc));
+  case BC_RETM:
+    return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc));
+  case BC_TSETM:
+    return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
+  default:
+    if (bc_op(*pc) >= BC_FUNCF)
+      return (int)((BCReg)(L->top - L->base) + 1);
+    return 0;
+  }
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/1f27b840/lib/luajit/src/lj_trace.h
----------------------------------------------------------------------
diff --git a/lib/luajit/src/lj_trace.h b/lib/luajit/src/lj_trace.h
new file mode 100644
index 0000000..4fbe5cf
--- /dev/null
+++ b/lib/luajit/src/lj_trace.h
@@ -0,0 +1,53 @@
+/*
+** Trace management.
+** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+*/
+
+#ifndef _LJ_TRACE_H
+#define _LJ_TRACE_H
+
+#include "lj_obj.h"
+
+#if LJ_HASJIT
+#include "lj_jit.h"
+#include "lj_dispatch.h"
+
+/* Trace errors. */
+typedef enum {
+#define TREDEF(name, msg)	LJ_TRERR_##name,
+#include "lj_traceerr.h"
+  LJ_TRERR__MAX
+} TraceError;
+
+LJ_FUNC_NORET void lj_trace_err(jit_State *J, TraceError e);
+LJ_FUNC_NORET void lj_trace_err_info(jit_State *J, TraceError e);
+
+/* Trace management. */
+LJ_FUNC void LJ_FASTCALL lj_trace_free(global_State *g, GCtrace *T);
+LJ_FUNC void lj_trace_reenableproto(GCproto *pt);
+LJ_FUNC void lj_trace_flushproto(global_State *g, GCproto *pt);
+LJ_FUNC void lj_trace_flush(jit_State *J, TraceNo traceno);
+LJ_FUNC int lj_trace_flushall(lua_State *L);
+LJ_FUNC void lj_trace_initstate(global_State *g);
+LJ_FUNC void lj_trace_freestate(global_State *g);
+
+/* Event handling. */
+LJ_FUNC void lj_trace_ins(jit_State *J, const BCIns *pc);
+LJ_FUNCA void LJ_FASTCALL lj_trace_hot(jit_State *J, const BCIns *pc);
+LJ_FUNCA int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr);
+
+/* Signal asynchronous abort of trace or end of trace. */
+#define lj_trace_abort(g)	(G2J(g)->state &= ~LJ_TRACE_ACTIVE)
+#define lj_trace_end(J)		(J->state = LJ_TRACE_END)
+
+#else
+
+#define lj_trace_flushall(L)	(UNUSED(L), 0)
+#define lj_trace_initstate(g)	UNUSED(g)
+#define lj_trace_freestate(g)	UNUSED(g)
+#define lj_trace_abort(g)	UNUSED(g)
+#define lj_trace_end(J)		UNUSED(J)
+
+#endif
+
+#endif