Ignore:
Timestamp:
Dec 14, 2007, 4:25:45 PM (17 years ago)
Author:
[email protected]
Message:

Add logic for TCMalloc to release memory to the system

Reviewed by Maciej and Oliver.

Add final changes to make TCMalloc release memory to the system.
This results in a 0.4% regression against ToT, but this is offset
against the gains made by the original TCMalloc r38 merge - in fact
we retain around 0.3-0.4% progression overall.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/FastMalloc.cpp

    r28455 r28727  
    236236#endif
    237237
     238#ifndef PRIuS
     239#define PRIuS "zu"
     240#endif
     241
    238242// Calling pthread_getspecific through a global function pointer is faster than a normal
    239243// call to the function on Mac OS X, and it's used in performance-critical code. So we
     
    672676  }
    673677  if (sc != kNumClasses) {
    674     MESSAGE("wrong number of size classes: found %d instead of %d\n",
     678    MESSAGE("wrong number of size classes: found %" PRIuS " instead of %d\n",
    675679            sc, int(kNumClasses));
    676680    abort();
     
    691695    const size_t sc = SizeClass(size);
    692696    if (sc == 0) {
    693       MESSAGE("Bad size class %d for %" PRIuS "\n", sc, size);
     697      MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size);
    694698      abort();
    695699    }
    696700    if (sc > 1 && size <= class_to_size[sc-1]) {
    697       MESSAGE("Allocating unnecessarily large class %d for %" PRIuS
     701      MESSAGE("Allocating unnecessarily large class %" PRIuS " for %" PRIuS
    698702              "\n", sc, size);
    699703      abort();
    700704    }
    701705    if (sc >= kNumClasses) {
    702       MESSAGE("Bad size class %d for %" PRIuS "\n", sc, size);
     706      MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size);
    703707      abort();
    704708    }
    705709    const size_t s = class_to_size[sc];
    706710    if (size > s) {
    707       MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %d)\n", s, size, sc);
     711     MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc);
    708712      abort();
    709713    }
    710714    if (s == 0) {
    711       MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %d)\n", s, size, sc);
     715      MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc);
    712716      abort();
    713717    }
     
    13291333  if (scavenge_counter_ >= 0) return;  // Not yet time to scavenge
    13301334
    1331   // Never delay scavenging for more than the following number of
    1332   // deallocated pages.  With 4K pages, this comes to 4GB of
    1333   // deallocation.
    1334   static const int kMaxReleaseDelay = 1 << 20;
    1335 
    13361335  // If there is nothing to release, wait for so many pages before
    1337   // scavenging again.  With 4K pages, this comes to 1GB of memory.
    1338   static const int kDefaultReleaseDelay = 1 << 18;
    1339 
    1340   const double rate = FLAGS_tcmalloc_release_rate;
    1341   if (rate <= 1e-6) {
    1342     // Tiny release rate means that releasing is disabled.
    1343     scavenge_counter_ = kDefaultReleaseDelay;
    1344     return;
    1345   }
     1336  // scavenging again.  With 4K pages, this comes to 16MB of memory.
     1337  static const size_t kDefaultReleaseDelay = 1 << 8;
    13461338
    13471339  // Find index of free list to scavenge
     
    13581350      DLL_Prepend(&slist->returned, s);
    13591351
    1360       // Compute how long to wait until we return memory.
    1361       // FLAGS_tcmalloc_release_rate==1 means wait for 1000 pages
    1362       // after releasing one page.
    1363       const double mult = 1000.0 / rate;
    1364       double wait = mult * static_cast<double>(s->length);
    1365       if (wait > kMaxReleaseDelay) {
    1366         // Avoid overflow and bound to reasonable range
    1367         wait = kMaxReleaseDelay;
    1368       }
    1369       scavenge_counter_ = static_cast<int64_t>(wait);
    1370 
    1371       scavenge_index_ = index;  // Scavenge at index+1 next time
     1352      scavenge_counter_ = max(64UL, min(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay)));
     1353//      fprintf(stderr, "Released %zu pages at 0x%08zx to the system from index %zu.  Delaying for %lld pages before scavenging next.\n", s->length, s->start << kPageShift, index, scavenge_counter_);
     1354
     1355      if (index == kMaxPages && !DLL_IsEmpty(&slist->normal))
     1356        scavenge_index_ = index - 1;
     1357      else
     1358        scavenge_index_ = index;
    13721359      return;
    13731360    }
     
    13771364  // Nothing to scavenge, delay for a while
    13781365  scavenge_counter_ = kDefaultReleaseDelay;
     1366//  fprintf(stderr, "Nothing to scavenge.  Delaying for %lld pages before scavenging next.\n", scavenge_counter_);
    13791367}
    13801368
Note: See TracChangeset for help on using the changeset viewer.