Open Bug 1738566 Opened 10 months ago Updated 1 month ago

Scrolling and dragging a section of graph on perfherder spends a lot of time in JS

Categories

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

defect

Tracking

()

People

(Reporter: mayankleoboy1, Unassigned)

References

(Blocks 1 open bug, )

Details

Attachments

(1 file)

I had opened perfherder https://treeherder.mozilla.org/perfherder/graphs?highlightAlerts=1&highlightChangelogData=1&series=mozilla-central,3735864,1,13&series=mozilla-central,3735864,1,13&series=mozilla-central,3412570,1,13&series=autoland,3390938,1,13&timerange=5184000&zoom=1634152491755,1635216203477,183,500.78176801554355

Then I selected some region of the graph, and was using the mouse to move the selected region across the timeline

ER: Smooth movement
AR: janky movement. and the underlying graph takes a bit to come up

https://share.firefox.dev/3vYmjKY

Attached image image.png

Iain, any ideas on what this could be from the profile?

Blocks: jsperf
Type: enhancement → defect
Flags: needinfo?(iireland)

It looks like the JS that's running is lodash. In particular, the function that shows up in the profiler as e.exports is baseAssignValue:

function baseAssignValue(object, key, value) {
  if (key == '__proto__' && defineProperty) {
    defineProperty(object, key, {
      'configurable': true,
      'enumerable': true,
      'value': value,
      'writable': true
    });
  } else {
    object[key] = value;
  }
}

c< is _.defaults:

var defaults = baseRest(function(object, sources) {
  object = Object(object);

  var index = -1;
  var length = sources.length;
  var guard = length > 2 ? sources[2] : undefined;

  if (guard && isIterateeCall(sources[0], sources[1], guard)) {
    length = 1;
  }

  while (++index < length) {
    var source = sources[index];
    var props = keysIn(source);
    var propsIndex = -1;
    var propsLength = props.length;

    while (++propsIndex < propsLength) {
      var key = props[propsIndex];
      var value = object[key];

      if (value === undefined ||
          (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
        object[key] = source[key];
      }
    }
  }

  return object;
});

And 636/l< is the implementation of _.assign:

var assign = createAssigner(function(object, source) {
  if (isPrototype(source) || isArrayLike(source)) {
    copyObject(source, keys(source), object);
    return;
  }
  for (var key in source) {
    if (hasOwnProperty.call(source, key)) {
      assignValue(object, key, source[key]);
    }
  }
});

So I think the hotspots here are megamorphic property access (including hasOwnProperty). This is consistent with NativeSetProperty, GetNativeDataPropertyByValuePure, and hasNativeDataPropertyPure being the hottest C++ code.

The megamorphic property lookup cache in Jan's Watchtower work might help with this.

Flags: needinfo?(iireland)

Per Comment 3, we can see if the current work on Watchtower helps with this. I will mark it as a P2 for now so we can validate this once we make more progress on Jan's work.

Severity: -- → S3
Priority: -- → P2

FWIW, this the profile from latest nightly : https://share.firefox.dev/3crEvqE

You need to log in before you can comment on or make changes to this bug.