aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-11-22 17:45:08 +0100
committerDmitry Vyukov <dvyukov@google.com>2022-11-23 09:09:39 +0100
commitf2248a0a06cf02cc83adfc073a0fab1ab53b344f (patch)
treed355752a42754d184ac3339a8c2aba0f1417389c
parent3c4ffce72a611aaf547c0e0047b4aefc0dde86fd (diff)
executor: reduce zlib memory consumption
The images we unpack has huge ranges of 0s. Currently we write all bytes and as the result page in whole unpacked image. Don't write 0s since we just mmaped zero memory. This reduces btrfs_0 seed memory consumption from 130MB to 6MB.
-rw-r--r--executor/common_zlib.h13
-rw-r--r--pkg/csource/generated.go26
2 files changed, 24 insertions, 15 deletions
diff --git a/executor/common_zlib.h b/executor/common_zlib.h
index 5f8124318..24382ac0c 100644
--- a/executor/common_zlib.h
+++ b/executor/common_zlib.h
@@ -98,8 +98,10 @@ static int puff_stored(struct puff_state* s)
return 2; // not enough input
if (s->outcnt + len > s->outlen)
return 1; // not enough output space
- while (len--)
- s->out[s->outcnt++] = s->in[s->incnt++];
+ for (; len--; s->outcnt++, s->incnt++) {
+ if (s->in[s->incnt])
+ s->out[s->outcnt] = s->in[s->incnt];
+ }
// done with a valid stored block
return 0;
@@ -243,7 +245,8 @@ static int puff_codes(struct puff_state* s,
// write out the literal
if (s->outcnt == s->outlen)
return 1;
- s->out[s->outcnt] = symbol;
+ if (symbol)
+ s->out[s->outcnt] = symbol;
s->outcnt++;
} else if (symbol > 256) { // length
// get and compute length
@@ -264,8 +267,8 @@ static int puff_codes(struct puff_state* s,
if (s->outcnt + len > s->outlen)
return 1;
while (len--) {
- s->out[s->outcnt] =
- dist > s->outcnt ? 0 : s->out[s->outcnt - dist];
+ if (dist <= s->outcnt && s->out[s->outcnt - dist])
+ s->out[s->outcnt] = s->out[s->outcnt - dist];
s->outcnt++;
}
}
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 9ee0705c2..61b95e4cf 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -6387,8 +6387,10 @@ static int puff_stored(struct puff_state* s)
return 2;
if (s->outcnt + len > s->outlen)
return 1;
- while (len--)
- s->out[s->outcnt++] = s->in[s->incnt++];
+ for (; len--; s->outcnt++, s->incnt++) {
+ if (s->in[s->incnt])
+ s->out[s->outcnt] = s->in[s->incnt];
+ }
return 0;
}
struct puff_huffman {
@@ -6483,7 +6485,8 @@ static int puff_codes(struct puff_state* s,
if (symbol < 256) {
if (s->outcnt == s->outlen)
return 1;
- s->out[s->outcnt] = symbol;
+ if (symbol)
+ s->out[s->outcnt] = symbol;
s->outcnt++;
} else if (symbol > 256) {
symbol -= 257;
@@ -6499,8 +6502,8 @@ static int puff_codes(struct puff_state* s,
if (s->outcnt + len > s->outlen)
return 1;
while (len--) {
- s->out[s->outcnt] =
- dist > s->outcnt ? 0 : s->out[s->outcnt - dist];
+ if (dist <= s->outcnt && s->out[s->outcnt - dist])
+ s->out[s->outcnt] = s->out[s->outcnt - dist];
s->outcnt++;
}
}
@@ -11528,8 +11531,10 @@ static int puff_stored(struct puff_state* s)
return 2;
if (s->outcnt + len > s->outlen)
return 1;
- while (len--)
- s->out[s->outcnt++] = s->in[s->incnt++];
+ for (; len--; s->outcnt++, s->incnt++) {
+ if (s->in[s->incnt])
+ s->out[s->outcnt] = s->in[s->incnt];
+ }
return 0;
}
struct puff_huffman {
@@ -11624,7 +11629,8 @@ static int puff_codes(struct puff_state* s,
if (symbol < 256) {
if (s->outcnt == s->outlen)
return 1;
- s->out[s->outcnt] = symbol;
+ if (symbol)
+ s->out[s->outcnt] = symbol;
s->outcnt++;
} else if (symbol > 256) {
symbol -= 257;
@@ -11640,8 +11646,8 @@ static int puff_codes(struct puff_state* s,
if (s->outcnt + len > s->outlen)
return 1;
while (len--) {
- s->out[s->outcnt] =
- dist > s->outcnt ? 0 : s->out[s->outcnt - dist];
+ if (dist <= s->outcnt && s->out[s->outcnt - dist])
+ s->out[s->outcnt] = s->out[s->outcnt - dist];
s->outcnt++;
}
}