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);
|
||||
}
|
||||
|
||||
int
|
||||
scheme_getc(Scheme_Object *port)
|
||||
int scheme_getc(Scheme_Object *port)
|
||||
{
|
||||
char s[MAX_UTF8_CHAR_BYTES];
|
||||
unsigned int r[1];
|
||||
|
@ -3362,7 +3361,7 @@ scheme_getc(Scheme_Object *port)
|
|||
}
|
||||
|
||||
int
|
||||
scheme_get_byte(Scheme_Object *port)
|
||||
scheme_get_byte(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||
{
|
||||
char s[1];
|
||||
int v;
|
||||
|
@ -4194,10 +4193,10 @@ int scheme_close_should_force_port_closed()
|
|||
|
||||
/****************************** main output writer ******************************/
|
||||
|
||||
intptr_t
|
||||
scheme_put_byte_string(const char *who, Scheme_Object *port,
|
||||
const char *str, intptr_t d, intptr_t len,
|
||||
int rarely_block)
|
||||
static intptr_t
|
||||
put_byte_string_slow(const char *who, Scheme_Object *port,
|
||||
const char *str, intptr_t d, intptr_t len,
|
||||
int rarely_block)
|
||||
{
|
||||
/* 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
|
||||
|
@ -4262,6 +4261,32 @@ scheme_put_byte_string(const char *who, Scheme_Object *port,
|
|||
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_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,
|
||||
char *buffer, intptr_t offset, intptr_t size,
|
||||
int nonblock,
|
||||
Scheme_Object *unless)
|
||||
char *buffer, intptr_t offset, intptr_t size,
|
||||
int nonblock,
|
||||
Scheme_Object *unless)
|
||||
XFORM_ASSERT_NO_CONVERSION
|
||||
{
|
||||
Scheme_FD *fip;
|
||||
intptr_t bc;
|
||||
|
@ -8206,9 +8232,9 @@ static intptr_t flush_fd(Scheme_Output_Port *op,
|
|||
}
|
||||
|
||||
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)
|
||||
fd_write_string_slow(Scheme_Output_Port *port,
|
||||
const char *str, intptr_t d, intptr_t len,
|
||||
int rarely_block, int enable_break)
|
||||
{
|
||||
/* Note: !flush => !rarely_block, !len => flush */
|
||||
|
||||
|
@ -8280,6 +8306,30 @@ fd_write_string(Scheme_Output_Port *port,
|
|||
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
|
||||
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);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
read_char (int argc, Scheme_Object *argv[])
|
||||
static Scheme_Object *read_char_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
static Scheme_Object *
|
||||
read_byte (int argc, Scheme_Object *argv[])
|
||||
static Scheme_Object *read_byte_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -4107,13 +4137,13 @@ newline (int argc, Scheme_Object *argv[])
|
|||
}
|
||||
|
||||
static Scheme_Object *
|
||||
write_byte (int argc, Scheme_Object *argv[])
|
||||
write_byte_slow (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Object *port;
|
||||
int v;
|
||||
unsigned char buffer[1];
|
||||
|
||||
if (argc && !SCHEME_INTP(argv[0]))
|
||||
if (!SCHEME_INTP(argv[0]))
|
||||
scheme_wrong_contract("write-byte", "byte?", 0, argc, argv);
|
||||
v = SCHEME_INT_VAL(argv[0]);
|
||||
if ((v < 0) || (v > 255))
|
||||
|
@ -4136,14 +4166,31 @@ write_byte (int argc, Scheme_Object *argv[])
|
|||
}
|
||||
|
||||
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;
|
||||
unsigned char buffer[MAX_UTF8_CHAR_BYTES];
|
||||
unsigned int ubuffer[1];
|
||||
int len;
|
||||
|
||||
if (argc && !SCHEME_CHARP(argv[0]))
|
||||
if (!SCHEME_CHARP(argv[0]))
|
||||
scheme_wrong_contract("write-char", "char?", 0, argc, argv);
|
||||
if (argc > 1) {
|
||||
if (!SCHEME_OUTPUT_PORTP(argv[1]))
|
||||
|
@ -4162,6 +4209,23 @@ write_char (int argc, Scheme_Object *argv[])
|
|||
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[])
|
||||
{
|
||||
Scheme_Input_Port *ip;
|
||||
|
|
Loading…
Reference in New Issue
Block a user