Skip to content
Permalink
Browse files
8261782: [lworld] Add support for PrimitiveObject interface
  • Loading branch information
Srikanth Adayapalam committed Feb 22, 2021
1 parent e88ff83 commit f421b939851139ac5a8e575e78d1cec0886617b0
@@ -27,7 +27,39 @@

/**
* A restricted interface implemented by all identity objects.
* @since 1.14
*/
* IdentityObject: An object with identity.
*
* *Identity* is a property of certain objects, determined at instance creation
* time and preserved throughout the life of the object. While an object's field
* values may change, its identity is constant. Object identities are unique: no
* two objects created by different instance creation operations can have the same
* identity.
*
* Every object is either an *identity object* or a *primitive object*. Primitive
* objects lack identity.
*
* The following operations have special behavior when applied to identity objects:
*
* - The `==` operator, and the default implementation of the `Object.equals`
* method, compare the identities of their operands, producing `true` for an
* identity object only if the object is being compared to itself.
*
* - The `System.identityHashCode` method, and the default implementation of the
* `Object.hashCode` method, generate a hash code from an identity object's
* identity.
*
* - The `synchronized` modifier and `synchronized` statement are only able to
* successfully acquire a lock when applied to an identity object.
*
* A class may implement `IdentityObject` or `PrimitiveObject`, but never both.
* Primitive classes always implement `PrimitiveObject`, while all other concrete
* classes (except `Object`) implicitly implement `IdentityObject`.
*
* Abstract classes and interfaces may implement or extend this interface if they
* wish to guarantee that all instances of the class or interface have identity.
*
* @since 1.16
*/
public interface IdentityObject {
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package java.lang;

/**
* A restricted interface implemented by all primitive objects.
*
* A primitive object is an instance of a primitive class, lacking identity.
*
* Every object is either an *identity object* or a *primitive object*. Identity
* objects have a unique identity determined for them at instance creation time and
* preserved throughout their life.
*
* Primitive objects do *not* have an identity. Instead, they simply aggregate a
* set of immutable field values. The lack of identity enables certain performance
* optimizations by Java Virtual Machine implementations.
* The following operations have special behavior when applied to primitive
* objects:
*
* - The `==` operator, and the default implementation of the `Object.equals`
* method, compare the values of the operands' fields. Primitive objects
* created at different points in a program may be `==`.
*
* - The `System.identityHashCode` method, and the default implementation of the
* `Object.hashCode` method, generate a hash code from the hash codes of a
* primitive object's fields.
*
* - The `synchronized` modifier and `synchronized` statement always fail when
* applied to a primitive object.
*
* A class may implement `PrimitiveObject` or `IdentityObject`, but never both.
* Primitive classes always implement `PrimitiveObject`, while all other concrete
* classes (except `Object`) implicitly implement `IdentityObject`.
*
* Abstract classes and interfaces may implement or extend this interface if they
* wish to guarantee that all instances of the class or interface are primitive
* objects.
*
* @since 1.16
*/

public interface PrimitiveObject {
}
@@ -223,6 +223,7 @@ public static Symtab instance(Context context) {
public final Type typeDescriptorType;
public final Type recordType;
public final Type identityObjectType;
public final Type primitiveObjectType;
public final Type valueBasedType;

/** The symbol representing the length field of an array.
@@ -598,6 +599,7 @@ public String toString() {
typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor");
recordType = enterClass("java.lang.Record");
identityObjectType = enterClass("java.lang.IdentityObject");
primitiveObjectType = enterClass("java.lang.PrimitiveObject");
valueBasedType = enterClass("jdk.internal.ValueBased");

synthesizeEmptyInterfaceIfMissing(autoCloseableType);
@@ -607,6 +609,7 @@ public String toString() {
synthesizeEmptyInterfaceIfMissing(serializedLambdaType);
synthesizeEmptyInterfaceIfMissing(stringConcatFactory);
synthesizeEmptyInterfaceIfMissing(identityObjectType);
synthesizeEmptyInterfaceIfMissing(primitiveObjectType);
synthesizeBoxTypeIfMissing(doubleType);
synthesizeBoxTypeIfMissing(floatType);
synthesizeBoxTypeIfMissing(voidType);
@@ -2241,7 +2241,7 @@ public Type asSuper(Type t, Symbol sym, boolean checkReferenceProjection) {
if (!isPrimitiveClass(t))
return syms.objectType;
}
if (sym.type == syms.identityObjectType) {
if (sym == syms.identityObjectType.tsym) {
// IdentityObject is super interface of every concrete identity class other than jlO
if (t.isPrimitiveClass() || t.tsym == syms.objectType.tsym)
return null;
@@ -2250,6 +2250,12 @@ public Type asSuper(Type t, Symbol sym, boolean checkReferenceProjection) {
if (t.hasTag(CLASS) && !t.isReferenceProjection() && !t.tsym.isInterface() && !t.tsym.isAbstract()) {
return syms.identityObjectType;
} // else fall through and look for explicit coded super interface
} else if (sym == syms.primitiveObjectType.tsym) {
if (t.isPrimitiveClass() || t.isReferenceProjection())
return syms.primitiveObjectType;
if (t.hasTag(ARRAY) || t.tsym == syms.objectType.tsym)
return null;
// else fall through and look for explicit coded super interface
}
return asSuper.visit(t, sym);
}
@@ -2695,8 +2695,14 @@ void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
}
checkCompatibleConcretes(pos, c);

if (c.isPrimitiveClass() && types.asSuper(c, syms.identityObjectType.tsym, true) != null) {
boolean implementsIdentityObject = types.asSuper(c, syms.identityObjectType.tsym, true) != null;
boolean implementsPrimitiveObject = types.asSuper(c, syms.primitiveObjectType.tsym, true) != null;
if (c.isPrimitiveClass() && implementsIdentityObject) {
log.error(pos, Errors.PrimitiveClassMustNotImplementIdentityObject(c));
} else if (implementsPrimitiveObject && !c.isPrimitiveClass() && !c.isReferenceProjection() && !c.tsym.isInterface() && !c.tsym.isAbstract()) {
log.error(pos, Errors.IdentityClassMustNotImplementPrimitiveObject(c));
} else if (implementsPrimitiveObject && implementsIdentityObject) {
log.error(pos, Errors.MutuallyIncompatibleSuperInterfaces(c));
}
}

@@ -3820,6 +3820,14 @@ compiler.err.generic.parameterization.with.primitive.class=\
compiler.err.primitive.class.must.not.implement.identity.object=\
The primitive class {0} attempts to implement the incompatible interface IdentityObject

# 0: type
compiler.err.identity.class.must.not.implement.primitive.object=\
The identity class {0} attempts to implement the incompatible interface PrimitiveObject

# 0: type
compiler.err.mutually.incompatible.super.interfaces=\
The type {0} attempts to implement the mutually incompatible interfaces PrimitiveObject and IdentityObject

# 0: symbol, 1: type
compiler.err.concrete.supertype.for.primitive.class=\
The concrete class {1} is not allowed to be a super class of the primitive class {0} either directly or indirectly
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

// key: compiler.err.identity.class.must.not.implement.primitive.object
// key: compiler.err.mutually.incompatible.super.interfaces

class Identity implements PrimitiveObject {
abstract class Inner implements IdentityObject, PrimitiveObject {}
}
@@ -29,8 +29,7 @@
*/

public class InstanceOfTopTypeTest {
interface InlineObject {}
static primitive class V implements InlineObject {
static primitive class V {
int x = 42;
}

@@ -39,28 +38,28 @@ public static void main(String [] args) {
Object o = new InstanceOfTopTypeTest();
if (o instanceof IdentityObject)
points++; // 1
if (o instanceof InlineObject)
if (o instanceof PrimitiveObject)
throw new AssertionError("Broken");
o = new V();
if (o instanceof IdentityObject)
throw new AssertionError("Broken");
if (o instanceof InlineObject)
if (o instanceof PrimitiveObject)
points++; // 2
Object [] oa = new InstanceOfTopTypeTest[] { new InstanceOfTopTypeTest() };
if (oa instanceof IdentityObject)
points++; // 3
if (oa[0] instanceof IdentityObject)
points++; // 4
if (oa[0] instanceof InlineObject)
if (oa[0] instanceof PrimitiveObject)
throw new AssertionError("Broken");
oa = new V[] { new V() };
if (oa instanceof IdentityObject)
points++; // 5
if (oa[0] instanceof IdentityObject)
throw new AssertionError("Broken");
if (oa[0] instanceof InlineObject)
if (oa[0] instanceof PrimitiveObject)
points++;
if (points != 6)
throw new AssertionError("Broken top type set up" + points);
if (points != 4)
throw new AssertionError("Broken top type set up " + points);
}
}

0 comments on commit f421b93

Please sign in to comment.