Changeset 43383 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
May 7, 2009, 6:58:47 PM (16 years ago)
Author:
[email protected]
Message:

2009-05-07 Gavin Barraclough <[email protected]>

Reviewed by Maciej Stachowiak.

Previously, when appending to an existing string and growing the underlying buffer,
we would actually allocate 110% of the required size in order to give us some space
to expand into. Now we treat strings differently based on their size:

Small Strings (up to 4 pages):
Expand the allocation size to 112.5% of the amount requested. This is largely sicking
to our previous policy, however 112.5% is cheaper to calculate.

Medium Strings (up to 128 pages):
For pages covering multiple pages over-allocation is less of a concern - any unused
space will not be paged in if it is not used, so this is purely a VM overhead. For
these strings allocate 2x the requested size.

Large Strings (to infinity and beyond!):
Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow
any individual string be responsible for.

Additionally, round small allocations up to a multiple of 16 bytes, and medium and
large allocations up to a multiple of page size.

~1.5% progression on Sunspider, due to 5% improvement on tagcloud & 15% on validate.

  • runtime/UString.cpp: (JSC::expandedSize):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/UString.cpp

    r43339 r43383  
    369369#endif
    370370
    371 // put these early so they can be inlined
    372 static inline size_t expandedSize(size_t size, size_t otherSize)
    373 {
    374     // Do the size calculation in two parts, returning overflowIndicator if
    375     // we overflow the maximum value that we can handle.
    376 
    377     if (size > maxUChars())
     371// Put these early so they can be inlined.
     372static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
     373{
     374    // Combine capacitySize & precapacitySize to produce a single size to allocate,
     375    // check that doing so does not result in overflow.
     376    size_t size = capacitySize + precapacitySize;
     377    if (size < capacitySize)
    378378        return overflowIndicator();
    379379
    380     size_t expandedSize = ((size + 10) / 10 * 11) + 1;
    381 
    382     // If 'size' was originally just less than maxUChars() then we may have just overflowed.
    383     // The next check won't catch this, since the subtraction will underflow.  Alternatively,
    384     // rather than failing we could just back off from the expansion here?
    385     if (expandedSize > maxUChars())
    386         return overflowIndicator();
    387 
    388     if (maxUChars() - expandedSize < otherSize)
    389         return overflowIndicator();
    390 
    391     return expandedSize + otherSize;
     380    // Small Strings (up to 4 pages):
     381    // Expand the allocation size to 112.5% of the amount requested.  This is largely sicking
     382    // to our previous policy, however 112.5% is cheaper to calculate.
     383    if (size < 0x4000) {
     384        size_t expandedSize = ((size + (size >> 3)) | 15) + 1;
     385        // Given the limited range within which we calculate the expansion in this
     386        // fashion the above calculation should never overflow.
     387        ASSERT(expandedSize >= size);
     388        ASSERT(expandedSize < maxUChars());
     389        return expandedSize;
     390    }
     391
     392    // Medium Strings (up to 128 pages):
     393    // For pages covering multiple pages over-allocation is less of a concern - any unused
     394    // space will not be paged in if it is not used, so this is purely a VM overhead.  For
     395    // these strings allocate 2x the requested size.
     396    if (size < 0x80000) {
     397        size_t expandedSize = ((size + size) | 0xfff) + 1;
     398        // Given the limited range within which we calculate the expansion in this
     399        // fashion the above calculation should never overflow.
     400        ASSERT(expandedSize >= size);
     401        ASSERT(expandedSize < maxUChars());
     402        return expandedSize;
     403    }
     404
     405    // Large Strings (to infinity and beyond!):
     406    // Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow
     407    // any individual string be responsible for.
     408    size_t expandedSize = ((size + (size >> 3)) | 0xfff) + 1;
     409
     410    // Check for overflow - any result that is at least as large as requested (but
     411    // still below the limit) is okay.
     412    if ((expandedSize >= size) && (expandedSize < maxUChars()))
     413        return expandedSize;
     414    return overflowIndicator();
    392415}
    393416
Note: See TracChangeset for help on using the changeset viewer.