diff --git a/mycpp/gc_dict.h b/mycpp/gc_dict.h index 7c8adb58f5..97e453f5a7 100644 --- a/mycpp/gc_dict.h +++ b/mycpp/gc_dict.h @@ -37,6 +37,11 @@ List* ListFromDictSlab(Slab* index, Slab* slab, int n) { template class Dict { + // Relates to minimum slab size. This is good for Dict, Dict, Dict, but possibly suboptimal for Dict. But that + // case is rare. + static const int kMinItems = 4; + public: Dict() : GC_CLASS_FIXED(header_, field_mask(), sizeof(Dict)), @@ -121,6 +126,14 @@ class Dict { } DISALLOW_COPY_AND_ASSIGN(Dict) + + private: + int RoundCapacity(int n) { + if (n < kMinItems) { + return kMinItems; + } + return RoundUp(n); + } }; template @@ -157,7 +170,7 @@ void Dict::reserve(int n) { // if (capacity_ < n) { // TODO: use load factor, not exact fit // calculate the number of keys and values we should have - capacity_ = RoundUp(n + kCapacityAdjust) - kCapacityAdjust; + capacity_ = RoundCapacity(n + kCapacityAdjust) - kCapacityAdjust; // TODO: This is SPARSE. How to compute a size that ensures a decent // load factor? diff --git a/mycpp/gc_list.h b/mycpp/gc_list.h index 94272fc051..4d042e2a13 100644 --- a/mycpp/gc_list.h +++ b/mycpp/gc_list.h @@ -25,18 +25,13 @@ class GlobalList { template class List { - // TODO: Move methods that don't allocate or resize: out of gc_heap? - // - allocate: append(), extend() - // - resize: pop(), clear() - // - neither: reverse(), sort() -- these are more like functions. Except - // sort() is a templated method that depends on type param T. - // - neither: index(), slice() - + // Relate slab size to number of items (capacity) // 8 / 4 = 2 items, or 8 / 8 = 1 item static const int kCapacityAdjust = kSlabHeaderSize / sizeof(T); static_assert(kSlabHeaderSize % sizeof(T) == 0, "Slab header size should be multiple of item size"); + // Relates to minimum Slab size. // Smallest non-empty List should have about 4 items, or 3 without header // Smallest non-empty List should have about 8 items, or 7 without header static const int kMinItems = 32 / sizeof(T); diff --git a/mycpp/gc_slab.h b/mycpp/gc_slab.h index 33beb741d3..4e2c5ecb8b 100644 --- a/mycpp/gc_slab.h +++ b/mycpp/gc_slab.h @@ -6,18 +6,14 @@ #include "mycpp/common.h" // DISALLOW_COPY_AND_ASSIGN #include "mycpp/gc_obj.h" // GC_OBJ -// Return the size of a resizeable allocation. For now we just round up by -// powers of 2. This could be optimized later. CPython has an interesting -// policy in listobject.c. +// Return the size of a resizeable allocation. Just round up to the nearest +// power of 2. (CPython has an interesting policy in listobject.c.) // // https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2 -inline int RoundUp(int n) { - // Note: List::RoundCapacity refines this. TODO: remove this check when we - // have Dict::RoundCapacity. - if (n < 4) { - return 4; - } +// +// Used by List and Dict. +inline int RoundUp(int n) { // TODO: what if int isn't 32 bits? n--; n |= n >> 1;