src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java
changeset 54669 ad45b3802d4e
parent 52645 74cf02d5f6e2
equal deleted inserted replaced
54668:0bda2308eded 54669:ad45b3802d4e
     1 /*
     1 /*
     2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    20  * or visit www.oracle.com if you need additional information or have any
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 package jdk.vm.ci.hotspot;
    23 package jdk.vm.ci.hotspot;
    24 
    24 
    25 import static jdk.internal.misc.Unsafe.ADDRESS_SIZE;
    25 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
    26 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
       
    27 import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmFieldModifiers;
       
    28 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
    26 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
    29 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
    27 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
       
    28 import static jdk.internal.misc.Unsafe.ADDRESS_SIZE;
    30 
    29 
    31 import java.lang.annotation.Annotation;
    30 import java.lang.annotation.Annotation;
    32 import java.lang.reflect.Field;
    31 
    33 import java.util.HashMap;
    32 import jdk.internal.vm.annotation.Stable;
    34 
    33 
    35 import jdk.vm.ci.meta.JavaConstant;
    34 import jdk.vm.ci.meta.JavaConstant;
    36 import jdk.vm.ci.meta.JavaType;
    35 import jdk.vm.ci.meta.JavaType;
    37 import jdk.vm.ci.meta.ResolvedJavaType;
    36 import jdk.vm.ci.meta.ResolvedJavaType;
    38 import jdk.vm.ci.meta.UnresolvedJavaType;
    37 import jdk.vm.ci.meta.UnresolvedJavaType;
    42  */
    41  */
    43 class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
    42 class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
    44 
    43 
    45     private final HotSpotResolvedObjectTypeImpl holder;
    44     private final HotSpotResolvedObjectTypeImpl holder;
    46     private JavaType type;
    45     private JavaType type;
       
    46 
       
    47     /**
       
    48      * Value of {@code fieldDescriptor::access_flags()}.
       
    49      */
    47     private final int offset;
    50     private final int offset;
       
    51 
       
    52     /**
       
    53      * Value of {@code fieldDescriptor::index()}.
       
    54      */
    48     private final short index;
    55     private final short index;
    49 
    56 
    50     /**
    57     /**
    51      * This value contains all flags as stored in the VM including internal ones.
    58      * This value contains all flags as stored in the VM including internal ones.
    52      */
    59      */
    66     @Override
    73     @Override
    67     public boolean equals(Object obj) {
    74     public boolean equals(Object obj) {
    68         if (this == obj) {
    75         if (this == obj) {
    69             return true;
    76             return true;
    70         }
    77         }
    71         if (obj instanceof HotSpotResolvedJavaField) {
    78         if (obj instanceof HotSpotResolvedJavaFieldImpl) {
    72             HotSpotResolvedJavaFieldImpl that = (HotSpotResolvedJavaFieldImpl) obj;
    79             HotSpotResolvedJavaFieldImpl that = (HotSpotResolvedJavaFieldImpl) obj;
    73             if (that.offset != this.offset || that.isStatic() != this.isStatic()) {
    80             if (that.offset != this.offset || that.isStatic() != this.isStatic()) {
    74                 return false;
    81                 return false;
    75             } else if (this.holder.equals(that.holder)) {
    82             } else if (this.holder.equals(that.holder)) {
    76                 return true;
    83                 return true;
    84         return holder.hashCode() ^ offset;
    91         return holder.hashCode() ^ offset;
    85     }
    92     }
    86 
    93 
    87     @Override
    94     @Override
    88     public int getModifiers() {
    95     public int getModifiers() {
    89         return modifiers & jvmFieldModifiers();
    96         return modifiers & HotSpotModifiers.jvmFieldModifiers();
    90     }
    97     }
    91 
    98 
    92     @Override
    99     @Override
    93     public boolean isInternal() {
   100     public boolean isInternal() {
    94         return (modifiers & config().jvmAccFieldInternal) != 0;
   101         return (modifiers & config().jvmAccFieldInternal) != 0;
    99      *
   106      *
   100      * @return true iff this is a non-static field and its declaring class is assignable from
   107      * @return true iff this is a non-static field and its declaring class is assignable from
   101      *         {@code object}'s class
   108      *         {@code object}'s class
   102      */
   109      */
   103     @Override
   110     @Override
   104     public boolean isInObject(JavaConstant constant) {
   111     public boolean isInObject(JavaConstant object) {
   105         if (isStatic()) {
   112         if (isStatic()) {
   106             return false;
   113             return false;
   107         }
   114         }
   108         Object object = ((HotSpotObjectConstantImpl) constant).object();
   115         HotSpotObjectConstant constant = (HotSpotObjectConstant) object;
   109         return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectTypeImpl.fromObjectClass(object.getClass()));
   116         return getDeclaringClass().isAssignableFrom(constant.getType());
   110     }
   117     }
   111 
   118 
   112     @Override
   119     @Override
   113     public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
   120     public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
   114         return holder;
   121         return holder;
   125         // a ClassCastException below
   132         // a ClassCastException below
   126         JavaType currentType = type;
   133         JavaType currentType = type;
   127         if (currentType instanceof UnresolvedJavaType) {
   134         if (currentType instanceof UnresolvedJavaType) {
   128             // Don't allow unresolved types to hang around forever
   135             // Don't allow unresolved types to hang around forever
   129             UnresolvedJavaType unresolvedType = (UnresolvedJavaType) currentType;
   136             UnresolvedJavaType unresolvedType = (UnresolvedJavaType) currentType;
   130             ResolvedJavaType resolved = holder.lookupType(unresolvedType, false);
   137             JavaType resolved = HotSpotJVMCIRuntime.runtime().lookupType(unresolvedType.getName(), holder, false);
   131             if (resolved != null) {
   138             if (resolved instanceof ResolvedJavaType) {
   132                 type = resolved;
   139                 type = resolved;
   133             }
   140             }
   134         }
   141         }
   135         return type;
   142         return type;
       
   143 
   136     }
   144     }
   137 
   145 
   138     @Override
   146     @Override
   139     public int getOffset() {
   147     public int getOffset() {
   140         return offset;
   148         return offset;
   141     }
   149     }
   142 
   150 
       
   151     /**
       
   152      * Gets the value of this field's index (i.e. {@code fieldDescriptor::index()} in the encoded
       
   153      * fields of the declaring class.
       
   154      */
       
   155     int getIndex() {
       
   156         return index;
       
   157     }
       
   158 
   143     @Override
   159     @Override
   144     public String toString() {
   160     public String toString() {
   145         return format("HotSpotField<%H.%n %t:") + offset + ">";
   161         return format("HotSpotResolvedJavaFieldImpl<%H.%n %t:") + offset + ">";
   146     }
   162     }
   147 
   163 
   148     @Override
   164     @Override
   149     public boolean isSynthetic() {
   165     public boolean isSynthetic() {
   150         return (config().jvmAccSynthetic & modifiers) != 0;
   166         return (config().jvmAccSynthetic & modifiers) != 0;
   151     }
   167     }
   152 
   168 
   153     /**
   169     /**
   154      * Checks if this field has the {@code Stable} annotation.
   170      * Checks if this field has the {@link Stable} annotation.
   155      *
   171      *
   156      * @return true if field has {@code Stable} annotation, false otherwise
   172      * @return true if field has {@link Stable} annotation, false otherwise
   157      */
   173      */
   158     @Override
   174     @Override
   159     public boolean isStable() {
   175     public boolean isStable() {
   160         return (config().jvmAccFieldStable & modifiers) != 0;
   176         return (config().jvmAccFieldStable & modifiers) != 0;
   161     }
   177     }
   178     @Override
   194     @Override
   179     public Annotation[] getAnnotations() {
   195     public Annotation[] getAnnotations() {
   180         if (!hasAnnotations()) {
   196         if (!hasAnnotations()) {
   181             return new Annotation[0];
   197             return new Annotation[0];
   182         }
   198         }
   183         return toJava().getAnnotations();
   199         return runtime().reflection.getFieldAnnotations(this);
   184     }
   200     }
   185 
   201 
   186     @Override
   202     @Override
   187     public Annotation[] getDeclaredAnnotations() {
   203     public Annotation[] getDeclaredAnnotations() {
   188         if (!hasAnnotations()) {
   204         if (!hasAnnotations()) {
   189             return new Annotation[0];
   205             return new Annotation[0];
   190         }
   206         }
   191         return toJava().getDeclaredAnnotations();
   207         return runtime().reflection.getFieldDeclaredAnnotations(this);
   192     }
   208     }
   193 
   209 
   194     @Override
   210     @Override
   195     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   211     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   196         if (!hasAnnotations()) {
   212         if (!hasAnnotations()) {
   197             return null;
   213             return null;
   198         }
   214         }
   199         return toJava().getAnnotation(annotationClass);
   215         return runtime().reflection.getFieldAnnotation(this, annotationClass);
   200     }
       
   201 
       
   202     /**
       
   203      * Gets a {@link Field} object corresponding to this object. This method always returns the same
       
   204      * {@link Field} object for a given {@link HotSpotResolvedJavaFieldImpl}. This ensures
       
   205      * {@link #getDeclaredAnnotations()}, {@link #getAnnotations()} and
       
   206      * {@link #getAnnotation(Class)} are stable with respect to the identity of the
       
   207      * {@link Annotation} objects they return.
       
   208      */
       
   209     private Field toJava() {
       
   210         synchronized (holder) {
       
   211             HashMap<HotSpotResolvedJavaFieldImpl, Field> cache = holder.reflectionFieldCache;
       
   212             if (cache == null) {
       
   213                 cache = new HashMap<>();
       
   214                 holder.reflectionFieldCache = cache;
       
   215             }
       
   216             Field reflect = cache.get(this);
       
   217             if (reflect == null) {
       
   218                 reflect = compilerToVM().asReflectionField(holder, index);
       
   219                 cache.put(this, reflect);
       
   220             }
       
   221             return reflect;
       
   222         }
       
   223     }
   216     }
   224 }
   217 }