prepack icon indicating copy to clipboard operation
prepack copied to clipboard

Leaking bindings stops tracking their values

Open NTillmann opened this issue 6 years ago • 1 comments

Prepacking this...

(function () {
    function f(g) {
        let x = 23;
        function f() { return x; }
        g(f); // <- this leaks x
        x = 1;
        x = 2;
        x = 3;
        x = 4;
        x = 5;
        return x;
    }
    global.__optimize && __optimize(f);
    global.inspect = function() { return f(g => g()); }
})();

results in the following (at least after #2010 lands):

(function () {
  var _$2 = this;

  var _1 = function (g) {
    var __scope_0 = new Array(1);

    var __scope_1 = function (__selector) {
      var __captured;

      switch (__selector) {
        case 0:
          __captured = [void 0];
          break;

        default:
          throw new Error("Unknown scope selector");
      }

      __scope_0[__selector] = __captured;
      return __captured;
    };

    var _A = function () {
      var __captured__scope_2 = __scope_0[0] || __scope_1(0);

      return __captured__scope_2[0];
    };

    (__scope_0[0] || __scope_1(0))[0] = 23;

    var _$0 = g(_A);

    (__scope_0[0] || __scope_1(0))[0] = 1;
    (__scope_0[0] || __scope_1(0))[0] = 2;
    (__scope_0[0] || __scope_1(0))[0] = 3;
    (__scope_0[0] || __scope_1(0))[0] = 4;
    (__scope_0[0] || __scope_1(0))[0] = 5;

    var _$1 = (__scope_0[0] || __scope_1(0))[0];

    return _$1;
  };

  var _0 = function () {
    return _1(g => g());
  };

  _$2.inspect = _0;
}).call(this);

Ignoring the whole (__scope_0[0] || __scope_1(0))[0] verbosity, this is not great because, because after havocing...

  • Prepack emits every single binding update as a generator entry; it should only be necessary to emit the last one before the next call to an unknown function and at function exit.
  • Prepack doesn't even know internally any more what the last value actually is; that's why the return x results in code that actually reads the memory location. And worse, this lack of knowledge might cause the code to run into other prepack limitations, and suppress further optimization potential.

NTillmann avatar May 24 '18 00:05 NTillmann

#2031 made the situation a bit better for bindings, as at least for final objects the leaked final descriptor is kept around and used.

NTillmann avatar May 26 '18 00:05 NTillmann