mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 12:38:02 +02:00
script: Recompress strings using LZO whilst binding traces
Try using the lighter-weight LZO decompressor in an effort to speed up replays (at the cost of making the bound traces slightly larger). Presuming that with the slight increase in file size (from -1% to +10%), the file data remains in the readahead buffer cache, replays see a performance improvement of between 5-10%. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
9194904fa8
commit
45a4b42a36
7 changed files with 226 additions and 55 deletions
12
configure.ac
12
configure.ac
|
|
@ -47,6 +47,18 @@ AC_CHECK_LIB(z, compress,
|
|||
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])],
|
||||
[have_libz="no (requires zlib http://www.gzip.org/zlib/)"])
|
||||
|
||||
save_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(lzo2, lzo2a_decompress,
|
||||
[AC_CHECK_HEADER(lzo/lzo2a.h, [
|
||||
have_lzo=yes
|
||||
AC_DEFINE(HAVE_LZO, 1, [Define to 1 if you have lzo available])
|
||||
lzo_LIBS="-llzo2"
|
||||
],
|
||||
[have_lzo="no (requires lzpo http://www.oberhumer.com/opensource/lzo/)"])],
|
||||
[have_lzo="no (requires lzpo http://www.oberhumer.com/opensource/lzo/)"])
|
||||
AC_SUBST(lzo_LIBS)
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
AC_CHECK_LIB(dl, dlsym,
|
||||
[have_dlsym=yes; have_dl=yes],
|
||||
[have_dlsym=no; have_dl=no])
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ libcairo_script_interpreter_la_SOURCES = \
|
|||
$(NULL)
|
||||
libcairo_script_interpreter_la_CFLAGS = $(CAIRO_CFLAGS)
|
||||
libcairo_script_interpreter_la_LDFLAGS = -version-info $(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols)
|
||||
libcairo_script_interpreter_la_LIBADD = $(top_builddir)/src/libcairo.la $(CAIRO_LIBS) -lz
|
||||
libcairo_script_interpreter_la_LIBADD = $(top_builddir)/src/libcairo.la $(CAIRO_LIBS) $(lzo_LIBS) -lz
|
||||
|
||||
csi_replay_SOURCES = csi-replay.c
|
||||
csi_replay_CFLAGS = $(CAIRO_CFLAGS)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@
|
|||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#if HAVE_LZO
|
||||
#include <lzo/lzo2a.h>
|
||||
#endif
|
||||
|
||||
#define CHUNK_SIZE 32768
|
||||
|
||||
#define OWN_STREAM 0x1
|
||||
|
|
@ -166,12 +170,32 @@ csi_file_new_from_string (csi_t *ctx,
|
|||
return status;
|
||||
|
||||
tmp_str = tmp_obj.datum.string;
|
||||
if (uncompress ((Bytef *) tmp_str->string, &len,
|
||||
(Bytef *) src->string, src->len) != Z_OK)
|
||||
{
|
||||
switch (src->method) {
|
||||
case NONE:
|
||||
default:
|
||||
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
|
||||
#if HAVE_ZLIB
|
||||
case ZLIB:
|
||||
if (uncompress ((Bytef *) tmp_str->string, &len,
|
||||
(Bytef *) src->string, src->len) != Z_OK)
|
||||
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
#endif
|
||||
#if HAVE_LZO
|
||||
case LZO:
|
||||
if (lzo2a_decompress ((lzo_bytep) src->string, src->len,
|
||||
(lzo_bytep) tmp_str->string, &len,
|
||||
NULL))
|
||||
status = _csi_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (_csi_unlikely (status)) {
|
||||
csi_string_free (ctx, tmp_str);
|
||||
_csi_slab_free (ctx, file, sizeof (csi_file_t));
|
||||
return _csi_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return status;
|
||||
}
|
||||
|
||||
file->src = tmp_str;
|
||||
|
|
|
|||
|
|
@ -508,6 +508,7 @@ csi_string_new (csi_t *ctx,
|
|||
}
|
||||
string->len = len;
|
||||
string->deflate = 0;
|
||||
string->method = NONE;
|
||||
|
||||
string->base.type = CSI_OBJECT_TYPE_STRING;
|
||||
string->base.ref = 1;
|
||||
|
|
@ -534,6 +535,7 @@ csi_string_deflate_new (csi_t *ctx,
|
|||
|
||||
string = obj->datum.string;
|
||||
string->deflate = out_len;
|
||||
string->method = ZLIB;
|
||||
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -556,6 +558,7 @@ csi_string_new_from_bytes (csi_t *ctx,
|
|||
string->string = bytes;
|
||||
string->len = len;
|
||||
string->deflate = 0;
|
||||
string->method = NONE;
|
||||
|
||||
string->base.type = CSI_OBJECT_TYPE_STRING;
|
||||
string->base.ref = 1;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,14 @@
|
|||
#include <math.h>
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include <assert.h>
|
||||
|
||||
#if HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LZO
|
||||
#include <lzo/lzo2a.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
# ifdef HAVE_UNISTD_H
|
||||
|
|
@ -1756,17 +1763,37 @@ inflate_string (csi_t *ctx, csi_string_t *src)
|
|||
if (bytes == NULL)
|
||||
return NULL;
|
||||
|
||||
if (uncompress ((Bytef *) bytes, &len,
|
||||
(Bytef *) src->string, src->len) != Z_OK)
|
||||
{
|
||||
_csi_free (ctx, bytes);
|
||||
bytes = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes[len] = '\0';
|
||||
switch (src->method) {
|
||||
default:
|
||||
case NONE:
|
||||
free (bytes);
|
||||
return NULL;
|
||||
|
||||
#if HAVE_ZLIB
|
||||
case ZLIB:
|
||||
if (uncompress ((Bytef *) bytes, &len,
|
||||
(Bytef *) src->string, src->len) != Z_OK)
|
||||
{
|
||||
_csi_free (ctx, bytes);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_LZO
|
||||
case LZO:
|
||||
if (lzo2a_decompress ((Bytef *) src->string, src->len,
|
||||
(Bytef *) bytes, &len,
|
||||
NULL))
|
||||
{
|
||||
_csi_free (ctx, bytes);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
bytes[len] = '\0';
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -392,6 +392,11 @@ struct _csi_string {
|
|||
csi_compound_object_t base;
|
||||
csi_integer_t len;
|
||||
csi_integer_t deflate;
|
||||
enum {
|
||||
NONE,
|
||||
ZLIB,
|
||||
LZO,
|
||||
} method;
|
||||
char *string;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,10 +38,15 @@
|
|||
#include <math.h> /* pow */
|
||||
#include <stdio.h> /* EOF */
|
||||
#include <stdint.h> /* for {INT,UINT}*_{MIN,MAX} */
|
||||
#include <stdlib.h> /* malloc/free */
|
||||
#include <string.h> /* memset */
|
||||
#include <assert.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#if HAVE_LZO
|
||||
#include <lzo/lzo2a.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG_SCAN 0
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
|
|
@ -124,7 +129,8 @@ fprintf_obj (FILE *stream, csi_t *ctx, const csi_object_t *obj)
|
|||
obj->datum.matrix->matrix.y0);
|
||||
break;
|
||||
case CSI_OBJECT_TYPE_STRING:
|
||||
fprintf (stream, "string: len=%ld\n", obj->datum.string->len);
|
||||
fprintf (stream, "string: len=%ld, defate=%ld, method=%d\n",
|
||||
obj->datum.string->len, obj->datum.string->deflate, obj->datum.string->method);
|
||||
break;
|
||||
|
||||
/* cairo */
|
||||
|
|
@ -799,6 +805,7 @@ string_read (csi_t *ctx,
|
|||
uint32_t u32;
|
||||
scan_read (scan, src, &u32, 4);
|
||||
obj->datum.string->deflate = be32 (u32);
|
||||
obj->datum.string->method = compressed;
|
||||
}
|
||||
|
||||
if (_csi_likely (len))
|
||||
|
|
@ -994,8 +1001,13 @@ scan_none:
|
|||
obj.type &= ~CSI_OBJECT_ATTR_EXECUTABLE;
|
||||
break;
|
||||
|
||||
#define STRING_LZO 154
|
||||
case STRING_LZO:
|
||||
scan_read (scan, src, &u.u32, 4);
|
||||
string_read (ctx, scan, src, be32 (u.u32), LZO, &obj);
|
||||
break;
|
||||
|
||||
/* unassigned */
|
||||
case 154:
|
||||
case 155:
|
||||
case 156:
|
||||
case 157:
|
||||
|
|
@ -1569,51 +1581,139 @@ _translate_string (csi_t *ctx,
|
|||
uint16_t u16;
|
||||
uint32_t u32;
|
||||
} u;
|
||||
int len;
|
||||
void *buf;
|
||||
unsigned long hdr_len, buf_len, deflate;
|
||||
int method;
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
if (string->len <= UINT8_MAX) {
|
||||
hdr = STRING_1;
|
||||
u.u8 = string->len;
|
||||
len = 1;
|
||||
} else if (string->len <= UINT16_MAX) {
|
||||
hdr = STRING_2_MSB;
|
||||
u.u16 = string->len;
|
||||
len = 2;
|
||||
} else {
|
||||
hdr = STRING_4_MSB;
|
||||
u.u32 = string->len;
|
||||
len = 4;
|
||||
buf = string->string;
|
||||
buf_len = string->len;
|
||||
deflate = string->deflate;
|
||||
method = string->method;
|
||||
|
||||
#if HAVE_LZO
|
||||
if (method == NONE && buf_len > 16) {
|
||||
unsigned long mem_len = 2*string->len > LZO2A_999_MEM_COMPRESS ? 2*string->len : LZO2A_999_MEM_COMPRESS;
|
||||
void *mem = malloc (mem_len);
|
||||
void *work = malloc(LZO2A_999_MEM_COMPRESS);
|
||||
|
||||
if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
|
||||
(lzo_bytep) mem, &mem_len,
|
||||
work) == 0 &&
|
||||
8+2*mem_len < buf_len)
|
||||
{
|
||||
method = LZO;
|
||||
deflate = buf_len;
|
||||
buf_len = mem_len;
|
||||
buf = mem;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (mem);
|
||||
}
|
||||
|
||||
free (work);
|
||||
}
|
||||
#else
|
||||
if (string->len <= UINT8_MAX) {
|
||||
hdr = STRING_1;
|
||||
u.u8 = string->len;
|
||||
len = 1;
|
||||
} else if (string->len <= UINT16_MAX) {
|
||||
hdr = STRING_2_LSB;
|
||||
u.u16 = string->len;
|
||||
len = 2;
|
||||
} else {
|
||||
hdr = STRING_4_LSB;
|
||||
u.u32 = string->len;
|
||||
len = 4;
|
||||
#if HAVE_ZLIB
|
||||
if (method == ZLIB) {
|
||||
buf_len = string->deflate;
|
||||
buf = malloc (string->deflate);
|
||||
if (uncompress ((Bytef *) buf, &buf_len,
|
||||
(Bytef *) string->string, string->len) == Z_OK)
|
||||
{
|
||||
if (buf_len <= 8 + 2*string->len) {
|
||||
method = NONE;
|
||||
deflate = 0;
|
||||
} else {
|
||||
unsigned long mem_len = 2*string->deflate;
|
||||
void *mem = malloc (mem_len);
|
||||
void *work = malloc(LZO2A_999_MEM_COMPRESS);
|
||||
|
||||
if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
|
||||
(lzo_bytep) mem, &mem_len,
|
||||
work) == 0)
|
||||
{
|
||||
if (8 + mem_len > buf_len) {
|
||||
method = NONE;
|
||||
deflate = 0;
|
||||
} else {
|
||||
free (buf);
|
||||
method = LZO;
|
||||
deflate = buf_len;
|
||||
buf_len = mem_len;
|
||||
buf = mem;
|
||||
assert(deflate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free (buf);
|
||||
buf = string->string;
|
||||
buf_len = string->len;
|
||||
}
|
||||
|
||||
free (work);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free (buf);
|
||||
buf = string->string;
|
||||
buf_len = string->len;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (string->deflate)
|
||||
hdr |= STRING_DEFLATE;
|
||||
#endif
|
||||
|
||||
closure->write_func (closure->closure,
|
||||
(unsigned char *) &hdr, 1);
|
||||
closure->write_func (closure->closure,
|
||||
(unsigned char *) &u, len);
|
||||
if (string->deflate) {
|
||||
uint32_t u32 = to_be32 (string->deflate);
|
||||
closure->write_func (closure->closure,
|
||||
(unsigned char *) &u32, 4);
|
||||
if (method == LZO) {
|
||||
hdr = STRING_LZO;
|
||||
u.u32 = to_be32 (buf_len);
|
||||
hdr_len = 4;
|
||||
} else {
|
||||
#if WORDS_BIGENDIAN
|
||||
if (buf_len <= UINT8_MAX) {
|
||||
hdr = STRING_1;
|
||||
u.u8 = buf_len;
|
||||
hdr_len = 1;
|
||||
} else if (buf_len <= UINT16_MAX) {
|
||||
hdr = STRING_2_MSB;
|
||||
u.u16 = buf_len;
|
||||
hdr_len = 2;
|
||||
} else {
|
||||
hdr = STRING_4_MSB;
|
||||
u.u32 = buf_len;
|
||||
hdr_len = 4;
|
||||
}
|
||||
#else
|
||||
if (buf_len <= UINT8_MAX) {
|
||||
hdr = STRING_1;
|
||||
u.u8 = buf_len;
|
||||
hdr_len = 1;
|
||||
} else if (buf_len <= UINT16_MAX) {
|
||||
hdr = STRING_2_LSB;
|
||||
u.u16 = buf_len;
|
||||
hdr_len = 2;
|
||||
} else {
|
||||
hdr = STRING_4_LSB;
|
||||
u.u32 = buf_len;
|
||||
hdr_len = 4;
|
||||
}
|
||||
#endif
|
||||
if (deflate) {
|
||||
assert (method == ZLIB);
|
||||
hdr |= STRING_DEFLATE;
|
||||
}
|
||||
}
|
||||
closure->write_func (closure->closure,
|
||||
(unsigned char *) string->string, string->len);
|
||||
|
||||
closure->write_func (closure->closure, (unsigned char *) &hdr, 1);
|
||||
closure->write_func (closure->closure, (unsigned char *) &u, hdr_len);
|
||||
if (deflate) {
|
||||
uint32_t u32 = to_be32 (deflate);
|
||||
closure->write_func (closure->closure, (unsigned char *) &u32, 4);
|
||||
}
|
||||
closure->write_func (closure->closure, (unsigned char *) buf, buf_len);
|
||||
|
||||
if (buf != string->string)
|
||||
free (buf);
|
||||
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue