JS: specialize unpackCString# CAFs
Summary
We should generate better JS code for unpackCString# "xyz"#
.
Steps to reproduce
Consider the following example:
module Main where
xyz :: String
xyz = "xyz"
main = putStrLn xyz
We generate:
// "xyz"#: offset 0 + array of bytes
var h$mainZCMainzixyzz1_2 = 0;
var h$mainZCMainzixyzz1_1 = h$rawStringData([120, 121, 122]);
// CAF object
var h$mainZCMainzixyzz = h$d();
h$stc(h$mainZCMainzixyzz, h$mainZCMainzixyzz_e, [h$ghczmprimZCGHCziCStringziunpackCStringzh]);
// Fun infotable + entry code
h$o(h$mainZCMainzixyzz_e, 0, 0, 1, 256, null);
function h$mainZCMainzixyzz_e() {
var a = h$r1.d1;
h$bh();
h$r3 = h$mainZCMainzixyzz1_2;
h$r2 = h$mainZCMainzixyzz1_1;
h$r1 = a;
return h$ap_1_2_fast();
};
Ideally we would have much more code sharing as the entry code is always almost the same.
For example, the CAF could capture the Addr# like this:
h$stc(h$mainZCMainzixyzz, h$mainZCMainzixyzz_e, [h$ghczmprimZCGHCziCStringziunpackCStringzh, h$mainZCMainzixyzz1_1, h$mainZCMainzixyzz1_2]);
// Fun infotable + entry code
h$o(h$mainZCMainzixyzz_e, ...);
function h$mainZCMainzixyzz_e() {
var a = h$r1.d1;
var b = h$r1.d2.d1;
var c = h$r1.d2.d2;
h$bh();
h$r3 = c;
h$r2 = b;
h$r1 = a;
return h$ap_1_2_fast();
};
Then #24743 would take care of sharing the entry code which would always be the same.
We might also be more clever and detect that we're dealing with unpackCString#
, similarly to what native backends do: see Note [unpack_cstring closures] in rts/StgStdThunks.cmm
Also the offset is always 0
for these constant strings, so we should try to inline the offset and to not generate the variables as it is a bit ridiculous to have:
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim67_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim67_1=h$rawStringData([68,69,76]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzilvl122_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzilvl122_1=h$rawStringData([92,38]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim65_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim65_1=h$rawStringData([83,80]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim63_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim63_1=h$rawStringData([85,83]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim61_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim61_1=h$rawStringData([82,83]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim59_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim59_1=h$rawStringData([71,83]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim57_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim57_1=h$rawStringData([70,83]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim55_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim55_1=h$rawStringData([69,83,67]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim53_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim53_1=h$rawStringData([83,85,66]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim51_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim51_1=h$rawStringData([69,77]);
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim49_2=0;
var h$ghczminternalZCGHCziInternalziTextziReadziLexzim49_1=h$rawStringData([67,65,78]);
...