dwarves: Allow the apps to steal compile units as they are created

So that we immensely reduce the memory footprint by doing filtering and
other processing/pretty printing as the cus are loaded, discarding them
right away.

The next cset will use this scheme in pahole.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2009-03-13 14:59:32 -03:00
parent 489e3b585c
commit 18e9ad4936
3 changed files with 49 additions and 26 deletions

View File

@ -866,24 +866,10 @@ static int cu__fixup_ctf_bitfields(struct cu *self)
return err;
}
static int cus__fixup_ctf_bitfields(struct cus *self)
{
int err = 0;
struct cu *pos;
list_for_each_entry(pos, &self->cus, node) {
err = cu__fixup_ctf_bitfields(pos);
if (err)
break;
}
return err;
}
int ctf__load(struct cus *self, struct conf_load *conf __unused,
const char *filename)
int ctf__load(struct cus *self, struct conf_load *conf, const char *filename)
{
struct ctf_state state;
int wordsize;
int wordsize, err;
memset(&state, 0, sizeof(state));
@ -907,13 +893,20 @@ int ctf__load(struct cus *self, struct conf_load *conf __unused,
if (state.cu == NULL)
oom("cu__new");
cus__add(self, state.cu);
dump_ctf(&state);
elf_end(state.elf);
close(state.in_fd);
return cus__fixup_ctf_bitfields(self);
err = cu__fixup_ctf_bitfields(state.cu);
/*
* The app stole this cu, possibly deleting it,
* so forget about it
*/
if (conf->steal && conf->steal(state.cu, conf))
return 0;
cus__add(self, state.cu);
return err;
}

View File

@ -1582,8 +1582,8 @@ static void die__process(Dwarf_Die *die, struct cu *cu)
cu__recode_dwarf_types(cu);
}
static void cus__load_module(struct cus *self, struct conf_load *conf,
Dwfl_Module *mod, Dwarf *dw)
static int cus__load_module(struct cus *self, struct conf_load *conf,
Dwfl_Module *mod, Dwarf *dw)
{
Dwarf_Off off = 0, noff;
size_t cuhl;
@ -1609,11 +1609,29 @@ static void cus__load_module(struct cus *self, struct conf_load *conf,
oom("cu__new");
cu->extra_dbg_info = conf ? conf->extra_dbg_info : 0;
die__process(cu_die, cu);
cus__add(self, cu);
off = noff;
if (conf->steal != NULL) {
switch (conf->steal(cu, conf)) {
case LSK__STOP_LOADING:
return DWARF_CB_ABORT;
case LSK__STOLEN:
/*
* The app stole this cu, possibly deleting it,
* so forget about it:
*/
continue;
case LSK__KEEPIT:
break;
}
}
if (!cu->extra_dbg_info)
cu__for_all_tags(cu, tag__delete_priv, NULL);
off = noff;
cus__add(self, cu);
}
return DWARF_CB_OK;
}
struct process_dwflmod_parms {
@ -1641,9 +1659,10 @@ static int cus__process_dwflmod(Dwfl_Module *dwflmod,
Dwarf_Addr dwbias;
Dwarf *dw = dwfl_module_getdwarf(dwflmod, &dwbias);
int err = DWARF_CB_OK;
if (dw != NULL) {
++parms->nr_dwarf_sections_found;
cus__load_module(self, parms->conf, dwflmod, dw);
err = cus__load_module(self, parms->conf, dwflmod, dw);
}
/*
* XXX We will fall back to try finding other debugging
@ -1655,7 +1674,7 @@ static int cus__process_dwflmod(Dwfl_Module *dwflmod,
* __func__, dwfl_errmsg(-1));
*/
return DWARF_CB_OK;
return err;
}
static int cus__process_file(struct cus *self, struct conf_load *conf, int fd,

View File

@ -21,12 +21,23 @@
extern struct strings *strings;
struct cu;
enum load_steal_kind {
LSK__KEEPIT,
LSK__STOLEN,
LSK__STOP_LOADING,
};
/** struct conf_load - load configuration
* @extra_dbg_info - keep original debugging format extra info
* (e.g. DWARF's decl_{line,file}, id, etc)
*/
struct conf_load {
bool extra_dbg_info;
bool extra_dbg_info;
enum load_steal_kind (*steal)(struct cu *self,
struct conf_load *conf);
void *cookie;
};
struct cus {