VirtualBox

Changeset 1934 in kBuild


Ignore:
Timestamp:
Oct 24, 2008 10:24:02 PM (16 years ago)
Author:
bird
Message:

kmk: Implemented lazy resolving of $+, $, $? and $|. This saves > 30% memory and also a bit of time.

Location:
trunk/src/kmk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r1932 r1934  
    140140        -DCONFIG_WITH_PRINT_STATS_SWITCH \
    141141        -DCONFIG_WITH_RDONLY_VARIABLE_VALUE \
     142        -DCONFIG_WITH_LAZY_DEP_LISTS \
    142143        \
    143144        -DKBUILD_HOST=\"$(BUILD_TARGET)\" \
  • trunk/src/kmk/Makefile.kmk

    r1932 r1934  
    170170        CONFIG_WITH_PRINT_STATS_SWITCH \
    171171        CONFIG_WITH_RDONLY_VARIABLE_VALUE \
     172        CONFIG_WITH_LAZY_DEPS_VARS \
    172173        \
    173174        KBUILD_HOST=\"$(KBUILD_TARGET)\" \
     
    517518        fi
    518519
    519 
    520 test_all:       test_math test_stack test_shell test_if1of test_local test_includedep test_2ndtargetexp test_30_continued_on_failure
    521 
     520test_lazy_deps_vars:
     521        $(MAKE) -C $(kmk_PATH) -f testcase-lazy-deps-vars.kmk
     522
     523
     524test_all:       test_math test_stack test_shell test_if1of test_local test_includedep test_2ndtargetexp test_30_continued_on_failure test_lazy_deps_vars
     525
     526
  • trunk/src/kmk/commands.c

    r1933 r1934  
    2626#include <windows.h>
    2727#include "w32err.h"
     28#endif
     29#ifdef CONFIG_WITH_LAZY_DEPS_VARS
     30# include <assert.h>
    2831#endif
    2932
     
    175178#endif /* CONFIG_WITH_RDONLY_VARIABLE_VALUE */
    176179
     180#ifndef CONFIG_WITH_LAZY_DEPS_VARS
    177181  /* Compute the values for $^, $+, $?, and $|.  */
    178182
     
    317321  }
    318322
     323#else  /* CONFIG_WITH_LAZY_DEPS_VARS */
     324
     325  /* Make a copy of the current dependency chain for later use in
     326     potential $(dep-pluss $@) calls.  Then drop duplicate deps.  */
     327
     328  /* assert (file->org_deps == NULL); - FIXME? */
     329  free_dep_chain (file->org_deps);
     330  file->org_deps = copy_dep_chain (file->deps);
     331
     332  uniquize_deps (file->deps);
     333
     334#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
    319335#undef  DEFINE_VARIABLE
    320336}
  • trunk/src/kmk/filedef.h

    r1857 r1934  
    3030    const char *vpath;          /* VPATH/vpath pathname */
    3131    struct dep *deps;           /* all dependencies, including duplicates */
     32#ifdef CONFIG_WITH_LAZY_DEPS_VARS
     33    struct dep *org_deps;       /* original dependencies before
     34                                   duplicates were dropped. */
     35#endif
    3236    struct commands *cmds;      /* Commands to execute for this target.  */
    3337    int command_flags;          /* Flags OR'd in for cmds; see commands.h.  */
  • trunk/src/kmk/function.c

    r1932 r1934  
    21852185
    21862186
     2187#ifdef CONFIG_WITH_LAZY_DEPS_VARS
     2188
     2189/* This is also in file.c (bad).  */
     2190# if VMS
     2191#  define FILE_LIST_SEPARATOR ','
     2192# else
     2193#  define FILE_LIST_SEPARATOR ' '
     2194# endif
     2195
     2196/* Implements $^ and $+.
     2197
     2198   The first is somes with with FUNCNAME 'dep', the second as 'dep-all'.
     2199
     2200   If no second argument is given, or if it's empty, or if it's zero,
     2201   all dependencies will be returned.  If the second argument is non-zero
     2202   the dependency at that position will be returned.  If the argument is
     2203   negative a fatal error is thrown.  */
     2204static char *
     2205func_deps (char *o, char **argv, const char *funcname)
     2206{
     2207  unsigned int idx = 0;
     2208  struct file *file;
     2209
     2210  /* Handle the argument if present. */
     2211
     2212  if (argv[1])
     2213    {
     2214      char *p = argv[1];
     2215      while (isspace ((unsigned int)*p))
     2216        p++;
     2217      if (*p != '\0')
     2218        {
     2219          char *n;
     2220          long l = strtol (p, &n, 0);
     2221          while (isspace ((unsigned int)*n))
     2222            n++;
     2223          idx = l;
     2224          if (*n != '\0' || l < 0 || (long)idx != l)
     2225            fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
     2226        }
     2227    }
     2228
     2229  /* Find the file and select the list corresponding to FUNCNAME. */
     2230
     2231  file = lookup_file (argv[0]);
     2232  if (file)
     2233    {
     2234      struct dep *deps = funcname[4] != '\0' && file->org_deps
     2235                       ? file->org_deps : file->deps;
     2236      struct dep *d;
     2237
     2238      if (idx == 0 /* all */)
     2239        {
     2240          unsigned int total_len = 0;
     2241
     2242          /* calc the result length. */
     2243
     2244          for (d = deps; d; d = d->next)
     2245            if (!d->ignore_mtime)
     2246              {
     2247                const char *c = dep_name (d);
     2248
     2249#ifndef NO_ARCHIVES
     2250                if (ar_name (c))
     2251                  {
     2252                    c = strchr (c, '(') + 1;
     2253                    total_len += strlen (c);
     2254                  }
     2255                else
     2256#else
     2257                  total_len += strcache2_get_len (&file_strcache, c) + 1;
     2258#endif
     2259              }
     2260
     2261          if (total_len)
     2262            {
     2263              /* prepare the variable buffer dude wrt to the output size and
     2264                 pass along the strings.  */
     2265
     2266              o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
     2267
     2268              for (d = deps; d; d = d->next)
     2269                if (!d->ignore_mtime)
     2270                  {
     2271                    unsigned int len;
     2272                    const char *c = dep_name (d);
     2273
     2274#ifndef NO_ARCHIVES
     2275                    if (ar_name (c))
     2276                      {
     2277                        c = strchr (c, '(') + 1;
     2278                        len += strlen (c);
     2279                      }
     2280                    else
     2281#else
     2282                      len = strcache2_get_len (&file_strcache, c) + 1;
     2283#endif
     2284                    o = variable_buffer_output (o, c, len);
     2285                    o[-1] = FILE_LIST_SEPARATOR;
     2286                  }
     2287
     2288                --o;        /* nuke the last list separator */
     2289                *o = '\0';
     2290            }
     2291        }
     2292      else
     2293        {
     2294          /* Dependency given by index.  */
     2295
     2296          for (d = deps; d; d = d->next)
     2297            if (!d->ignore_mtime)
     2298              {
     2299                if (--idx == 0) /* 1 based indexing */
     2300                  {
     2301                    unsigned int len;
     2302                    const char *c = dep_name (d);
     2303
     2304#ifndef NO_ARCHIVES
     2305                    if (ar_name (c))
     2306                      {
     2307                        c = strchr (c, '(') + 1;
     2308                        len += strlen (c) - ;
     2309                      }
     2310                    else
     2311#else
     2312                        len = strcache2_get_len (&file_strcache, c);
     2313#endif
     2314                    o = variable_buffer_output (o, c, len);
     2315                    break;
     2316                  }
     2317              }
     2318        }
     2319    }
     2320
     2321  return o;
     2322}
     2323
     2324/* Implements $?.
     2325
     2326   If no second argument is given, or if it's empty, or if it's zero,
     2327   all dependencies will be returned.  If the second argument is non-zero
     2328   the dependency at that position will be returned.  If the argument is
     2329   negative a fatal error is thrown.  */
     2330static char *
     2331func_deps_newer (char *o, char **argv, const char *funcname)
     2332{
     2333  unsigned int idx = 0;
     2334  struct file *file;
     2335
     2336  /* Handle the argument if present. */
     2337
     2338  if (argv[1])
     2339    {
     2340      char *p = argv[1];
     2341      while (isspace ((unsigned int)*p))
     2342        p++;
     2343      if (*p != '\0')
     2344        {
     2345          char *n;
     2346          long l = strtol (p, &n, 0);
     2347          while (isspace ((unsigned int)*n))
     2348            n++;
     2349          idx = l;
     2350          if (*n != '\0' || l < 0 || (long)idx != l)
     2351            fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
     2352        }
     2353    }
     2354
     2355  /* Find the file. */
     2356
     2357  file = lookup_file (argv[0]);
     2358  if (file)
     2359    {
     2360      struct dep *deps = file->deps;
     2361      struct dep *d;
     2362
     2363      if (idx == 0 /* all */)
     2364        {
     2365          unsigned int total_len = 0;
     2366
     2367          /* calc the result length. */
     2368
     2369          for (d = deps; d; d = d->next)
     2370            if (!d->ignore_mtime && d->changed)
     2371              {
     2372                const char *c = dep_name (d);
     2373
     2374#ifndef NO_ARCHIVES
     2375                if (ar_name (c))
     2376                  {
     2377                    c = strchr (c, '(') + 1;
     2378                    total_len += strlen (c);
     2379                  }
     2380                else
     2381#else
     2382                  total_len += strcache2_get_len (&file_strcache, c) + 1;
     2383#endif
     2384              }
     2385
     2386          if (total_len)
     2387            {
     2388              /* prepare the variable buffer dude wrt to the output size and
     2389                 pass along the strings.  */
     2390
     2391              o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
     2392
     2393              for (d = deps; d; d = d->next)
     2394                if (!d->ignore_mtime && d->changed)
     2395                  {
     2396                    unsigned int len;
     2397                    const char *c = dep_name (d);
     2398
     2399#ifndef NO_ARCHIVES
     2400                    if (ar_name (c))
     2401                      {
     2402                        c = strchr (c, '(') + 1;
     2403                        len += strlen (c);
     2404                      }
     2405                    else
     2406#else
     2407                      len = strcache2_get_len (&file_strcache, c) + 1;
     2408#endif
     2409                    o = variable_buffer_output (o, c, len);
     2410                    o[-1] = FILE_LIST_SEPARATOR;
     2411                  }
     2412
     2413                --o;        /* nuke the last list separator */
     2414                *o = '\0';
     2415            }
     2416        }
     2417      else
     2418        {
     2419          /* Dependency given by index.  */
     2420
     2421          for (d = deps; d; d = d->next)
     2422            if (!d->ignore_mtime && d->changed)
     2423              {
     2424                if (--idx == 0) /* 1 based indexing */
     2425                  {
     2426                    unsigned int len;
     2427                    const char *c = dep_name (d);
     2428
     2429#ifndef NO_ARCHIVES
     2430                    if (ar_name (c))
     2431                      {
     2432                        c = strchr (c, '(') + 1;
     2433                        len += strlen (c) - ;
     2434                      }
     2435                    else
     2436#else
     2437                        len = strcache2_get_len (&file_strcache, c);
     2438#endif
     2439                    o = variable_buffer_output (o, c, len);
     2440                    break;
     2441                  }
     2442              }
     2443        }
     2444    }
     2445
     2446  return o;
     2447}
     2448
     2449/* Implements $|, the order only dependency list.
     2450
     2451   If no second argument is given, or if it's empty, or if it's zero,
     2452   all dependencies will be returned.  If the second argument is non-zero
     2453   the dependency at that position will be returned.  If the argument is
     2454   negative a fatal error is thrown.  */
     2455static char *
     2456func_deps_order_only (char *o, char **argv, const char *funcname)
     2457{
     2458  unsigned int idx = 0;
     2459  struct file *file;
     2460
     2461  /* Handle the argument if present. */
     2462
     2463  if (argv[1])
     2464    {
     2465      char *p = argv[1];
     2466      while (isspace ((unsigned int)*p))
     2467        p++;
     2468      if (*p != '\0')
     2469        {
     2470          char *n;
     2471          long l = strtol (p, &n, 0);
     2472          while (isspace ((unsigned int)*n))
     2473            n++;
     2474          idx = l;
     2475          if (*n != '\0' || l < 0 || (long)idx != l)
     2476            fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
     2477        }
     2478    }
     2479
     2480  /* Find the file. */
     2481
     2482  file = lookup_file (argv[0]);
     2483  if (file)
     2484    {
     2485      struct dep *deps = file->deps;
     2486      struct dep *d;
     2487
     2488      if (idx == 0 /* all */)
     2489        {
     2490          unsigned int total_len = 0;
     2491
     2492          /* calc the result length. */
     2493
     2494          for (d = deps; d; d = d->next)
     2495            if (d->ignore_mtime)
     2496              {
     2497                const char *c = dep_name (d);
     2498
     2499#ifndef NO_ARCHIVES
     2500                if (ar_name (c))
     2501                  {
     2502                    c = strchr (c, '(') + 1;
     2503                    total_len += strlen (c);
     2504                  }
     2505                else
     2506#else
     2507                  total_len += strcache2_get_len (&file_strcache, c) + 1;
     2508#endif
     2509              }
     2510
     2511          if (total_len)
     2512            {
     2513              /* prepare the variable buffer dude wrt to the output size and
     2514                 pass along the strings.  */
     2515
     2516              o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
     2517
     2518              for (d = deps; d; d = d->next)
     2519                if (d->ignore_mtime)
     2520                  {
     2521                    unsigned int len;
     2522                    const char *c = dep_name (d);
     2523
     2524#ifndef NO_ARCHIVES
     2525                    if (ar_name (c))
     2526                      {
     2527                        c = strchr (c, '(') + 1;
     2528                        len += strlen (c);
     2529                      }
     2530                    else
     2531#else
     2532                      len = strcache2_get_len (&file_strcache, c) + 1;
     2533#endif
     2534                    o = variable_buffer_output (o, c, len);
     2535                    o[-1] = FILE_LIST_SEPARATOR;
     2536                  }
     2537
     2538                --o;        /* nuke the last list separator */
     2539                *o = '\0';
     2540            }
     2541        }
     2542      else
     2543        {
     2544          /* Dependency given by index.  */
     2545
     2546          for (d = deps; d; d = d->next)
     2547            if (d->ignore_mtime)
     2548              {
     2549                if (--idx == 0) /* 1 based indexing */
     2550                  {
     2551                    unsigned int len;
     2552                    const char *c = dep_name (d);
     2553
     2554#ifndef NO_ARCHIVES
     2555                    if (ar_name (c))
     2556                      {
     2557                        c = strchr (c, '(') + 1;
     2558                        len += strlen (c) - ;
     2559                      }
     2560                    else
     2561#else
     2562                        len = strcache2_get_len (&file_strcache, c);
     2563#endif
     2564                    o = variable_buffer_output (o, c, len);
     2565                    break;
     2566                  }
     2567              }
     2568        }
     2569    }
     2570
     2571  return o;
     2572}
     2573#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
     2574
     2575
    21872576
    21882577#ifdef CONFIG_WITH_DEFINED
     
    38444233
    38454234      initialize_file_variables (file, 1 /* reading - FIXME: we don't know? */);
    3846       set_file_variables (file);
     4235      set_file_variables (file); /* FIXME: this must *NOT* be done twice! */
    38474236      chop_commands (cmds);
    38484237
     
    40734462  { STRING_SIZE_TUPLE("not"),           0,  1,  1,  func_not},
    40744463#endif
     4464#ifdef CONFIG_WITH_LAZY_DEPS_VARS
     4465  { STRING_SIZE_TUPLE("deps"),          1,  2,  1,  func_deps},
     4466  { STRING_SIZE_TUPLE("deps-all"),      1,  2,  1,  func_deps},
     4467  { STRING_SIZE_TUPLE("deps-newer"),    1,  2,  1,  func_deps_newer},
     4468  { STRING_SIZE_TUPLE("deps-oo"),       1,  2,  1,  func_deps_order_only},
     4469#endif
    40754470#ifdef CONFIG_WITH_DEFINED
    40764471  { STRING_SIZE_TUPLE("defined"),       1,  1,  1,  func_defined},
  • trunk/src/kmk/variable.c

    r1932 r1934  
    14101410  define_variable ("^F", 2, "$(notdir $^)", o_automatic, 1);
    14111411  define_variable ("+F", 2, "$(notdir $+)", o_automatic, 1);
     1412#ifdef CONFIG_WITH_LAZY_DEPS_VARS
     1413  define_variable ("^", 1, "$(deps $@)", o_automatic, 1);
     1414  define_variable ("+", 1, "$(deps-all $@)", o_automatic, 1);
     1415  define_variable ("?", 1, "$(deps-newer $@)", o_automatic, 1);
     1416  define_variable ("|", 1, "$(deps-oo $@)", o_automatic, 1);
     1417#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
    14121418}
    14131419
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette