tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

stringbuffer-6.js (3752B)


      1 // Test that long strings allocated by rope flattening have a string buffer.
      2 
      3 gczeal(0);
      4 
      5 // Must match sizeof(mozilla::StringBuffer)
      6 const StringBufferSizeInBytes = 8;
      7 
      8 function checkRefCount(s, expected) {
      9    // stringRepresentation and the bufferRefCount field aren't available in
     10    // all builds.
     11    if (getBuildConfiguration("debug")) {
     12        finishBackgroundFree();
     13        var repr = JSON.parse(stringRepresentation(s));
     14        assertEq(repr.bufferRefCount, expected);
     15    }
     16 }
     17 function checkExtensibleCapacity(s, expected) {
     18    if (getBuildConfiguration("debug")) {
     19        var repr = JSON.parse(stringRepresentation(s));
     20        assertEq(repr.capacity, expected);
     21    }
     22 }
     23 
     24 function testBasicLatin1() {
     25    var s1 = ensureLinearString("a".repeat(1000));
     26    var s2 = ensureLinearString("b".repeat(1000));
     27    var flattened1 = ensureLinearString(newRope(s1, s2));
     28    checkRefCount(flattened1, 1);
     29    // Test that the string's capacity + StringBuffer + null terminator fills up
     30    // a jemalloc bucket of 2048 bytes.
     31    var expectedCapacity = 2048 - StringBufferSizeInBytes - 1 /* null terminator */;
     32    checkExtensibleCapacity(flattened1, expectedCapacity);
     33 
     34    // Move string buffer to flattened2 and turn flattened into a dependent string.
     35    var flattened2 = ensureLinearString(flattened1 + "abcdef");
     36    checkRefCount(flattened1, undefined);
     37    checkRefCount(flattened2, 1);
     38    assertEq(flattened2.length, 2006);
     39 
     40    // Share the StringBuffer with another JS string.
     41    var sharedBuffer = newString(flattened2, {shareStringBuffer: true});
     42    checkRefCount(flattened2, 2);
     43 
     44    // Because there are now multiple references, we don't use the extensible buffer.
     45    var flattened3 = ensureLinearString(flattened2 + "abcdef");
     46    checkRefCount(flattened2, 2);
     47    checkRefCount(flattened3, 1);
     48    checkExtensibleCapacity(flattened3, expectedCapacity);
     49 }
     50 testBasicLatin1();
     51 
     52 function testBasicTwoByte() {
     53    var s1 = ensureLinearString("\u1234".repeat(500));
     54    var s2 = ensureLinearString("\u1256".repeat(500));
     55    var flattened1 = ensureLinearString(newRope(s1, s2));
     56    checkRefCount(flattened1, 1);
     57    // Test that the string's capacity + StringBuffer + null terminator fills up
     58    // a jemalloc bucket of 2048 bytes.
     59    var expectedCapacity = 1024 - StringBufferSizeInBytes / 2 - 1 /* null terminator */;
     60    checkExtensibleCapacity(flattened1, expectedCapacity);
     61 
     62    // Move string buffer to flattened2 and turn flattened into a dependent string.
     63    var flattened2 = ensureLinearString(flattened1 + "abcdef");
     64    checkRefCount(flattened1, undefined);
     65    checkRefCount(flattened2, 1);
     66    assertEq(flattened2.length, 1006);
     67 
     68    // Share the StringBuffer with another JS string.
     69    var sharedBuffer = newString(flattened2, {shareStringBuffer: true});
     70    checkRefCount(flattened2, 2);
     71 
     72    // Because there are now multiple references, we don't use the extensible buffer.
     73    var flattened3 = ensureLinearString(flattened2 + "abcdef");
     74    checkRefCount(flattened2, 2);
     75    checkRefCount(flattened3, 1);
     76    checkExtensibleCapacity(flattened3, expectedCapacity);
     77 }
     78 testBasicTwoByte();
     79 
     80 function testBufferTransfer(fromNursery, toNursery) {
     81    var s1 = ensureLinearString("a".repeat(1000));
     82    var s2 = ensureLinearString("b".repeat(1000));
     83    var flattened1 = ensureLinearString(newRope(s1, s2, {nursery: fromNursery}));
     84    checkRefCount(flattened1, 1);
     85 
     86    var flattened2 = ensureLinearString(newRope(flattened1, "abcdef", {nursery: toNursery}));
     87    checkRefCount(flattened1, undefined);
     88    checkRefCount(flattened2, 1);
     89    gc();
     90    checkRefCount(flattened2, 1);
     91 }
     92 testBufferTransfer(false, false);
     93 testBufferTransfer(false, true);
     94 testBufferTransfer(true, false);
     95 testBufferTransfer(true, true);