Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dart2js produces bailout-heavy code for simple example of requestAnimationFrame #10071

Closed
sethladd opened this issue Apr 20, 2013 · 10 comments
Closed
Labels
closed-obsolete Closed as the reported issue is no longer relevant P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js

Comments

@sethladd
Copy link
Contributor

Consider this code:

import 'dart:html';

double _renderTime = 0;

loop(final num currentTime) {
  window.requestAnimationFrame(loop);
  
  if (_renderTime == 0)
    _renderTime = currentTime;

  if (_renderTime > currentTime)
    _renderTime = currentTime;
  
  double deltaTime = currentTime - _renderTime;
  double deltaTimeSec = deltaTime / 1000.0;
  double currentTimeSec = currentTime / 1000.0;
  
  if (deltaTime >= 1) {
    _renderTime = currentTime;
  }
}

void main() {
  window.requestAnimationFrame(loop);
}

Here's the generated code:

$.loop = function(currentTime) {
  var t1;
  if (typeof currentTime !== "number")
    return $.loop$bailout(1, currentTime);
  $.requestAnimationFrame$1$x(window, $.loop);
  t1 = $._renderTime;
  if (typeof t1 !== "number")
    return $.loop$bailout(2, currentTime, t1);
  if (t1 === 0)
    $._renderTime = currentTime;
  t1 = $._renderTime;
  if (typeof t1 !== "number")
    return $.loop$bailout(3, currentTime, t1);
  if (t1 > currentTime)
    $._renderTime = currentTime;
  t1 = $._renderTime;
  if (typeof t1 !== "number")
    return $.loop$bailout(4, currentTime, t1);
  if (currentTime - t1 >= 1)
    $._renderTime = currentTime;
};

Can we reduce the generated checks and bailouts?

@sethladd
Copy link
Contributor Author

@sethladd
Copy link
Contributor Author

One suggestion is to rewrite to:

import 'dart:html';

class Looper {
  double _renderTime = 0; // A field

  var loop; // Cached closure to pass to rAF.

  Looper() {
    loop = _loop; // Constructor needed only to initialize the cached closure.
  }

  void kick() {
    window.requestAnimationFrame(loop);
  }

  _loop(currentTime) {
    kick();
    if (currentTime is !num) throw "Impossible"; // Teach that currentTime is num.

    if (_renderTime == 0)
      _renderTime = currentTime;

    if (_renderTime > currentTime)
      _renderTime = currentTime;

    double deltaTime = currentTime - _renderTime;
    double deltaTimeSec = deltaTime / 1000.0;
    double currentTimeSec = currentTime / 1000.0;

    if (deltaTime >= 1) {
      _renderTime = currentTime;
    }
  }
}

void main() {
  new Looper().kick();
}

@sethladd
Copy link
Contributor Author

Added C3 label.

@kasperl
Copy link

kasperl commented Apr 22, 2013

Added this to the Later milestone.

@kasperl
Copy link

kasperl commented May 23, 2013

Added TriageForM5 label.

@kasperl
Copy link

kasperl commented May 28, 2013

Removed TriageForM5 label.

@kasperl
Copy link

kasperl commented Jul 10, 2014

Removed this from the Later milestone.
Added Oldschool-Milestone-Later label.

@kasperl
Copy link

kasperl commented Aug 4, 2014

Removed Oldschool-Milestone-Later label.

@srawlins
Copy link
Member

I think this is fixed, unless I'm running dart2js differently. Lines reduced from 21 to 16:

$ cat issue-10071.dart
import 'dart:html';

double _renderTime = 0;

loop(final num currentTime) {
  window.requestAnimationFrame(loop);

  if (_renderTime == 0)
    _renderTime = currentTime;

  if (_renderTime > currentTime)
    _renderTime = currentTime;

  double deltaTime = currentTime - _renderTime;
  double deltaTimeSec = deltaTime / 1000.0;
  double currentTimeSec = currentTime / 1000.0;

  if (deltaTime >= 1) {
    _renderTime = currentTime;
  }
}

void main() {
  window.requestAnimationFrame(loop);
}

$ dart2js issue-10071.dart
issue-10071.dart:3:20:
Warning: 'int' is not assignable to 'double'.
double _renderTime = 0;
                   ^
Dart file (issue-10071.dart) compiled to JavaScript: out.js

$ grep -A 16 'loop:' out.js
  loop: [function(currentTime) {
    var t1, deltaTime;
    t1 = window;
    C.Window_methods._ensureRequestAnimationFrame$0(t1);
    C.Window_methods._requestAnimationFrame$1(t1, W._wrapZone(F.loop$closure()));
    if (J.$eq($._renderTime, 0))
      $._renderTime = currentTime;
    if (J.$gt$n($._renderTime, currentTime))
      $._renderTime = currentTime;
    deltaTime = J.$sub$n(currentTime, $._renderTime);
    if (typeof deltaTime !== "number")
      return deltaTime.$div();
    if (typeof currentTime !== "number")
      return currentTime.$div();
    if (deltaTime >= 1)
      $._renderTime = currentTime;
  }, "call$1", "loop$closure", 2, 0, 6],

Only 2 check/bailout pairs, down from 4.

@floitschG
Copy link
Contributor

But it uses non-typed interceptor methods.
It looks like we don't catch that requestAnimationFrame calls the function with a double.

@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed triaged labels Feb 29, 2016
@munificent munificent removed the C3 label Jun 20, 2018
@sigmundch sigmundch added the closed-obsolete Closed as the reported issue is no longer relevant label Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-obsolete Closed as the reported issue is no longer relevant P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) web-dart2js
Projects
None yet
Development

No branches or pull requests

7 participants