| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
Miscellania:
Miscellania is a small island off the northernmost part
of the Fremennik Isles - RunScape Wiki
Miscellanea:
A collection of miscellaneous objects or writings - Merriam-Webster
|
|
|
|
|
|
|
| |
For classes being compiled (vs. being loaded from classfiles), keep the
source file path in the bytecode repo. This will allow to keep line
numbers when inlining from one class into another in case the two are
defined in the same compilation unit.
|
|\
| |
| | |
Remove legacy recursive classpath implementation
|
| | |
|
| | |
|
| |
| |
| |
| |
| | |
When inheriting multiple default methods, select the correct one to
inline. Implements method resolution according to the JVM spec.
|
|/
|
|
|
|
|
|
|
| |
Implicit conversions are now in package convert as ImplicitConversions,
ImplicitConversionsToScala and ImplicitConversionsToJava.
Deprecated WrapAsJava, WrapAsScala and the values in package object.
Improve documentation.
|
|
|
|
|
| |
If a class (trait) is a SAM type, store the name and descriptor of the
SAM in the ClassBType's InlineInfo.
|
|
|
|
|
|
|
|
|
| |
Store classes being compiled in a separate hash map. This allows
efficiently traversing all classes being compiled. It also simplifies
limiting the size of the cache of class nodes parsed from classfiles.
Also change the cache of class nodes parsed from classfiles to LRU
instead of FIFO.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When an indylambda closure is allocated and invoked within the same
method, rewrite the invocation to the implementation method.
This works for any indylambda / SAM type, not only Scala functions.
However, the Scala compiler (under -Xexperimental) currently desugars
function literals for non-FunctionN types to an anonymous class during
typer.
No testing yet, waiting for FunctionN to become SAMs first.
The feature requires scala-java8-compat to be on the classpath and a
number of compiler flags:
-Ydelambdafy:method -Ybackend:GenBCode -Yopt:closure-elimination -target:jvm-1.8
➜ scala git:(opt/closureInlining) ant -Dscala-java8-compat.package=1 -Dlocker.skip=1
➜ scala git:(opt/closureInlining) cd sandbox
➜ sandbox git:(opt/closureInlining) cat Fun.java
public interface Fun<T> {
T apply(T x);
}
➜ sandbox git:(opt/closureInlining) javac Fun.java
➜ sandbox git:(opt/closureInlining) cat Test.scala
class C {
val z = "too"
def f = {
val kap = "me! me!"
val f: Tuple2[String, String] => String = (o => z + kap + o.toString)
f(("a", "b"))
}
def g = {
val f: Int => String = x => x.toString
f(10)
}
def h = {
val f: Fun[Int] = x => x + 100 // Java SAM, requires -Xexperimental, will create an anonymous class in typer
f(10)
}
def i = {
val l = 10l
val f: (Long, String) => String = (x, s) => s + l + z + x
f(20l, "n")
}
def j = {
val f: Int => Int = x => x + 101 // specialized
f(33)
}
}
➜ sandbox git:(opt/closureInlining) ../build/quick/bin/scalac -target:jvm-1.8 -Yopt:closure-elimination -Ydelambdafy:method -Ybackend:GenBCode -Xexperimental -cp ../build/quick/scala-java8-compat:. Test.scala
➜ sandbox git:(opt/closureInlining) asm -a C.class
➜ sandbox git:(opt/closureInlining) cat C.asm
[...]
public g()Ljava/lang/String;
L0
INVOKEDYNAMIC apply()Lscala/compat/java8/JFunction1; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/LambdaMetafactory.altMetafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
// arguments:
(Ljava/lang/Object;)Ljava/lang/Object;,
// handle kind 0x6 : INVOKESTATIC
C.C$$$anonfun$2$adapted(Ljava/lang/Object;)Ljava/lang/String;,
(Ljava/lang/Object;)Ljava/lang/String;,
3,
1,
Lscala/Serializable;.class,
0
]
CHECKCAST scala/Function1
L1
ASTORE 1
L2
ALOAD 1
BIPUSH 10
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
ASTORE 2
POP
ALOAD 2
INVOKESTATIC C.C$$$anonfun$2$adapted (Ljava/lang/Object;)Ljava/lang/String;
CHECKCAST java/lang/String
L3
ARETURN
[...]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Issue precise warnings when the inliner fails to inline or analyze a
callsite. Inline failures may have various causes, for example because
some class cannot be found on the classpath when building the call
graph. So we need to store problems that happen early in the optimizer
(when building the necessary data structures, call graph, ClassBTypes)
to be able to report them later in case the inliner accesses the
related data.
We use Either to store these warning messages. The commit introduces
an implicit class `RightBiasedEither` to make Either easier to use for
error propagation. This would be subsumed by a biased either in the
standard library (or could use a Validation).
The `info` of each ClassBType is now an Either. There are two cases
where the info is not available:
- The type info should be parsed from a classfile, but the class
cannot be found on the classpath
- SI-9111, the type of a Java source originating class symbol cannot
be completed
This means that the operations on ClassBType that query the info now
return an Either, too.
Each Callsite in the call graph now stores the source position of the
call instruction. Since the call graph is built after code generation,
we build a map from invocation nodes to positions during code gen and
query it when building the call graph.
The new inliner can report a large number of precise warnings when a
callsite cannot be inlined, or if the inlining metadata cannot be
computed precisely, for example due to a missing classfile.
The new -Yopt-warnings multi-choice option allows configuring inliner
warnings.
By default (no option provided), a one-line summary is issued in case
there were callsites annotated @inline that could not be inlined.
|
|
|
|
|
| |
I observed cases (eg Scaladoc tests) where we end up with 17k+
ClassNodes, which makes 500 MB.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In order to inline a final trait method, callsites of such methods are
first re-written from interface calls to static calls of the trait's
implementation class. Then inlining proceeds as ususal.
One problem that came up during development was that mixin methods are
added to class symbols only for classes being compiled, but not for
others. In order to inline a mixin method, we need the InlineInfo,
which so far was built using the class (and method) symbols. So we had
a problem with separate compilation.
Looking up the symbol from a given classfile name was already known to
be brittle (it's also one of the weak points of the current inliner),
so we changed the strategy. Now the InlineInfo for every class is
encoded in a new classfile attribute.
This classfile attribute is relatively small, because all strings it
references (class internal names, method names, method descriptors)
would exist anyway in the constant pool, so it just adds a few
references.
When building the InlineInfo for a class symbol, we only look at the
symbol properties for symbols being compiled in the current run. For
unpickled symbols, we build the InlineInfo by reading the classfile
attribute.
This change also adds delambdafy:method classes to currentRun.symSource.
Otherwise, currentRun.compiles(lambdaClass) is false.
|
|
|
|
|
|
|
| |
The `ByteCodeRepository.classNode(InternalName)` method now returns an
option. Concretely, in mixed compilation, the compiler does not create
a ClassNode for Java classes, and they may not exist on the classpath
either.
|
|
|
|
|
|
|
|
|
| |
The method Inliner.inline clones the bytecode of a method and copies
the new instructions to the callsite with the necessary modifications.
See comments in the code.
More tests are added in a later commit which integrates the inliner
into the backend - tests are easier to write after that.
|
|
|
|
|
|
|
| |
Some instructions would cause an IllegalAccessError if they are
inlined into a different class.
Based on Miguel's implementation in 6efc0528c6.
|
|
- Rename CodeRepository to ByteCodeRepository
- Scaladoc on OptimizerReporting
- Scaladoc on ByteCodeRepository
|