summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/third_party/gperftools-2.5/src/common.cc47
-rw-r--r--src/third_party/gperftools-2.5/src/common.h4
2 files changed, 30 insertions, 21 deletions
diff --git a/src/third_party/gperftools-2.5/src/common.cc b/src/third_party/gperftools-2.5/src/common.cc
index 30b0a931480..215e6b1bf17 100644
--- a/src/third_party/gperftools-2.5/src/common.cc
+++ b/src/third_party/gperftools-2.5/src/common.cc
@@ -99,7 +99,7 @@ int AlignmentForSize(size_t size) {
int SizeMap::NumMoveSize(size_t size) {
if (size == 0) return 0;
- // Use approx 32k transfers between thread and central caches.
+ // Use a min of (8k, 2 count) transfers between thread and central caches.
int num = kTargetTransferBytes / size;
if (num < 2) num = 2;
@@ -135,6 +135,8 @@ void SizeMap::Init() {
// Compute the size classes we want to use
int sc = 1; // Next size class to assign
+ size_t potential_merge_sizes[kMaxSize];
+ int potential_merge_count = 0;
int alignment = kAlignment;
CHECK_CONDITION(kAlignment <= kMinAlign);
for (size_t size = kAlignment; size <= kMaxSize; size += alignment) {
@@ -142,38 +144,45 @@ void SizeMap::Init() {
CHECK_CONDITION((size % alignment) == 0);
int min_objects_per_span = kTargetTransferBytes / size;
- size_t psize = 0;
+ size_t span_size = 0;
do {
- psize += kPageSize;
+ span_size += kPageSize;
// Allocate enough pages so leftover is less than 1/8 of total.
// This bounds wasted space to at most 12.5%.
- while ((psize % size) > (psize >> 3)) {
- psize += kPageSize;
+ while ((span_size % size) > (span_size >> 3)) {
+ span_size += kPageSize;
}
// Continue to add pages until there are at least as many objects in
// the span as are needed when moving objects from the central
// freelists and spans to the thread caches.
- } while ((psize / size) < min_objects_per_span);
- const size_t my_pages = psize >> kPageShift;
-
- if (sc > 1 && my_pages == class_to_pages_[sc-1]) {
- // See if we can merge this into the previous class without
- // increasing the fragmentation of the previous class.
- const size_t my_objects = (my_pages << kPageShift) / size;
- const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)
- / class_to_size_[sc-1];
- if (my_objects == prev_objects) {
- // Adjust last class to include this size
- class_to_size_[sc-1] = size;
- continue;
- }
+ } while ((span_size / size) < min_objects_per_span);
+ const size_t my_pages = span_size >> kPageShift;
+
+ bool merge = (potential_merge_count != 0);
+ for (int i = 0; i < potential_merge_count; i++) {
+ // See if we can merge this into the previous class(es) without
+ // the fragmentation of any of them going over 12.5%.
+ int objects_per_span = span_size / size;
+ size_t waste = span_size - (potential_merge_sizes[i] * objects_per_span);
+ if (waste > (span_size >> 3))
+ merge = false;
+ }
+
+ if (merge) {
+ // Adjust last class to include this size
+ class_to_size_[sc-1] = size;
+ potential_merge_sizes[potential_merge_count++] = size;
+ continue;
}
+ potential_merge_sizes[0] = size;
+ potential_merge_count = 1;
// Add new class
class_to_pages_[sc] = my_pages;
class_to_size_[sc] = size;
sc++;
}
+
if (sc != kNumClasses) {
Log(kCrash, __FILE__, __LINE__,
"wrong number of size classes: (found vs. expected )", sc, kNumClasses);
diff --git a/src/third_party/gperftools-2.5/src/common.h b/src/third_party/gperftools-2.5/src/common.h
index c110aa403f8..253f23b1da8 100644
--- a/src/third_party/gperftools-2.5/src/common.h
+++ b/src/third_party/gperftools-2.5/src/common.h
@@ -88,10 +88,10 @@ static const size_t kPageShift = 15;
static const size_t kNumClasses = kBaseClasses + 69;
#elif defined(TCMALLOC_64K_PAGES)
static const size_t kPageShift = 16;
-static const size_t kNumClasses = kBaseClasses + 37;
+static const size_t kNumClasses = kBaseClasses + 32;
#else
static const size_t kPageShift = 12;
-static const size_t kNumClasses = kBaseClasses + 43;
+static const size_t kNumClasses = kBaseClasses + 33;
#endif
static const size_t kMaxThreadCacheSize = 4 << 20;