Sdk: Is tree-shaking removing unnecessary try/catch and try/finally?

Created on 9 Mar 2020  路  3Comments  路  Source: dart-lang/sdk

Hello,

Consider:

try {
  whatever();
} catch (err) {
  rethrow;
}

or:

try {
  whatever();
} finally {}

Then, in release builds, does it converts to:

whatever();

?


The reason why I'm asking is, I have multiple debug-only flags with code similar to:

assert(() {
  _debugIsDoingSomething = true;
  return true;
}());
doSomething();
assert(() {
  _debugIsDoingSomething = false;
  return true;
}());

But if doSomething throws, then _debugIsDoingSomething doesn't reset to false.

I could fix it by wrapping this code in a try/finally:

try {
  assert(() {
    _debugIsDoingSomething = true;
    return true;
  }());
  doSomething();
} finally {
  assert(() {
    _debugIsDoingSomething = false;
    return true;
  }());
}

But then I fear that I would impact release builds for debug-only features (even if the impact is tiny).

area-vm type-performance

Most helpful comment

2397862762f40e20d2e63308a7994d124e33ada5 removes unnecessary try/catch and try/finally very early in AOT. This makes sure that try/catch and try/finally disappear without a trace and don't have any effect on optimizations in the cases @rrousselGit listed above in Flutter profile and release modes.

Do we need to remove unnecessary try/catch and try/finally statements in JIT mode (Flutter debug mode)? Do you know any real cases where it would be useful to remove try/catch and try/finally later in the optimization pipeline (e.g. when finally becomes empty after optimizations such as inlining)? In such case we might need to add this optimization later into the optimizing pipeline as well.

All 3 comments

Back in https://codereview.chromium.org/2322853003, the VM would remove any try-finally with an empty finally. That was implemented in the VM's frontend, but it appears to not have been ported during the transition to the Dart 2 frontend.

Compiling,

try { print("Hello"); } finally {}

I see PC descriptors with a try index, both in JIT and AOT (try-ix should be -1).

pc                  kind        deopt-id    tok-ix  try-ix  yield-idx
...
0x86                unopt-call      18      27  0   -1
...

So it looks like this needs to be re-done.

@alexmarkov @mkustermann

Assigning @alexmarkov, since he started working on it.

2397862762f40e20d2e63308a7994d124e33ada5 removes unnecessary try/catch and try/finally very early in AOT. This makes sure that try/catch and try/finally disappear without a trace and don't have any effect on optimizations in the cases @rrousselGit listed above in Flutter profile and release modes.

Do we need to remove unnecessary try/catch and try/finally statements in JIT mode (Flutter debug mode)? Do you know any real cases where it would be useful to remove try/catch and try/finally later in the optimization pipeline (e.g. when finally becomes empty after optimizations such as inlining)? In such case we might need to add this optimization later into the optimizing pipeline as well.

Was this page helpful?
0 / 5 - 0 ratings