📄 dt_ident.c
字号:
{ if (idp->di_data != NULL) free(((dt_idsig_t *)idp->di_data)->dis_args); free(idp->di_data);}static voiddt_iddtor_node(dt_ident_t *idp){ dt_idnode_t *inp = idp->di_data; if (inp != NULL) { dt_node_link_free(&inp->din_list); free(inp); }}static voiddt_iddtor_free(dt_ident_t *idp){ free(idp->di_data);}static voiddt_iddtor_args(dt_ident_t *idp){ dt_ident_t *next, *old; assert(!(idp->di_flags & DT_IDFLG_ARGNDX)); for (old = idp->di_data; old != NULL; old = next) { next = old->di_next; free(old->di_name); free(old); }}static size_tdt_idsize_type(dt_ident_t *idp){ return (ctf_type_size(idp->di_ctfp, idp->di_type));}/*ARGSUSED*/static size_tdt_idsize_none(dt_ident_t *idp){ return (0);}const dt_idops_t dt_idops_assc = { dt_idcook_assc, dt_idctor_default, dt_iddtor_sign, dt_idsize_none,};const dt_idops_t dt_idops_func = { dt_idcook_func, dt_idctor_default, dt_iddtor_sign, dt_idsize_none,};const dt_idops_t dt_idops_args = { dt_idcook_args, dt_idctor_args, dt_iddtor_args, dt_idsize_none,};const dt_idops_t dt_idops_regs = { dt_idcook_regs, dt_idctor_default, dt_iddtor_free, dt_idsize_none,};const dt_idops_t dt_idops_type = { dt_idcook_type, dt_idctor_default, dt_iddtor_free, dt_idsize_type,};const dt_idops_t dt_idops_thaw = { dt_idcook_thaw, dt_idctor_default, dt_iddtor_free, dt_idsize_type,};const dt_idops_t dt_idops_inline = { dt_idcook_thaw, dt_idctor_default, dt_iddtor_node, dt_idsize_type,};const dt_idops_t dt_idops_probe = { dt_idcook_thaw, dt_idctor_default, dt_probe_destroy, dt_idsize_none,};static voiddt_idhash_populate(dt_idhash_t *dhp){ const dt_ident_t *idp = dhp->dh_tmpl; dhp->dh_tmpl = NULL; /* clear dh_tmpl first to avoid recursion */ dt_dprintf("populating %s idhash from %p\n", dhp->dh_name, (void *)idp); for (; idp->di_name != NULL; idp++) { if (dt_idhash_insert(dhp, idp->di_name, idp->di_kind, idp->di_flags, idp->di_id, idp->di_attr, idp->di_vers, idp->di_ops ? idp->di_ops : &dt_idops_thaw, idp->di_iarg, 0) == NULL) longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); }}dt_idhash_t *dt_idhash_create(const char *name, const dt_ident_t *tmpl, uint_t min, uint_t max){ dt_idhash_t *dhp; size_t size; assert(min <= max); size = sizeof (dt_idhash_t) + sizeof (dt_ident_t *) * (_dtrace_strbuckets - 1); if ((dhp = malloc(size)) == NULL) return (NULL); bzero(dhp, size); dhp->dh_name = name; dhp->dh_tmpl = tmpl; dhp->dh_nextid = min; dhp->dh_minid = min; dhp->dh_maxid = max; dhp->dh_hashsz = _dtrace_strbuckets; return (dhp);}voiddt_idhash_destroy(dt_idhash_t *dhp){ dt_ident_t *idp, *next; ulong_t i; for (i = 0; i < dhp->dh_hashsz; i++) { for (idp = dhp->dh_hash[i]; idp != NULL; idp = next) { next = idp->di_next; dt_ident_destroy(idp); } } free(dhp);}voiddt_idhash_update(dt_idhash_t *dhp){ uint_t nextid = dhp->dh_minid; dt_ident_t *idp; ulong_t i; for (i = 0; i < dhp->dh_hashsz; i++) { for (idp = dhp->dh_hash[i]; idp != NULL; idp = idp->di_next) { if (idp->di_kind == DT_IDENT_ARRAY || idp->di_kind == DT_IDENT_SCALAR) nextid = MAX(nextid, idp->di_id + 1); } } dhp->dh_nextid = nextid;}dt_ident_t *dt_idhash_lookup(dt_idhash_t *dhp, const char *name){ size_t len; ulong_t h = dt_strtab_hash(name, &len) % dhp->dh_hashsz; dt_ident_t *idp; if (dhp->dh_tmpl != NULL) dt_idhash_populate(dhp); /* fill hash w/ initial population */ for (idp = dhp->dh_hash[h]; idp != NULL; idp = idp->di_next) { if (strcmp(idp->di_name, name) == 0) return (idp); } return (NULL);}intdt_idhash_nextid(dt_idhash_t *dhp, uint_t *p){ if (dhp->dh_nextid >= dhp->dh_maxid) return (-1); /* no more id's are free to allocate */ *p = dhp->dh_nextid++; return (0);}ulong_tdt_idhash_size(const dt_idhash_t *dhp){ return (dhp->dh_nelems);}const char *dt_idhash_name(const dt_idhash_t *dhp){ return (dhp->dh_name);}dt_ident_t *dt_idhash_insert(dt_idhash_t *dhp, const char *name, ushort_t kind, ushort_t flags, uint_t id, dtrace_attribute_t attr, uint_t vers, const dt_idops_t *ops, void *iarg, ulong_t gen){ dt_ident_t *idp; ulong_t h; if (dhp->dh_tmpl != NULL) dt_idhash_populate(dhp); /* fill hash w/ initial population */ idp = dt_ident_create(name, kind, flags, id, attr, vers, ops, iarg, gen); if (idp == NULL) return (NULL); h = dt_strtab_hash(name, NULL) % dhp->dh_hashsz; idp->di_next = dhp->dh_hash[h]; dhp->dh_hash[h] = idp; dhp->dh_nelems++; if (dhp->dh_defer != NULL) dhp->dh_defer(dhp, idp); return (idp);}voiddt_idhash_xinsert(dt_idhash_t *dhp, dt_ident_t *idp){ ulong_t h; if (dhp->dh_tmpl != NULL) dt_idhash_populate(dhp); /* fill hash w/ initial population */ h = dt_strtab_hash(idp->di_name, NULL) % dhp->dh_hashsz; idp->di_next = dhp->dh_hash[h]; dhp->dh_hash[h] = idp; dhp->dh_nelems++; if (dhp->dh_defer != NULL) dhp->dh_defer(dhp, idp);}voiddt_idhash_delete(dt_idhash_t *dhp, dt_ident_t *key){ size_t len; ulong_t h = dt_strtab_hash(key->di_name, &len) % dhp->dh_hashsz; dt_ident_t **pp = &dhp->dh_hash[h]; dt_ident_t *idp; for (idp = dhp->dh_hash[h]; idp != NULL; idp = idp->di_next) { if (idp == key) break; else pp = &idp->di_next; } assert(idp == key); *pp = idp->di_next; assert(dhp->dh_nelems != 0); dhp->dh_nelems--; dt_ident_destroy(idp);}static intdt_idhash_comp(const void *lp, const void *rp){ const dt_ident_t *lhs = *((const dt_ident_t **)lp); const dt_ident_t *rhs = *((const dt_ident_t **)rp); return ((int)(lhs->di_id - rhs->di_id));}voiddt_idhash_iter(dt_idhash_t *dhp, dt_idhash_f *func, void *data){ dt_ident_t **ids; dt_ident_t *idp; ulong_t i, j; if (dhp->dh_tmpl != NULL) dt_idhash_populate(dhp); /* fill hash w/ initial population */ ids = alloca(sizeof (dt_ident_t *) * dhp->dh_nelems); for (i = 0, j = 0; i < dhp->dh_hashsz; i++) { for (idp = dhp->dh_hash[i]; idp != NULL; idp = idp->di_next) ids[j++] = idp; } qsort(ids, dhp->dh_nelems, sizeof (dt_ident_t *), dt_idhash_comp); for (i = 0; i < dhp->dh_nelems; i++) func(dhp, ids[i], data);}dt_ident_t *dt_ident_create(const char *name, ushort_t kind, ushort_t flags, uint_t id, dtrace_attribute_t attr, uint_t vers, const dt_idops_t *ops, void *iarg, ulong_t gen){ dt_ident_t *idp; char *s = NULL; if ((name != NULL && (s = strdup(name)) == NULL) || (idp = malloc(sizeof (dt_ident_t))) == NULL) { free(s); return (NULL); } idp->di_name = s; idp->di_kind = kind; idp->di_flags = flags; idp->di_id = id; idp->di_attr = attr; idp->di_vers = vers; idp->di_ops = ops; idp->di_iarg = iarg; idp->di_data = NULL; idp->di_ctfp = NULL; idp->di_type = CTF_ERR; idp->di_next = NULL; idp->di_gen = gen; idp->di_lineno = yylineno; return (idp);}voiddt_ident_destroy(dt_ident_t *idp){ idp->di_ops->di_dtor(idp); free(idp->di_name); free(idp);}voiddt_ident_morph(dt_ident_t *idp, ushort_t kind, const dt_idops_t *ops, void *iarg){ idp->di_ops->di_dtor(idp); idp->di_kind = kind; idp->di_ops = ops; idp->di_iarg = iarg; idp->di_data = NULL;}dtrace_attribute_tdt_ident_cook(dt_node_t *dnp, dt_ident_t *idp, dt_node_t **pargp){ dtrace_attribute_t attr; dt_node_t *args, *argp; int argc = 0; attr = dt_node_list_cook(pargp, DT_IDFLG_REF); args = pargp ? *pargp : NULL; for (argp = args; argp != NULL; argp = argp->dn_list) argc++; if (idp == dnp->dn_ident) { /* * If the ident we've been passed is the ident that corresponds * to the node, we're going to call through the identifier ops * to construct the identifier -- potentially changing it. */ dnp->dn_ident = idp->di_ops->di_ctor(dnp, argc, args); idp = dnp->dn_ident; } idp->di_ops->di_cook(dnp, idp, argc, args); if (idp->di_flags & DT_IDFLG_USER) dnp->dn_flags |= DT_NF_USERLAND; return (dt_attr_min(attr, idp->di_attr));}voiddt_ident_type_assign(dt_ident_t *idp, ctf_file_t *fp, ctf_id_t type){ idp->di_ctfp = fp; idp->di_type = type;}dt_ident_t *dt_ident_resolve(dt_ident_t *idp){ while (idp->di_flags & DT_IDFLG_INLINE) { const dt_node_t *dnp = ((dt_idnode_t *)idp->di_data)->din_root; switch (dnp->dn_kind) { case DT_NODE_VAR: case DT_NODE_SYM: case DT_NODE_FUNC: case DT_NODE_AGG: case DT_NODE_INLINE: idp = dnp->dn_ident; continue; } if (dt_node_is_dynamic(dnp)) idp = dnp->dn_ident; else break; } return (idp);}size_tdt_ident_size(dt_ident_t *idp){ idp = dt_ident_resolve(idp); return (idp->di_ops->di_size(idp));}intdt_ident_unref(const dt_ident_t *idp){ return (idp->di_gen == yypcb->pcb_hdl->dt_gen && (idp->di_flags & (DT_IDFLG_REF|DT_IDFLG_MOD|DT_IDFLG_DECL)) == 0);}const char *dt_idkind_name(uint_t kind){ switch (kind) { case DT_IDENT_ARRAY: return ("associative array"); case DT_IDENT_SCALAR: return ("scalar"); case DT_IDENT_PTR: return ("pointer"); case DT_IDENT_FUNC: return ("function"); case DT_IDENT_AGG: return ("aggregation"); case DT_IDENT_AGGFUNC: return ("aggregating function"); case DT_IDENT_ACTFUNC: return ("tracing function"); case DT_IDENT_XLSOU: return ("translated data"); case DT_IDENT_XLPTR: return ("pointer to translated data"); case DT_IDENT_SYMBOL: return ("external symbol reference"); case DT_IDENT_ENUM: return ("enumerator"); case DT_IDENT_PRAGAT: return ("#pragma attributes"); case DT_IDENT_PRAGBN: return ("#pragma binding"); case DT_IDENT_PROBE: return ("probe definition"); default: return ("<?>"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -