diff options
author | Mike Pall <mike> | 2010-02-08 05:30:57 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-02-08 05:30:57 +0100 |
commit | 6194b1c896c78c2ba0436053dcae596725317e9c (patch) | |
tree | c3fc29eddcb51e3717fce1d00eff29f9a211f300 /src/lj_parse.c | |
parent | f275a9d7ef1a47c30cbb9c70897914d633dff14c (diff) | |
download | luajit-6194b1c896c78c2ba0436053dcae596725317e9c.tar.gz luajit-6194b1c896c78c2ba0436053dcae596725317e9c.tar.bz2 luajit-6194b1c896c78c2ba0436053dcae596725317e9c.zip |
Redesign of prototype generation, part 5: colocation of protoype arrays.
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index ec355403..678dc4fa 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -853,7 +853,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
853 | } else if (expr_isk(e)) { | 853 | } else if (expr_isk(e)) { |
854 | e->k = VKFALSE; | 854 | e->k = VKFALSE; |
855 | return; | 855 | return; |
856 | } else if (e->k == VJMP) { | 856 | } else if (e->k == VJMP) { |
857 | invertcond(fs, e); | 857 | invertcond(fs, e); |
858 | return; | 858 | return; |
859 | } else if (e->k == VRELOCABLE) { | 859 | } else if (e->k == VRELOCABLE) { |
@@ -1026,22 +1026,32 @@ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) | |||
1026 | 1026 | ||
1027 | /* -- Function state management ------------------------------------------- */ | 1027 | /* -- Function state management ------------------------------------------- */ |
1028 | 1028 | ||
1029 | /* NYI: compress debug info. */ | ||
1030 | |||
1031 | /* Fixup bytecode and lineinfo for prototype. */ | ||
1032 | static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo) | ||
1033 | { | ||
1034 | MSize i, n = fs->pc; | ||
1035 | BCInsLine *base = fs->bcbase; | ||
1036 | setmref(pt->bc, bc); | ||
1037 | setmref(pt->lineinfo, lineinfo); | ||
1038 | pt->sizebc = n; | ||
1039 | bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */ | ||
1040 | for (i = 0; i < n; i++) { | ||
1041 | bc[i] = base[i].ins; | ||
1042 | lineinfo[i] = base[i].line; | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1029 | /* Fixup constants for prototype. */ | 1046 | /* Fixup constants for prototype. */ |
1030 | static void fs_fixup_k(FuncState *fs, GCproto *pt) | 1047 | static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) |
1031 | { | 1048 | { |
1032 | GCtab *kt; | 1049 | GCtab *kt; |
1033 | TValue *array; | 1050 | TValue *array; |
1034 | Node *node; | 1051 | Node *node; |
1035 | BCReg nkgc; | 1052 | MSize i, hmask; |
1036 | MSize i, hmask, sizek; | ||
1037 | GCRef *kptr; | ||
1038 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); | 1053 | checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants"); |
1039 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); | 1054 | checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants"); |
1040 | nkgc = round_nkgc(fs->nkgc); | ||
1041 | sizek = (MSize)(nkgc*sizeof(GCRef) + fs->nkn*sizeof(lua_Number)); | ||
1042 | kptr = lj_mem_newt(fs->L, sizek, GCRef); | ||
1043 | if (nkgc) setgcrefnull(kptr[0]); /* May be uninitialized otherwise. */ | ||
1044 | kptr += nkgc; | ||
1045 | setmref(pt->k, kptr); | 1055 | setmref(pt->k, kptr); |
1046 | pt->sizekn = fs->nkn; | 1056 | pt->sizekn = fs->nkn; |
1047 | pt->sizekgc = fs->nkgc; | 1057 | pt->sizekgc = fs->nkgc; |
@@ -1060,7 +1070,7 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) | |||
1060 | ((lua_Number *)kptr)[kidx] = numV(&n->key); | 1070 | ((lua_Number *)kptr)[kidx] = numV(&n->key); |
1061 | } else { | 1071 | } else { |
1062 | GCobj *o = gcV(&n->key); | 1072 | GCobj *o = gcV(&n->key); |
1063 | setgcref(kptr[~kidx], o); | 1073 | setgcref(((GCRef *)kptr)[~kidx], o); |
1064 | lj_gc_objbarrier(fs->L, pt, o); | 1074 | lj_gc_objbarrier(fs->L, pt, o); |
1065 | } | 1075 | } |
1066 | } | 1076 | } |
@@ -1068,16 +1078,29 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) | |||
1068 | } | 1078 | } |
1069 | 1079 | ||
1070 | /* Fixup upvalues for prototype. */ | 1080 | /* Fixup upvalues for prototype. */ |
1071 | static void fs_fixup_uv(FuncState *fs, GCproto *pt) | 1081 | static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv) |
1072 | { | 1082 | { |
1073 | MSize i, n = fs->nuv; | 1083 | MSize i, n = fs->nuv; |
1074 | uint16_t *uv = lj_mem_newvec(fs->L, n, uint16_t); | ||
1075 | setmref(pt->uv, uv); | 1084 | setmref(pt->uv, uv); |
1076 | pt->sizeuv = n; | 1085 | pt->sizeuv = n; |
1077 | for (i = 0; i < n; i++) | 1086 | for (i = 0; i < n; i++) |
1078 | uv[i] = fs->uvloc[i].slot; | 1087 | uv[i] = fs->uvloc[i].slot; |
1079 | } | 1088 | } |
1080 | 1089 | ||
1090 | /* Fixup debug info for prototype. */ | ||
1091 | static void fs_fixup_dbg(FuncState *fs, GCproto *pt, VarInfo *vi, MSize sizevi) | ||
1092 | { | ||
1093 | MSize i, n = fs->nuv; | ||
1094 | GCRef *uvname = (GCRef *)((char *)vi + sizevi*sizeof(VarInfo)); | ||
1095 | VarInfo *vstack = fs->ls->vstack; | ||
1096 | setmref(pt->varinfo, vi); | ||
1097 | setmref(pt->uvname, uvname); | ||
1098 | pt->sizevarinfo = sizevi; | ||
1099 | memcpy(vi, &vstack[fs->vbase], sizevi*sizeof(VarInfo)); | ||
1100 | for (i = 0; i < n; i++) | ||
1101 | setgcref(uvname[i], gcref(vstack[fs->uvloc[i].vidx].name)); | ||
1102 | } | ||
1103 | |||
1081 | /* Check if bytecode op returns. */ | 1104 | /* Check if bytecode op returns. */ |
1082 | static int bcopisret(BCOp op) | 1105 | static int bcopisret(BCOp op) |
1083 | { | 1106 | { |
@@ -1128,6 +1151,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
1128 | { | 1151 | { |
1129 | lua_State *L = ls->L; | 1152 | lua_State *L = ls->L; |
1130 | FuncState *fs = ls->fs; | 1153 | FuncState *fs = ls->fs; |
1154 | MSize sizevi; | ||
1155 | size_t sizept, ofsk, ofsuv, ofsdbg, ofsli; | ||
1131 | GCproto *pt; | 1156 | GCproto *pt; |
1132 | 1157 | ||
1133 | /* Apply final fixups. */ | 1158 | /* Apply final fixups. */ |
@@ -1135,61 +1160,41 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
1135 | lua_assert(fs->bl == NULL); | 1160 | lua_assert(fs->bl == NULL); |
1136 | fs_fixup_ret(fs); | 1161 | fs_fixup_ret(fs); |
1137 | 1162 | ||
1163 | /* Calculate total size of prototype including all colocated arrays. */ | ||
1164 | sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); | ||
1165 | sizept = (sizept + sizeof(lua_Number)-1) & ~(sizeof(lua_Number)-1); | ||
1166 | ofsk = sizept; | ||
1167 | sizept += fs->nkn*sizeof(lua_Number); | ||
1168 | ofsuv = sizept; | ||
1169 | sizept += ((fs->nuv+1)&~1)*2; | ||
1170 | ofsdbg = sizept; | ||
1171 | sizevi = ls->vtop - fs->vbase; | ||
1172 | sizept += sizevi*sizeof(VarInfo) + fs->nuv*sizeof(GCRef); | ||
1173 | ofsli = sizept; | ||
1174 | sizept += fs->pc*sizeof(BCLine); | ||
1175 | |||
1138 | /* Allocate prototype and initialize its fields. */ | 1176 | /* Allocate prototype and initialize its fields. */ |
1139 | pt = lj_func_newproto(L); | 1177 | pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); |
1178 | pt->gct = ~LJ_TPROTO; | ||
1179 | pt->sizept = (MSize)sizept; | ||
1140 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); | 1180 | setgcref(pt->chunkname, obj2gco(ls->chunkname)); |
1181 | pt->trace = 0; | ||
1141 | pt->flags = fs->flags; | 1182 | pt->flags = fs->flags; |
1142 | pt->numparams = fs->numparams; | 1183 | pt->numparams = fs->numparams; |
1143 | pt->framesize = fs->framesize; | 1184 | pt->framesize = fs->framesize; |
1144 | pt->linedefined = fs->linedefined; | 1185 | pt->linedefined = fs->linedefined; |
1145 | pt->lastlinedefined = line; | 1186 | pt->lastlinedefined = line; |
1146 | 1187 | ||
1147 | /* Anchor prototype since allocation of the arrays may fail. */ | 1188 | fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), |
1148 | setprotoV(L, L->top, pt); | 1189 | (BCLine *)((char *)pt + ofsli)); |
1149 | incr_top(L); | 1190 | fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); |
1150 | 1191 | fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv)); | |
1151 | fs_fixup_k(fs, pt); | 1192 | fs_fixup_dbg(fs, pt, (VarInfo *)((char *)pt + ofsdbg), sizevi); |
1152 | fs_fixup_uv(fs, pt); | ||
1153 | |||
1154 | { | ||
1155 | MSize i, n = fs->pc; | ||
1156 | BCInsLine *base = fs->bcbase; | ||
1157 | BCLine *lineinfo; | ||
1158 | BCIns *bc = lj_mem_newvec(L, n, BCIns); | ||
1159 | setmref(pt->bc, bc); | ||
1160 | pt->sizebc = fs->pc; | ||
1161 | lineinfo = lj_mem_newvec(L, n, BCLine); | ||
1162 | setmref(pt->lineinfo, lineinfo); | ||
1163 | pt->sizelineinfo = n; | ||
1164 | for (i = 0; i < n; i++) { | ||
1165 | bc[i] = base[i].ins; | ||
1166 | lineinfo[i] = base[i].line; | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | { | ||
1171 | MSize n = ls->vtop - fs->vbase; | ||
1172 | VarInfo *vi = lj_mem_newvec(L, n, VarInfo); | ||
1173 | memcpy(vi, &ls->vstack[fs->vbase], n*sizeof(VarInfo)); | ||
1174 | setmref(pt->varinfo, vi); | ||
1175 | pt->sizevarinfo = n; | ||
1176 | } | ||
1177 | |||
1178 | { | ||
1179 | MSize i, n = fs->nuv; | ||
1180 | GCRef *uvname = lj_mem_newvec(L, n, GCRef); | ||
1181 | for (i = 0; i < n; i++) | ||
1182 | setgcref(uvname[i], gcref(ls->vstack[fs->uvloc[i].vidx].name)); | ||
1183 | setmref(pt->uvname, uvname); | ||
1184 | pt->sizeuvname = n; | ||
1185 | } | ||
1186 | 1193 | ||
1187 | lj_vmevent_send(L, BC, | 1194 | lj_vmevent_send(L, BC, |
1188 | setprotoV(L, L->top++, pt); | 1195 | setprotoV(L, L->top++, pt); |
1189 | ); | 1196 | ); |
1190 | 1197 | ||
1191 | L->top--; /* Pop prototype. */ | ||
1192 | |||
1193 | L->top--; /* Pop table of constants. */ | 1198 | L->top--; /* Pop table of constants. */ |
1194 | ls->vtop = fs->vbase; /* Reset variable stack. */ | 1199 | ls->vtop = fs->vbase; /* Reset variable stack. */ |
1195 | ls->fs = fs->prev; | 1200 | ls->fs = fs->prev; |
@@ -1427,7 +1432,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
1427 | lex_match(ls, TK_end, TK_function, line); | 1432 | lex_match(ls, TK_end, TK_function, line); |
1428 | pt = fs_finish(ls, lastline); | 1433 | pt = fs_finish(ls, lastline); |
1429 | fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ | 1434 | fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ |
1430 | fs->bclim = ls->sizebcstack - oldbase; | 1435 | fs->bclim = (BCPos)(ls->sizebcstack - oldbase); |
1431 | /* Store new prototype in the constant array of the parent. */ | 1436 | /* Store new prototype in the constant array of the parent. */ |
1432 | kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); | 1437 | kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); |
1433 | expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); | 1438 | expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); |