From e75cff570c23f2d140b4fdf4e242436f72c83fdc Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 17 Feb 2011 23:47:26 -0800 Subject: Return updated buf as second return value, to free up a reg. --- src/upb_decoder.c | 22 ++++++++++++++-------- src/upb_decoder_x64.asm | 25 +++++++++++++++++-------- src/upb_string.c | 2 ++ 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); } -- cgit v1.2.3