summaryrefslogtreecommitdiff
path: root/upb/pb
diff options
context:
space:
mode:
Diffstat (limited to 'upb/pb')
-rw-r--r--upb/pb/decoder.c55
-rw-r--r--upb/pb/decoder.h4
-rw-r--r--upb/pb/decoder_x64.dasc201
-rw-r--r--upb/pb/glue.c4
-rw-r--r--upb/pb/textprinter.c51
5 files changed, 198 insertions, 117 deletions
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index 2bfc717..18bb430 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -95,6 +95,10 @@ typedef struct {
// Maps (upb_handlers* or upb_fielddef*) -> int32 pclabel_base
upb_inttable pclabels;
+ // For marking labels that should go into the generated code.
+ // Maps pclabel -> owned char* label.
+ upb_inttable asmlabels;
+
// This is not the same as len(pclabels) because the table only contains base
// offsets for each def, but each def can have many pclabels.
uint32_t pclabel_count;
@@ -131,7 +135,7 @@ static const upb_decoder_typeinfo upb_decoder_types[] = {
static upb_selector_t getselector(const upb_fielddef *f,
upb_handlertype_t type) {
upb_selector_t selector;
- bool ok = upb_getselector(f, type, &selector);
+ bool ok = upb_handlers_getselector(f, type, &selector);
UPB_ASSERT_VAR(ok, ok);
return selector;
}
@@ -165,11 +169,11 @@ void freeplan(void *_p) {
free(p);
}
-static decoderplan *getdecoderplan(const upb_handlers *h) {
+static const decoderplan *getdecoderplan(const upb_handlers *h) {
if (upb_handlers_frametype(h) != upb_pbdecoder_getframetype())
return NULL;
upb_selector_t sel;
- if (!upb_getselector(UPB_BYTESTREAM_BYTES, UPB_HANDLER_STRING, &sel))
+ if (!upb_handlers_getselector(UPB_BYTESTREAM_BYTES, UPB_HANDLER_STRING, &sel))
return NULL;
return upb_handlers_gethandlerdata(h, sel);
}
@@ -180,7 +184,7 @@ bool upb_pbdecoder_isdecoder(const upb_handlers *h) {
bool upb_pbdecoder_hasjitcode(const upb_handlers *h) {
#ifdef UPB_USE_JIT_X64
- decoderplan *p = getdecoderplan(h);
+ const decoderplan *p = getdecoderplan(h);
if (!p) return false;
return p->jit_code != NULL;
#else
@@ -190,7 +194,7 @@ bool upb_pbdecoder_hasjitcode(const upb_handlers *h) {
}
const upb_handlers *upb_pbdecoder_getdesthandlers(const upb_handlers *h) {
- decoderplan *p = getdecoderplan(h);
+ const decoderplan *p = getdecoderplan(h);
if (!p) return NULL;
return p->dest_handlers;
}
@@ -290,7 +294,6 @@ static void suspendjmp(upb_pbdecoder *d) {
}
static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) {
- assert(len >= 0);
assert(d->ptr == d->end);
d->bufstart_ofs += (d->ptr - d->buf);
switchtobuf(d, buf, buf + len);
@@ -583,7 +586,7 @@ static const upb_fielddef *decode_tag(upb_pbdecoder *d) {
uint32_t tag = decode_v32(d);
uint8_t wire_type = tag & 0x7;
uint32_t fieldnum = tag >> 3; const upb_fielddef *f = NULL;
- const upb_handlers *h = upb_sinkframe_handlers(upb_sink_top(d->sink));
+ const upb_handlers *h = d->sink->top->h; // TODO(haberman): rm
f = upb_msgdef_itof(upb_handlers_msgdef(h), fieldnum);
bool packed = false;
@@ -646,17 +649,19 @@ static const upb_fielddef *decode_tag(upb_pbdecoder *d) {
}
}
-void *start(const upb_sinkframe *fr, size_t size_hint) {
+void *start(void *closure, const void *handler_data, size_t size_hint) {
+ UPB_UNUSED(handler_data);
UPB_UNUSED(size_hint);
- upb_pbdecoder *d = upb_sinkframe_userdata(fr);
+ upb_pbdecoder *d = closure;
assert(d);
assert(d->sink);
upb_sink_startmsg(d->sink);
return d;
}
-bool end(const upb_sinkframe *fr) {
- upb_pbdecoder *d = upb_sinkframe_userdata(fr);
+bool end(void *closure, const void *handler_data) {
+ UPB_UNUSED(handler_data);
+ upb_pbdecoder *d = closure;
if (d->residual_end > d->residual) {
// We have preserved bytes.
@@ -668,7 +673,6 @@ bool end(const upb_sinkframe *fr) {
if (d->top == d->stack + 1 &&
d->top->is_sequence &&
!d->top->is_packed) {
- assert(upb_sinkframe_depth(upb_sink_top(d->sink)) == 1);
pop_seq(d);
}
if (d->top != d->stack) {
@@ -680,47 +684,47 @@ bool end(const upb_sinkframe *fr) {
return true;
}
-size_t decode(const upb_sinkframe *fr, const char *buf, size_t size) {
- upb_pbdecoder *d = upb_sinkframe_userdata(fr);
- decoderplan *plan = upb_sinkframe_handlerdata(fr);
+size_t decode(void *closure, const void *hd, const char *buf, size_t size) {
+ upb_pbdecoder *d = closure;
+ const decoderplan *plan = hd;
UPB_UNUSED(plan);
- assert(upb_sinkframe_handlers(upb_sink_top(d->sink)) == plan->dest_handlers);
+ assert(d->sink->top->h == plan->dest_handlers);
if (size == 0) return 0;
// Assume we'll consume the whole buffer unless this is overwritten.
d->ret = size;
+ d->buf_param = buf;
+ d->size_param = size;
if (_setjmp(d->exitjmp)) {
// Hit end-of-buffer or error.
return d->ret;
}
- d->buf_param = buf;
- d->size_param = size;
if (d->residual_end > d->residual) {
// We have residual bytes from the last buffer.
- d->userbuf_remaining = size;
+ d->userbuf_remaining = d->size_param;
} else {
d->userbuf_remaining = 0;
- advancetobuf(d, buf, size);
+ advancetobuf(d, buf, d->size_param);
if (d->top != d->stack &&
upb_fielddef_isstring(d->top->f) &&
!d->top->is_sequence) {
// Last buffer ended in the middle of a string; deliver more of it.
size_t len = d->top->end_ofs - offset(d);
- if (size >= len) {
+ if (d->size_param >= len) {
upb_sink_putstring(d->sink, getselector(d->top->f, UPB_HANDLER_STRING),
d->ptr, len);
advance(d, len);
pop_string(d);
} else {
upb_sink_putstring(d->sink, getselector(d->top->f, UPB_HANDLER_STRING),
- d->ptr, size);
- advance(d, size);
+ d->ptr, d->size_param);
+ advance(d, d->size_param);
d->residual_end = d->residual;
advancetobuf(d, d->residual, 0);
- return size;
+ return d->size_param;
}
}
}
@@ -762,7 +766,8 @@ size_t decode(const upb_sinkframe *fr, const char *buf, size_t size) {
}
}
-void init(void *_d) {
+void init(void *_d, upb_pipeline *p) {
+ UPB_UNUSED(p);
upb_pbdecoder *d = _d;
d->limit = &d->stack[UPB_MAX_NESTING];
d->sink = NULL;
diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h
index 4307434..c1b6cb3 100644
--- a/upb/pb/decoder.h
+++ b/upb/pb/decoder.h
@@ -70,10 +70,6 @@ const upb_handlers *upb_pbdecoder_getdesthandlers(const upb_handlers *h);
namespace upb {
-template<> inline const FrameType* GetFrameType<upb::pb::Decoder>() {
- return upb_pbdecoder_getframetype();
-}
-
namespace pb {
inline bool ResetDecoderSink(Decoder* r, Sink* sink) {
return upb_pbdecoder_resetsink(r, sink);
diff --git a/upb/pb/decoder_x64.dasc b/upb/pb/decoder_x64.dasc
index 7d4c537..154fee3 100644
--- a/upb/pb/decoder_x64.dasc
+++ b/upb/pb/decoder_x64.dasc
@@ -12,9 +12,11 @@
|// function) we must respect alignment rules. All x86-64 systems require
|// 16-byte stack alignment.
+#define _GNU_SOURCE
#include <stdio.h>
#include <sys/mman.h>
#include "dynasm/dasm_x86.h"
+#include "upb/shim/shim.h"
#ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON
@@ -61,7 +63,7 @@ static uint32_t upb_getpclabel(decoderplan *plan, const void *obj, int n) {
return upb_value_getuint32(v) + n;
}
-static upb_jitmsginfo *upb_getmsginfo(decoderplan *plan,
+static upb_jitmsginfo *upb_getmsginfo(const decoderplan *plan,
const upb_handlers *h) {
upb_value v;
bool found = upb_inttable_lookupptr(&plan->msginfo, h, &v);
@@ -161,6 +163,7 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; }
|.define ARG2_64, rsi
|.define ARG3_32, edx
|.define ARG3_64, rdx
+|.define ARG4_32, ecx
|.define ARG4_64, rcx
|.define XMMARG1, xmm0
@@ -193,13 +196,11 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; }
||{
|| uintptr_t data = (uintptr_t)gethandlerdata(h, f, type);
|| if (data > 0xffffffff) {
-| mov64 rax, data
-| mov SINKFRAME->u.handler_data, rax
-|| } else if (data > 0x7fffffff) {
-| mov eax, data
-| mov SINKFRAME->u.handler_data, rax
+| mov64 ARG2_64, data
+|| } else if (data) {
+| mov ARG2_32, data
|| } else {
-| mov qword SINKFRAME->u.handler_data, data
+| xor ARG2_32, ARG2_32
|| }
|| }
|.endmacro
@@ -269,6 +270,8 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; }
|// table on the raw (length-masked) varint to save 3-4 cycles of latency.
|// Currently only support tables where all entries are in the array part.
|.macro dyndispatch_, h
+|| asmlabel(plan, "_UPB_MCODE_DISPATCH_%s.%d",
+|| upb_msgdef_fullname(upb_handlers_msgdef(h)), rand());
|=>upb_getpclabel(plan, h, DYNDISPATCH):
| decode_loaded_varint, 0
| mov ecx, esi
@@ -310,22 +313,21 @@ static void upb_assert_notnull(void *addr) { assert(addr != NULL); (void)addr; }
|
|.macro pushsinkframe, handlers, field, endtype
| mov rax, DECODER->sink
-| mov dword SINKFRAME->u.selector, getselector(field, endtype)
+| mov dword SINKFRAME->selector, getselector(field, endtype)
| lea rcx, [SINKFRAME + sizeof(upb_sinkframe)] // rcx for short addressing
| cmp rcx, SINK:rax->limit
| jae ->exit_jit // Frame stack overflow.
| mov64 r9, (uintptr_t)handlers
| mov SINKFRAME:rcx->h, r9
| mov SINKFRAME:rcx->closure, CLOSURE
-| mov SINK:rax->top_, rcx
-| mov SINKFRAME:rcx->sink_, rax
+| mov SINK:rax->top, rcx
| mov SINKFRAME, rcx
|.endmacro
|
|.macro popsinkframe
| sub SINKFRAME, sizeof(upb_sinkframe)
| mov rax, DECODER->sink
-| mov SINK:rax->top_, SINKFRAME
+| mov SINK:rax->top, SINKFRAME
| mov CLOSURE, SINKFRAME->closure
|.endmacro
|
@@ -415,12 +417,28 @@ static uintptr_t gethandlerdata(const upb_handlers *h, const upb_fielddef *f,
return (uintptr_t)upb_handlers_gethandlerdata(h, getselector(f, type));
}
+static void asmlabel(decoderplan *plan, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ char *str = NULL;
+ size_t size = 0;
+ upb_vrprintf(&str, &size, 0, fmt, ap);
+ va_end(ap);
+ uint32_t label = plan->pclabel_count++;
+ dasm_growpc(plan, plan->pclabel_count);
+ |=>label:
+ upb_inttable_insert(&plan->asmlabels, label, upb_value_ptr(str));
+}
+
// Decodes the next val into ARG2, advances PTR.
static void upb_decoderplan_jit_decodefield(decoderplan *plan,
size_t tag_size,
const upb_handlers *h,
const upb_fielddef *f) {
// Decode the value into arg 3 for the callback.
+ asmlabel(plan, "UPB_MCODE_DECODE_FIELD_%s.%s",
+ upb_msgdef_fullname(upb_handlers_msgdef(h)),
+ upb_fielddef_name(f));
switch (upb_fielddef_descriptortype(f)) {
case UPB_DESCRIPTOR_TYPE_DOUBLE:
| movsd XMMARG1, qword [PTR + tag_size]
@@ -496,39 +514,36 @@ static void upb_decoderplan_jit_decodefield(decoderplan *plan,
upb_func *handler = gethandler(h, f, UPB_HANDLER_STARTSTR);
if (handler) {
+ // void* startstr(void *c, const void *hd, size_t hint)
| mov DECODER->tmp_len, ARG2_32
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
+ | mov ARG3_64, ARG2_64
| load_handler_data h, f, UPB_HANDLER_STARTSTR
| callp handler
| check_ptr_ret
- | mov CLOSURE, rax
- | mov ARG3_32, DECODER->tmp_len
+ | mov ARG1_64, rax // sub-closure
+ | mov ARG4_32, DECODER->tmp_len
} else {
- | mov ARG3_64, ARG2_64
+ | mov ARG1_64, CLOSURE
+ | mov ARG4_64, ARG2_64
}
handler = gethandler(h, f, UPB_HANDLER_STRING);
if (handler) {
- // TODO: push a real frame so we can resume into the string.
- // (but maybe do this only if the string breaks).
- | pushsinkframe h, f, UPB_HANDLER_ENDSTR
-
- // size_t str(const upb_sinkframe *frame, const char *buf, size_t len)
- | mov ARG1_64, SINKFRAME
+ // size_t str(void *c, const void *hd, const char *buf, size_t len)
| load_handler_data h, f, UPB_HANDLER_STRING
- | mov ARG2_64, PTR
+ | mov ARG3_64, PTR
| callp handler
// TODO: properly handle returns other than "n" (the whole string).
| add PTR, rax
- | popsinkframe
} else {
- | add PTR, ARG3_64
+ | add PTR, ARG4_64
}
handler = gethandler(h, f, UPB_HANDLER_ENDSTR);
if (handler) {
// bool endstr(const upb_sinkframe *frame);
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| load_handler_data h, f, UPB_HANDLER_ENDSTR
| callp handler
| check_bool_ret
@@ -553,13 +568,16 @@ static void upb_decoderplan_jit_callcb(decoderplan *plan,
const upb_fielddef *f) {
// Call callbacks. Specializing the append accessors didn't yield a speed
// increase in benchmarks.
+ asmlabel(plan, "UPB_MCODE_CALLCB_%s.%s",
+ upb_msgdef_fullname(upb_handlers_msgdef(h)),
+ upb_fielddef_name(f));
if (upb_fielddef_issubmsg(f)) {
// Call startsubmsg handler (if any).
upb_func *startsubmsg = gethandler(h, f, UPB_HANDLER_STARTSUBMSG);
if (startsubmsg) {
// upb_sflow_t startsubmsg(const upb_sinkframe *frame)
| mov DECODER->tmp_len, ARG2_32
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| load_handler_data h, f, UPB_HANDLER_STARTSUBMSG
| callp startsubmsg
| check_ptr_ret
@@ -594,37 +612,46 @@ static void upb_decoderplan_jit_callcb(decoderplan *plan,
upb_func *endsubmsg = gethandler(h, f, UPB_HANDLER_ENDSUBMSG);
if (endsubmsg) {
// upb_flow_t endsubmsg(void *closure, upb_value fval);
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| load_handler_data h, f, UPB_HANDLER_ENDSUBMSG
| callp endsubmsg
| check_bool_ret
}
} else if (!upb_fielddef_isstring(f)) {
upb_handlertype_t handlertype = upb_handlers_getprimitivehandlertype(f);
+ upb_selector_t sel = getselector(f, handlertype);
upb_func *handler = gethandler(h, f, handlertype);
- const upb_stdmsg_fval *fv = (void*)gethandlerdata(h, f, handlertype);
- // Test for callbacks we can specialize.
- // Can't switch() on function pointers.
- if (handler == (void*)&upb_stdmsg_setint64 ||
- handler == (void*)&upb_stdmsg_setuint64) {
- | mov [CLOSURE + fv->offset], ARG2_64
- | sethas CLOSURE, fv->hasbit
- } else if (handler == (void*)&upb_stdmsg_setdouble) {
- | movsd qword [CLOSURE + fv->offset], XMMARG1
- | sethas CLOSURE, fv->hasbit
- } else if (handler == (void*)&upb_stdmsg_setint32 ||
- handler == (void*)&upb_stdmsg_setuint32) {
- | mov [CLOSURE + fv->offset], ARG2_32
- | sethas CLOSURE, fv->hasbit
- } else if (handler == (void*)&upb_stdmsg_setfloat) {
- | movss dword [CLOSURE + fv->offset], XMMARG1
- | sethas CLOSURE, fv->hasbit
- } else if (handler == (void*)&upb_stdmsg_setbool) {
- | mov [CLOSURE + fv->offset], ARG2_8
- | sethas CLOSURE, fv->hasbit
+ const upb_shim_data *data = upb_shim_getdata(h, sel);
+ if (data) {
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT64:
+ | mov [CLOSURE + data->offset], ARG2_64
+ break;
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_ENUM:
+ | mov [CLOSURE + data->offset], ARG2_32
+ break;
+ case UPB_TYPE_DOUBLE:
+ | movsd qword [CLOSURE + data->offset], XMMARG1
+ break;
+ case UPB_TYPE_FLOAT:
+ | movss dword [CLOSURE + data->offset], XMMARG1
+ break;
+ case UPB_TYPE_BOOL:
+ | mov [CLOSURE + data->offset], ARG2_8
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ case UPB_TYPE_MESSAGE:
+ assert(false); break;
+ }
+ | sethas CLOSURE, data->hasbit
} else if (handler) {
// bool value(const upb_sinkframe* frame, ctype val)
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
+ | mov ARG3_64, ARG2_64
| load_handler_data h, f, handlertype
| callp handler
| check_bool_ret
@@ -647,7 +674,7 @@ static void upb_decoderplan_jit_endseq(decoderplan *plan,
| popframe
upb_func *endseq = gethandler(h, f, UPB_HANDLER_ENDSEQ);
if (endseq) {
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| load_handler_data h, f, UPB_HANDLER_ENDSEQ
| callp endseq
}
@@ -658,6 +685,9 @@ static void upb_decoderplan_jit_field(decoderplan *plan,
const upb_handlers *h,
const upb_fielddef *f,
const upb_fielddef *next_f) {
+ asmlabel(plan, "UPB_MCODE_FIELD_%s.%s",
+ upb_msgdef_fullname(upb_handlers_msgdef(h)),
+ upb_fielddef_name(f));
uint64_t tag = upb_get_encoded_tag(f);
uint64_t next_tag = next_f ? upb_get_encoded_tag(next_f) : 0;
int tag_size = upb_value_size(tag);
@@ -672,7 +702,7 @@ static void upb_decoderplan_jit_field(decoderplan *plan,
if (upb_fielddef_isseq(f)) {
upb_func *startseq = gethandler(h, f, UPB_HANDLER_STARTSEQ);
if (startseq) {
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| load_handler_data h, f, UPB_HANDLER_STARTSEQ
| callp startseq
| check_ptr_ret
@@ -726,6 +756,8 @@ static int upb_compare_uint32(const void *a, const void *b) {
static void upb_decoderplan_jit_msg(decoderplan *plan,
const upb_handlers *h) {
+ asmlabel(plan, "UPB_MCODE_DECODEMSG_%s",
+ upb_msgdef_fullname(upb_handlers_msgdef(h)));
|=>upb_getpclabel(plan, h, AFTER_STARTMSG):
| push rbp
| mov rbp, rsp
@@ -739,7 +771,7 @@ static void upb_decoderplan_jit_msg(decoderplan *plan,
upb_startmsg_handler *startmsg = upb_handlers_getstartmsg(h);
if (startmsg) {
// upb_flow_t startmsg(void *closure);
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| callp startmsg
| check_bool_ret
}
@@ -792,7 +824,7 @@ static void upb_decoderplan_jit_msg(decoderplan *plan,
upb_endmsg_handler *endmsg = upb_handlers_getendmsg(h);
if (endmsg) {
// void endmsg(void *closure, upb_status *status) {
- | mov ARG1_64, SINKFRAME
+ | mov ARG1_64, CLOSURE
| mov ARG2_64, DECODER->sink
| mov ARG2_64, SINK:ARG2_64->pipeline_
| add ARG2_64, offsetof(upb_pipeline, status_)
@@ -815,6 +847,7 @@ static void upb_decoderplan_jit(decoderplan *plan) {
// calculate the structure offsets ourself instead of symbolically
// (ie. [r15 + 0xcd] instead of DECODER->ptr). So we tolerate a bit of
// unnecessary duplication/redundancy.
+ asmlabel(plan, "upb_jit_trampoline");
| push rbp
| mov rbp, rsp
| push r15
@@ -828,13 +861,14 @@ static void upb_decoderplan_jit(decoderplan *plan) {
| mov DECODER->saved_rbp, rbp
| mov FRAME, DECODER:ARG1_64->top
| mov rax, DECODER:ARG1_64->sink
- | mov SINKFRAME, SINK:rax->top_
+ | mov SINKFRAME, SINK:rax->top
| mov CLOSURE, SINKFRAME->closure
| mov PTR, DECODER->ptr
// TODO: push return addresses for re-entry (will be necessary for multiple
// buffer support).
| call ARG2_64
+ asmlabel(plan, "exitjit");
|->exit_jit:
| mov rbp, DECODER->saved_rbp
| lea rsp, [rbp - 48]
@@ -903,6 +937,8 @@ static void upb_decoderplan_makejit(decoderplan *plan) {
upb_inttable_init(&plan->pclabels, UPB_CTYPE_UINT32);
upb_decoderplan_jit_assignpclabels(plan, plan->dest_handlers);
+ upb_inttable_init(&plan->asmlabels, UPB_CTYPE_PTR);
+
void **globals = malloc(UPB_JIT_GLOBAL__MAX * sizeof(*globals));
dasm_init(plan, 1);
dasm_setupglobal(plan, globals, UPB_JIT_GLOBAL__MAX);
@@ -947,18 +983,57 @@ static void upb_decoderplan_makejit(decoderplan *plan) {
upb_inttable_uninit(&plan->pclabels);
- dasm_free(plan);
- free(globals);
-
mprotect(plan->jit_code, plan->jit_size, PROT_EXEC | PROT_READ);
#ifndef NDEBUG
- // View with: objdump -M intel -D -b binary -mi386 -Mx86-64 /tmp/machine-code
- // Or: ndisasm -b 64 /tmp/machine-code
- FILE *f = fopen("/tmp/machine-code", "wb");
- fwrite(plan->jit_code, plan->jit_size, 1, f);
- fclose(f);
+ // Dump to a .o file in /tmp, for easy inspection.
+
+ // Convert all asm labels from pclabel offsets to machine code offsets.
+ upb_inttable mclabels;
+ upb_inttable_init(&mclabels, UPB_CTYPE_PTR);
+ upb_inttable_begin(&i, &plan->asmlabels);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_inttable_insert(
+ &mclabels,
+ dasm_getpclabel(plan, upb_inttable_iter_key(&i)),
+ upb_inttable_iter_value(&i));
+ }
+
+ FILE *f = fopen("/tmp/upb-jit-code.s", "w");
+ if (f) {
+ fputs(" .text", f);
+ size_t linelen = 0;
+ for (size_t i = 0; i < plan->jit_size; i++) {
+ upb_value v;
+ if (upb_inttable_lookup(&mclabels, i, &v)) {
+ const char *label = upb_value_getptr(v);
+ fprintf(f, "\n\n_%s:\n", label);
+ fprintf(f, " .globl _%s", label);
+ linelen = 1000;
+ }
+ if (linelen >= 77) {
+ linelen = fprintf(f, "\n .byte %u", plan->jit_code[i]);
+ } else {
+ linelen += fprintf(f, ",%u", plan->jit_code[i]);
+ }
+ }
+ fputs("\n", f);
+ fclose(f);
+ } else {
+ fprintf(stderr, "Couldn't open /tmp/upb-jit-code.s for writing/\n");
+ }
+
+ upb_inttable_uninit(&mclabels);
#endif
+
+ upb_inttable_begin(&i, &plan->asmlabels);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ free(upb_value_getptr(upb_inttable_iter_value(&i)));
+ }
+ upb_inttable_uninit(&plan->asmlabels);
+
+ dasm_free(plan);
+ free(globals);
}
static void upb_decoderplan_freejit(decoderplan *plan) {
@@ -975,10 +1050,10 @@ static void upb_decoderplan_freejit(decoderplan *plan) {
// TODO: unregister
}
-static void upb_decoder_enterjit(upb_pbdecoder *d, decoderplan *plan) {
+static void upb_decoder_enterjit(upb_pbdecoder *d, const decoderplan *plan) {
if (plan->jit_code &&
d->top == d->stack &&
- d->sink->top_ == d->sink->stack &&
+ d->sink->top == d->sink->stack &&
d->ptr && d->ptr < d->jit_end) {
#ifndef NDEBUG
register uint64_t rbx asm ("rbx") = 11;
diff --git a/upb/pb/glue.c b/upb/pb/glue.c
index bcde039..2c621f4 100644
--- a/upb/pb/glue.c
+++ b/upb/pb/glue.c
@@ -30,7 +30,7 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
// Create sinks.
upb_sink *reader_sink = upb_pipeline_newsink(&pipeline, reader_h);
upb_sink *decoder_sink = upb_pipeline_newsink(&pipeline, decoder_h);
- upb_pbdecoder *d = upb_sinkframe_userdata(upb_sink_base(decoder_sink));
+ upb_pbdecoder *d = upb_sink_getobj(decoder_sink);
upb_pbdecoder_resetsink(d, reader_sink);
// Push input data.
@@ -42,7 +42,7 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
return NULL;
}
- upb_descreader *r = upb_sinkframe_userdata(upb_sink_base(reader_sink));
+ upb_descreader *r = upb_sink_getobj(reader_sink);
upb_def **defs = upb_descreader_getdefs(r, owner, n);
upb_def **defscopy = malloc(sizeof(upb_def*) * (*n));
memcpy(defscopy, defs, sizeof(upb_def*) * (*n));
diff --git a/upb/pb/textprinter.c b/upb/pb/textprinter.c
index 91c1e2d..08eda15 100644
--- a/upb/pb/textprinter.c
+++ b/upb/pb/textprinter.c
@@ -38,8 +38,7 @@ static int endfield(upb_textprinter *p) {
return 0;
}
-static int putescaped(upb_textprinter *p, const char *buf, size_t len,
- bool preserve_utf8) {
+static int putescaped(const char* buf, size_t len, bool preserve_utf8) {
// Based on CEscapeInternal() from Google's protobuf release.
char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf);
const char *end = buf + len;
@@ -84,9 +83,9 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len,
}
#define TYPE(name, ctype, fmt) \
- static bool put ## name(const upb_sinkframe *frame, ctype val) { \
- upb_textprinter *p = upb_sinkframe_userdata(frame); \
- const upb_fielddef *f = upb_sinkframe_handlerdata(frame); \
+ static bool put ## name(void *closure, const void *handler_data, ctype val) {\
+ upb_textprinter *p = closure; \
+ const upb_fielddef *f = handler_data; \
CHECK(indent(p)); \
puts(upb_fielddef_name(f)); \
puts(": "); \
@@ -97,9 +96,9 @@ static int putescaped(upb_textprinter *p, const char *buf, size_t len,
return false; \
}
-static bool putbool(const upb_sinkframe *frame, bool val) {
- upb_textprinter *p = upb_sinkframe_userdata(frame);
- const upb_fielddef *f = upb_sinkframe_handlerdata(frame);
+static bool putbool(void *closure, const void *handler_data, bool val) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = handler_data;
CHECK(indent(p));
puts(upb_fielddef_name(f));
puts(": ");
@@ -121,44 +120,49 @@ TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g")
TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g")
// Output a symbolic value from the enum if found, else just print as int32.
-static bool putenum(const upb_sinkframe *frame, int32_t val) {
- const upb_fielddef *f = upb_sinkframe_handlerdata(frame);
+static bool putenum(void *closure, const void *handler_data, int32_t val) {
+ const upb_fielddef *f = handler_data;
const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
const char *label = upb_enumdef_iton(enum_def, val);
if (label) {
puts(label);
} else {
- CHECK(putint32(frame, val));
+ CHECK(putint32(closure, handler_data, val));
}
return true;
err:
return false;
}
-static void *startstr(const upb_sinkframe *frame, size_t size_hint) {
+static void *startstr(void *closure, const void *handler_data,
+ size_t size_hint) {
+ UPB_UNUSED(handler_data);
UPB_UNUSED(size_hint);
- upb_textprinter *p = upb_sinkframe_userdata(frame);
+ upb_textprinter *p = closure;
putchar('"');
return p;
}
-static bool endstr(const upb_sinkframe *frame) {
+static bool endstr(void *closure, const void *handler_data) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(handler_data);
putchar('"');
return true;
}
-static size_t putstr(const upb_sinkframe *frame, const char *buf, size_t len) {
- upb_textprinter *p = upb_sinkframe_userdata(frame);
- const upb_fielddef *f = upb_sinkframe_handlerdata(frame);
- CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING));
+static size_t putstr(void *closure, const void *hd, const char *buf,
+ size_t len) {
+ UPB_UNUSED(closure);
+ const upb_fielddef *f = hd;
+ CHECK(putescaped(buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING));
return len;
err:
return 0;
}
-static void *startsubmsg(const upb_sinkframe *frame) {
- upb_textprinter *p = upb_sinkframe_userdata(frame);
- const upb_fielddef *f = upb_sinkframe_handlerdata(frame);
+static void *startsubmsg(void *closure, const void *handler_data) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = handler_data;
CHECK(indent(p));
printf("%s {", upb_fielddef_name(f));
if (!p->single_line)
@@ -169,8 +173,9 @@ err:
return UPB_BREAK;
}
-static bool endsubmsg(const upb_sinkframe *frame) {
- upb_textprinter *p = upb_sinkframe_userdata(frame);
+static bool endsubmsg(void *closure, const void *handler_data) {
+ UPB_UNUSED(handler_data);
+ upb_textprinter *p = closure;
p->indent_depth--;
CHECK(indent(p));
putchar('}');
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback