Closed Bug 1159629 Opened 7 years ago Closed 2 years ago

Poor performance caused by imprecise type information on locals variables.

Categories

(Core :: JavaScript Engine: JIT, defect, P5)

defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: mbx, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

1.78 KB, application/x-javascript
Details
Attached file x.js
In the following example, |x| is always an instance of |X|. However, because of the |if (T === 0) ... | guard the type set collected at each property access is |undefined, X| which leads to poor performance.

var T = 0;

function fun() {
  var s = dateNow();
  var x;
  if (T === 0) x = new X();
  for (var i = 0; i < 200000000; i++) {
    x.a ++;
    x.b ++;
    x.c ++;
    x.foo();
  }
  print("fun1 " + (dateNow() - s).toFixed(2) + " ms");
}

This looks like a strange pattern, but it occurs in practice in j2me.js, where the compiler emits a special function prologue to handle on-stack-replacement of Java frames:

var osr = true;
var osrLocals = [1, null, {}];
var osrPC = 17;


function fun(a) {
  var a, b, c;
  if (osr {
    a = osrLocals[0];
    b = osrLocals[1];
    c = osrLocals[2];
  }
  if (osrPC === 0) { 
    .... 
  } else if (osrPC === 17) { 
    ...
  }
  ...
}


See attached benchmark for various type set patterns:

var x = new X();                               686.31 ms
var x; if (T === 0) x = new X();               807.06 ms
var x = null; if (T === 0) x = new X();        819.09 ms
var x = {}; if (T === 0) x = new X();         3117.11 ms
var x = 0; if (T === 0) x = new X();          1986.95 ms
var x = ""; if (T === 0) x = new X();         8832.09 ms
var x = [null]; if (T === 0) x[0] = new X();   683.26 ms
Bug 1131523 should help the property access case, but does not fix the general problem (you could have a similar problem with {undefined, int32}).

If T === 0 is by far the most common case, you could try something like:

    function MaybeNewX() { if (T === 0) return new X(); return null; }

    var x = MaybeNewX();

Type barriers on the return value may help Ion in this case, but it will be slower in the Baseline JIT or if our inlining heuristics fail for some reason.

Is it feasible to generate a separate version of this function for the OSR case?
Depends on: 1131523
The problem is not limited to the OSR case. Java reuses local slots for values of different types, and   since we compile Java locals to JS locals we will be running into this problem frequently.
Blocks: jsperf
Priority: -- → P5

I get the same performance for all seven functions with Warp, therefore resolving as WFM.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.