eliminate static, absurdly large table sizes in all cases in pdb->raddbg path; markup & diagnostics of table sizes vs. counts, to begin gathering data for table size prediction path

This commit is contained in:
Ryan Fleury
2024-02-09 11:50:04 -08:00
parent 7f357b264c
commit 2d63234c92
5 changed files with 118 additions and 24 deletions
+21 -1
View File
@@ -56,7 +56,7 @@ commands =
},
.rjf_f2 =
{
.win = "build raddbg_from_pdb",
.win = "build raddbg_from_pdb telemetry",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
@@ -72,6 +72,24 @@ commands =
.save_dirty_files = true,
.cursor_at_end = false,
},
.rjf_f4 =
{
.win = "build raddbg_from_pdb release telemetry && pushd build && raddbg_from_pdb.exe --exe:mule_main.exe --pdb:mule_main.pdb --out:mule_main.raddbg --capture && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.rjf_f5 =
{
.win = "pushd build && raddbg_from_pdb.exe --exe:mule_main.exe --pdb:mule_main.pdb --out:mule_main.raddbg --capture && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg =
{
.win = "build raddbg",
@@ -141,5 +159,7 @@ fkey_command_override =
.F1 = "rjf_f1",
.F2 = "rjf_f2",
.F3 = "rjf_f3",
.F4 = "rjf_f4",
.F5 = "rjf_f5",
},
};
+31 -7
View File
@@ -7,7 +7,7 @@
//- init
static CONS_Root*
cons_root_new(CONS_RootParams *params){
Arena *arena = arena_alloc__sized(GB(64), MB(256));
Arena *arena = arena_alloc__sized(GB(64), MB(64));
CONS_Root *result = push_array(arena, CONS_Root, 1);
result->arena = arena;
@@ -49,6 +49,7 @@ cons_root_new(CONS_RootParams *params){
cons__u64toptr_init(arena, &result->scope_map, BKTCOUNT(params->bucket_count_scopes));
cons__u64toptr_init(arena, &result->local_map, BKTCOUNT(params->bucket_count_locals));
cons__u64toptr_init(arena, &result->type_from_id_map, BKTCOUNT(params->bucket_count_types));
cons__str8toptr_init(arena, &result->construct_map, 4096);
#undef BKTCOUNT
}
@@ -1336,6 +1337,7 @@ cons_symbol_handle_from_user_id(CONS_Root *root, U64 symbol_user_id){
static void
cons_symbol_set_info(CONS_Root *root, CONS_Symbol *symbol, CONS_SymbolInfo *info){
ProfBeginFunction();
CONS_SymbolKind kind = info->kind;
if (symbol->kind != CONS_SymbolKind_NULL){
@@ -1408,7 +1410,8 @@ cons_symbol_set_info(CONS_Root *root, CONS_Symbol *symbol, CONS_SymbolInfo *info
map = cons__name_map_for_kind(root, RADDBG_NameMapKind_Procedures);
}break;
}
if (map != 0){
if(map != 0) ProfScope("save name map")
{
cons__name_map_add_pair(root, map, symbol->name, symbol->idx);
}
}
@@ -1419,6 +1422,7 @@ cons_symbol_set_info(CONS_Root *root, CONS_Symbol *symbol, CONS_SymbolInfo *info
cons__name_map_add_pair(root, map, symbol->link_name, symbol->idx);
}
}
ProfEnd();
}
// scopes
@@ -1697,12 +1701,14 @@ cons__type_udt_from_record_type(CONS_Root *root, CONS_Type *type){
static void
cons__scope_recursive_set_symbol(CONS_Scope *scope, CONS_Symbol *symbol){
ProfBeginFunction();
scope->symbol = symbol;
for (CONS_Scope *node = scope->first_child;
node != 0;
node = node->next_sibling){
cons__scope_recursive_set_symbol(node, symbol);
}
ProfEnd();
}
// name maps
@@ -1713,6 +1719,8 @@ cons__name_map_for_kind(CONS_Root *root, RADDBG_NameMapKind kind){
if (kind < RADDBG_NameMapKind_COUNT){
if (root->name_maps[kind] == 0){
root->name_maps[kind] = push_array(root->arena, CONS__NameMap, 1);
root->name_maps[kind]->buckets_count = 16384;
root->name_maps[kind]->buckets = push_array(root->arena, CONS__NameMapNode *, root->name_maps[kind]->buckets_count);
}
result = root->name_maps[kind];
}
@@ -1721,9 +1729,11 @@ cons__name_map_for_kind(CONS_Root *root, RADDBG_NameMapKind kind){
static void
cons__name_map_add_pair(CONS_Root *root, CONS__NameMap *map, String8 string, U32 idx){
ProfBeginFunction();
// hash
U64 hash = raddbg_hash(string.str, string.size);
U64 bucket_idx = hash%ArrayCount(map->buckets);
U64 bucket_idx = hash%map->buckets_count;
// find existing name node
CONS__NameMapNode *match = 0;
@@ -1774,6 +1784,8 @@ cons__name_map_add_pair(CONS_Root *root, CONS__NameMap *map, String8 string, U32
idx_node->idx[insert_i] = idx;
match->idx_count += 1;
}
ProfEnd();
}
// u64 to ptr map
@@ -1830,11 +1842,18 @@ cons__u64toptr_insert(Arena *arena, CONS__U64ToPtrMap *map, U64 key,
// str8 to ptr map
static void
cons__str8toptr_init(Arena *arena, CONS__Str8ToPtrMap *map, U64 bucket_count)
{
map->buckets_count = bucket_count;
map->buckets = push_array(arena, CONS__Str8ToPtrNode*, map->buckets_count);
}
static void*
cons__str8toptr_lookup(CONS__Str8ToPtrMap *map, String8 key, U64 hash){
ProfBeginFunction();
void *result = 0;
U64 bucket_idx = hash%ArrayCount(map->buckets);
U64 bucket_idx = hash%map->buckets_count;
for (CONS__Str8ToPtrNode *node = map->buckets[bucket_idx];
node != 0;
node = node->next){
@@ -1850,7 +1869,7 @@ cons__str8toptr_lookup(CONS__Str8ToPtrMap *map, String8 key, U64 hash){
static void
cons__str8toptr_insert(Arena *arena, CONS__Str8ToPtrMap *map, String8 key, U64 hash, void *ptr){
ProfBeginFunction();
U64 bucket_idx = hash%ArrayCount(map->buckets);
U64 bucket_idx = hash%map->buckets_count;
CONS__Str8ToPtrNode *node = push_array(arena, CONS__Str8ToPtrNode, 1);
SLLStackPush(map->buckets[bucket_idx], node);
@@ -1858,6 +1877,7 @@ cons__str8toptr_insert(Arena *arena, CONS__Str8ToPtrMap *map, String8 key, U64 h
node->key = push_str8_copy(arena, key);
node->hash = hash;
node->ptr = ptr;
map->pair_count += 1;
ProfEnd();
}
@@ -1883,6 +1903,10 @@ cons__bake_ctx_begin(void){
Arena *arena = arena_alloc();
CONS__BakeCtx *result = push_array(arena, CONS__BakeCtx, 1);
result->arena = arena;
result->strs.buckets_count = 16384;
result->strs.buckets = push_array(arena, CONS__StringNode *, result->strs.buckets_count);
result->idxs.buckets_count = 16384;
result->idxs.buckets = push_array(arena, CONS__IdxRunNode *, result->idxs.buckets_count);
cons__string(result, str8_lit(""));
@@ -1913,7 +1937,7 @@ cons__string(CONS__BakeCtx *bctx, String8 str){
CONS__Strings *strs = &bctx->strs;
U64 hash = raddbg_hash(str.str, str.size);
U64 bucket_idx = hash%ArrayCount(strs->buckets);
U64 bucket_idx = hash%strs->buckets_count;
// look for a match
CONS__StringNode *match = 0;
@@ -1965,7 +1989,7 @@ cons__idx_run(CONS__BakeCtx *bctx, U32 *idx_run, U32 count){
CONS__IdxRuns *idxs = &bctx->idxs;
U64 hash = cons__idx_run_hash(idx_run, count);
U64 bucket_idx = hash%ArrayCount(idxs->buckets);
U64 bucket_idx = hash%idxs->buckets_count;
// look for a match
CONS__IdxRunNode *match = 0;
+10 -4
View File
@@ -483,7 +483,8 @@ typedef struct CONS__NameMapNode{
} CONS__NameMapNode;
typedef struct CONS__NameMap{
CONS__NameMapNode *buckets[1<<24];
CONS__NameMapNode **buckets;
U64 buckets_count;
CONS__NameMapNode *first;
CONS__NameMapNode *last;
U64 name_count;
@@ -529,9 +530,12 @@ typedef struct CONS__Str8ToPtrNode{
} CONS__Str8ToPtrNode;
typedef struct CONS__Str8ToPtrMap{
CONS__Str8ToPtrNode *buckets[1<<24];
CONS__Str8ToPtrNode **buckets;
U64 buckets_count;
U64 pair_count;
} CONS__Str8ToPtrMap;
static void cons__str8toptr_init(Arena *arena, CONS__Str8ToPtrMap *map, U64 bucket_count);
static void*cons__str8toptr_lookup(CONS__Str8ToPtrMap *map, String8 key, U64 hash);
static void cons__str8toptr_insert(Arena *arena, CONS__Str8ToPtrMap *map,
String8 key, U64 hash, void *ptr);
@@ -640,7 +644,8 @@ typedef struct CONS__StringNode{
typedef struct CONS__Strings{
CONS__StringNode *order_first;
CONS__StringNode *order_last;
CONS__StringNode *buckets[1<<24];
CONS__StringNode **buckets;
U64 buckets_count;
U32 count;
} CONS__Strings;
@@ -657,7 +662,8 @@ typedef struct CONS__IdxRunNode{
typedef struct CONS__IdxRuns{
CONS__IdxRunNode *order_first;
CONS__IdxRunNode *order_last;
CONS__IdxRunNode *buckets[1<<24];
CONS__IdxRunNode **buckets;
U64 buckets_count;
U32 count;
U32 idx_count;
} CONS__IdxRuns;
+44 -8
View File
@@ -151,6 +151,14 @@ pdbconv_types_and_symbols(PDBCONV_TypesSymbolsParams *params, CONS_Root *out_roo
pdb_ctx->section_count = params->sections->count;
pdb_ctx->root = out_root;
pdb_ctx->temp_arena = arena_alloc();
pdb_ctx->fwd_map.buckets_count = 16384;
pdb_ctx->fwd_map.buckets = push_array(pdb_ctx->temp_arena, PDBCONV_FwdNode *, pdb_ctx->fwd_map.buckets_count);
pdb_ctx->frame_proc_map.buckets_count = 16384;
pdb_ctx->frame_proc_map.buckets = push_array(pdb_ctx->temp_arena, PDBCONV_FrameProcNode *, pdb_ctx->frame_proc_map.buckets_count);
pdb_ctx->known_globals.buckets_count = 16384;
pdb_ctx->known_globals.buckets = push_array(pdb_ctx->temp_arena, PDBCONV_KnownGlobalNode *, pdb_ctx->known_globals.buckets_count);
pdb_ctx->link_names.buckets_count = 16384;
pdb_ctx->link_names.buckets = push_array(pdb_ctx->temp_arena, PDBCONV_LinkNameNode *, pdb_ctx->link_names.buckets_count);
// convert types
pdbconv_type_cons_main_passes(pdb_ctx);
@@ -1733,7 +1741,7 @@ pdbconv_type_from_name(PDBCONV_Ctx *ctx, String8 name){
static void
pdbconv_type_fwd_map_set(Arena *arena, PDBCONV_FwdMap *map, CV_TypeId key, CV_TypeId val){
U64 bucket_idx = key%ArrayCount(map->buckets);
U64 bucket_idx = key%map->buckets_count;
// search for an existing match
PDBCONV_FwdNode *match = 0;
@@ -1751,6 +1759,7 @@ pdbconv_type_fwd_map_set(Arena *arena, PDBCONV_FwdMap *map, CV_TypeId key, CV_Ty
match = push_array(arena, PDBCONV_FwdNode, 1);
SLLStackPush(map->buckets[bucket_idx], match);
match->key = key;
map->pair_count += 1;
}
// set node's val
@@ -1760,7 +1769,7 @@ pdbconv_type_fwd_map_set(Arena *arena, PDBCONV_FwdMap *map, CV_TypeId key, CV_Ty
static CV_TypeId
pdbconv_type_fwd_map_get(PDBCONV_FwdMap *map, CV_TypeId key){
ProfBeginFunction();
U64 bucket_idx = key%ArrayCount(map->buckets);
U64 bucket_idx = key%map->buckets_count;
// search for an existing match
PDBCONV_FwdNode *match = 0;
@@ -1880,6 +1889,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
default:break;
case CV_SymKind_END:
ProfScope("CV_SymKind_END")
{
// pop scope stack
pdbconv_symbol_pop_scope(ctx);
@@ -1888,6 +1898,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_FRAMEPROC:
ProfScope("CV_SymKind_FRAMEPROC")
{
if (sizeof(CV_SymFrameproc) > cap){
// TODO(allen): error
@@ -1898,6 +1909,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_BLOCK32:
ProfScope("CV_SymKind_BLOCK32")
{
if (sizeof(CV_SymBlock32) > cap){
// TODO(allen): error
@@ -1923,6 +1935,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
case CV_SymKind_LDATA32:
case CV_SymKind_GDATA32:
ProfScope("CV_SymKind_LDATA32/CV_SymKind_GDATA32")
{
if (sizeof(CV_SymData32) > cap){
// TODO(allen): error
@@ -1984,6 +1997,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
case CV_SymKind_LPROC32:
case CV_SymKind_GPROC32:
ProfScope("CV_SymKind_LPROC32/CV_SymKind_GPROC32")
{
if (sizeof(CV_SymProc32) > cap){
// TODO(allen): error
@@ -2061,6 +2075,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_REGREL32:
ProfScope("CV_SymKind_REGREL32")
{
if (sizeof(CV_SymRegrel32) > cap){
// TODO(allen): error
@@ -2159,6 +2174,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
case CV_SymKind_LTHREAD32:
case CV_SymKind_GTHREAD32:
ProfScope("CV_SymKind_LTHREAD32/CV_SymKind_GTHREAD32")
{
if (sizeof(CV_SymThread32) > cap){
// TODO(allen): error
@@ -2210,6 +2226,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_LOCAL:
ProfScope("CV_SymKind_LOCAL")
{
if (sizeof(CV_SymLocal) > cap){
// TODO(allen): error
@@ -2264,6 +2281,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_DEFRANGE_REGISTER:
ProfScope("CV_SymKind_DEFRANGE_REGISTER")
{
if (sizeof(CV_SymDefrangeRegister) > cap){
// TODO(allen): error
@@ -2296,6 +2314,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL:
ProfScope("CV_SymKind_DEFRANGE_FRAMEPOINTER_REL")
{
if (sizeof(CV_SymDefrangeFramepointerRel) > cap){
// TODO(allen): error
@@ -2335,6 +2354,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER:
ProfScope("CV_SymKind_DEFRANGE_SUBFIELD_REGISTER")
{
if (sizeof(CV_SymDefrangeSubfieldRegister) > cap){
// TODO(allen): error
@@ -2371,6 +2391,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
ProfScope("CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE")
{
if (sizeof(CV_SymDefrangeFramepointerRelFullScope) > cap){
// TODO(allen): error
@@ -2406,6 +2427,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_DEFRANGE_REGISTER_REL:
ProfScope("CV_SymKind_DEFRANGE_REGISTER_REL")
{
if (sizeof(CV_SymDefrangeRegisterRel) > cap){
// TODO(allen): error
@@ -2447,6 +2469,7 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id){
}break;
case CV_SymKind_FILESTATIC:
ProfScope("CV_SymKind_FILESTATIC")
{
if (sizeof(CV_SymFileStatic) > cap){
// TODO(allen): error
@@ -2541,9 +2564,10 @@ pdbconv_gather_link_names(PDBCONV_Ctx *ctx, CV_SymParsed *sym){
static void
pdbconv_symbol_frame_proc_write(PDBCONV_Ctx *ctx,CONS_Symbol *key,PDBCONV_FrameProcData *data){
ProfBeginFunction();
U64 key_int = IntFromPtr(key);
PDBCONV_FrameProcMap *map = &ctx->frame_proc_map;
U32 bucket_idx = key_int%ArrayCount(map->buckets);
U32 bucket_idx = key_int%map->buckets_count;
// find match
PDBCONV_FrameProcNode *match = 0;
@@ -2567,14 +2591,17 @@ pdbconv_symbol_frame_proc_write(PDBCONV_Ctx *ctx,CONS_Symbol *key,PDBCONV_FrameP
SLLStackPush(map->buckets[bucket_idx], match);
match->key = key;
MemoryCopyStruct(&match->data, data);
map->pair_count += 1;
}
ProfEnd();
}
static PDBCONV_FrameProcData*
pdbconv_symbol_frame_proc_read(PDBCONV_Ctx *ctx, CONS_Symbol *key){
ProfBeginFunction();
U64 key_int = IntFromPtr(key);
PDBCONV_FrameProcMap *map = &ctx->frame_proc_map;
U32 bucket_idx = key_int%ArrayCount(map->buckets);
U32 bucket_idx = key_int%map->buckets_count;
// find match
PDBCONV_FrameProcData *result = 0;
@@ -2587,6 +2614,7 @@ pdbconv_symbol_frame_proc_read(PDBCONV_Ctx *ctx, CONS_Symbol *key){
}
}
ProfEnd();
return(result);
}
@@ -2661,8 +2689,9 @@ pdbconv_known_global_hash(String8 name, U64 voff){
static B32
pdbconv_known_global_lookup(PDBCONV_KnownGlobalSet *set, String8 name, U64 voff){
ProfBeginFunction();
U64 hash = pdbconv_known_global_hash(name, voff);
U64 bucket_idx = hash%ArrayCount(set->buckets);
U64 bucket_idx = hash%set->buckets_count;
PDBCONV_KnownGlobalNode *match = 0;
for (PDBCONV_KnownGlobalNode *node = set->buckets[bucket_idx];
@@ -2677,13 +2706,15 @@ pdbconv_known_global_lookup(PDBCONV_KnownGlobalSet *set, String8 name, U64 voff)
}
B32 result = (match != 0);
ProfEnd();
return(result);
}
static void
pdbconv_known_global_insert(Arena *arena, PDBCONV_KnownGlobalSet *set, String8 name, U64 voff){
ProfBeginFunction();
U64 hash = pdbconv_known_global_hash(name, voff);
U64 bucket_idx = hash%ArrayCount(set->buckets);
U64 bucket_idx = hash%set->buckets_count;
PDBCONV_KnownGlobalNode *match = 0;
for (PDBCONV_KnownGlobalNode *node = set->buckets[bucket_idx];
@@ -2703,7 +2734,9 @@ pdbconv_known_global_insert(Arena *arena, PDBCONV_KnownGlobalSet *set, String8 n
node->key_name = push_str8_copy(arena, name);
node->key_voff = voff;
node->hash = hash;
set->global_count += 1;
}
ProfEnd();
}
// location info helpers
@@ -2843,18 +2876,20 @@ pdbconv_location_over_lvar_addr_range(PDBCONV_Ctx *ctx,
static void
pdbconv_link_name_save(Arena *arena, PDBCONV_LinkNameMap *map, U64 voff, String8 name){
U64 hash = (voff >> 3) ^ ((7 & voff) << 6);
U64 bucket_idx = hash%ArrayCount(map->buckets);
U64 bucket_idx = hash%map->buckets_count;
PDBCONV_LinkNameNode *node = push_array(arena, PDBCONV_LinkNameNode, 1);
SLLStackPush(map->buckets[bucket_idx], node);
node->voff = voff;
node->name = push_str8_copy(arena, name);
map->link_name_count += 1;
}
static String8
pdbconv_link_name_find(PDBCONV_LinkNameMap *map, U64 voff){
ProfBeginFunction();
U64 hash = (voff >> 3) ^ ((7 & voff) << 6);
U64 bucket_idx = hash%ArrayCount(map->buckets);
U64 bucket_idx = hash%map->buckets_count;
String8 result = {0};
for (PDBCONV_LinkNameNode *node = map->buckets[bucket_idx];
@@ -2866,6 +2901,7 @@ pdbconv_link_name_find(PDBCONV_LinkNameMap *map, U64 voff){
}
}
ProfEnd();
return(result);
}
+12 -4
View File
@@ -53,7 +53,9 @@ typedef struct PDBCONV_FwdNode{
} PDBCONV_FwdNode;
typedef struct PDBCONV_FwdMap{
PDBCONV_FwdNode *buckets[1<<24];
PDBCONV_FwdNode **buckets;
U64 buckets_count;
U64 pair_count;
} PDBCONV_FwdMap;
typedef struct PDBCONV_TypeRev{
@@ -74,7 +76,9 @@ typedef struct PDBCONV_FrameProcNode{
} PDBCONV_FrameProcNode;
typedef struct PDBCONV_FrameProcMap{
PDBCONV_FrameProcNode *buckets[1<<24];
PDBCONV_FrameProcNode **buckets;
U64 buckets_count;
U64 pair_count;
} PDBCONV_FrameProcMap;
typedef struct PDBCONV_ScopeNode{
@@ -91,7 +95,9 @@ typedef struct PDBCONV_KnownGlobalNode{
} PDBCONV_KnownGlobalNode;
typedef struct PDBCONV_KnownGlobalSet{
PDBCONV_KnownGlobalNode *buckets[1<<24];
PDBCONV_KnownGlobalNode **buckets;
U64 buckets_count;
U64 global_count;
} PDBCONV_KnownGlobalSet;
typedef struct PDBCONV_TypesSymbolsParams{
@@ -111,7 +117,9 @@ typedef struct PDBCONV_LinkNameNode{
} PDBCONV_LinkNameNode;
typedef struct PDBCONV_LinkNameMap{
PDBCONV_LinkNameNode *buckets[1<<24];
PDBCONV_LinkNameNode **buckets;
U64 buckets_count;
U64 link_name_count;
} PDBCONV_LinkNameMap;
typedef struct PDBCONV_Ctx{