static void
profiler_executable_memory_region_destroy (ProfilerExecutableMemoryRegionData *data) {
- if (data->file_name != NULL) {
- g_free (data->file_name);
- }
- if (data->symbols != NULL) {
- g_free (data->symbols);
- }
if (data->file != NULL) {
executable_file_close (data);
data->file = NULL;
regions->next_id ++;
}
+static gboolean
+regions_are_equivalent (ProfilerExecutableMemoryRegionData *region1, ProfilerExecutableMemoryRegionData *region2) {
+ if ((region1->start == region2->start) &&
+ (region1->end == region2->end) &&
+ (region1->file_offset == region2->file_offset) &&
+ ! strcmp (region1->file_name, region2->file_name)) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+static int
+compare_regions (const void *a1, const void *a2) {
+ ProfilerExecutableMemoryRegionData *r1 = * (ProfilerExecutableMemoryRegionData**) a1;
+ ProfilerExecutableMemoryRegionData *r2 = * (ProfilerExecutableMemoryRegionData**) a2;
+ return (r1->start < r2->start)? -1 : ((r1->start > r2->start)? 1 : 0);
+}
+
static void
restore_old_regions (ProfilerExecutableMemoryRegions *old_regions, ProfilerExecutableMemoryRegions *new_regions) {
int old_i;
int new_i;
- for (old_i = 0; old_i < old_regions->regions_count; old_i++) {
- ProfilerExecutableMemoryRegionData *old_region = old_regions->regions [old_i];
- for (new_i = 0; new_i < new_regions->regions_count; new_i++) {
- ProfilerExecutableMemoryRegionData *new_region = new_regions->regions [new_i];
- if ((old_region->start == new_region->start) &&
- (old_region->end == new_region->end) &&
- (old_region->file_offset == new_region->file_offset) &&
- ! strcmp (old_region->file_name, new_region->file_name)) {
+ for (new_i = 0; new_i < new_regions->regions_count; new_i++) {
+ ProfilerExecutableMemoryRegionData *new_region = new_regions->regions [new_i];
+ for (old_i = 0; old_i < old_regions->regions_count; old_i++) {
+ ProfilerExecutableMemoryRegionData *old_region = old_regions->regions [old_i];
+ if ( regions_are_equivalent (old_region, new_region)) {
new_regions->regions [new_i] = old_region;
old_regions->regions [old_i] = new_region;
}
}
-static int
-compare_regions (const void *a1, const void *a2) {
- ProfilerExecutableMemoryRegionData *r1 = * (ProfilerExecutableMemoryRegionData**) a1;
- ProfilerExecutableMemoryRegionData *r2 = * (ProfilerExecutableMemoryRegionData**) a2;
- return (r1->start < r2->start)? -1 : ((r1->start > r2->start)? 1 : 0);
+static void
+sort_regions (ProfilerExecutableMemoryRegions *regions) {
+ if (regions->regions_count > 1) {
+ int i;
+
+ qsort (regions->regions, regions->regions_count, sizeof (ProfilerExecutableMemoryRegionData *), compare_regions);
+
+ i = 1;
+ while (i < regions->regions_count) {
+ ProfilerExecutableMemoryRegionData *current_region = regions->regions [i];
+ ProfilerExecutableMemoryRegionData *previous_region = regions->regions [i - 1];
+
+ if (regions_are_equivalent (previous_region, current_region)) {
+ int j;
+
+ if (! current_region->is_new) {
+ profiler_executable_memory_region_destroy (previous_region);
+ regions->regions [i - 1] = current_region;
+ } else {
+ profiler_executable_memory_region_destroy (current_region);
+ }
+
+ for (j = i + 1; j < regions->regions_count; j++) {
+ regions->regions [j - 1] = regions->regions [j];
+ }
+
+ regions->regions_count --;
+ } else {
+ i++;
+ }
+ }
+ }
}
static void
-sort_regions (ProfilerExecutableMemoryRegions *regions) {
- qsort (regions->regions, regions->regions_count, sizeof (ProfilerExecutableMemoryRegionData *), compare_regions);
+fix_region_references (ProfilerExecutableMemoryRegions *regions) {
+ int i;
+ for (i = 0; i < regions->regions_count; i++) {
+ ProfilerExecutableMemoryRegionData *region = regions->regions [i];
+ if (region->file_region_reference != NULL) {
+ region->file_region_reference->region = region;
+ }
+ }
}
static void
if (file == NULL) {
guint16 test = 0x0102;
- int file_name_length = strlen (region->file_name);
struct stat stat_buffer;
int symtab_index = 0;
int strtab_index = 0;
file->next_new_file = files->new_files;
files->new_files = file;
- /* Skip files whose name doesn't end in ".so" */
- if ((region->file_name [file_name_length - 1] != 'o') || (region->file_name [file_name_length - 2] != 's') || (region->file_name [file_name_length - 3] != '.')) {
- file->fd = -1;
- return file;
- }
-
file->fd = open (region->file_name, O_RDONLY);
if (file->fd == -1) {
//g_warning ("Cannot open file '%s': '%s'", region->file_name, strerror (errno));
executable_file_add_region_reference (file, region);
}
- if (file->next_new_file == NULL) {
- file->next_new_file = files->new_files;
- files->new_files = file;
- }
return file;
}
}
if (file->section_regions != NULL) {
g_free (file->section_regions);
+ file->section_regions = NULL;
}
g_free (file);
}
LOG_WRITER_THREAD ("Refreshing memory regions...");
scan_process_regions (new_regions);
- restore_old_regions (old_regions, new_regions);
sort_regions (new_regions);
+ restore_old_regions (old_regions, new_regions);
+ fix_region_references (new_regions);
LOG_WRITER_THREAD ("Refreshed memory regions.");
LOG_WRITER_THREAD ("Building symbol tables...");
} else {
profiler->flags &= ~MONO_PROFILE_STATISTICAL;
}
+ } else if (! (strcmp (argument, "save-allocation-caller") && strcmp (argument, "sac"))) {
+ profiler->action_flags.save_allocation_caller = TRUE_IF_NOT_MINUS;
} else if (! (strcmp (argument, "save-allocation-stack") && strcmp (argument, "sas"))) {
profiler->action_flags.save_allocation_stack = TRUE_IF_NOT_MINUS;
} else if (! (strcmp (argument, "allocations-carry-id") && strcmp (argument, "aci"))) {