chakra-core / ChakraCore

ChakraCore is an open source Javascript engine with a C API.
MIT License
9.12k stars 1.2k forks source link

`let` vs `var` generates a lot more instructions #800

Open Cellule opened 8 years ago

Cellule commented 8 years ago

Sorry in advance I haven't been able to get a simpler repro case at this time. My test case is the following

const n = 500;
function getTest(name) {
  var fn;
  eval(`fn = function memcopy_${name}(a, b, start, end) {for (let i = start; i < end; i++) { b[i] = a[i]; }}`);
  return fn
}
var foo = getTest("Int8")
var src = new Int8Array(n);
src.fill(1);
var dst = new Int8Array(n);
foo(src, dst, 0, 250);
foo(src, dst, 250, n);

This code generates the following IR

Function Entry
    s7.var          =  NewBlockScope                                          #0000 
    s15(s7->i)<?,,--,s?,s?>.var = InitLetFld  0xXXXXXXXX (null)[PrimitiveOrObject].var #0002 
Every uses of `i`
    s19.var         =  LdSlotArr      s17(s7[2]).var                          #0017 
    s8.var          =  LdSlot         s20(s19[0])<?,,--,s?,s?>.var            #0017 

This IR makes it hard to make proper optimizations (in this case Array optimizations).

If we change the let keyword for a var, i becomes a regular variable. Is it possible to make let variables behave exactly the same as a regular var if there is no redefinition inside the function ? Should this be done at Bytecode level, IR Builder or Globopt ?

pleath commented 8 years ago

The fact that the code is in eval is the limiting factor for us, right? We could theoretically make the eval code gen close enough to non-eval code to make the optimizer’s life easier, but it would take some effort. Is this a synthetic test case?

--Paul

From: Michael Ferris [mailto:notifications@github.com] Sent: Wednesday, April 13, 2016 11:27 AM To: Microsoft/ChakraCore ChakraCore@noreply.github.com Subject: [Microsoft/ChakraCore] let vs var generates a lot more instructions (#800)

Sorry in advance I haven't been able to get a simpler repro case at this time. My test case is the following

const n = 500;

function getTest(name) {

var fn;

eval(fn = function memcopy_${name}(a, b, start, end) {for (let i = start; i < end; i++) { b[i] = a[i]; }});

return fn

}

var foo = getTest("Int8")

var src = new Int8Array(n);

src.fill(1);

var dst = new Int8Array(n);

foo(src, dst, 0, 250);

foo(src, dst, 250, n);

This code generates the following IR

Function Entry

s7.var          =  NewBlockScope                                          #0000

s15(s7->i)<?,,--,s?,s?>.var = InitLetFld  0xXXXXXXXX (null)[PrimitiveOrObject].var #0002

Every uses of i

s19.var         =  LdSlotArr      s17(s7[2]).var                          #0017

s8.var          =  LdSlot         s20(s19[0])<?,,--,s?,s?>.var            #0017

This IR makes it hard to make proper optimizations (in this case Array optimizations).

If we change the let keyword for a var, i becomes a regular variable. Is it possible to make let variables behave exactly the same as a regular var if there is no redefinition inside the function ? Should this be done at Bytecode level, IR Builder or Globopt ?

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHubhttps://github.com/Microsoft/ChakraCore/issues/800

Cellule commented 8 years ago

I'm not entirely sure, but it's true that I haven't been able to repro outside of eval. I wrote that test case, to type specialize each function differently. Regardless, this means that let (and possibly const) inside of eval will always be much slower than var

ianwjhalliday commented 8 years ago

I don't see why we need to make a scope object for the for loop's scope in this case. Doesn't matter that it is in an eval, there is no nested eval nor any capture.

pleath commented 8 years ago

Right, that's why I say that it's theoretically possible to fix this. My only question is the priority relative to RS1 bugs.

-- Paul


From: Ian Hallidaymailto:notifications@github.com Sent: ‎4/‎13/‎2016 7:17 PM To: Microsoft/ChakraCoremailto:ChakraCore@noreply.github.com Cc: Paul Leathersmailto:pleath@microsoft.com Subject: Re: [Microsoft/ChakraCore] let vs var generates a lot more instructions (#800)

I don't see why we need to make a scope object for the for loop's scope in this case. Doesn't matter that it is in an eval, there is no nested eval nor any capture.

— You are receiving this because you commented. Reply to this email directly or view it on GitHubhttps://github.com/Microsoft/ChakraCore/issues/800#issuecomment-209724601