Skip to content
Permalink
Browse files
8244227: [lworld] Explore an implementation where the reference proje…
…ction and value projection types are backed by a single class symbol

Reviewed-by: mcimadamore
  • Loading branch information
Srikanth Adayapalam committed Apr 9, 2021
1 parent f816f29 commit c68ce892ca267e9b93ebfd3b693cfe4cb55b8c70
Showing with 531 additions and 384 deletions.
  1. +1 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
  2. +4 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Printer.java
  3. +7 −135 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
  4. +41 −21 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
  5. +1 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
  6. +66 −47 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
  7. +20 −13 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
  8. +2 −2 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
  9. +0 −4 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
  10. +1 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
  11. +3 −3 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
  12. +17 −5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
  13. +0 −14 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java
  14. +6 −23 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
  15. +0 −7 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
  16. +0 −10 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
  17. +37 −40 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
  18. +81 −12 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
  19. +2 −2 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
  20. +6 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java
  21. +5 −16 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/TransValues.java
  22. +1 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java
  23. +4 −4 .../tools/javac/annotations/typeAnnotations/classfile/BridgeShouldHaveNoInteriorAnnotationsTest.java
  24. +103 −0 test/langtools/tools/javac/api/TestApisWithProjections.java
  25. +73 −0 test/langtools/tools/javac/valhalla/lworld-values/AsSuperTests.java
  26. +2 −2 test/langtools/tools/javac/valhalla/lworld-values/AttributesTest.java
  27. +2 −2 test/langtools/tools/javac/valhalla/lworld-values/CheckQuestionInMessages.out
  28. +8 −8 test/langtools/tools/javac/valhalla/lworld-values/ClassLiteralTypingNegativeTest.out
  29. +1 −1 test/langtools/tools/javac/valhalla/lworld-values/ConditionalTypeTest.out
  30. +31 −3 test/langtools/tools/javac/valhalla/lworld-values/EnhancedForLoopTest.java
  31. +3 −3 test/langtools/tools/javac/valhalla/lworld-values/GenericInlineTest.out
  32. +2 −2 test/langtools/tools/javac/valhalla/lworld-values/OverloadingPhaseTest.out
  33. +1 −1 test/langtools/tools/javac/valhalla/lworld-values/TypeRelationsNegativeTest.out
@@ -1225,7 +1225,7 @@ public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
ClassType ct = (ClassType) errorType;
return extraType2OriginalMap.computeIfAbsent(ct, tt ->
new ClassType(ct.getEnclosingType(), ct.typarams_field,
ct.tsym, ct.getMetadata()) {
ct.tsym, ct.getMetadata(), ct.isReferenceProjection()) {
@Override
public Type baseType() { return ct; }
@Override
@@ -234,6 +234,10 @@ public String visitClassType(ClassType t, Locale locale) {
buf.append(printAnnotations(t));
buf.append(className(t, true, locale));
}
if (t.isReferenceProjection()) {
buf.append('.');
buf.append(t.tsym.name.table.names.ref);
}
if (t.getTypeArguments().nonEmpty()) {
buf.append('<');
buf.append(visitTypes(t.getTypeArguments(), locale));
@@ -426,18 +426,10 @@ public boolean isReferenceProjection() {
}

/**
* Return the value projection IFF 'this' happens to be derived reference projection, null
* otherwise.
* If this is the symbol for a reference projection class, what is the class for which
* this is a projection ??
*/
public Symbol valueProjection() {
return null;
}

/**
* Return the reference projection IFF 'this' happens to be inline class, null
* otherwise.
*/
public Symbol referenceProjection() {
public ClassSymbol valueProjection() {
return null;
}

@@ -1328,12 +1320,6 @@ public RootPackageSymbol(Name name, Symbol owner,
*/
private List<RecordComponent> recordComponents = List.nil();

/* the 'other' projection: If 'this' is an inline class then 'projection' is its reference projection
and vice versa.
*/
public ClassSymbol projection;


// sealed classes related fields
/** The classes, or interfaces, permitted to extend this class, or interface
*/
@@ -1393,7 +1379,8 @@ public Type erasure(Types types) {
if (erasure_field == null)
erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
List.nil(), this,
type.getMetadata());
type.getMetadata(),
type.isReferenceProjection());
return erasure_field;
}

@@ -1663,65 +1650,6 @@ public boolean isRecord() {
return (flags_field & RECORD) != 0;
}

@Override
public boolean isReferenceProjection() {
return projection != null && projection.isPrimitiveClass();
}

@Override
public ClassSymbol valueProjection() {
return isReferenceProjection() ? projection : null;
}

@Override
public ClassSymbol referenceProjection() {
if (!isPrimitiveClass())
return null;

if (projection != null)
return projection;

ClassType ct = (ClassType) this.type;
ClassType projectedType = new ClassType(ct.getEnclosingType(), ct.typarams_field, null);
projectedType.allparams_field = ct.allparams_field;
projectedType.supertype_field = ct.supertype_field;

projectedType.interfaces_field = ct.interfaces_field;
projectedType.all_interfaces_field = ct.all_interfaces_field;
projectedType.projection = ct;
ct.projection = projectedType;

Name projectionName = this.name.append('$', this.name.table.names.ref);
long projectionFlags = (this.flags() & ~(PRIMITIVE_CLASS | UNATTRIBUTED | FINAL)) | SEALED;

projection = new ClassSymbol(projectionFlags, projectionName, projectedType, this.owner);
projection.members_field = WriteableScope.create(projection);
for (Symbol s : this.members().getSymbols(s->(s.kind == MTH || s.kind == VAR), NON_RECURSIVE)) {
Symbol clone = null;
if (s.kind == MTH) {
MethodSymbol valMethod = (MethodSymbol)s;
MethodSymbol refMethod = valMethod.clone(projection);
valMethod.projection = refMethod;
refMethod.projection = valMethod;
clone = refMethod;
} else if (s.kind == VAR) {
VarSymbol valVar = (VarSymbol)s;
VarSymbol refVar = valVar.clone(projection);
valVar.projection = refVar;
refVar.projection = valVar;
clone = refVar;
}
projection.members_field.enter(clone);
}
projection.completer = Completer.NULL_COMPLETER;
projection.sourcefile = this.sourcefile;
projection.flatname = this.flatname.append('$', this.name.table.names.ref);
projection.permitted = List.of(this);
projection.projection = this;
projectedType.tsym = projection;
return projection;
}

@DefinedBy(Api.LANGUAGE_MODEL)
public List<Type> getPermittedSubclasses() {
return permitted.map(s -> s.type);
@@ -1748,11 +1676,6 @@ public ClassSymbol referenceProjection() {
*/
public int adr = -1;

/* The 'other' projection: If 'this' is a field of an inline class, then 'projection' is the
its doppleganger in its referene projection class and vice versa.
*/
public VarSymbol projection;

/** Construct a variable symbol, given its flags, name, type and owner.
*/
public VarSymbol(long flags, Name name, Type type, Symbol owner) {
@@ -1785,7 +1708,6 @@ public Object poolKey(Types types) {
v.pos = pos;
v.adr = adr;
v.data = data;
v.projection = projection;
// System.out.println("clone " + v + " in " + newOwner);//DEBUG
return v;
}
@@ -1838,18 +1760,6 @@ public void setLazyConstValue(final Env<AttrContext> env,
setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, variable, type));
}

@Override
public VarSymbol referenceProjection() {
return this.owner.isPrimitiveClass() ?
this.owner.referenceProjection() != null ? projection : null
: null;
}

@Override
public VarSymbol valueProjection() {
return projection != null ? projection.owner.isPrimitiveClass() ? projection : null: null;
}

/**
* The variable's constant value, if this is a constant.
* Before the constant value is evaluated, it points to an
@@ -2026,11 +1936,6 @@ public boolean isPreserved() {
*/
public Attribute defaultValue = null;

/* The 'other' projection: If 'this' is a method of an inline class, then 'projection' is the
its doppleganger in its referene projection class and vice versa.
*/
public MethodSymbol projection;

/** Construct a method symbol, given its flags, name, type and owner.
*/
public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
@@ -2053,7 +1958,6 @@ public Object poolKey(Types types) {
}
};
m.code = code;
m.projection = projection;
return m;
}

@@ -2138,7 +2042,7 @@ public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {

// check for a direct implementation
if (other.isOverridableIn((TypeSymbol)owner) &&
types.asSuper(owner.type, other.owner) != null &&
types.asSuper(owner.type.referenceProjectionOrSelf(), other.owner) != null &&
types.isSameType(erasure(types), other.erasure(types)))
return true;

@@ -2202,24 +2106,12 @@ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean
boolean requireConcreteIfInherited) {
if (isConstructor() || _other.kind != MTH) return false;


/* If any inline types are involved, ask the same question in the reference universe,
where the hierarchy is navigable
*/
if (origin.isPrimitiveClass())
origin = (TypeSymbol) origin.referenceProjection();

if (this.owner.isPrimitiveClass()) {
return this.projection != null &&
this.projection.overrides(_other, origin, types, checkResult, requireConcreteIfInherited);
}

if (this == _other) return true;
MethodSymbol other = (MethodSymbol)_other;

// check for a direct implementation
if (other.isOverridableIn((TypeSymbol)owner) &&
types.asSuper(owner.type, other.owner) != null) {
types.asSuper(owner.type.referenceProjectionOrSelf(), other.owner) != null) {
Type mt = types.memberType(owner.type, this);
Type ot = types.memberType(owner.type, other);
if (types.isSubSignature(mt, ot)) {
@@ -2269,14 +2161,6 @@ private boolean isOverridableIn(TypeSymbol origin) {
@Override
public boolean isInheritedIn(Symbol clazz, Types types) {

/* If any inline types are involved, ask the same question in the reference universe,
where the hierarchy is navigable
*/
if (clazz.isPrimitiveClass())
clazz = clazz.referenceProjection();
if (this.owner.isPrimitiveClass())
return this.projection.isInheritedIn(clazz, types);

switch ((int)(flags_field & Flags.AccessFlags)) {
case PUBLIC:
return !this.owner.isInterface() ||
@@ -2291,18 +2175,6 @@ public boolean isLambdaMethod() {
return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
}

@Override
public MethodSymbol referenceProjection() {
return this.owner.isPrimitiveClass() ?
this.owner.referenceProjection() != null ? projection : null
: null;
}

@Override
public MethodSymbol valueProjection() {
return projection != null ? projection.owner.isPrimitiveClass() ? projection : null : null;
}

/** override this method to point to the original enclosing method if this method symbol represents a synthetic
* lambda method
*/

0 comments on commit c68ce89

Please sign in to comment.