- Timestamp:
- Oct 13, 2008 3:58:07 AM (16 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/file.c
r1851 r1857 41 41 /* Hash table of files the makefile knows how to make. */ 42 42 43 #ifndef KMK 43 44 static unsigned long 44 45 file_hash_1 (const void *key) … … 56 57 file_hash_cmp (const void *x, const void *y) 57 58 { 58 #ifdef KMK 59 /* since the names live in the strcache, there is a raging likelylood 60 that we'll match on the string pointer. Which is wee bit faster... */ 61 struct file const *xf = ((struct file const *) x); 62 struct file const *yf = ((struct file const *) y); 59 return_ISTRING_COMPARE (((struct file const *) x)->hname, 60 ((struct file const *) y)->hname); 61 } 62 #else /* KMK */ 63 64 static unsigned long 65 file_hash_1 (const void *key) 66 { 67 struct file const *f = (struct file const *)key; 68 69 /* If it's cached, get the hash from the strcache. */ 70 if (f->name != (const char *)f) 71 return strcache_get_hash1 (f->hname); 72 73 return_ISTRING_HASH_1 (f->hname); 74 } 75 76 static unsigned long 77 file_hash_2 (const void *key) 78 { 79 struct file const *f = (struct file const *)key; 80 81 /* If it's cached, get the hash from the strcache. */ 82 if (f->name != (const char *)f) 83 return strcache_get_hash2 (f->hname); 84 85 return_ISTRING_HASH_2 (f->hname); 86 } 87 88 static int 89 file_hash_cmp (const void *x, const void *y) 90 { 91 struct file const *xf = ((struct file const *) x); 92 struct file const *yf = ((struct file const *) y); 93 94 /* The file name strings all live in the strcache. However, 95 lookup_file may or may not have a string from the cache. It indicates 96 that it's responsible for the lookup by setting file::name to point 97 to the file structure itself. So, when file::name points elsewhere 98 we can omit the string compare, while when it isn't we can only 99 check if they match that way. */ 100 63 101 if (xf->hname == yf->hname) 64 102 return 0; 103 if ( xf->name != (const char *)xf 104 && yf->name != (const char *)yf) 105 return 1; 106 65 107 return_ISTRING_COMPARE (xf->hname, yf->hname); 66 #else 67 return_ISTRING_COMPARE (((struct file const *) x)->hname, 68 ((struct file const *) y)->hname); 69 #endif 70 } 108 } 109 110 #endif /* KMK */ 71 111 72 112 #ifndef FILE_BUCKETS … … 83 123 */ 84 124 125 #ifndef KMK 85 126 struct file * 86 127 lookup_file (const char *name) 128 #else /* KMK */ 129 MY_INLINE struct file * 130 lookup_file_common (const char *name, int cached) 131 #endif /* KMK */ 87 132 { 88 133 struct file *f; … … 132 177 #endif 133 178 179 #ifdef KMK 180 /* uncached lookup indicator hack. */ 181 file_key.name = !cached ? (const char *)&file_key : NULL; 182 #endif 134 183 file_key.hname = name; 135 184 f = hash_find_item (&files, &file_key); … … 141 190 return f; 142 191 } 192 193 #ifdef KMK 194 /* Given a name, return the struct file * for that name, 195 or nil if there is none. */ 196 197 struct file * 198 lookup_file (const char *name) 199 { 200 return lookup_file_common (name, 0 /* cached */); 201 } 202 203 /* Given a name in the strcache, return the struct file * for that name, 204 or nil if there is none. */ 205 struct file * 206 lookup_file_cached (const char *name) 207 { 208 assert (strcache_iscached (name)); 209 return lookup_file_common (name, 1 /* cached */); 210 } 211 #endif /* KMK */ 212 143 213 144 214 /* Look up a file record for file NAME and return it. … … 222 292 struct file *deleted_file; 223 293 struct file *f; 294 295 #ifdef KMK 296 assert (strcache_iscached (to_hname)); 297 assert (strcache_iscached (from_file->hname)); 298 file_key.name = NULL; /* cached lookup indicator hack. */ 299 #endif 224 300 225 301 /* If it's already that name, we're done. */ -
trunk/src/kmk/filedef.h
r1701 r1857 107 107 by the explicit multi target rule. */ 108 108 #endif 109 #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION 110 unsigned int need_2nd_target_expansion:1; /* Nonzero if this file needs 109 #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION 110 unsigned int need_2nd_target_expansion:1; /* Nonzero if this file needs 111 111 second expansion of its name. Whether it 112 112 can receive this is decided at parse time, … … 122 122 123 123 struct file *lookup_file (const char *name); 124 #ifdef KMK 125 struct file *lookup_file_cached (const char *name); 126 #endif 124 127 struct file *enter_file (const char *name); 125 128 struct dep *parse_prereqs (char *prereqs); -
trunk/src/kmk/make.h
r1854 r1857 511 511 #endif 512 512 #ifdef CONFIG_WITH_VALUE_LENGTH 513 struct strcache_pref 514 { 515 unsigned long hash1; 516 unsigned long hash2; 517 unsigned int len; 518 }; 519 520 int strcache_check_sanity (const char *str); 521 unsigned long strcache_get_hash2_fallback (const char *str); 522 513 523 MY_INLINE unsigned int strcache_get_len (const char *str) 514 524 { 515 unsigned int len = ((unsigned int *)str)[-1];516 MY_ASSERT_MSG (strcache_iscached (str), ("\n"));517 MY_ASSERT_MSG (str len (str) == len, ("\n"));525 struct strcache_pref const *prefix = (struct strcache_pref const *)str - 1; 526 unsigned int len = prefix->len; 527 MY_ASSERT_MSG (strcache_check_sanity (str) == 0, ("!\n")); 518 528 return len; 519 529 } 530 531 MY_INLINE unsigned int strcache_get_hash1 (const char *str) 532 { 533 struct strcache_pref const *prefix = (struct strcache_pref const *)str - 1; 534 unsigned long hash1 = prefix->hash1; 535 MY_ASSERT_MSG (strcache_check_sanity (str) == 0, ("!\n")); 536 return hash1; 537 } 538 539 MY_INLINE unsigned long strcache_get_hash2 (const char *str) 540 { 541 struct strcache_pref const *prefix = (struct strcache_pref const *)str - 1; 542 unsigned long hash2 = prefix->hash2; 543 MY_ASSERT_MSG (strcache_check_sanity (str) == 0, ("!\n")); 544 if (!hash2) 545 return strcache_get_hash2_fallback (str); 546 return hash2; 547 } 548 520 549 #endif 521 550 -
trunk/src/kmk/read.c
r1853 r1857 418 418 deps->next = read_makefiles; 419 419 read_makefiles = deps; 420 #ifndef KMK 420 421 deps->file = lookup_file (filename); 422 #else 423 deps->file = lookup_file_cached (filename); 424 #endif 421 425 if (deps->file == 0) 422 426 deps->file = enter_file (filename); … … 2302 2306 new entry if the file is a double-colon, which we don't want in 2303 2307 this situation. */ 2308 #ifndef KMK 2304 2309 f = lookup_file (name); 2305 2310 if (!f) 2306 2311 f = enter_file (strcache_add (name)); 2312 #else /* KMK */ 2313 /* XXX: this is probably already a cached string. */ 2314 fname = strcache_add (name); 2315 f = lookup_file_cached (fname); 2316 if (!f) 2317 f = enter_file (fname); 2318 #endif 2307 2319 else if (f->double_colon) 2308 2320 f = f->double_colon; … … 2645 2657 { 2646 2658 /* Double-colon. Make a new record even if there already is one. */ 2659 #ifndef KMK 2647 2660 f = lookup_file (name); 2661 #else /* KMK - the name is already in the cache, don't waste time. */ 2662 f = lookup_file_cached (name); 2663 #endif 2648 2664 2649 2665 /* Check for both : and :: rules. Check is_target so … … 2652 2668 fatal (flocp, 2653 2669 _("target file `%s' has both : and :: entries"), f->name); 2670 #ifndef KMK 2654 2671 f = enter_file (strcache_add (name)); 2672 #else /* KMK - the name is already in the cache, don't waste time. */ 2673 f = enter_file (name); 2674 #endif 2655 2675 /* If there was an existing entry and it was a double-colon entry, 2656 2676 enter_file will have returned a new one, making it the prev -
trunk/src/kmk/remake.c
r1110 r1857 386 386 if (file->multi_head != NULL && file->multi_head != file) 387 387 { 388 DBS (DB_VERBOSE, (_("Considering target file `%s' -> multi head `%s'.\n"), 388 DBS (DB_VERBOSE, (_("Considering target file `%s' -> multi head `%s'.\n"), 389 389 file->name, file->multi_head->name)); 390 390 file = file->multi_head; … … 505 505 506 506 /* Update all non-intermediate files we depend on, if necessary, 507 and see whether any of them is more recent than this file. 507 and see whether any of them is more recent than this file. 508 508 For explicit multitarget rules we must iterate all the output 509 509 files to get the correct picture. */ … … 523 523 int maybe_make; 524 524 int dontcare = 0; 525 525 526 526 check_renamed (d->file); 527 527 528 528 mtime = file_mtime (d->file); 529 529 check_renamed (d->file); 530 530 531 531 if (is_updating (d->file)) 532 532 { … … 561 561 continue; 562 562 } 563 563 564 564 #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET 565 565 d->file->parent = f2; … … 568 568 #endif 569 569 maybe_make = must_make; 570 570 571 571 /* Inherit dontcare flag from our parent. */ 572 572 if (rebuilding_makefiles) … … 575 575 d->file->dontcare = file->dontcare; 576 576 } 577 578 577 578 579 579 dep_status |= check_dep (d->file, depth, this_mtime, &maybe_make); 580 580 581 581 /* Restore original dontcare flag. */ 582 582 if (rebuilding_makefiles) 583 583 d->file->dontcare = dontcare; 584 584 585 585 if (! d->ignore_mtime) 586 586 must_make = maybe_make; 587 587 588 588 check_renamed (d->file); 589 589 590 590 { 591 591 register struct file *f = d->file; … … 600 600 while (f != 0); 601 601 } 602 602 603 603 if (dep_status != 0 && !keep_going_flag) 604 604 break; 605 605 606 606 if (!running) 607 607 /* The prereq is considered changed if the timestamp has changed while … … 609 609 d->changed = ((file_mtime (d->file) != mtime) 610 610 || (mtime == NONEXISTENT_MTIME)); 611 611 612 612 lastd = d; 613 613 d = d->next; … … 633 633 { 634 634 int dontcare = 0; 635 635 636 636 FILE_TIMESTAMP mtime = file_mtime (d->file); 637 637 check_renamed (d->file); … … 641 641 d->file->parent = file; 642 642 #endif 643 643 644 644 /* Inherit dontcare flag from our parent. */ 645 645 if (rebuilding_makefiles) … … 648 648 d->file->dontcare = file->dontcare; 649 649 } 650 651 650 651 652 652 dep_status |= update_file (d->file, depth); 653 653 654 654 /* Restore original dontcare flag. */ 655 655 if (rebuilding_makefiles) 656 656 d->file->dontcare = dontcare; 657 657 658 658 check_renamed (d->file); 659 659 660 660 { 661 661 register struct file *f = d->file; … … 670 670 while (f != 0); 671 671 } 672 672 673 673 if (dep_status != 0 && !keep_going_flag) 674 674 break; 675 675 676 676 if (!running) 677 677 #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET … … 741 741 #endif 742 742 check_renamed (d->file); 743 743 744 744 if (! d->ignore_mtime) 745 745 { … … 753 753 must_make = 1; 754 754 #endif 755 755 756 756 /* Set DEPS_CHANGED if this dep actually changed. */ 757 757 deps_changed |= d->changed; 758 758 } 759 759 760 760 /* Set D->changed if either this dep actually changed, 761 761 or its dependent, FILE, is older or does not exist. */ 762 762 d->changed |= noexist || d_mtime > this_mtime; 763 763 764 764 if (!noexist && ISDB (DB_BASIC|DB_VERBOSE)) 765 765 { 766 766 const char *fmt = 0; 767 767 768 768 if (d->ignore_mtime) 769 769 { … … 783 783 else if (ISDB (DB_VERBOSE)) 784 784 fmt = _("Prerequisite `%s' is older than target `%s'.\n"); 785 785 786 786 if (fmt) 787 787 { -
trunk/src/kmk/strcache.c
r1854 r1857 61 61 } 62 62 63 #ifndef CONFIG_WITH_VALUE_LENGTH 63 64 static const char * 64 65 add_string(const char *str, int len) … … 67 68 struct strcache *sp; 68 69 const char *res; 69 #ifdef CONFIG_WITH_VALUE_LENGTH70 int str_len = len;71 char *tmp;72 73 /* Add space a length prefix and the terminator and assure74 (somewhat) natural alignment. */75 len += sizeof(unsigned int) + 1;76 len = (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1);77 --len;78 #endif79 70 80 71 /* If the string we want is too large to fit into a single buffer, then … … 98 89 99 90 /* Add the string to the best cache. */ 100 #ifndef CONFIG_WITH_VALUE_LENGTH101 91 res = best->end; 102 92 memcpy (best->end, str, len); … … 105 95 best->bytesfree -= len + 1; 106 96 ++best->count; 97 return res; 98 } 99 107 100 #else /* CONFIG_WITH_VALUE_LENGTH */ 108 tmp = best->end; 109 best->end += len + 1; 110 assert(!((size_t)tmp & (sizeof(void *) - 1))); 111 112 *(unsigned int *)tmp = str_len; /* length prefix */ 113 tmp += sizeof(unsigned int); 114 115 res = tmp; 116 memcpy (tmp, str, str_len); 117 tmp += str_len; 118 *(tmp++) = '\0'; 119 120 best->bytesfree -= len + 1; 101 102 static const char * 103 add_string(const char *str, struct strcache_pref *prefix) 104 { 105 struct strcache *best = NULL; 106 struct strcache *sp; 107 struct strcache_pref *real_prefix; 108 int len; 109 const char *res; 110 char *dst; 111 112 /* Calc the entry length; the prefix data + the string + alignment. */ 113 len = sizeof(struct strcache_pref) + prefix->len + 1; 114 len = (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 115 116 /* If the string we want is too large to fit into a single buffer, then 117 we're screwed; nothing will ever fit! Change the maximum size of the 118 cache to be big enough. */ 119 if (len > bufsize) 120 bufsize = len * 2; 121 122 /* First, find a cache with enough free space. We always look through all 123 the blocks and choose the one with the best fit (the one that leaves the 124 least amount of space free). */ 125 for (sp = strcache; sp != NULL; sp = sp->next) 126 if (sp->bytesfree >= len && (!best || best->bytesfree > sp->bytesfree)) 127 best = sp; 128 129 /* If nothing is big enough, make a new cache. */ 130 if (!best) 131 best = new_cache(); 132 133 assert (best->bytesfree >= len); 134 135 /* Add the string to the best cache. */ 136 real_prefix = (struct strcache_pref *)best->end; 137 *real_prefix = *prefix; 138 139 res = dst = (char *)(real_prefix + 1); 140 assert(!((size_t)res & (sizeof(void *) - 1))); 141 memcpy (dst, str, prefix->len); 142 dst += prefix->len; 143 *(dst++) = '\0'; 144 145 best->end += len; 146 best->bytesfree -= len; 121 147 ++best->count; 122 148 123 assert (tmp <= best->end);124 assert (!((size_t)res & (sizeof(void *) - 1)));125 #endif /* CONFIG_WITH_VALUE_LENGTH */126 149 return res; 127 150 } 128 151 129 130 /* Hash table of strings in the cache. */131 132 #ifdef CONFIG_WITH_VALUE_LENGTH133 152 /* Hackish globals for passing data to the hash functions. 134 153 There isn't really any other way without running the 135 154 risk of breaking rehashing. */ 136 155 static const char *lookup_string; 137 static unsigned int lookup_string_len; 138 # ifdef CONFIG_WITH_INCLUDEDEP 139 static unsigned long lookup_string_hash1; 140 static unsigned long lookup_string_hash2; 141 # endif /* CONFIG_WITH_INCLUDEDEP */ 156 static struct strcache_pref *lookup_prefix; 157 142 158 #endif /* CONFIG_WITH_VALUE_LENGTH */ 159 160 161 /* Hash table of strings in the cache. */ 143 162 144 163 static unsigned long 145 164 str_hash_1 (const void *key) 146 165 { 147 #ifdef CONFIG_WITH_ INCLUDEDEP148 if ( (const char *) key == lookup_string && lookup_string_hash1)149 return lookup_ string_hash1;166 #ifdef CONFIG_WITH_VALUE_LENGTH 167 if (MY_PREDICT_TRUE ((const char *) key == lookup_string)) 168 return lookup_prefix->hash1; 150 169 #endif 151 170 return_ISTRING_HASH_1 ((const char *) key); … … 155 174 str_hash_2 (const void *key) 156 175 { 157 #ifdef CONFIG_WITH_INCLUDEDEP 158 if ((const char *) key == lookup_string && lookup_string_hash2) 159 return lookup_string_hash2; 176 #ifdef CONFIG_WITH_VALUE_LENGTH 177 if (MY_PREDICT_TRUE ((const char *) key == lookup_string)) 178 { 179 if (lookup_prefix->hash2) 180 { 181 unsigned long hash2 = 0; 182 ISTRING_HASH_2 ((const char *)key, hash2); 183 lookup_prefix->hash2 = hash2; 184 } 185 return lookup_prefix->hash2; 186 } 160 187 #endif 161 188 return_ISTRING_HASH_2 ((const char *) key); … … 172 199 kBuild scenario. */ 173 200 174 if ( (const char *) x == lookup_string)175 { 176 assert (lookup_ string_len == strlen ((const char *)x));177 if (strcache_get_len ((const char *)y) != lookup_ string_len)201 if (MY_PREDICT_TRUE ((const char *) x == lookup_string)) 202 { 203 assert (lookup_prefix->len == strlen ((const char *)x)); 204 if (strcache_get_len ((const char *)y) != lookup_prefix->len) 178 205 return -1; 179 206 } … … 185 212 static unsigned long total_adds = 0; 186 213 214 #ifndef CONFIG_WITH_VALUE_LENGTH 187 215 static const char * 188 216 add_hash (const char *str, int len) 189 217 { 190 218 /* Look up the string in the hash. If it's there, return it. */ 191 #ifndef CONFIG_WITH_VALUE_LENGTH192 219 char *const *slot = (char *const *) hash_find_slot (&strings, str); 193 220 const char *key = *slot; 194 #else /* CONFIG_WITH_VALUE_LENGTH */195 char *const *slot;196 const char *key;197 198 lookup_string = str;199 lookup_string_len = len;200 slot = (char *const *) hash_find_slot (&strings, str);201 key = *slot;202 #endif /* CONFIG_WITH_VALUE_LENGTH */203 221 204 222 /* Count the total number of adds we performed. */ … … 213 231 return key; 214 232 } 233 234 #else /* CONFIG_WITH_VALUE_LENGTH */ 235 236 static const char * 237 add_hash (const char *str, int len, unsigned long hash1, unsigned long hash2) 238 { 239 char *const *slot; 240 const char *key; 241 struct strcache_pref prefix; 242 243 /* Look up the string in the hash. If it's there, return it. */ 244 prefix.len = len; 245 prefix.hash2 = hash2; 246 if (!hash1 && !hash2) 247 ISTRING_HASH_1 (str, hash1); 248 prefix.hash1 = hash1; 249 250 lookup_string = str; 251 lookup_prefix = &prefix; 252 253 slot = (char *const *) hash_find_slot (&strings, str); 254 key = *slot; 255 256 /* Count the total number of adds we performed. */ 257 ++total_adds; 258 259 if (!HASH_VACANT (key)) 260 return key; 261 262 /* Not there yet so add it to a buffer, then into the hash table. */ 263 key = add_string (str, &prefix); 264 hash_insert_at (&strings, key, slot); 265 return key; 266 } 267 268 /* Verifies that a string cache entry didn't change and that the 269 prefix is still valid. */ 270 int 271 strcache_check_sanity (const char *str) 272 { 273 struct strcache_pref const *prefix = (struct strcache_pref const *)str - 1; 274 unsigned long hash; 275 276 if (strlen (str) != prefix->len) 277 { 278 MY_ASSERT_MSG (0, ("len: %u != %u - '%s'\n", (unsigned int)strlen (str), 279 prefix->len, str)); 280 return -1; 281 } 282 283 hash = 0; 284 ISTRING_HASH_1 (str, hash); 285 if (hash != prefix->hash1) 286 { 287 MY_ASSERT_MSG (0, ("hash1: %lx != %lx - '%s'\n", hash, prefix->hash1, str)); 288 return -1; 289 } 290 291 if (prefix->hash2) 292 { 293 hash = 0; 294 ISTRING_HASH_2 (str, hash); 295 if (hash != prefix->hash2) 296 { 297 MY_ASSERT_MSG (0, ("hash2: %lx != %lx - '%s'\n", hash, prefix->hash2, str)); 298 return -1; 299 } 300 } 301 302 return 0; 303 } 304 305 /* Fallback for when the hash2 value isn't present. */ 306 unsigned long 307 strcache_get_hash2_fallback (const char *str) 308 { 309 struct strcache_pref *prefix = (struct strcache_pref *)str - 1; 310 unsigned long hash2 = 0; 311 312 ISTRING_HASH_2 (str, hash2); 313 prefix->hash2 = hash2; 314 315 return hash2; 316 } 317 318 #endif /* CONFIG_WITH_VALUE_LENGTH */ 215 319 216 320 /* Returns true if the string is in the cache; false if not. */ … … 233 337 strcache_add (const char *str) 234 338 { 339 #ifndef CONFIG_WITH_VALUE_LENGTH 235 340 return add_hash (str, strlen (str)); 341 #else 342 /* XXX: calc the hash1 while determining the string length. */ 343 return add_hash (str, strlen (str), 0, 0); 344 #endif 236 345 } 237 346 … … 249 358 } 250 359 360 #ifndef CONFIG_WITH_VALUE_LENGTH 251 361 return add_hash (str, len); 362 #else 363 /* XXX: eliminate the alloca mess using the prefixing? */ 364 return add_hash (str, len, 0, 0); 365 #endif 252 366 } 253 367 … … 260 374 unsigned long hash2) 261 375 { 262 const char *retstr; 263 264 assert (hash1 == str_hash_1 (str)); 265 assert (hash2 == str_hash_2 (str)); 266 267 lookup_string_hash1 = hash1; 268 lookup_string_hash2 = hash2; 269 270 retstr = add_hash (str, len); 271 272 lookup_string_hash1 = 0; 273 lookup_string_hash2 = 0; 274 275 return retstr; 376 return add_hash (str, len, hash1, hash2); 276 377 } 277 378
Note:
See TracChangeset
for help on using the changeset viewer.