| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| | |
SI-9909: corrected stream example so it does not give forward reference
|
| |
| |
| |
| | |
error
|
|\ \
| | |
| | | |
SI-9750 scala.util.Properties.isJavaAtLeast works with JDK9
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Don't assume spec is just major, but allow arbitrary version
number for both spec value and user value to check.
Only the first three dot-separated fields are considered,
after skipping optional leading value "1" in legacy format.
Minimal validity checks of user arg are applied. Leading three
fields, if present, must be number values, but subsequent
fields are ignored.
Note that a version number is not a version string, which
optionally includes pre and build info, `9-ea+109`.
|
| | |
| | |
| | |
| | |
| | | |
A good opportunity to simplify the API. Versions are strings,
but a spec version is just a number.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Leaves the error string as is, but adds test to show how it looks.
Java calls it a version number. `Not a version: 1.9`.
Don't strip `1.` prefix recursively. (That was Snytt's fault.)
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The utility method compares javaSpecVersion, which has the
form "1.8" previously and "9" going forward.
The method accepts "1.n" for n < 9. More correctly, the string
argument should be a single number.
Supports JEP-223.
|
| | |
| | |
| | |
| | |
| | |
| | | |
just in time for Halloween. "boostrap" is definitely the most
adorable typo evah -- and one of the most common, too. but we don't
want to scare anybody.
|
|\ \ \
| | | |
| | | | |
Replace deprecated conforms
|
| | | |
| | | |
| | | | |
Replace deprecated conforms with identity.
|
|\ \ \ \
| | | | |
| | | | | |
SI-9906: override ListBuffer.last/lastOption to run in O(1) time
|
| | |_|/
| |/| |
| | | |
| | | | |
Also update scaladocs for those two methods.
|
|\ \ \ \
| | | | |
| | | | | |
Rewrite TraversableLike.stringPrefix not to blow up code size in Scala.js.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The commit 30876fe2dd8cbe657a6cad6b11bbc34f10c29b36 changed
`TraversableLike.stringPrefix` to report nicer results for inner
classes and method-local classes. The changes included calls to
`String.split()`, `Character.isDigit()` and `Character.isUpperCase()`.
This was particularly bad for Scala.js, because those methods
bring with them huge parts of the JDK (the `java.util.regex.*`
implementation on the one hand, and the Unicode database on the
other hand), which increased generated code size by 6 KB after
minimification and gzip for an application that does not otherwise
use those methods. This sudden increase is tracked in the Scala.js
bug tracker at https://github.com/scala-js/scala-js/issues/2591.
This commit rewrites `TraversableLike.stringPrefix` in a very
imperative way, without resorting to those methods. The behavior
is (mostly) preserved. There can be different results when
`getClass().getName()` contains non-ASCII lowercase letters and/or
digits. Those will now be recognized as user-defined instead of
likely compiler-synthesized (which is a progression). There still
are false positives for ASCII lowercase letters, which cause the
`stringPrefix` to be empty (as before).
Since the new implementation is imperative anyway, at least I made
it not allocate anything but the result `String` in the common
case where the result does not contain any `.`.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Merge 2.11 to 2.12
|
| |\ \ \ \ \ |
|
| | |\ \ \ \ \
| | | | | | | |
| | | | | | | | |
Doc: capitalize doesn't handle non-BMP characters
|
| | | | | | | | |
|
| |\| | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
Including PRs #5199, #5405
|
| | |/ / / / /
| | | | | | |
| | | | | | |
| | | | | | | |
ProcessBuilder.lines is deprecated
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
Cherry-picked c5f3d3f286ee5c26c8ddcf10f6878058e8f7e040
Edited comment: in stringOf, let GenIterable subsume
both Iterable and ParIterable.
This change is required for Scala.js compatibility as it does not
support parallel collections.
Conflicts:
src/library/scala/runtime/ScalaRunTime.scala
|
|/ / / / / / |
|
|\ \ \ \ \ \
| |_|_|_|/ /
|/| | | | | |
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Looking at the class hierarchy around ClassTag and Manifest, the only
class that had a serialVersionUID is AnyValManifest, where the hierarchy
is something like:
trait ClassTag // extends Serializable
|- class GenericClassTag
|- trait Manifest
|- class ClassTypeManifest
|- class SingletonTypeManifest
|- ...
|- abstract class AnyValManifest // has SerialVersionUID
|- class DoubleManifest
|- ...
Note that AnyValManifest is an abstract class, so the SerialVersionUID
annotation does not help there.
This commit adds explicit SerialVersionUID annotations to (hopefully)
all subclasses of ClassTag, to make sure they are stable under
compatible changes (such as changing -Xmixin-force-forwarders).
|
|\| | | | |
| | | | | |
| | | | | | |
merge 2.12.0 onto 2.12.x [ci: last-only]
|
| |\ \ \ \ \
| | | | | | |
| | | | | | | |
Emit local module like lazy val
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
There's still a lot of duplication,
as well as plenty of opportunities
for constant folding / simplification.
|
| |/ / / / /
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
for two reasons:
* to facilitate warning-free cross-compilation between Scala 2.11
and 2.12
* because it's not clear that .swap is a good replacement for .left
Either.right seems almost certain to be deprecated in 2.13.
Either.left's future is uncertain; see discussion (and links to
additional discussions) at https://github.com/scala/scala/pull/5135
|
| | |/ / /
| |/| | |
| | | | |
| | | | | |
Also consistently use "LAMP/EPFL" and not "EPFL LAMP".
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This follows the Scaladoc, and makes
```
"abcdef".indexOf('c', -1)
```
work like
```
"abcdef".toVector.indexOf('c', -1)
```
|
|\ \ \ \
| | | | |
| | | | |
| | | | |
| | | | | |
SD-208 Restore 2.11 names for arrayOps implicits
Fix scala/scala-dev#208
|
| | |/ /
| |/| | |
|
| | | | |
|
|\ \ \ \
| |/ / /
|/| | | |
Fields: expand lazy vals during fields, like modules
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Essentially, we fuse mixin and lazyvals into the fields phase.
With fields mixing in trait members into subclasses, we
have all info needed to compute bitmaps, and thus we can
synthesize the synchronisation logic as well.
By doing this before erasure we get better signatures,
and before specialized means specialized lazy vals work now.
Mixins is now almost reduced to its essence: implementing
super accessors and forwarders. It still synthesizes
accessors for param accessors and early init trait vals.
Concretely, trait lazy vals are mixed into subclasses
with the needed synchronization logic in place, as do
lazy vals in classes and methods. Similarly, modules
are initialized using double checked locking.
Since the code to initialize a module is short,
we do not emit compute methods for modules (anymore).
For simplicity, local lazy vals do not get a compute method either.
The strange corner case of constant-typed final lazy vals
is resolved in favor of laziness, by no longer assigning
a constant type to a lazy val (see widenIfNecessary in namers).
If you explicitly ask for something lazy, you get laziness;
with the constant-typedness implicit, it yields to the
conflicting `lazy` modifier because it is explicit.
Co-Authored-By: Lukas Rytz <lukas@lightbend.com>
Fixes scala/scala-dev#133
Inspired by dotc, desugar a local `lazy val x = rhs` into
```
val x$lzy = new scala.runtime.LazyInt()
def x(): Int = {
x$lzy.synchronized {
if (!x$lzy.initialized) {
x$lzy.initialized = true
x$lzy.value = rhs
}
x$lzy.value
}
}
```
Note that the 2.11 decoding (into a local variable and a bitmap) also
creates boxes for local lazy vals, in fact two for each lazy val:
```
def f = {
lazy val x = 0
x
}
```
desugars to
```
public int f() {
IntRef x$lzy = IntRef.zero();
VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0);
return this.x$1(x$lzy, bitmap$0);
}
private final int x$lzycompute$1(IntRef x$lzy$1, VolatileByteRef bitmap$0$1) {
C c = this;
synchronized (c) {
if ((byte)(bitmap$0$1.elem & 1) == 0) {
x$lzy$1.elem = 0;
bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 1);
}
return x$lzy$1.elem;
}
}
private final int x$1(IntRef x$lzy$1, VolatileByteRef bitmap$0$1) {
return (byte)(bitmap$0$1.elem & 1) == 0 ?
this.x$lzycompute$1(x$lzy$1, bitmap$0$1) : x$lzy$1.elem;
}
```
An additional problem with the above encoding is that the `lzycompute`
method synchronizes on `this`. In connection with the new lambda
encoding that no longer generates anonymous classes, captured lazy vals
no longer synchronize on the lambda object.
The new encoding solves this problem (scala/scala-dev#133)
by synchronizing on the lazy holder.
Currently, we don't exploit the fact that the initialized field
is `@volatile`, because it's not clear the performance is needed
for local lazy vals (as they are not contended, and as soon as
the VM warms up, biased locking should deal with that)
Note, be very very careful when moving to double-checked locking,
as this needs a different variation than the one we use for
class-member lazy vals. A read of a volatile field of a class
does not necessarily impart any knowledge about a "subsequent" read
of another non-volatile field of the same object. A pair of
volatile reads and write can be used to implement a lock, but it's
not clear if the complexity is worth an unproven performance gain.
(Once the performance gain is proven, let's change the encoding.)
- don't explicitly init bitmap in bytecode
- must apply method to () explicitly after uncurry
|
|\ \ \ \
| | | | |
| | | | | |
SI-9823 Collections perf: favor virtual call over instanceof
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This avoids concurrent usages of collections in NUMA architectures
from falling of a performance cliff due to an implementation detail
of interface instanceof checks in HotSpot JVM.
The VM contains a one element cache in the metadata of each class
to record the most recent successful test for a interface.
For example:
classOf[Serializable].isAssignableFrom(classOf[Some[_]])
Would, in addition to returning `true`, set:
classOf[Some[_]]._secondary_super_cache = classOf[Serializable]
This is done to hide the fact that interface tests are O(N),
where N is the number of inherited interfaces.
This scheme is discussed in "Fast Subtype Checking for the
HotSpot JVM" (Click, Rose) [1]
However, if this cache repeatedly misses, not only are we
exposed to the linear search of the secondary super type array,
but we are also required to write back to the cache. If other
cores are operating on the same cache line, this can lead to
a significant slowdown ("cache thrashing"). This effect will
by most (or only?) visible on multi socket machines.
The pathological case is:
scala> Iterator.continually(List(classOf[Product], classOf[Serializable])).flatten.take(100).map(intf => intf.isAssignableFrom(classOf[Some[_]])).count(x => x)
res19: Int = 100
Which, if run on a multi-socket machine, should be much slower
than:
scala> (Iterator.continually(classOf[Product]).take(50) ++ Iterator.continually(classOf[Serializable]).take(50)).map(intf => intf.isAssignableFrom(classOf[Some[_]])).count(x => x)
res20: Int = 100
This commit avoids a interface test in a hot path in the collections
by instead using virtual dispatch to differentiate between
IndexedSeqLike and other collections. HotSpot will still use some
shared bookkeeping ("inline cache" [2]) at the callsites of
this method, but these stabilize in the megamorphic usage and no
longer force expensive cache line synchronization.
[1] https://www.researchgate.net/publication/221552851_Fast_subtype_checking_in_the_HotSpot_JVM
[2] https://wiki.openjdk.java.net/display/HotSpot/PerformanceTechniques
|
|/ / /
| | |
| | |
| | |
| | | |
Follow-up to remove the overloads, which is source
compatible, in favor of unapply(Any).
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The check for inheriting two conflicting members was wrong for default
methods, leading to a missing error message.
We were also not issuing "needs `override' modifier" when overriding a
default method.
Removes two methods:
- `isDeferredOrJavaDefault` had a single use that is removed in this commit.
- `isDeferredNotJavaDefault` is redundant with `isDeferred`, because
no default method has the `DEFERRED` flag:
- For symbols originating in the classfile parser this was the case
from day one: default methods don't receive the `DEFERRED` flag.
Only abstract interface methods do, as they have the `JAVA_ACC_ABSTRACT`
flag in bytecode, which the classfile parser translates to `DEFERRED`.
- For symbols created by the Java source parser, we don't add the
`DEFERRED` to default methods anymore since 373db1e.
Fixes scala/scala-dev#128
|
|\ \ \
| | | |
| | | | |
SD-193 Lock down lambda deserialization
|
| | | |
| | | |
| | | |
| | | |
| | | | |
- Remove unused references to "addTargetMethods"
- Require that `targetMethodMap` is provided
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The old design allowed a forged `SerializedLambda` to be
deserialized into a lambda that could call any private method
in the host class.
This commit passes through the list of all lambda impl methods
to the bootstrap method and verifies that you are deserializing
one of these.
The new test case shows that a forged lambda can no longer call
the private method, and that the new encoding is okay with a large
number of lambdas in a file.
We already have method handle constants in the constant pool
to support the invokedynamic through LambdaMetafactory, so
the only additional cost will be referring to these in
the boostrap args for `LambdaDeserialize`, 2 bytes per lambda.
I checked this with an example:
https://gist.github.com/retronym/e343d211f7536d06f1fef4b499a0a177
Fixes SD-193
|
|\ \ \ \
| | | | |
| | | | | |
SI-7838 Document the multi-threading semantics of List and Vector
|
| | | | |
| | | | |
| | | | |
| | | | | |
Making them completely thread-safe would be too expensive (in terms
of performance of single-threaded use cases).
|
|\ \ \ \ \
| | | | | |
| | | | | | |
SI-8576 Minimal changes for `-Xcheckinit` compatibility
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
As explained in https://issues.scala-lang.org/browse/SI-8576, I expect
serialization compatibility between builds with and without
`-Xcheckinit` to be unattainable. This commit contains some minor fixes
for issues discovered while running builds with `-Xcheckinit`:
- Add `@SerialVersionUID` to `scala.collection.immutable.Vector`, as
requested in SI-8576. Note that this does not make `Vector`
serialization compatible.
- Use lazy initialization for `global` in `PresentationCompilation`. It
used to access the uninitialized `self` variable (which seems to be
inconsequential in practice and only fails under `-Xcheckinit`).
We should consider using `Externalizable` instead of `Serializable` for
collections in 2.13 to make collection classes serialization compatible.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
SI-8434 Make generic Set operations build the same kind of Set
|
| |/ / / / /
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
When building from a `Set` implementation that was statically seen as
a `collection.GenSet` or `collection.Set`, we used to build a default
`Set` implementation determined by `GenSetFactory.setCanBuildFrom`.
This change modifies `setCanBuildFrom` to determine the correct
implementation at runtime by asking the source `Set`’s companion object
for the `Builder`.
Tests are in `NewBuilderTest.mapPreservesCollectionType`, including lots
of disabled tests for which I believe there is no solution under the
current collection library design.
`Map` suffers from the same problem as `Set`. This *can* be fixed in the
same way as for `Set` with some non-trivial changes (see the note in
`NewBuilderTest`), so it is probably best left for Scala 2.13.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
SI-9019 TraversableLike stringPrefix broken for inner classes
|
| | |_|_|_|/
| |/| | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This version preserves outer class and object names but discards
any part of the name after a `$` that does not start with an upper-case
letter. When an integer literal occurs after a `$`, the prefix up to
that point is dropped so that classes defined within methods appear as
top-level.
|