reduce overhead for simple port char/byte reads/writes
Cut the overhead by 30% or so by making the fast path need less cooperation with the GC.
This commit is contained in:
parent
6c9a4cb470
commit
8e7792d85a
|
@ -3312,8 +3312,7 @@ static MZ_INLINE intptr_t get_one_byte(GC_CAN_IGNORE const char *who,
|
||||||
return get_one_byte_slow(who, port, buffer, 0, 0);
|
return get_one_byte_slow(who, port, buffer, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int scheme_getc(Scheme_Object *port)
|
||||||
scheme_getc(Scheme_Object *port)
|
|
||||||
{
|
{
|
||||||
char s[MAX_UTF8_CHAR_BYTES];
|
char s[MAX_UTF8_CHAR_BYTES];
|
||||||
unsigned int r[1];
|
unsigned int r[1];
|
||||||
|
@ -3362,7 +3361,7 @@ scheme_getc(Scheme_Object *port)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
scheme_get_byte(Scheme_Object *port)
|
scheme_get_byte(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||||
{
|
{
|
||||||
char s[1];
|
char s[1];
|
||||||
int v;
|
int v;
|
||||||
|
@ -4194,10 +4193,10 @@ int scheme_close_should_force_port_closed()
|
||||||
|
|
||||||
/****************************** main output writer ******************************/
|
/****************************** main output writer ******************************/
|
||||||
|
|
||||||
intptr_t
|
static intptr_t
|
||||||
scheme_put_byte_string(const char *who, Scheme_Object *port,
|
put_byte_string_slow(const char *who, Scheme_Object *port,
|
||||||
const char *str, intptr_t d, intptr_t len,
|
const char *str, intptr_t d, intptr_t len,
|
||||||
int rarely_block)
|
int rarely_block)
|
||||||
{
|
{
|
||||||
/* Unlike the main reader, the main writer is simple. It doesn't
|
/* Unlike the main reader, the main writer is simple. It doesn't
|
||||||
have to deal with peeks and specials, so it's a thin wrapper on
|
have to deal with peeks and specials, so it's a thin wrapper on
|
||||||
|
@ -4262,6 +4261,32 @@ scheme_put_byte_string(const char *who, Scheme_Object *port,
|
||||||
return oout;
|
return oout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intptr_t
|
||||||
|
scheme_put_byte_string(GC_CAN_IGNORE const char *who, Scheme_Object *port,
|
||||||
|
GC_CAN_IGNORE const char *str, intptr_t d, intptr_t len,
|
||||||
|
int rarely_block)
|
||||||
|
{
|
||||||
|
intptr_t out;
|
||||||
|
|
||||||
|
if (SCHEME_OUTPORTP(port)
|
||||||
|
&& !((Scheme_Output_Port *)port)->closed
|
||||||
|
&& (rarely_block != -1)
|
||||||
|
&& (len == 1)
|
||||||
|
&& !((Scheme_Output_Port *)port)->p.count_lines) {
|
||||||
|
Scheme_Output_Port *op = (Scheme_Output_Port *)port;
|
||||||
|
Scheme_Write_String_Fun ws;
|
||||||
|
ws = op->write_string_fun;
|
||||||
|
out = ws(op, str, d, 1, rarely_block, 0);
|
||||||
|
if (out) {
|
||||||
|
op->p.position += out;
|
||||||
|
return out;
|
||||||
|
} else if (rarely_block)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return put_byte_string_slow(who, port, str, d, len, rarely_block);
|
||||||
|
}
|
||||||
|
|
||||||
void scheme_write_byte_string(const char *str, intptr_t len, Scheme_Object *port)
|
void scheme_write_byte_string(const char *str, intptr_t len, Scheme_Object *port)
|
||||||
{
|
{
|
||||||
(void)scheme_put_byte_string("write-string", port, str, 0, len, 0);
|
(void)scheme_put_byte_string("write-string", port, str, 0, len, 0);
|
||||||
|
@ -6923,9 +6948,10 @@ static intptr_t fd_get_string_slow(Scheme_Input_Port *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
static intptr_t fd_get_string(Scheme_Input_Port *port,
|
static intptr_t fd_get_string(Scheme_Input_Port *port,
|
||||||
char *buffer, intptr_t offset, intptr_t size,
|
char *buffer, intptr_t offset, intptr_t size,
|
||||||
int nonblock,
|
int nonblock,
|
||||||
Scheme_Object *unless)
|
Scheme_Object *unless)
|
||||||
|
XFORM_ASSERT_NO_CONVERSION
|
||||||
{
|
{
|
||||||
Scheme_FD *fip;
|
Scheme_FD *fip;
|
||||||
intptr_t bc;
|
intptr_t bc;
|
||||||
|
@ -8206,9 +8232,9 @@ static intptr_t flush_fd(Scheme_Output_Port *op,
|
||||||
}
|
}
|
||||||
|
|
||||||
static intptr_t
|
static intptr_t
|
||||||
fd_write_string(Scheme_Output_Port *port,
|
fd_write_string_slow(Scheme_Output_Port *port,
|
||||||
const char *str, intptr_t d, intptr_t len,
|
const char *str, intptr_t d, intptr_t len,
|
||||||
int rarely_block, int enable_break)
|
int rarely_block, int enable_break)
|
||||||
{
|
{
|
||||||
/* Note: !flush => !rarely_block, !len => flush */
|
/* Note: !flush => !rarely_block, !len => flush */
|
||||||
|
|
||||||
|
@ -8280,6 +8306,30 @@ fd_write_string(Scheme_Output_Port *port,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static intptr_t
|
||||||
|
fd_write_string(Scheme_Output_Port *port,
|
||||||
|
const char *str, intptr_t d, intptr_t len,
|
||||||
|
int rarely_block, int enable_break)
|
||||||
|
XFORM_ASSERT_NO_CONVERSION
|
||||||
|
{
|
||||||
|
Scheme_FD *fop;
|
||||||
|
intptr_t l;
|
||||||
|
int flush = (!len || rarely_block);
|
||||||
|
|
||||||
|
fop = (Scheme_FD *)port->port_data;
|
||||||
|
|
||||||
|
if (!flush && !fop->flushing && (fop->flush != MZ_FLUSH_ALWAYS)) {
|
||||||
|
l = MZPORT_FD_BUFFSIZE - fop->bufcount;
|
||||||
|
if (len <= l) {
|
||||||
|
memcpy(fop->buffer + fop->bufcount, str + d, len);
|
||||||
|
fop->bufcount += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd_write_string_slow(port, str, d, len, rarely_block, enable_break);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fd_close_output(Scheme_Output_Port *port)
|
fd_close_output(Scheme_Output_Port *port)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3112,9 +3112,24 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in
|
||||||
return _scheme_make_char(ch);
|
return _scheme_make_char(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *read_char_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||||
read_char (int argc, Scheme_Object *argv[])
|
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = scheme_getc(port);
|
||||||
|
|
||||||
|
if (ch == EOF)
|
||||||
|
return scheme_eof;
|
||||||
|
else
|
||||||
|
return _scheme_make_char(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *
|
||||||
|
read_char (int argc, Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION
|
||||||
|
{
|
||||||
|
if (argc && SCHEME_INPUT_PORTP(argv[0]))
|
||||||
|
return read_char_fast(argv[0]);
|
||||||
|
|
||||||
return do_read_char("read-char", argc, argv, 0, 0, 0);
|
return do_read_char("read-char", argc, argv, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3136,9 +3151,24 @@ peek_char_spec (int argc, Scheme_Object *argv[])
|
||||||
return do_read_char("peek-char-or-special", argc, argv, 1, 1, 0);
|
return do_read_char("peek-char-or-special", argc, argv, 1, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *read_byte_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||||
read_byte (int argc, Scheme_Object *argv[])
|
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = scheme_get_byte(port);
|
||||||
|
|
||||||
|
if (ch == EOF)
|
||||||
|
return scheme_eof;
|
||||||
|
else
|
||||||
|
return scheme_make_integer(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *
|
||||||
|
read_byte (int argc, Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION
|
||||||
|
{
|
||||||
|
if (argc && SCHEME_INPUT_PORTP(argv[0]))
|
||||||
|
return read_byte_fast(argv[0]);
|
||||||
|
|
||||||
return do_read_char("read-byte", argc, argv, 0, 0, 1);
|
return do_read_char("read-byte", argc, argv, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4107,13 +4137,13 @@ newline (int argc, Scheme_Object *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *
|
||||||
write_byte (int argc, Scheme_Object *argv[])
|
write_byte_slow (int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
Scheme_Object *port;
|
Scheme_Object *port;
|
||||||
int v;
|
int v;
|
||||||
unsigned char buffer[1];
|
unsigned char buffer[1];
|
||||||
|
|
||||||
if (argc && !SCHEME_INTP(argv[0]))
|
if (!SCHEME_INTP(argv[0]))
|
||||||
scheme_wrong_contract("write-byte", "byte?", 0, argc, argv);
|
scheme_wrong_contract("write-byte", "byte?", 0, argc, argv);
|
||||||
v = SCHEME_INT_VAL(argv[0]);
|
v = SCHEME_INT_VAL(argv[0]);
|
||||||
if ((v < 0) || (v > 255))
|
if ((v < 0) || (v > 255))
|
||||||
|
@ -4136,14 +4166,31 @@ write_byte (int argc, Scheme_Object *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
static Scheme_Object *
|
static Scheme_Object *
|
||||||
write_char (int argc, Scheme_Object *argv[])
|
write_byte (int argc, GC_CAN_IGNORE Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION
|
||||||
|
{
|
||||||
|
if (SCHEME_INTP(argv[0])
|
||||||
|
&& (SCHEME_INT_VAL(argv[0]) >= 0)
|
||||||
|
&& (SCHEME_INT_VAL(argv[0]) <= 255)
|
||||||
|
&& SCHEME_OUTPUT_PORTP(argv[1])) {
|
||||||
|
char buffer[1];
|
||||||
|
buffer[0] = SCHEME_INT_VAL(argv[0]);
|
||||||
|
scheme_put_byte_string("write-byte", argv[1],
|
||||||
|
buffer, 0, 1,
|
||||||
|
0);
|
||||||
|
return scheme_void;
|
||||||
|
} else
|
||||||
|
return write_byte_slow(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *
|
||||||
|
write_char_slow (int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
Scheme_Object *port;
|
Scheme_Object *port;
|
||||||
unsigned char buffer[MAX_UTF8_CHAR_BYTES];
|
unsigned char buffer[MAX_UTF8_CHAR_BYTES];
|
||||||
unsigned int ubuffer[1];
|
unsigned int ubuffer[1];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (argc && !SCHEME_CHARP(argv[0]))
|
if (!SCHEME_CHARP(argv[0]))
|
||||||
scheme_wrong_contract("write-char", "char?", 0, argc, argv);
|
scheme_wrong_contract("write-char", "char?", 0, argc, argv);
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if (!SCHEME_OUTPUT_PORTP(argv[1]))
|
if (!SCHEME_OUTPUT_PORTP(argv[1]))
|
||||||
|
@ -4162,6 +4209,23 @@ write_char (int argc, Scheme_Object *argv[])
|
||||||
return scheme_void;
|
return scheme_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Scheme_Object *
|
||||||
|
write_char (int argc, GC_CAN_IGNORE Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION
|
||||||
|
{
|
||||||
|
if (argc
|
||||||
|
&& SCHEME_CHARP(argv[0])
|
||||||
|
&& (SCHEME_CHAR_VAL(argv[0]) < 128)
|
||||||
|
&& SCHEME_OUTPUT_PORTP(argv[1])) {
|
||||||
|
char buffer[1];
|
||||||
|
buffer[0] = SCHEME_CHAR_VAL(argv[0]);
|
||||||
|
scheme_put_byte_string("write-char", argv[1],
|
||||||
|
buffer, 0, 1,
|
||||||
|
0);
|
||||||
|
return scheme_void;
|
||||||
|
} else
|
||||||
|
return write_char_slow(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
static Scheme_Object *port_read_handler(int argc, Scheme_Object *argv[])
|
static Scheme_Object *port_read_handler(int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
Scheme_Input_Port *ip;
|
Scheme_Input_Port *ip;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user