Skip to content

Instantly share code, notes, and snippets.

@jimblandy
Created February 23, 2015 21:58
Show Gist options
  • Select an option

  • Save jimblandy/14231fda8d54196e1a52 to your computer and use it in GitHub Desktop.

Select an option

Save jimblandy/14231fda8d54196e1a52 to your computer and use it in GitHub Desktop.
ubi::Node::size test for JSStrings
// Check JS::ubi::Node::size results for strings.
// We actually hard-code specific sizes into this test, even though they're
// implementation details, because in practice there are only two architecture
// variants to consider (32-bit and 64-bit), and if these sizes change, that's
// something SpiderMonkey hackers really want to know; they're supposed to be
// stable.
// Run this test only if we're using jemalloc. Other malloc implementations
// exhibit surprising behaviors. For example, 32-bit Fedora builds have
// non-deterministic allocation sizes.
var config = getBuildConfiguration();
if (!config['moz-memory'])
quit(0);
if (config['pointer-byte-size'] == 4)
var s = (s32, s64) => s32
else
var s = (s32, s64) => s64
// Return the byte size of |obj|, ensuring that the size is not affected by
// being tenured. (We use 'survives a GC' as an approximation for 'tenuring'.)
function tByteSize(obj) {
var nurserySize = byteSize(obj);
minorgc();
var tenuredSize = byteSize(obj);
if (nurserySize != tenuredSize) {
print("nursery size: " + nurserySize + " tenured size: " + tenuredSize);
return -1; // make the stack trace point at the real test
}
return tenuredSize;
}
// Latin-1 flat strings.
// I am not sure when these transition from thin inline to fat inline to not
// inline. The comments in String.h go on and on without actually saying what
// lengths fit in which representations, so I got bored and watched television
// rather than sorting out exactly which transitions here mean what.
assertEq(tByteSize(""), s(16, 24));
assertEq(tByteSize("1"), s(16, 24));
assertEq(tByteSize("1234567"), s(16, 24));
assertEq(tByteSize("12345678"), s(32, 24));
assertEq(tByteSize("123456789.12345"), s(32, 24));
assertEq(tByteSize("123456789.123456"), s(32, 32));
assertEq(tByteSize("123456789.123456789.123"), s(32, 32));
assertEq(tByteSize("123456789.123456789.1234"), s(48, 56));
assertEq(tByteSize("123456789.123456789.123456789.1"), s(48, 56));
assertEq(tByteSize("123456789.123456789.123456789.12"), s(64, 72));
// Inline char16_t atoms.
// "Impassionate gods have never seen the red that is the Tatsuta River."
// - Ariwara no Narihira
// (No, I can't read this either. It's used in an anime. --JimB)
assertEq(tByteSize("千"), s(16, 24));
assertEq(tByteSize("千早"), s(16, 24));
assertEq(tByteSize("千早ぶ"), s(16, 24));
assertEq(tByteSize("千早ぶる"), s(32, 24));
assertEq(tByteSize("千早ぶる神"), s(32, 24));
assertEq(tByteSize("千早ぶる神代"), s(32, 24));
assertEq(tByteSize("千早ぶる神代も"), s(32, 24));
assertEq(tByteSize("千早ぶる神代もき"), s(32, 32));
assertEq(tByteSize("千早ぶる神代もきかず龍"), s(32, 32));
assertEq(tByteSize("千早ぶる神代もきかず龍田"), s(48, 56));
assertEq(tByteSize("千早ぶる神代もきかず龍田川 か"), s(48, 56));
assertEq(tByteSize("千早ぶる神代もきかず龍田川 から"), s(64, 72));
assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水く"), s(64, 72));
assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くく"), s(80, 88));
assertEq(tByteSize("千早ぶる神代もきかず龍田川 からくれなゐに水くくるとは"), s(80, 88));
// A Latin-1 rope. This changes size when flattened.
var rope8 = "0123456789012345678901234567890123456789"; // 40 characters
for (var i = 0; i < 10; i++) // 1024 repetitions
rope8 = rope8 + rope8;
assertEq(tByteSize(rope8), s(16, 24))
rope8.match(/x/, function() { assertEq(true, false); });
assertEq(tByteSize(rope8), s(16 + 65536, 24 + 65536));
// A char16_t rope. This changes size when flattened.
var rope16 = "✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏"; // 32 characters
for (var i = 0; i < 10; i++) // 1024 repetitions
rope16 = rope16 + rope16;
assertEq(tByteSize(rope16), s(16, 24))
rope16.match(/x/, function() { assertEq(true, false); });
assertEq(tByteSize(rope16), s(16 + 131072, 24 + 131072));
// Latin-1 and char16_t dependent strings. (Undependend strings are not really
// a distinct representation.)
assertEq(tByteSize(rope8.substr(1000, 2000)), s(16, 24));
assertEq(tByteSize(rope16.substr(1000, 2000)), s(16, 24));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment