Function hidden classes

Benchmark created by Kevin Gadd on


Description

Functions in v8 have hidden classes like objects, and functions only get fully optimized if using the default hidden class

Preparation HTML

<script>
var f1 = function (n) {
  return n;
};
var f2 = function (n) {
  return n;
};

f2.toString = function () { return "f2"; };
Object.defineProperty(f2, "displayName", { value: "f2" });
Object.defineProperty(f2, "debugName", { value: "f2" });

Function.prototype.invoke1 = function () {
  return this.apply(null, arguments);
};

Function.prototype.invoke2 = function () {
  return this.apply(null, arguments);
};

Function.prototype.invoke3 = function () {
  return this.apply(null, arguments);
};

var count = 5000;

// Feed information into the ICs for each function
for (var i = 0; i < count; i++) {
  f1.invoke1(1);
  f2.invoke2(1);

  // The IC for invoke3 will get two different hidden class entries, which deoptimizes it
  if (i % 2 == 0)
    f1.invoke3(1);
  else
    f2.invoke3(1);
}
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Direct (unmodified)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f1(i);
}
if (sum != 12497500)
  throw new Error();
ready
Direct (modified)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f2(i);
}
if (sum != 12497500)
  throw new Error();
ready
.call (unmodified)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f1.call(this, i);
}
if (sum != 12497500)
  throw new Error();
ready
.call (modified)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f2.call(this, i);
}
if (sum != 12497500)
  throw new Error();
ready
Consistent IC information (unmodified fn)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f1.invoke1(i);
}
if (sum != 12497500)
  throw new Error();
ready
Consistent IC information (modified fn)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f2.invoke2(i);
}
if (sum != 12497500)
  throw new Error();
ready
Conflicting IC information (unmodified fn)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f1.invoke3(i);
}
if (sum != 12497500)
  throw new Error();
ready
Conflicting IC information (modified fn)
var sum = 0;
for (var i = 0; i < count; i++) {
  sum += f2.invoke3(i);
}
if (sum != 12497500)
  throw new Error();
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.