summaryrefslogtreecommitdiff
path: root/Modules/_pickle.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-01-20 16:42:44 +0200
committerGitHub <noreply@github.com>2018-01-20 16:42:44 +0200
commit1211c9a9897a174b7261ca258cabf289815a40d8 (patch)
treea43814a9172d44d64d7427d10249c816e5f4ef0e /Modules/_pickle.c
parentbd5c7d238c01b90fbfae8ea45b47bd601900abaf (diff)
downloadcpython-git-1211c9a9897a174b7261ca258cabf289815a40d8.tar.gz
bpo-32503: Avoid creating too small frames in pickles. (#5127)
Diffstat (limited to 'Modules/_pickle.c')
-rw-r--r--Modules/_pickle.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index f8cbea12e8..f06a87d04f 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -119,8 +119,8 @@ enum {
/* Prefetch size when unpickling (disabled on unpeekable streams) */
PREFETCH = 8192 * 16,
+ FRAME_SIZE_MIN = 4,
FRAME_SIZE_TARGET = 64 * 1024,
-
FRAME_HEADER_SIZE = 9
};
@@ -949,13 +949,6 @@ _write_size64(char *out, size_t value)
}
}
-static void
-_Pickler_WriteFrameHeader(PicklerObject *self, char *qdata, size_t frame_len)
-{
- qdata[0] = FRAME;
- _write_size64(qdata + 1, frame_len);
-}
-
static int
_Pickler_CommitFrame(PicklerObject *self)
{
@@ -966,7 +959,14 @@ _Pickler_CommitFrame(PicklerObject *self)
return 0;
frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE;
qdata = PyBytes_AS_STRING(self->output_buffer) + self->frame_start;
- _Pickler_WriteFrameHeader(self, qdata, frame_len);
+ if (frame_len >= FRAME_SIZE_MIN) {
+ qdata[0] = FRAME;
+ _write_size64(qdata + 1, frame_len);
+ }
+ else {
+ memmove(qdata, qdata + FRAME_HEADER_SIZE, frame_len);
+ self->output_len -= FRAME_HEADER_SIZE;
+ }
self->frame_start = -1;
return 0;
}