On Tue, Aug 21, 2012 at 6:25 AM, Richard Guenther <richard.guent...@gmail.com> wrote: > On Mon, Aug 20, 2012 at 3:18 AM, Dehao Chen <de...@google.com> wrote: >> ping.... > > Conceptually I like the change. Can a libcpp maintainer please have a 2nd > look? > > Dehao, did you do any compile-time and memory-usage benchmarks?
I don't have a memory benchmarks at hand. But I've tested it through some huge apps, each of which takes more than 1 hour to build on a modern machine. None of them had observed noticeable memory footprint and compile time increase. Thanks, Dehao > > Thanks, > Richard. > >> Thanks, >> Dehao >> >> On Tue, Aug 14, 2012 at 10:13 AM, Dehao Chen <de...@google.com> wrote: >>> Hi, Dodji, >>> >>> Thanks for the review. I've fixed all the addressed issues. I'm >>> attaching the related changes: >>> >>> Thanks, >>> Dehao >>> >>> libcpp/ChangeLog: >>> 2012-08-01 Dehao Chen <de...@google.com> >>> >>> * include/line-map.h (MAX_SOURCE_LOCATION): New value. >>> (location_adhoc_data_init): New. >>> (location_adhoc_data_fini): New. >>> (get_combined_adhoc_loc): New. >>> (get_data_from_adhoc_loc): New. >>> (get_location_from_adhoc_loc): New. >>> (COMBINE_LOCATION_DATA): New. >>> (IS_ADHOC_LOC): New. >>> (expanded_location): New field. >>> * line-map.c (location_adhoc_data): New. >>> (location_adhoc_data_htab): New. >>> (curr_adhoc_loc): New. >>> (location_adhoc_data): New. >>> (allocated_location_adhoc_data): New. >>> (location_adhoc_data_hash): New. >>> (location_adhoc_data_eq): New. >>> (location_adhoc_data_update): New. >>> (get_combined_adhoc_loc): New. >>> (get_data_from_adhoc_loc): New. >>> (get_location_from_adhoc_loc): New. >>> (location_adhoc_data_init): New. >>> (location_adhoc_data_fini): New. >>> (linemap_lookup): Change to use new location. >>> (linemap_ordinary_map_lookup): Likewise. >>> (linemap_macro_map_lookup): Likewise. >>> (linemap_macro_map_loc_to_def_point): Likewise. >>> (linemap_macro_map_loc_unwind_toward_spel): Likewise. >>> (linemap_get_expansion_line): Likewise. >>> (linemap_get_expansion_filename): Likewise. >>> (linemap_location_in_system_header_p): Likewise. >>> (linemap_location_from_macro_expansion_p): Likewise. >>> (linemap_macro_loc_to_spelling_point): Likewise. >>> (linemap_macro_loc_to_def_point): Likewise. >>> (linemap_macro_loc_to_exp_point): Likewise. >>> (linemap_resolve_location): Likewise. >>> (linemap_unwind_toward_expansion): Likewise. >>> (linemap_unwind_to_first_non_reserved_loc): Likewise. >>> (linemap_expand_location): Likewise. >>> (linemap_dump_location): Likewise. >>> >>> Index: libcpp/line-map.c >>> =================================================================== >>> --- libcpp/line-map.c (revision 190209) >>> +++ libcpp/line-map.c (working copy) >>> @@ -25,6 +25,7 @@ >>> #include "line-map.h" >>> #include "cpplib.h" >>> #include "internal.h" >>> +#include "hashtab.h" >>> >>> static void trace_include (const struct line_maps *, const struct line_map >>> *); >>> static const struct line_map * linemap_ordinary_map_lookup (struct >>> line_maps *, >>> @@ -50,6 +51,135 @@ >>> extern unsigned num_expanded_macros_counter; >>> extern unsigned num_macro_tokens_counter; >>> >>> +/* Data structure to associate an arbitrary data to a source location. */ >>> +struct location_adhoc_data { >>> + source_location locus; >>> + void *data; >>> +}; >>> + >>> +/* The following data structure encodes a location with some adhoc data >>> + and maps it to a new unsigned integer (called an adhoc location) >>> + that replaces the original location to represent the mapping. >>> + >>> + The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the >>> + highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as >>> + the original location. Once identified as the adhoc_loc, the lower 31 >>> + bits of the integer is used to index the location_adhoc_data array, >>> + in which the locus and associated data is stored. */ >>> + >>> +static htab_t location_adhoc_data_htab; >>> +static source_location curr_adhoc_loc; >>> +static struct location_adhoc_data *location_adhoc_data; >>> +static unsigned int allocated_location_adhoc_data; >>> + >>> +/* Hash function for location_adhoc_data hashtable. */ >>> + >>> +static hashval_t >>> +location_adhoc_data_hash (const void *l) >>> +{ >>> + const struct location_adhoc_data *lb = >>> + (const struct location_adhoc_data *) l; >>> + return (hashval_t) lb->locus + (size_t) &lb->data; >>> +} >>> + >>> +/* Compare function for location_adhoc_data hashtable. */ >>> + >>> +static int >>> +location_adhoc_data_eq (const void *l1, const void *l2) >>> +{ >>> + const struct location_adhoc_data *lb1 = >>> + (const struct location_adhoc_data *) l1; >>> + const struct location_adhoc_data *lb2 = >>> + (const struct location_adhoc_data *) l2; >>> + return lb1->locus == lb2->locus && lb1->data == lb2->data; >>> +} >>> + >>> +/* Update the hashtable when location_adhoc_data is reallocated. */ >>> + >>> +static int >>> +location_adhoc_data_update (void **slot, void *data) >>> +{ >>> + *((char **) slot) += ((char *) location_adhoc_data - (char *) data); >>> + return 1; >>> +} >>> + >>> +/* Combine LOCUS and DATA to a combined adhoc loc. */ >>> + >>> +source_location >>> +get_combined_adhoc_loc (source_location locus, void *data) >>> +{ >>> + struct location_adhoc_data lb; >>> + struct location_adhoc_data **slot; >>> + >>> + linemap_assert (data); >>> + >>> + if (IS_ADHOC_LOC (locus)) >>> + locus = location_adhoc_data[locus & MAX_SOURCE_LOCATION].locus; >>> + if (locus == 0 && data == NULL) >>> + return 0; >>> + lb.locus = locus; >>> + lb.data = data; >>> + slot = (struct location_adhoc_data **) >>> + htab_find_slot (location_adhoc_data_htab, &lb, INSERT); >>> + if (*slot == NULL) >>> + { >>> + *slot = location_adhoc_data + curr_adhoc_loc; >>> + location_adhoc_data[curr_adhoc_loc] = lb; >>> + if (++curr_adhoc_loc >= allocated_location_adhoc_data) >>> + { >>> + char *orig_location_adhoc_data = (char *) location_adhoc_data; >>> + allocated_location_adhoc_data *= 2; >>> + location_adhoc_data = XRESIZEVEC (struct location_adhoc_data, >>> + location_adhoc_data, >>> + allocated_location_adhoc_data); >>> + htab_traverse (location_adhoc_data_htab, >>> location_adhoc_data_update, >>> + orig_location_adhoc_data); >>> + } >>> + } >>> + return ((*slot) - location_adhoc_data) | 0x80000000; >>> +} >>> + >>> +/* Return the data for the adhoc loc. */ >>> + >>> +void * >>> +get_data_from_adhoc_loc (source_location loc) >>> +{ >>> + linemap_assert (IS_ADHOC_LOC (loc)); >>> + return location_adhoc_data[loc & MAX_SOURCE_LOCATION].data; >>> +} >>> + >>> +/* Return the location for the adhoc loc. */ >>> + >>> +source_location >>> +get_location_from_adhoc_loc (source_location loc) >>> +{ >>> + linemap_assert (IS_ADHOC_LOC (loc)); >>> + return location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> +} >>> + >>> +/* Initialize the location_adhoc_data structure. */ >>> + >>> +void >>> +location_adhoc_data_init (void) >>> +{ >>> + location_adhoc_data_htab = htab_create (100, location_adhoc_data_hash, >>> + location_adhoc_data_eq, NULL); >>> + curr_adhoc_loc = 0; >>> + allocated_location_adhoc_data = 100; >>> + location_adhoc_data = XNEWVEC (struct location_adhoc_data, >>> + allocated_location_adhoc_data); >>> +} >>> + >>> +/* Finalize the location_adhoc_data structure. */ >>> + >>> +void >>> +location_adhoc_data_fini (void) >>> +{ >>> + allocated_location_adhoc_data = 0; >>> + XDELETEVEC (location_adhoc_data); >>> + htab_delete (location_adhoc_data_htab); >>> +} >>> + >>> /* Initialize a line map set. */ >>> >>> void >>> @@ -509,6 +639,8 @@ >>> const struct line_map* >>> linemap_lookup (struct line_maps *set, source_location line) >>> { >>> + if (IS_ADHOC_LOC (line)) >>> + line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus; >>> if (linemap_location_from_macro_expansion_p (set, line)) >>> return linemap_macro_map_lookup (set, line); >>> return linemap_ordinary_map_lookup (set, line); >>> @@ -525,6 +657,9 @@ >>> unsigned int md, mn, mx; >>> const struct line_map *cached, *result; >>> >>> + if (IS_ADHOC_LOC (line)) >>> + line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus; >>> + >>> if (set == NULL || line < RESERVED_LOCATION_COUNT) >>> return NULL; >>> >>> @@ -570,6 +705,9 @@ >>> unsigned int md, mn, mx; >>> const struct line_map *cached, *result; >>> >>> + if (IS_ADHOC_LOC (line)) >>> + line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set)); >>> >>> if (set == NULL) >>> @@ -648,6 +786,9 @@ >>> { >>> unsigned token_no; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (linemap_macro_expansion_map_p (map) >>> && location >= MAP_START_LOCATION (map)); >>> linemap_assert (location >= RESERVED_LOCATION_COUNT); >>> @@ -672,6 +813,9 @@ >>> { >>> unsigned token_no; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (linemap_macro_expansion_map_p (map) >>> && location >= MAP_START_LOCATION (map)); >>> linemap_assert (location >= RESERVED_LOCATION_COUNT); >>> @@ -696,6 +840,9 @@ >>> { >>> const struct line_map *map = NULL; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> if (location < RESERVED_LOCATION_COUNT) >>> return 0; >>> >>> @@ -720,6 +867,9 @@ >>> { >>> const struct line_map *map = NULL; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> if (location < RESERVED_LOCATION_COUNT) >>> return NULL; >>> >>> @@ -754,6 +904,9 @@ >>> { >>> const struct line_map *map = NULL; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> if (location < RESERVED_LOCATION_COUNT) >>> return false; >>> >>> @@ -793,6 +946,9 @@ >>> linemap_location_from_macro_expansion_p (struct line_maps *set, >>> source_location location) >>> { >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (location <= MAX_SOURCE_LOCATION >>> && (set->highest_location >>> < LINEMAPS_MACRO_LOWEST_LOCATION (set))); >>> @@ -933,6 +1089,9 @@ >>> { >>> struct line_map *map; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (set && location >= RESERVED_LOCATION_COUNT); >>> >>> while (true) >>> @@ -967,6 +1126,9 @@ >>> { >>> struct line_map *map; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (set && location >= RESERVED_LOCATION_COUNT); >>> >>> while (true) >>> @@ -1005,6 +1167,9 @@ >>> { >>> struct line_map *map; >>> >>> + if (IS_ADHOC_LOC (location)) >>> + location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus; >>> + >>> linemap_assert (set && location >= RESERVED_LOCATION_COUNT); >>> >>> while (true) >>> @@ -1074,6 +1239,9 @@ >>> enum location_resolution_kind lrk, >>> const struct line_map **map) >>> { >>> + if (IS_ADHOC_LOC (loc)) >>> + loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> + >>> if (loc < RESERVED_LOCATION_COUNT) >>> { >>> /* A reserved location wasn't encoded in a map. Let's return a >>> @@ -1121,6 +1289,9 @@ >>> source_location resolved_location; >>> const struct line_map *resolved_map; >>> >>> + if (IS_ADHOC_LOC (loc)) >>> + loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> + >>> resolved_location = >>> linemap_macro_map_loc_unwind_toward_spelling (*map, loc); >>> resolved_map = linemap_lookup (set, resolved_location); >>> @@ -1157,6 +1328,9 @@ >>> source_location resolved_loc; >>> const struct line_map *map0 = NULL, *map1 = NULL; >>> >>> + if (IS_ADHOC_LOC (loc)) >>> + loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> + >>> map0 = linemap_lookup (set, loc); >>> if (!linemap_macro_expansion_map_p (map0)) >>> return loc; >>> @@ -1198,6 +1372,11 @@ >>> expanded_location xloc; >>> >>> memset (&xloc, 0, sizeof (xloc)); >>> + if (IS_ADHOC_LOC (loc)) >>> + { >>> + loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> + xloc.data = location_adhoc_data[loc & MAX_SOURCE_LOCATION].data; >>> + } >>> >>> if (loc < RESERVED_LOCATION_COUNT) >>> /* The location for this token wasn't generated from a line map. >>> @@ -1290,6 +1469,9 @@ >>> const char *path = "", *from = ""; >>> int l = -1, c = -1, s = -1, e = -1; >>> >>> + if (IS_ADHOC_LOC (loc)) >>> + loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus; >>> + >>> if (loc == 0) >>> return;