Created
February 23, 2015 21:58
-
-
Save jimblandy/14231fda8d54196e1a52 to your computer and use it in GitHub Desktop.
ubi::Node::size test for JSStrings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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