summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #3798 from adriaanm/scalapAdriaan Moors2014-06-021-0/+5
|\ | | | | Include scalap in the distro.
| * Include scalap in the distro.Adriaan Moors2014-05-281-0/+5
| |
* | Merge pull request #3774 from lrytz/opt/backendWipLukas Rytz2014-06-0113-1063/+744
|\ \ | | | | | | More type safe implementation of BType, cleanups in GenBCode
| * | Unit tests for new BType classesLukas Rytz2014-06-011-1/+4
| | |
| * | Rewrite BType to a type hierarchy.Lukas Rytz2014-06-018-849/+508
| | | | | | | | | | | | | | | | | | | | | | | | | | | This makes BTypes more type safe. It fixes at least one bug: the old BTypes are not actually hash-consed. This worked because the equals method used to have a fallback that would compare the represented string character-by-character.
| * | Move class BType to separate component, include it by composition.Lukas Rytz2014-05-227-62/+72
| | | | | | | | | | | | | | | | | | Rewire BType in its new location with the rest of the backend. Remove the now-empty BCodeGlue.
| * | More cleanups and commenting in GenBCodeLukas Rytz2014-05-213-35/+20
| | |
| * | Re-use the exsiting range of the name table when using subName.Lukas Rytz2014-05-211-4/+10
| | | | | | | | | | | | The sub-name can just point to a smaller range of the array.
| * | Cleanups in Names.scalaLukas Rytz2014-05-211-53/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Enter only fully constructed Name objects into the hash table, this should make lookupTypeName thread-safe. Clean up lookupTypeName - the hash code for a type name is the same as for its correspondent term name. Going from a type name toTermName should never create a new TermName instance. Assert that.
| * | Minor cleanups and commenting around BType.Lukas Rytz2014-05-212-76/+103
| | | | | | | | | | | | Use `length` instead of `size` on arrays in `reflect/internal/Names`.
| * | Cleanups for tracing in GenBCode, improve some commentsLukas Rytz2014-05-214-11/+17
| | |
* | | Merge pull request #3770 from retronym/ticket/8607Grzegorz Kossakowski2014-05-291-7/+5
|\ \ \ | | | | | | | | SI-8607 Fix erasure for value class inheriting from private class
| * | | SI-8607 Generalize previous change to preEraseJason Zaugg2014-05-211-14/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the previous commit, we avoided an awkward chain of casts by exploiting the knowledge that Scala defined classes will by JVM accessible, and as such immune to `LinkageError`s when used as the target of a cast. This commit generalized this to the entire fix for SI-4283, rather than just for derived value classes.
| * | | SI-8607 Fix erasure for value class inheriting from private classJason Zaugg2014-05-211-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The fix for SI-4283 added a pre-emptive cast of the qualifier of a selection `qual.a` to avoid later casting to the owner of `a` if that owner might be inaccessible at the call site. This fixed a `LinkageError`. In the enclosed test, this cast led to the following diff in the tree shapes (with respect to a version with a public base class). [erasure] - new p1.C.<init>(c.$asInstanceOf[scala.this.Int]()).a(); + new p1.C.<init>(new p1.C.<init>(c.$asInstanceOf[scala.this.Int]()).$asInstanceOf[ErasedValueType( class C, scala.this.Int)]().$asInstanceOf[scala.this.Int]()).a(); [posterasure] - new p1.C.<init>(c).a(); + new p1.C.<init>(new p1.C.<init>(c).$asInstanceOf[scala.this.Int]().$asInstanceOf[scala.this.Int]()) .a(); () What we really wanted to end up with is: new p1.C.<init>(c).$asInstanceOf[C]().a(); The stray cast leads to the crash: error: should have been unboxed by erasure: new p1.C.<init>(c).$asInstanceOf[scala.this.Int]() Rather than trying to fix this in erasure/posterasure, this commit instead relies on the fact the owner of `a` cannot be Java defined if `qual`s type is a derived value class. This follows from the restrictions we place on value classes. With this knowledge, we elide the cast altogether in this case.
* | | | Merge pull request #3791 from S11001001/ticket/8346Ichoran2014-05-293-6/+24
|\ \ \ \ | |_|_|/ |/| | | SI-8346 Rebuild invariant sets in #toSet, avoiding CCE
| * | | SI-8346: Rebuild invariant sets in #toSet, avoiding CCE.Stephen Compall2014-05-243-6/+24
| | |/ | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | SI-3953 caused several types of sets' operations to trivially throw `ClassCastException` after using inherited covariant #toSet method, by doing an unchecked cast that is only safe for intrinsically covariant set data structures like `HashSet`, but totally unsafe for others like `TreeSet` or `Enumeration.ValueSet`. This change moves the cast to the leaves of the class hierarchy where that is safe, and incidentally undeprecates overriding Set#toSet.
* | | Merge pull request #3735 from lefou/osgi-fixAdriaan Moors2014-05-2811-8/+30
|\ \ \ | | | | | | | | OSGi: Restrict Import-Package for scala.*
| * | | Re-added the scala.util.parsing package import, with optional resolution.Tobias Roeser2014-05-091-1/+1
| | | |
| * | | Refined package imports for scala modules.Tobias Roeser2014-05-061-2/+2
| | | | | | | | | | | | | | | | Made scala.xml.* import optional and removed scala.util.parsing.json import.
| * | | Add JavaSE-1.7 to set of required execution environments.Tobias Roeser2014-05-0511-21/+11
| | | | | | | | | | | | | | | | Without it, Equinox on Java 7 might spit out some warnings, which might lead to the wrong impression, that the Scala bundles are not well supported for newer platforms.
| * | | Restrict Import-Package for scala.*Tobias Roeser2014-04-3011-8/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Restrict the Import-Package OSGi manifest entry to match only binary compatible scala.* packages. This is necessary, because the Scala OSGi versions do not match the OSGi semantic versioning policy and are not binary compatible between their OSGi minor versions. This means that e.g. the scala-compiler-2.11 bundle will never work if it imports a scala.* package from 2.10 or 2.12. Thus this patch enforces a tight version range, only accepting versions within the same minor version. E.g. Applied to version 2.11.1 the range would expand to "[2.11,2.12)". Additionally, a Java 6 execution environment will be enforced for OSGi. All module bundles need to have their own version numbers. This was not the case before this commit. Although these module bundles were only build for testing, they are needed to be correct, now, that we have stricter package import constraints and some test cases rely on them.
* | | | Merge pull request #3733 from retronym/topic/pr-3712-resubmitJason Zaugg2014-05-271-1/+3
|\ \ \ \ | | | | | | | | | | SI-8475 Fix off by one in GroupedIterator when Streaming
| * | | | SI-8475 Fix off by one in GroupedIterator when StreamingJean-Remi Desjardins2014-05-091-1/+3
| | | | | | | | | | | | | | | | | | | | This also affected sliding and grouped since they defer to GroupedIterator
* | | | | Merge pull request #3794 from lrytz/t8625Jason Zaugg2014-05-271-3/+10
|\ \ \ \ \ | | | | | | | | | | | | SI-8625 fix unreachability analysis for boolean expressions
| * | | | | SI-8625 fix unreachability analysis for boolean expressionsLukas Rytz2014-05-271-3/+10
| | | | | |
* | | | | | Merge pull request #3782 from retronym/topic/opt-scopeJason Zaugg2014-05-275-27/+33
|\ \ \ \ \ \ | |/ / / / / |/| | | | | Compiler optimizations for Scopes, checkDoubleDefs, Namer
| * | | | | Optimize enforcement of dependent method type restrictionsJason Zaugg2014-05-261-5/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - No need to check the result type, as dependent method types are now enabled unconditionally. - This also means we can only need to check methods with two or more parameter lists.
| * | | | | Fast path in Namer for methods without defaultsJason Zaugg2014-05-261-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Either direct defaults, or directly inherited. The avoids `addDefaultGetters` in most cases, and the expensive duplication of trees therein.
| * | | | | Optimize nested scope creationJason Zaugg2014-05-263-15/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can copy the hash table from the parent scope, rather than constructing it from scratch. This takes us to: % rm -rf /tmp/pkg; (for i in {1..50}; do for j in {1..100}; do echo "package pkg { class A_${i}_${j}___(val a: Int, val b: Int) }"; done; done) > sandbox/A1.scala && time qbin/scalac -Ybackend:GenASM -J-Xmx1G -J-XX:MaxPermSize=400M -d /tmp sandbox/A1.scala; real 0m19.639s // head~1 was 0m35.662s user 0m41.683s // head~1 was 0m58.275s sys 0m1.886s In more detail, this commit: - Removes the unused `fingerprint` constructor parameter from scopes. This is a remnant from a previous optimization attempt - Leave only one constructor on Scope which creates an empty scope - Update the factory method, `newNestedScope`, to copy the hash table from the parent if it exists. We can rely on the invariant that `outer.hashTable != null || outer.size < MIN_HASH)`, so we don't need `if (size >= MIN_HASH) createHash()` anymore. This used to be needed in `Scope#<init>`, which accepted an aribitrary `initElems: ScopeEntry`. - Update subclasses and factories of `Scope` in runtime reflection to accomodate the change. Pleasingly, we could actually remove the override for `newNestedScope`. - Unit tests the functionality I'm touching
| * | | | | Eliminate some N^2 performance in type checkingJason Zaugg2014-05-261-4/+7
| | |_|/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Where N is the number of members of the enclosing package. Double definition errors for top level classes/objects are issued elsewhere, as demonstrated by the enclosed test. So we can omit the call to `checkNoDoubleDefs` in this content. We can't omit the call to `addSynthetics` for package class owners (case- and value-class synthetic companions are added here), but we can make the process cheaper by moving the expensive-but-usually-true call to `shouldAdd`. Here's an example of the improvement. % rm -rf /tmp/pkg; (for i in {1..50}; do for j in {1..100}; do echo "package pkg { class A_${i}_${j}___(val a: Int, val b: Int) }"; done; done) > sandbox/A1.scala && time scalac-hash v2.11.0 -Ybackend:GenASM -J-Xmx1G -J-XX:MaxPermSize=400M -d /tmp sandbox/A1.scala; real 0m49.762s user 1m12.376s sys 0m2.371s % rm -rf /tmp/pkg; (for i in {1..50}; do for j in {1..100}; do echo "package pkg { class A_${i}_${j}___(val a: Int, val b: Int) }"; done; done) > sandbox/A1.scala && time qbin/scalac -Ybackend:GenASM -J-Xmx1G -J-XX:MaxPermSize=400M -d /tmp sandbox/A1.scala; real 0m35.662s user 0m58.275s sys 0m2.355s We've still got another source of pathological performance in creating nested scopes that I'll fix in the next commit.
* / | | | SI-8617 Avoid rangepos crash for OptManifest materializerJason Zaugg2014-05-241-1/+1
|/ / / / | | | | | | | | | | | | The tree to create a `NoManifest` was unpositioned.
* | | / Upgrade ASM to 5.0.2Lukas Rytz2014-05-2069-313/+3846
| |_|/ |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is a squashed version of all commits in PR #3747. For future upgrades, consult the README and check the commits in https://github.com/scala/scala/pull/3747/commits There's one bug in ASM 5.0.2 that breaks scalac: http://forge.ow2.org/tracker/?func=detail&aid=317200&group_id=23&atid=100023 This bug is fixed in ASM trunk, the patch has been merged into this commit. A future upgrade of ASM should contain the fix.
* | | Merge pull request #3756 from mkubala/ticket/8591Jason Zaugg2014-05-201-0/+1
|\ \ \ | | | | | | | | SI-8591 Scaladoc: Problem with scrolling under Safari on iOS
| * | | SI-8591 Scaladoc: Problem with scrolling under Safari on iOSMarcin Kubala2014-05-161-0/+1
| | | |
* | | | Merge pull request #3748 from retronym/ticket/8587Jason Zaugg2014-05-202-8/+7
|\ \ \ \ | | | | | | | | | | SI-8587 Explicitly document forall/exists for empty collections
| * | | | SI-8587 Explicitly document forall/exists for empty collectionsJason Zaugg2014-05-142-8/+7
| |/ / / | | | | | | | | | | | | | | | | | | | | This behaviour isn't always intuitive for newcomers. Also changes inadvertant doc comment to an impl. comment.
* | | | Merge pull request #3761 from som-snytt/issue/8507-onlyJason Zaugg2014-05-201-47/+50
|\ \ \ \ | | | | | | | | | | SI-8507 Avoid lazy val in StringContext
| * | | | SI-8507 Avoid lazy val in StringContextSom Snytt2014-05-131-47/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This mild refactor eliminates the lazy val StringBuilder and arguably makes the code easier to read. There is a small unit test but no benchmark to prove anything useful about performance. The ticket notes contention due to lazy implementation.
* | | | | SI-8601 Don't treat newarray as dead codeJason Zaugg2014-05-191-1/+1
| | | | | | | | | | | | | | | | | | | | Otherwise we lose the side effect of a `NegativeArraySizeException`.
* | | | | SI-8601 Avoid over-eager optimization of LOAD_FIELDJason Zaugg2014-05-192-5/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It can NPE or trigger static class initilization, we can't elimiate it without changing semantics. To make sure we don't thwart closure elimination, I've allowed DCE to eliminate a non-static LOAD_FIELD of a member of a closure class. It would be more general to track nullity of the reciever (e.g, `this` or `new Foo` cannot be null), but that would require more infrastructure in this phase. I've added a test for closure inlining based on a a suggestion by @dragos. This actually passes if we remove the (LOAD_FIELD, DROP) peephole optimization for `closelim` altogether. But I chose to adapt that optimization (only allow it for non-static, closure fields), rather then remove it alogether, in the interests of treading lightly.
* | | | | SI-8601 Don't treat int/long division, or arraylength, as dead-codeJason Zaugg2014-05-191-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `{i, l}div` and `{i, l}rem` throw an `ArithmeticException` if the divisor is 0. `arraylength` throws a `NullPointerException` on a null reference. JVM Spec: > The only integer operations that can throw an exception are the > integer divide instructions (idiv and ldiv) and the integer > remainder instructions (irem and lrem), which throw an > ArithmeticException if the divisor is zero. > The Java virtual machine's floating-point operators do not throw > runtime exceptions > If the arrayref is null, the arraylength instruction throws a > NullPointerException. I checked the other primitives in `ICode` to see if anything else should be considered as live code. Pure: // jvm : {i, l, f, d}neg case class Negation(kind: TypeKind) extends Primitive // jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull} // if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne} case class Test(op: TestOp, kind: TypeKind, zero: Boolean) extends Primitive // jvm : lcmp, {f, d}cmp{l, g} case class Comparison(op: ComparisonOp, kind: TypeKind) extends Primitive Impure: {i, l}{div, rem}, otherwise pure // jvm : {i, l, f, d}{add, sub, mul, div, rem} case class Arithmetic(op: ArithmeticOp, kind: TypeKind) extends Primitive Pure (overflow is silent, NaN.toInt is defined): // jvm : {i, l}{and, or, xor} case class Logical(op: LogicalOp, kind: TypeKind) extends Primitive // jvm : {i, l}{shl, ushl, shr} case class Shift(op: ShiftOp, kind: TypeKind) extends Primitive // jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s} case class Conversion(src: TypeKind, dst: TypeKind) extends Primitive Impure! May NPE! // jvm : arraylength case class ArrayLength(kind: TypeKind) extends Primitive Pure (we know that StringBuilder.{<init>, append, toString} are pure and `append` is null safe.) // jvm : It should call the appropiate 'append' method on StringBuffer case class StringConcat(el: TypeKind) extends Primitive // jvm: it should create a new StringBuffer case object StartConcat extends Primitive // jvm: convert StringBuffer to a String case object EndConcat extends Primitive
* | | | | Revert "SI-8601 Don't treat int/long division, or arraylength, as dead-code"Adriaan Moors2014-05-191-2/+0
| | | | | | | | | | | | | | | | | | | | This reverts commit ee611cd76c29fedd416162e482c7ab3f15b831ca.
* | | | | Revert "SI-8601 Avoid over-eager optimization of LOAD_FIELD"Adriaan Moors2014-05-192-5/+6
| | | | | | | | | | | | | | | | | | | | This reverts commit 0b432f9cd22b6e9770852e5b331a15f0534a312c.
* | | | | Revert "SI-8601 Don't treat newarray as dead code"Adriaan Moors2014-05-191-1/+1
| | | | | | | | | | | | | | | | | | | | This reverts commit 70b912a87433c9589af33e4f8b33dca39abb66e5.
* | | | | SI-8601 Don't treat newarray as dead codeJason Zaugg2014-05-181-1/+1
| | | | | | | | | | | | | | | | | | | | Otherwise we lose the side effect of a `NegativeArraySizeException`.
* | | | | SI-8601 Avoid over-eager optimization of LOAD_FIELDJason Zaugg2014-05-182-6/+5
| | | | | | | | | | | | | | | | | | | | | | | | | It can NPE or trigger static class initilization, we can't elimiate it without changing semantics.
* | | | | SI-8601 Don't treat int/long division, or arraylength, as dead-codeJason Zaugg2014-05-181-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `{i, l}div` and `{i, l}rem` throw an `ArithmeticException` if the divisor is 0. `arraylength` throws a `NullPointerException` on a null reference. JVM Spec: > The only integer operations that can throw an exception are the > integer divide instructions (idiv and ldiv) and the integer > remainder instructions (irem and lrem), which throw an > ArithmeticException if the divisor is zero. > The Java virtual machine's floating-point operators do not throw > runtime exceptions > If the arrayref is null, the arraylength instruction throws a > NullPointerException. I checked the other primitives in `ICode` to see if anything else should be considered as live code. Pure: // jvm : {i, l, f, d}neg case class Negation(kind: TypeKind) extends Primitive // jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull} // if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne} case class Test(op: TestOp, kind: TypeKind, zero: Boolean) extends Primitive // jvm : lcmp, {f, d}cmp{l, g} case class Comparison(op: ComparisonOp, kind: TypeKind) extends Primitive Impure: {i, l}{div, rem}, otherwise pure // jvm : {i, l, f, d}{add, sub, mul, div, rem} case class Arithmetic(op: ArithmeticOp, kind: TypeKind) extends Primitive Pure (overflow is silent, NaN.toInt is defined): // jvm : {i, l}{and, or, xor} case class Logical(op: LogicalOp, kind: TypeKind) extends Primitive // jvm : {i, l}{shl, ushl, shr} case class Shift(op: ShiftOp, kind: TypeKind) extends Primitive // jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s} case class Conversion(src: TypeKind, dst: TypeKind) extends Primitive Impure! May NPE! // jvm : arraylength case class ArrayLength(kind: TypeKind) extends Primitive Pure (we know that StringBuilder.{<init>, append, toString} are pure and `append` is null safe.) // jvm : It should call the appropiate 'append' method on StringBuffer case class StringConcat(el: TypeKind) extends Primitive // jvm: it should create a new StringBuffer case object StartConcat extends Primitive // jvm: convert StringBuffer to a String case object EndConcat extends Primitive
* | | | | Merge pull request #3738 from retronym/ticket/8574Jason Zaugg2014-05-172-1/+2
|\ \ \ \ \ | |_|/ / / |/| | | | SI-8574 Copy @SerialVersionUID, etc, to specialized subclasses
| * | | | SI-8574 Copy @SerialVersionUID, etc, to specialized subclassesJason Zaugg2014-05-162-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The test case demonstrates that this is important for serialization and for strictfp. (Although the latter is still pretty broken, see SI-7954.) Now that the synthetic subclass of `Tuple2[Int, Int]` also has the `@deprecatedInheritance` annotation, I had to change the spot that issues this warning to be silent after the typer phase. Otherwise, we get two warnings in `run/t3888.scala`. This also remedies double warnings that were incurred in `neg/t6162-inheritance`.
* | | | | SI-8582 emit InnerClasses attribute in GenBCodeLukas Rytz2014-05-131-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I removed the `-bcode` test since we have a build that passes `-Ybackend:GenBCode` to all tests. Short intro do the [`InnerClass` attribute][1]: - A class needs one `InnerClass` attribute for each of its nested classes - A class needs the `InnerClass` attribute for all (nested) classes that are mentioned in its constant pool The attribute for a nested class `A$B$C` consists of the long name of the outer class `A$B`, the short name of the inner class `C`, and an access flag set describig the visibility. The attribute seems to be used for reflection. [1]: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.6