scala-js/scala-js — pull request #1100 by sjrd (2014-09-22 18:42:04+00:00)
Title: Separate the knowledge query getMethodBody() from resolve calls.

The three existing knowledge queries staticCall, dynamicCall and
traitImplCall are not invalidated anymore if the *body* (the
`originalDef`) of a MethodImpl changes. They are invalidated only
for added methods, removed methods, and when a public "attribute"
of a method changes.

Attributes are the `inlineable` and `isTraitImplForwarder` flags.
They are exposed clearly in the MethodID interface, which is what
is returned from the three queries above.

A MethodID does not give access to its body. To do that, another,
separate knowledge query getMethodBody() is provided.

This separation follows what we described in the paper. It makes
sure we do not break our own assumptions by encoding in the type
system that MethodID only gives access to the flags that are
examined for the three xxCalls queries; and not to the body
itself.

It has at least one direct advantage in terms of accuracy of
detecting what to reoptimize: if only the body of an inlineable
method changes (but it remains inlineable and keeps the value of
its isTraitImplForwarder flag), then call sites that could call
that method with a dynamicCall, but cannot actually inline it
because there are multiple targets, need not be reoptimized.
This is especially important for the FunctionN.apply() case,
because all anonymous functions that are compiled as classes have
their apply method marked with `@inline`.

There is another potential advantage for the future: it makes it
possible, and sound, to decide to inline a method even if it does
not have the inlineable flag on.