| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
Jump optimization replaces an unnecessary conditional jump, e.g.
`IFNULL l; l: ...` by `POP`, which enables further push-pop elimination.
Also introduces a `-YoptTrace` flag that traces the progress of the
bytecode as it goes through local optimizations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Otherwise we lose the side effect of a `NegativeArraySizeException`.
A test for this case already exists (run/t8601b.scala), but it currently
enforces `-optimize -Ybackend:GenASM`, so it didn't trigger on the new
backend. However, PR #4814 was merged into 2.12.x and moved that test
over to the new backend and optimizer. After merging the 2.12.x into
the current optimizer branch (push-pop elimination), the test started
failing.
Also disable the optimizer for `jvm/bytecode-test-example`: it counts
the number of null checks in a method, the optimizer (rightly) eliminates
one of the two.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous methods to identify method invocations that can be
optimized, such as `isPredefAutoBox`, were String-based. Now we
obtain class and method signatures from symbols through the
BTypes infrastructure.
We also piggy-back on specialization's type transformer to create
all specialized subclasses of Tuple1/Tuple2. We'll do the same in
the future for FunctionN, but the current JFunctionN are written
in Java and specialized artisanally.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before identifying function callsites within the same method as a
closure allocation, run DCE. The ProdCons analysis used to identify
these function calls may crash if there is unreachable code, as
observed in the community build with scala-js.
The crash was rare because inlining, which is performed before closure
optimizations, already runs DCE. However, inlining may render more
code unreachable (e.g. when inlining a method that throws).
Also make sure that DCE is always performed on the callee before
inlining: move the DCE invocation into the inlineCallsite method,
which is also invoked by the closure optimizer.
|
| |
|
|
|
|
|
|
|
|
|
| |
Ensure that LDC instructions are only eliminated when the loaded value
is a numeric or string constant. Removing other literals may remove
a potential failure. [1] lists the kind of values that can be loaded
by a LDC
[1] https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc
|
|
|
|
|
|
|
|
|
| |
Optimize IFNULL branches to GOTO when (non-)nullness of the tested
value is known statically. This enables unreachable code to be
removed, which in turn enables boxes to be eliminated.
Changed a test flag from `-Ynooptimise` to `-Yopt:l:classpath` - I
still have to do this systematically, this will follow later.
|
| |
|
|
|
|
|
|
| |
Eliminate casts that are statically known to succeed. This enables
boxes to be eliminated and simplifies the implementation of closure
allocation elimination.
|
|
|
|
|
|
|
|
|
| |
Eliminate boxes, tuples and refs that are created and used within a
single method without escaping. For details on the implementation see
the doc comment in class BoxUnbox.
This commit also cleans up the logic of inter-dependent method-level
optimizations that run until reaching a fixpoint.
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
If a DUP is consumed by two POPs, ensure that the DUP and its producer
are eliminated. Before, only the DUP was eliminated, leaving an unused
value on the stack.
|
|
|
|
|
|
|
|
| |
For methods that are too large to run a producers-consumers analysis,
don't run the closure optimizer.
This is an oversight, all data flow analyses in the backend are
guarded by a method size check.
|
|
|
|
|
|
|
|
|
| |
Fix the "consumersOfOutputsFrom" in the prod-cons analysis to support
dummy instructions:
- UninitializedLocalProducer
- ParameterProducer
- ExceptionProducer
|
|
|
|
|
|
|
|
|
|
| |
Fixes https://github.com/scala/scala-dev/issues/52.
An IndyLambda may create a specialized function type, where the SAM
is the corresponding specialized variant of apply. If this closure
is invoked through the generic apply method, the closure optimizer
would previously not re-write the invocation to the $anonfun method.
This is now done, including the necessary box / unbox operations.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Copy propagation uses an AliasingAnalyzer: it replaces a `LOAD n`
instruction by `LOAD m` where m is the smallest alias of n. This
leads to stale STORE instructions.
Stale STOREs are identified using a ProdCons analyzer and replaced by
POPs.
Values that are pushed on the stack by a side-effect free instruction
and consumed by a POP are then removed by `eliminatePushPop`. This
includes elimination of unused closure allocations and unused boxes
and tuple allocations (*).
A final cleanup eliminates `STORE x; LOADx` pairs where the stored
value is not otherwise used.
Fixes
- https://github.com/scala/scala-dev/issues/25
- https://github.com/scala/scala-dev/issues/7
- https://github.com/scala/scala-dev/issues/14
- https://github.com/scala/scala-dev/issues/12
(*) We don't yet rewrite reads of boxes and tuples yet. For example,
`val x = (1, 2); x._1` remains a method invocation and the tuple
cannot be eliminated (https://github.com/scala/scala-dev/issues/11).
Inspired in many ways by Miguel's work!
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By convention (for performance), `aliasingFrame.aliases(slot) == null`
means that the value at `slot` has no aliases, so this is isomorphic
to having a singleton `AliasSet(slot)`.
When merging an AliasingFrame `other` into `this`, at every value slot
we have to keep the intersection of the two alias sets. In other words
we have to remove from `this.aliases(slot)` those values that are
not in `other.aliases(slot)`. This was wrong for the cases where
`other.aliases == null` - we did not treat this case as a singleton
set.
|
|
|
|
|
| |
When running DCE, directly remove eliminated callsites from the call
graph (instead delegating this task to the callees).
|
| |
|
|
|
|
|
|
|
|
|
| |
Previously the VarInstruction extractor did not include IINCs.
Also give rename the isVarInstruction predicate to isLoadStoreOrRet,
as it doesn't include IINC.
Also fixes a bug in removeJumpAndAdjustStack, it checked the wrong
opcode range before.
|
| |
|
|
|
|
|
| |
This allows using an AliasingAnalyzer for copy propagation
(subsequent commit).
|
|\
| |
| | |
Add Extractor and apply Method for SoftReference
|
| |
| |
| |
| |
| |
| |
| |
| | |
scala.ref.WeakReference has two features which are lacking in
scala.ref.SoftReference, an extractor and
a .apply method that greatly enhance the usability of
that class. This commit simply replicates that functionality for
SoftReference.
|
|\ \
| | |
| | | |
SI-9527 Fix NPE in ambiguous implicit error generation
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
In #4673, an annotation was added to allow customization of the
compiler error for ambigous implicits. This change had incorrect
assumptions about the shape of trees that would be generated during
implicit search, and failed to account for the results of eta expanded
methods when searching for a function type.
This commit:
- Uses the symbol from `ImpilcitInfo`, rather than calling
`Tree#symbol` which is fraught with the danger of returning a
null symbol for something other than an application.
- Adds a test for customized messages for a polymorphic, eta
expanded method, and generalizes `treeTypeArgs` to handle the
implicit tree of shape `{ (x: X) => f[A](x)}`.
|
|\ \ \
| | | |
| | | | |
Fixes an inconsistency between BoxesRunTime and Predef's autoboxing
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Previously autoboxing implicits in Predef were inconsistent with
BoxesRunTime box/unbox due to different treatment of unboxing of
nulls. Implicits didn't check for null and would crash with NPE
unlike the BoxesRunTime which correctly returned zero value of
given type.
The fix is trivial: lets just use asInstanceOfs to implement
implicits in Predef. This would ensure that both have the same
behaviour and that the two would not diverge again in the future.
|
|\ \ \ \
| | | | |
| | | | | |
More efficient way to compute maxLocals / maxStack
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The maximal number of produced values of any instruction is 6, so we
can safely encode the number of consumed and produced values into a
single Int as (prod << 3) + cons.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Even though the two bytecodes are not allowed in classfiles of
version 51+ (see [1]), we could encounter them when inlining from a
JAR file containing classfiles of older version.
[1] https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
In order to run an asm Analyzer, the maxLocals / maxStack values of
the method need to be computed. Asm doesn't provide an efficient
built-in for this purpose, but it computes these values while
serializing a class.
Previously, we used to serialize the method just to compute the max's,
which is inefficient. This commit implements a separate, efficient
traversal.
The computed values are also smaller, allowing to save space when
running an Analyzer: asm Analyzers only allocate a single stack slot
for long/double values, while the JVM allocates two. The maxStack
computed previously would always use two slots, which is not
necessary.
The new calculation was verified to be correct in the following way:
as a test, i left the old computation in place, ran the new one in
addition (in a special mode where the long/double values take two
slots) and asserted equality. Bootstrapping and test suite passed.
|
|\ \ \ \
| | | | |
| | | | | |
SI-9535 correct bytecode and generic signatures for @throws[TypeParam]
|
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | | |
For @throws[E] where E is not a class type, GenASM incorrectly writes
the non-class type to the classfile. GenBCode used to crash before
this commit. Now GenBCode correctly emits the erased type (like
javac) and adds a generic signature.
|
|\ \ \ \
| | | | |
| | | | | |
Remove unneeded overrides from ReplGLobal
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
These seem to have been originally added as a basis for future
REPL work, for instance moving away from textual code generation
to using a custom typechecker to include definitions and imports from
previous lines in scope.
But until such work is started, lets remove the as-yet-uneeded
customizations in the name of simplicity.
(Original commits by Som Snytt, extended by Jason Zaugg to remove
the custom typer.)
|
|\ \ \ \
| | | | |
| | | | | |
f interp test is junit
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Moves test/files/run/stringinterpolation_macro-run.scala to
the junit test class test/junit/scala/StringContextTest.scala.
Adds a couple of assertions to the test.
|
|\ \ \ \
| |/ / /
|/| | | |
Simplify and correctify calculation of the InnerClass attribute
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The InnerClass attribute needs to contain an entry for every nested
class that is defined or referenced in a class. Details are in a
doc comment in BTypes.scala.
Instead of collecting ClassBTypes of nested classes into a hash map
during code generation, traverse the class before writing it out to
disk. The previous approach was incorrect as soon as the generated
bytecode was modified by the optimzier (DCE, inlining).
Fixes https://github.com/scala/scala-dev/issues/21.
|
|\ \ \ \
| |/ / /
|/| | | |
merge 2.11 to 2.12 Oct 16
|
| |\ \ \
| | |_|/
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
there were merge conflicts in the Eclipse config that I resolved with
--ours. I invite @performantdata to submit a followup PR bringing the
Eclipse stuff into a good state on 2.12.x.
there was a test failure in
test/junit/scala/collection/mutable/OpenHashMapTest.scala
due to the 2.12 compiler emitting the field backing a
private var differently (with an unmangled name). Lukas
says the difference is expected, so I just updated the
code in the test.
there were no other merge conflicts.
% git log --decorate --oneline -1 origin/2.11.x | cat
ae5f0de (origin/HEAD, origin/2.11.x) Merge pull request #4791 from performantdata/issue/9508
% git log --decorate --oneline -1 origin/2.12.x | cat
c99e53e (HEAD -> 2.12.x, origin/2.12.x) Merge pull request #4797 from lrytz/M3-versions
% export MB=$(git merge-base 2.12.x origin/2.11.x)
% echo $MB
42cafa21f3c4a08c6dd34608278f810b6ec2886f
% git log --graph --oneline --decorate $MB...origin/2.11.x | cat
* ae5f0de (origin/HEAD, origin/2.11.x) Merge pull request #4791 from performantdata/issue/9508
|\
| * 08dca37 (origin/pull/4791) SI-9508 fix classpaths in Eclipse configuration
* | fe76232 Merge pull request #4798 from performantdata/issue/9513
|\ \
| * | 9c97a7f (origin/pull/4798) Suppress unneeded import.
| * | 30d704d Document some OpenHashMap internal methods.
| * | 1fb32fc SI-9513 decrement "deleted" count in OpenHashMap.put() when slot reused
| |/
* | 14f875c Merge pull request #4788 from dk14/patch-1
|\ \
| * | 42acd55 (origin/pull/4788) explicitly specify insertion-order feature in docs
| /
* | 68ce049 Merge pull request #4771 from som-snytt/issue/9492-here
|\ \
| * | f290962 (origin/pull/4771) SI-9492 Line trimming paste
| * | bc3589d SI-9492 REPL paste here doc
| /
* | 9834fc8 Merge pull request #4610 from todesking/spec-implicits-remove-obsolete
|\ \
| * | 46009b1 (origin/pull/4610) Add view/context-bound parameter ordering rule
| * | 6eba305 Spec: Implicit parameters with context/view bound is allowed since 2.10
| /
* | d792e35 Merge pull request #4789 from janekdb/2.11.x-param-names-predicates-operations
|\ \
| |/
|/|
| * b19a07e (origin/pull/4789) Rename forall, exists and find predicate and operator params.
|/
* 648c7a1 Merge pull request #4790 from SethTisue/issue/9501
|\
| * 40d12f1 (origin/pull/4790) SI-9501 link README to Scala Hacker Guide
* e0b5891 Merge pull request #4786 from performantdata/issue/9506
* 39acad8 (origin/pull/4786) SI-9506 suppress Scala IDE-generated files in the Eclipse project dirs
* 74dc364 SI-9506 suppress Scala IDE-generated files in the Eclipse project dirs
% git merge ae5f0de
Auto-merging src/repl/scala/tools/nsc/interpreter/ILoop.scala
Auto-merging src/library/scala/util/Either.scala
Auto-merging src/library/scala/runtime/Tuple3Zipped.scala
Auto-merging src/library/scala/runtime/Tuple2Zipped.scala
Auto-merging src/library/scala/collection/parallel/ParIterableLike.scala
Auto-merging src/library/scala/collection/immutable/ListMap.scala
Auto-merging src/library/scala/collection/TraversableLike.scala
Auto-merging src/eclipse/test-junit/.classpath
CONFLICT (content): Merge conflict in src/eclipse/test-junit/.classpath
Auto-merging src/eclipse/scaladoc/.classpath
CONFLICT (content): Merge conflict in src/eclipse/scaladoc/.classpath
Auto-merging src/eclipse/scala-compiler/.classpath
Auto-merging src/eclipse/repl/.classpath
CONFLICT (content): Merge conflict in src/eclipse/repl/.classpath
Auto-merging src/eclipse/partest/.classpath
CONFLICT (content): Merge conflict in src/eclipse/partest/.classpath
Auto-merging src/eclipse/interactive/.classpath
Auto-merging README.md
Automatic merge failed; fix conflicts and then commit the result.
% git checkout --ours src/eclipse/partest/.classpath
% git checkout --ours src/eclipse/repl/.classpath
% git checkout --ours src/eclipse/scaladoc/.classpath
% git checkout --ours src/eclipse/test-junit/.classpath
% git add -u
% emacs test/junit/scala/collection/mutable/OpenHashMapTest.scala
% git diff test/junit/scala/collection/mutable/OpenHashMapTest.scala | cat
...
- val field = m.getClass.getDeclaredField("scala$collection$mutable$OpenHashMap$$deleted")
+ val field = m.getClass.getDeclaredField("deleted")
...
% git add -u
|
| | |\ \
| | | | |
| | | | | |
SI-9508 fix classpaths in Eclipse configuration
|
| | | | | |
|