// Rewrites the dispatch tables into machine code offsets. static void patchdispatch(jitcompiler *jc) { upb_inttable_iter i; upb_inttable_begin(&i, &jc->group->methods); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i)); method->is_native_ = true; upb_inttable *dispatch = &method->dispatch; upb_inttable_iter i2; upb_inttable_begin(&i2, dispatch); for (; !upb_inttable_done(&i2); upb_inttable_next(&i2)) { uintptr_t key = upb_inttable_iter_key(&i2); if (key == 0) continue; uint64_t val = upb_value_getuint64(upb_inttable_iter_value(&i2)); uint64_t newval; if (key <= UPB_MAX_FIELDNUMBER) { // Primary slot. uint64_t oldofs = val >> 16; uint64_t newofs = dispatchofs(jc, method, oldofs); newval = (val & 0xffff) | (newofs << 16); assert((int64_t)newval > 0); } else { // Secondary slot. Since we have 64 bits for the value, we use an // absolute offset. newval = (uint64_t)(jc->group->jit_code + nativeofs(jc, method, val)); } bool ok = upb_inttable_replace(dispatch, key, upb_value_uint64(newval)); UPB_ASSERT_VAR(ok, ok); }
static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit, void *closure) { const mgroup *g = (const mgroup*)r; upb_inttable_iter i; upb_inttable_begin(&i, &g->methods); for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i)); visit(r, UPB_UPCAST(method), closure); } }
void upb_msgfactory_free(upb_msgfactory *f) { upb_inttable_iter i; upb_inttable_begin(&i, &f->layouts); for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i)); upb_msglayout_free(l); } upb_inttable_uninit(&f->layouts); upb_gfree(f); }
static void upb_enumdef_free(upb_refcounted *r) { upb_enumdef *e = (upb_enumdef*)r; upb_inttable_iter i; upb_inttable_begin(&i, &e->iton); for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) { // To clean up the upb_strdup() from upb_enumdef_addval(). free(upb_value_getcstr(upb_inttable_iter_value(&i))); } upb_strtable_uninit(&e->ntoi); upb_inttable_uninit(&e->iton); upb_def_uninit(upb_upcast(e)); free(e); }
static void freejitcompiler(jitcompiler *jc) { upb_inttable_iter i; upb_inttable_begin(&i, &jc->asmlabels); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { free(upb_value_getptr(upb_inttable_iter_value(&i))); } upb_inttable_uninit(&jc->asmlabels); upb_inttable_uninit(&jc->pclabels); upb_inttable_uninit(&jc->pcdefined); dasm_free(jc); free(jc->globals); free(jc); }
// Populates the given UPB_CTYPE_INT32 inttable with counts of ref2's that // originate from the given owner. static void getref2s(const upb_refcounted *owner, upb_inttable *tab) { upb_lock(); upb_inttable_iter i; upb_inttable_begin(&i, owner->ref2s); for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { upb_refcounted *to = (upb_refcounted*)upb_inttable_iter_key(&i); // To get the count we need to look in the target's table. upb_value v; bool found = upb_inttable_lookupptr(to->refs, owner, &v); assert(found); trackedref *ref = upb_value_getptr(v); upb_value count = upb_value_int32(ref->count); bool ok = upb_inttable_insertptr(tab, to, count); CHECK_OOM(ok); } upb_unlock(); }
upb_decoderplan *upb_decoderplan_new(upb_handlers *h, bool allowjit) { upb_decoderplan *p = malloc(sizeof(*p)); p->handlers = h; upb_handlers_ref(h); h->should_jit = allowjit; #ifdef UPB_USE_JIT_X64 p->jit_code = NULL; if (allowjit) upb_decoderplan_makejit(p); #endif // Set function pointers for each field's decode function. for (int i = 0; i < h->msgs_len; i++) { upb_mhandlers *m = h->msgs[i]; for(upb_inttable_iter i = upb_inttable_begin(&m->fieldtab); !upb_inttable_done(i); i = upb_inttable_next(&m->fieldtab, i)) { upb_itofhandlers_ent *e = upb_inttable_iter_value(i); upb_fhandlers *f = e->f; upb_decoderplan_initfhandlers(f); } } return p; }
bool upb_msg_done(upb_msg_iter *iter) { return upb_inttable_done(iter); }