summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoshua Haberman <joshua@reverberate.org>2011-02-17 23:47:26 -0800
committerJoshua Haberman <joshua@reverberate.org>2011-02-17 23:47:26 -0800
commite75cff570c23f2d140b4fdf4e242436f72c83fdc (patch)
tree8813c88ea897c0a427582022a6c04b8ab91248af /src
parentd8b215486245e84e33283b6047fb253bbb418e00 (diff)
Return updated buf as second return value, to free up a reg.
Diffstat (limited to 'src')
-rw-r--r--src/upb_decoder.c22
-rw-r--r--src/upb_decoder_x64.asm25
-rw-r--r--src/upb_string.c2
3 files changed, 33 insertions, 16 deletions
diff --git a/src/upb_decoder.c b/src/upb_decoder.c
index 0e6866b..47e67b6 100644
--- a/src/upb_decoder.c
+++ b/src/upb_decoder.c
@@ -13,9 +13,13 @@
// If the return value is other than UPB_CONTINUE, that is what the last
// callback returned.
-extern upb_flow_t upb_fastdecode(const char **p, const char *end,
- upb_value_handler_t value_cb, void *closure,
- void *table, int table_size);
+typedef struct {
+ upb_flow_t flow;
+ const char *ptr;
+} fastdecode_ret;
+extern fastdecode_ret upb_fastdecode(const char *p, const char *end,
+ upb_value_handler_t value_cb, void *closure,
+ void *table, int table_size);
/* Pure Decoding **************************************************************/
@@ -344,11 +348,13 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
// before falling through to the slow(er) path.
const char *end = UPB_MIN(d->end, d->submsg_end);
#ifdef USE_ASSEMBLY_FASTPATH
- CHECK_FLOW(upb_fastdecode(&d->ptr, end,
- d->dispatcher.top->handlers.set->value,
- d->dispatcher.top->handlers.closure,
- d->top->msgdef->itof.array,
- d->top->msgdef->itof.array_size));
+ fastdecode_ret ret = upb_fastdecode(d->ptr, end,
+ d->dispatcher.top->handlers.set->value,
+ d->dispatcher.top->handlers.closure,
+ d->top->msgdef->itof.array,
+ d->top->msgdef->itof.array_size);
+ CHECK_FLOW(ret.flow);
+ d->ptr = ret.ptr;
if (end - d->ptr < 12) {
DEBUGPRINTF("Off the fast path because <12 bytes of data\n");
} else {
diff --git a/src/upb_decoder_x64.asm b/src/upb_decoder_x64.asm
index 17d1ef7..c59d131 100644
--- a/src/upb_decoder_x64.asm
+++ b/src/upb_decoder_x64.asm
@@ -16,10 +16,10 @@ dispatch_table:
dq _upb_fastdecode.fixed64 ; fixed64
dq _upb_fastdecode.fixed32 ; fixed32
dq _upb_fastdecode.varint ; bool
- dq _upb_fastdecode.cant_fast_path ; string (TODO)
+ dq _upb_fastdecode.string ; string
dq _upb_fastdecode.cant_fast_path ; group (check_6)
dq _upb_fastdecode.cant_fast_path ; message
- dq _upb_fastdecode.cant_fast_path ; bytes (TODO)
+ dq _upb_fastdecode.string ; bytes
dq _upb_fastdecode.varint ; uint32
dq _upb_fastdecode.varint ; enum
dq _upb_fastdecode.fixed32 ; sfixed32
@@ -33,7 +33,7 @@ SECTION .text
; Register allocation.
%define BUF rbx ; const char *p, current buf position.
%define END rbp ; const char *end, where the buf ends (either submsg end or buf end)
-%define BUF_ADDR r12 ; upb_decoder *d.
+%define FREE r12 ; unused
%define FIELDDEF r13 ; upb_fielddef *f, needs to be preserved across varint decoding call.
%define CALLBACK r14
%define CLOSURE r15
@@ -41,7 +41,8 @@ SECTION .text
; Stack layout: *tableptr, uint32_t maxfield_times_8
%define STACK_SPACE 24 ; this value + 8 must be a multiple of 16.
%define TABLE_SPILL [rsp] ; our lookup table, indexed by field number.
-%define MAXFIELD_TIMES_8_SPILL [rsp+8]
+%define COMMITTED_BUF_SPILL [rsp+8]
+%define MAXFIELD_TIMES_8_SPILL [rsp+16]
; Executing the fast path requires the following conditions:
@@ -57,7 +58,9 @@ SECTION .text
; - check_6: the field is not a group or a message (or string, TODO)
; (this could be relaxed, but due to delegation it's a bit tricky).
; - if the value is a string, the entire string is available in
-; the buffer, and our cached string object can be recycled.
+; the buffer, and our cached string object can be recycled, and
+; our string object already references the source buffer, so
+; absolutely no refcount twiddling is required. (check_7)
%macro decode_and_dispatch_ 0
@@ -113,7 +116,7 @@ align 16
mov rsi, FIELDDEF
mov rcx, 33 ; RAW; we could pass the correct type, or only do this in non-debug modes.
call CALLBACK
- mov [BUF_ADDR], BUF
+ mov COMMITTED_BUF_SPILL, BUF
cmp eax, 0
jne .done ; Caller requested BREAK or SKIPSUBMSG.
%endmacro
@@ -139,8 +142,7 @@ _upb_fastdecode:
sub rsp, STACK_SPACE
; Parse arguments into reg vals and stack.
- mov BUF_ADDR, rdi
- mov BUF, [rdi]
+ mov BUF, rdi
mov END, rsi
mov CALLBACK, rdx
mov CLOSURE, rcx
@@ -205,10 +207,17 @@ align 16
call_callback
decode_and_dispatch
+align 16
+.string:
+
+
.cant_fast_path:
mov rax, 0 ; UPB_CONTINUE -- continue as before.
.done:
; If coming via done, preserve the user callback's return in rax.
+
+ ; Return committed buf pointer as second parameter.
+ mov rdx, COMMITTED_BUF_SPILL
add rsp, STACK_SPACE
pop r15
pop r14
diff --git a/src/upb_string.c b/src/upb_string.c
index 30ed88f..e6ea589 100644
--- a/src/upb_string.c
+++ b/src/upb_string.c
@@ -141,3 +141,5 @@ error:
fclose(f);
return NULL;
}
+
+void upb_string_noninlinerecycle(upb_string **_str) { return upb_string_recycle(_str); }
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback