dwarf: separate dwarf_tag from tag

So that, when not needing the DWARF info, the apps can tell that at load
time, and then the dwarf loader can just free all the dwarf_tags
allocated, reducing memory usage.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2009-03-09 14:43:47 -03:00
parent 822f8b675e
commit 250dded466
14 changed files with 103 additions and 49 deletions

View File

@ -797,7 +797,7 @@ failure:
/* If old_file is a character device, leave its cus empty */
if (!S_ISCHR(st.st_mode)) {
filenames[0] = old_filename;
err = cus__loadfl(old_cus, filenames);
err = cus__loadfl(old_cus, NULL, filenames);
if (err != 0) {
cus__print_error_msg("codiff", old_cus, old_filename, err);
return EXIT_FAILURE;
@ -812,7 +812,7 @@ failure:
/* If old_file is a character device, leave its cus empty */
if (!S_ISCHR(st.st_mode)) {
filenames[0] = new_filename;
err = cus__loadfl(new_cus, filenames);
err = cus__loadfl(new_cus, NULL, filenames);
if (err != 0) {
cus__print_error_msg("codiff", new_cus, new_filename, err);
return EXIT_FAILURE;

View File

@ -879,7 +879,8 @@ static int cus__fixup_ctf_bitfields(struct cus *self)
return err;
}
int ctf__load(struct cus *self, char *filenames[])
int ctf__load(struct cus *self, struct conf_load *conf __unused,
char *filenames[])
{
struct ctf_state state;
int wordsize;

View File

@ -9,7 +9,8 @@
*/
struct cus;
struct conf_load;
int ctf__load(struct cus *self, char *filenames[]);
int ctf__load(struct cus *self, struct conf_load *conf, char *filenames[]);
#endif /* _CTF_LOADER_H_ */

View File

@ -49,7 +49,7 @@ int main(int argc __unused, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + 1);
err = cus__loadfl(cus, NULL, argv + 1);
if (err != 0)
return EXIT_FAILURE;

View File

@ -247,18 +247,24 @@ static int attr_location(Dwarf_Die *die, Dwarf_Op **expr, size_t *exprlen)
static void *tag__alloc(size_t size)
{
struct dwarf_tag *dtag;
struct tag *self = malloc(size + sizeof(*dtag));
struct dwarf_tag *dtag = malloc(sizeof(*dtag));
if (self != NULL) {
dtag = ((void *)self) + size;
dtag->tag = self;
self->priv = dtag;
dtag->type = 0;
self->type = 0;
self->top_level = 0;
if (dtag == NULL)
return NULL;
struct tag *self = malloc(size);
if (self == NULL) {
free(dtag);
return NULL;
}
dtag->tag = self;
self->priv = dtag;
dtag->type = 0;
self->type = 0;
self->top_level = 0;
return self;
}
@ -1496,31 +1502,32 @@ static void cu__recode_dwarf_types(struct cu *self)
}
static const char *dwarf_tag__decl_file(const struct tag *self,
const struct cu *cu __unused)
const struct cu *cu)
{
struct dwarf_tag *dtag = self->priv;
return dtag ? strings__ptr(strings, dtag->decl_file) : NULL;
return cu->extra_dbg_info ?
strings__ptr(strings, dtag->decl_file) : NULL;
}
static uint32_t dwarf_tag__decl_line(const struct tag *self,
const struct cu *cu __unused)
const struct cu *cu)
{
struct dwarf_tag *dtag = self->priv;
return dtag ? dtag->decl_line : 0;
return cu->extra_dbg_info ? dtag->decl_line : 0;
}
static unsigned long long dwarf_tag__orig_id(const struct tag *self,
const struct cu *cu __unused)
const struct cu *cu)
{
struct dwarf_tag *dtag = self->priv;
return dtag ? dtag->id : 0;
return cu->extra_dbg_info ? dtag->id : 0;
}
static unsigned long long dwarf_tag__orig_type(const struct tag *self,
const struct cu *cu __unused)
const struct cu *cu)
{
struct dwarf_tag *dtag = self->priv;
return dtag ? dtag->type : 0;
return cu->extra_dbg_info ? dtag->type : 0;
}
static struct cu_orig_info dwarf_orig_info_ops = {
@ -1530,6 +1537,14 @@ static struct cu_orig_info dwarf_orig_info_ops = {
.tag__orig_type = dwarf_tag__orig_type,
};
static int tag__delete_priv(struct tag *self, struct cu *cu __unused,
void *cookie __unused)
{
free(self->priv);
self->priv = NULL;
return 0;
}
static void die__process(Dwarf_Die *die, struct cu *cu)
{
Dwarf_Die child;
@ -1560,7 +1575,8 @@ static void die__process(Dwarf_Die *die, struct cu *cu)
cu__recode_dwarf_types(cu);
}
static void cus__load_module(struct cus *self, Dwfl_Module *mod, Dwarf *dw)
static void cus__load_module(struct cus *self, struct conf_load *conf,
Dwfl_Module *mod, Dwarf *dw)
{
Dwarf_Off off = 0, noff;
size_t cuhl;
@ -1584,19 +1600,28 @@ static void cus__load_module(struct cus *self, Dwfl_Module *mod, Dwarf *dw)
build_id, build_id_len);
if (cu == NULL)
oom("cu__new");
cu->extra_dbg_info = conf ? conf->extra_dbg_info : 0;
die__process(cu_die, cu);
cus__add(self, cu);
if (!cu->extra_dbg_info)
cu__for_all_tags(cu, tag__delete_priv, NULL);
off = noff;
}
}
struct process_dwflmod_parms {
struct cus *cus;
struct conf_load *conf;
};
static int cus__process_dwflmod(Dwfl_Module *dwflmod,
void **userdata __unused,
const char *name __unused,
Dwarf_Addr base __unused,
void *arg)
{
struct cus *self = arg;
struct process_dwflmod_parms *parms = arg;
struct cus *self = parms->cus;
/*
* WARNING: Don't remove the seemingly useless call to
* dwfl_module_getelf, as it will change dwflmod internal state in a
@ -1609,7 +1634,7 @@ static int cus__process_dwflmod(Dwfl_Module *dwflmod,
Dwarf *dw = dwfl_module_getdwarf(dwflmod, &dwbias);
if (dw != NULL)
cus__load_module(self, dwflmod, dw);
cus__load_module(self, parms->conf, dwflmod, dw);
/*
* XXX We will fall back to try finding other debugging
* formats (CTF), so no point in telling this to the user
@ -1623,7 +1648,8 @@ static int cus__process_dwflmod(Dwfl_Module *dwflmod,
return DWARF_CB_OK;
}
static int cus__process_file(struct cus *self, int fd, const char *filename)
static int cus__process_file(struct cus *self, struct conf_load *conf, int fd,
const char *filename)
{
/* Duplicate an fd for dwfl_report_offline to swallow. */
int dwfl_fd = dup(fd);
@ -1651,8 +1677,13 @@ static int cus__process_file(struct cus *self, int fd, const char *filename)
dwfl_report_end(dwfl, NULL, NULL);
struct process_dwflmod_parms parms = {
.cus = self,
.conf = conf,
};
/* Process the one or more modules gleaned from this file. */
dwfl_getmodules(dwfl, cus__process_dwflmod, self, 0);
dwfl_getmodules(dwfl, cus__process_dwflmod, &parms, 0);
dwfl_end(dwfl);
return 0;
}
@ -1701,7 +1732,7 @@ out:
return err;
}
int dwarf__load(struct cus *self, char *filenames[], bool parsed __unused)
int dwarf__load(struct cus *self, struct conf_load *conf, char *filenames[])
{
int err = 0, i = 0;
@ -1716,7 +1747,7 @@ int dwarf__load(struct cus *self, char *filenames[], bool parsed __unused)
++i;
continue;
}
cus__process_file(self, fd, filenames[i]);
cus__process_file(self, conf, fd, filenames[i]);
close(fd);
++i;
}

View File

@ -9,8 +9,9 @@
*/
struct cus;
struct conf_load;
int dwarf__load_filename(struct cus *self, const char *filename);
int dwarf__load(struct cus *self, char *filenames[]);
int dwarf__load(struct cus *self, struct conf_load *conf, char *filenames[]);
#endif /* _DWARF_LOADER_H_ */

View File

@ -517,8 +517,7 @@ int cu__add_tag(struct cu *self, struct tag *tag, long *id)
}
struct cu *cu__new(const char *name, uint8_t addr_size,
const unsigned char *build_id,
int build_id_len)
const unsigned char *build_id, int build_id_len)
{
struct cu *self = malloc(sizeof(*self) + build_id_len);
@ -541,6 +540,7 @@ struct cu *cu__new(const char *name, uint8_t addr_size,
INIT_LIST_HEAD(&self->tool_list);
self->addr_size = addr_size;
self->extra_dbg_info = 0;
self->nr_inline_expansions = 0;
self->size_inline_expansions = 0;
@ -2588,9 +2588,9 @@ int cus__load(struct cus *self, const char *filename)
return err;
}
int cus__loadfl(struct cus *self, char *filenames[])
int cus__loadfl(struct cus *self, struct conf_load *conf, char *filenames[])
{
int err = dwarf__load(self, filenames);
int err = dwarf__load(self, conf, filenames);
/*
* If dwarf__load fails, try ctf__load. Eventually we should just
* register all the shared objects at some directory and ask them
@ -2601,7 +2601,7 @@ int cus__loadfl(struct cus *self, char *filenames[])
* by looking at the list of CUs found:
*/
if (list_empty(&self->cus))
err = ctf__load(self, filenames);
err = ctf__load(self, conf, filenames);
return err;
}

View File

@ -21,6 +21,14 @@
extern struct strings *strings;
/** 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;
};
struct cus {
struct list_head cus;
};
@ -104,6 +112,7 @@ struct cu {
void *priv;
struct cu_orig_info *orig_info;
uint8_t addr_size;
uint8_t extra_dbg_info:1;
uint16_t language;
unsigned long nr_inline_expansions;
size_t size_inline_expansions;
@ -665,7 +674,8 @@ extern size_t lexblock__fprintf(const struct lexblock *self,
const struct cu *cu, struct function *function,
uint16_t indent, FILE *fp);
extern int cus__loadfl(struct cus *self, char *filenames[]);
extern int cus__loadfl(struct cus *self, struct conf_load *conf,
char *filenames[]);
extern int cus__load(struct cus *self, const char *filename);
extern int cus__load_dir(struct cus *self, const char *dirname,
const char *filename_mask, const int recursive);

View File

@ -57,6 +57,8 @@ static struct conf_fprintf conf = {
.emit_stats = 1,
};
static struct conf_load conf_load;
struct structure {
struct list_head node;
struct class *class;
@ -988,13 +990,14 @@ static error_t pahole__options_parser(int key, char *arg,
case 'c': cacheline_size = atoi(arg); break;
case 'D': decl_exclude_prefix = arg;
decl_exclude_prefix_len = strlen(decl_exclude_prefix);
break;
conf_load.extra_dbg_info = 1; break;
case 'd': recursive = 1; break;
case 'E': conf.expand_types = 1; break;
case 'f': find_pointers_in_structs = 1;
class_name = arg; break;
case 'H': nr_holes = atoi(arg); break;
case 'I': conf.show_decl_info = 1; break;
case 'I': conf.show_decl_info = 1;
conf_load.extra_dbg_info = 1; break;
case 'i': find_containers = 1;
class_name = arg; break;
case 'l': conf.show_first_biggest_size_base_type_member = 1; break;
@ -1002,8 +1005,10 @@ static error_t pahole__options_parser(int key, char *arg,
case 'm': formatter = nr_methods_formatter; break;
case 'N': formatter = class_name_len_formatter; break;
case 'n': formatter = nr_members_formatter; break;
case 'O': class_dwarf_offset = strtoul(arg, NULL, 0); break;
case 'P': show_packable = 1; break;
case 'O': class_dwarf_offset = strtoul(arg, NULL, 0);
conf_load.extra_dbg_info = 1; break;
case 'P': show_packable = 1;
conf_load.extra_dbg_info = 1; break;
case 'p': conf.expand_pointers = 1; break;
case 'q': conf.emit_stats = 0;
conf.suppress_comments = 1;
@ -1061,7 +1066,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + remaining);
err = cus__loadfl(cus, &conf_load, argv + remaining);
if (err != 0) {
fputs("pahole: No debugging information found\n", stderr);
return EXIT_FAILURE;

View File

@ -112,7 +112,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + remaining);
err = cus__loadfl(cus, NULL, argv + remaining);
if (err != 0)
return EXIT_FAILURE;

View File

@ -29,6 +29,8 @@ static struct type_emissions emissions;
static struct conf_fprintf conf;
static struct conf_load conf_load;
struct fn_stats {
struct list_head node;
struct tag *tag;
@ -476,13 +478,16 @@ static error_t pfunct__options_parser(int key, char *arg,
case 'g': formatter = fn_stats_labels_fmtr; break;
case 'G': show_cc_uninlined = 1; break;
case 'H': show_cc_inlined = 1; break;
case 'i': show_inline_expansions = verbose = 1; break;
case 'i': show_inline_expansions = verbose = 1;
conf_load.extra_dbg_info = 1; break;
case 'I': formatter = fn_stats_inline_exps_fmtr; break;
case 'l': conf.show_decl_info = 1; break;
case 'l': conf.show_decl_info = 1;
conf_load.extra_dbg_info = 1; break;
case 't': show_total_inline_expansion_stats = 1; break;
case 'T': show_variables = 1; break;
case 'N': formatter = fn_stats_name_len_fmtr; break;
case 'V': verbose = 1; break;
case 'V': verbose = 1;
conf_load.extra_dbg_info = 1; break;
default: return ARGP_ERR_UNKNOWN;
}
@ -513,7 +518,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + remaining);
err = cus__loadfl(cus, &conf_load, argv + remaining);
if (err != 0)
return EXIT_FAILURE;

View File

@ -330,7 +330,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + remaining);
err = cus__loadfl(cus, NULL, argv + remaining);
if (err != 0)
return EXIT_FAILURE;

View File

@ -155,7 +155,7 @@ int main(int argc __unused, char *argv[])
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + 1);
err = cus__loadfl(cus, NULL, argv + 1);
if (err != 0)
return EXIT_FAILURE;

View File

@ -159,7 +159,7 @@ int main(int argc, char *argv[])
argp_help(&argp, stderr, ARGP_HELP_SEE, argv[0]);
return EXIT_FAILURE;
}
err = cus__loadfl(cus, argv + remaining);
err = cus__loadfl(cus, NULL, argv + remaining);
if (err != 0)
return EXIT_FAILURE;