Fixed buffers save long strings as external.
This commit is contained in:
2
ldump.c
2
ldump.c
@@ -126,7 +126,7 @@ static void dumpString (DumpState *D, TString *ts) {
|
||||
size_t size;
|
||||
const char *s = getlstr(ts, size);
|
||||
dumpSize(D, size + 2);
|
||||
dumpVector(D, s, size);
|
||||
dumpVector(D, s, size + 1); /* include ending '\0' */
|
||||
D->nstr++; /* one more saved string */
|
||||
setsvalue(D->L, &key, ts); /* the string is the key */
|
||||
setivalue(&value, D->nstr); /* its index is the value */
|
||||
|
||||
23
lundump.c
23
lundump.c
@@ -147,17 +147,24 @@ static TString *loadStringN (LoadState *S, Proto *p) {
|
||||
luaH_getint(S->h, idx, &stv);
|
||||
return tsvalue(&stv);
|
||||
}
|
||||
else if (size -= 2, size <= LUAI_MAXSHORTLEN) { /* short string? */
|
||||
char buff[LUAI_MAXSHORTLEN];
|
||||
loadVector(S, buff, size); /* load string into buffer */
|
||||
else if ((size -= 2) <= LUAI_MAXSHORTLEN) { /* short string? */
|
||||
char buff[LUAI_MAXSHORTLEN + 1]; /* extra space for '\0' */
|
||||
loadVector(S, buff, size + 1); /* load string into buffer */
|
||||
ts = luaS_newlstr(L, buff, size); /* create string */
|
||||
}
|
||||
else { /* long string */
|
||||
ts = luaS_createlngstrobj(L, size); /* create string */
|
||||
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
||||
luaD_inctop(L);
|
||||
loadVector(S, getlngstr(ts), size); /* load directly in final place */
|
||||
L->top.p--; /* pop string */
|
||||
if (S->fixed) { /* for a fixed buffer, use a fixed string */
|
||||
const char *s = getaddr(S, size + 1, char); /* get content address */
|
||||
ts = luaS_newextlstr(L, s, size, NULL, NULL);
|
||||
}
|
||||
else { /* create internal copy */
|
||||
ts = luaS_createlngstrobj(L, size); /* create string */
|
||||
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
||||
luaD_inctop(L);
|
||||
loadVector(S, getlngstr(ts), size); /* load directly in final place */
|
||||
loadByte(S); /* skip ending '\0' */
|
||||
L->top.p--; /* pop string */
|
||||
}
|
||||
}
|
||||
luaC_objbarrier(L, p, ts);
|
||||
S->nstr++; /* add string to list of saved strings */
|
||||
|
||||
@@ -3651,8 +3651,10 @@ Moreover, it may have a @Char{B} instead of a @Char{b},
|
||||
meaning a @emphx{fixed buffer} with the binary dump.
|
||||
|
||||
A fixed buffer means that the address returned by the reader function
|
||||
should contain the chunk until everything created by the chunk has
|
||||
been collected.
|
||||
will contain the chunk until everything created by the chunk has
|
||||
been collected;
|
||||
therefore, Lua can avoid copying to internal structures
|
||||
some parts of the chunk.
|
||||
(In general, a fixed buffer would keep the chunk
|
||||
as its contents until the end of the program,
|
||||
for instance with the chunk in ROM.)
|
||||
|
||||
@@ -528,13 +528,15 @@ do
|
||||
local N = 1000
|
||||
-- create a somewhat "large" source
|
||||
for i = 1, N do source[i] = "X = X + 1; " end
|
||||
-- add a long string to the source
|
||||
source[#source + 1] = string.format("Y = '%s'", string.rep("a", N));
|
||||
source = table.concat(source)
|
||||
-- give chunk an explicit name to avoid using source as name
|
||||
source = load(source, "name1")
|
||||
-- dump without debug information
|
||||
source = string.dump(source, true)
|
||||
-- each "X=X+1" generates 4 opcodes with 4 bytes each
|
||||
assert(#source > N * 4 * 4)
|
||||
-- each "X=X+1" generates 4 opcodes with 4 bytes each, plus the string
|
||||
assert(#source > N * 4 * 4 + N)
|
||||
collectgarbage(); collectgarbage()
|
||||
local m1 = collectgarbage"count" * 1024
|
||||
-- load dump using fixed buffer
|
||||
@@ -544,9 +546,11 @@ do
|
||||
]], source)
|
||||
collectgarbage()
|
||||
local m2 = collectgarbage"count" * 1024
|
||||
-- load used fewer than 300 bytes
|
||||
assert(m2 > m1 and m2 - m1 < 300)
|
||||
X = 0; code(); assert(X == N); X = nil
|
||||
-- load used fewer than 350 bytes. Code alone has more than 3*N bytes,
|
||||
-- and string literal has N bytes. Both were not loaded.
|
||||
assert(m2 > m1 and m2 - m1 < 350)
|
||||
X = 0; code(); assert(X == N and Y == string.rep("a", N))
|
||||
X = nil; Y = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user