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

Remove expensive debug assertion from dynlink #10184

Merged
merged 2 commits into from Feb 16, 2021

Conversation

lpw25
Copy link
Contributor

@lpw25 lpw25 commented Feb 1, 2021

Dynlink_common.check includes a call to an invariant function that just contains assertions. These assertions turn out to be expensive and don't really provide any benefit. This PR removes the call to invariant.

Copy link
Member

@dra27 dra27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't decide if the intention of let _ = function_name is more or less clear than switching off warning 32!

Equally if the check isn't useful, why not remove it entirely or, if it's potentially useful at some point in the future, change L278 to be if debugging_dynlink then State.invariant state;?

@@ -71,6 +71,8 @@ module Make (P : Dynlink_platform_intf.S) = struct
assert (String.Set.subset t.public_dynamically_loaded_units ifaces);
assert (String.Set.subset t.public_dynamically_loaded_units implems)

let _ = invariant
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not instead have let[@ocaml.warning "-32"] invariant t = above?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I prefer let _ = inveriant or let () = ignore invariant, which is a clear idiom (to me) and less visually noisy.

@gasche
Copy link
Member

gasche commented Feb 1, 2021

The invariant was added in 6526a0c (#1063).

These assertions turn out to be expensive and don't really provide any benefit.

Can you provide a bit more details?

  • What does "expensive" mean here? (The check is a bunch of call to String.Set.subset, do those sets get really large?)
  • What does "no benefit" mean here? The commit that introduces this change (among others) is called "make (nat)dynlink sound", and that seems beneficial enough. But then looking briefly at the code, it may be that some (or all?) of those checks can be statically discharged by carefully reading the implementation of the check function.

@lpw25
Copy link
Contributor Author

lpw25 commented Feb 1, 2021

What does "expensive" mean here?

I think the sets get very large. We have some cmxs files being loaded, that takes 14s and perf says that 53% of the time is spent in the invariant function.

What does "no benefit" mean here?

The function is only assert statements. If the code is correct then they can never be triggered. I think this is just a case of someone accidentally leaving in some debugging code when they had finished writing the feature.

if the check isn't useful, why not remove it entirely

The function is good documentation of the invariants of the data. It is a common idiom for a data-structure to include a function called invariants of this form. These are often useful when writing tests, but they are useful anyway as documentation.

@xavierleroy
Copy link
Contributor

I agree that these assertions should not be run by default. However, I don't like dead code left there just in case, with hacks to silence the "unused code" warning. In order of decreasing preference, I would rather

  1. remove the code entirely
  2. comment it out
  3. write it as
let debug = false
...
  if debug then check_invariants()
...

@lpw25 lpw25 force-pushed the remove-dynlink-invariants-check branch from 223e4ad to 83617de Compare February 15, 2021 11:32
@lpw25 lpw25 force-pushed the remove-dynlink-invariants-check branch from 83617de to 4e12f69 Compare February 15, 2021 12:02
@lpw25
Copy link
Contributor Author

lpw25 commented Feb 15, 2021

I went with option 1, rebased and added a Changes entry.

Copy link
Contributor

@xavierleroy xavierleroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks.

@xavierleroy xavierleroy merged commit 3dc3cd7 into ocaml:trunk Feb 16, 2021
garrigue pushed a commit to garrigue/ocaml that referenced this pull request Mar 3, 2021
smuenzel pushed a commit to smuenzel/ocaml that referenced this pull request Mar 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants