src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
branchJEP-349-branch
changeset 58343 ca19b94eac7a
parent 58271 e47423f1318b
parent 58341 21a03fa2f6b6
child 58357 fe78b5a87287
equal deleted inserted replaced
58271:e47423f1318b 58343:ca19b94eac7a
     1 /*
       
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 
       
    25 package org.graalvm.compiler.hotspot.meta;
       
    26 
       
    27 import java.util.function.Supplier;
       
    28 
       
    29 import org.graalvm.compiler.core.common.type.ObjectStamp;
       
    30 import org.graalvm.compiler.core.common.type.Stamp;
       
    31 import org.graalvm.compiler.core.common.type.StampFactory;
       
    32 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
       
    33 import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
       
    34 import org.graalvm.compiler.nodes.ConstantNode;
       
    35 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
       
    36 import org.graalvm.compiler.nodes.FrameState;
       
    37 import org.graalvm.compiler.nodes.ValueNode;
       
    38 import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
       
    39 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
       
    40 
       
    41 import jdk.vm.ci.hotspot.HotSpotConstantPool;
       
    42 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
       
    43 import jdk.vm.ci.meta.ConstantPool;
       
    44 import jdk.vm.ci.meta.ResolvedJavaMethod;
       
    45 import jdk.vm.ci.meta.ResolvedJavaType;
       
    46 
       
    47 public final class HotSpotClassInitializationPlugin implements ClassInitializationPlugin {
       
    48     private static boolean shouldApply(GraphBuilderContext builder, ResolvedJavaType type) {
       
    49         if (!builder.parsingIntrinsic()) {
       
    50             if (!type.isArray()) {
       
    51                 ResolvedJavaMethod method = builder.getGraph().method();
       
    52                 ResolvedJavaType methodHolder = method.getDeclaringClass();
       
    53                 // We can elide initialization nodes if type >=: methodHolder.
       
    54                 // The type is already initialized by either "new" or "invokestatic".
       
    55 
       
    56                 // Emit initialization node if type is an interface since:
       
    57                 // JLS 12.4: Before a class is initialized, its direct superclass must be
       
    58                 // initialized, but interfaces implemented by the class are not
       
    59                 // initialized and a class or interface type T will be initialized
       
    60                 // immediately before the first occurrence of accesses listed
       
    61                 // in JLS 12.4.1.
       
    62 
       
    63                 return !type.isAssignableFrom(methodHolder) || type.isInterface();
       
    64             } else if (!type.getComponentType().isPrimitive()) {
       
    65                 // Always apply to object array types
       
    66                 return true;
       
    67             }
       
    68         }
       
    69         return false;
       
    70     }
       
    71 
       
    72     @Override
       
    73     public boolean apply(GraphBuilderContext builder, ResolvedJavaType type, Supplier<FrameState> frameState, ValueNode[] classInit) {
       
    74         if (shouldApply(builder, type)) {
       
    75             Stamp hubStamp = builder.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
       
    76             ConstantNode hub = builder.append(ConstantNode.forConstant(hubStamp, ((HotSpotResolvedObjectType) type).klass(), builder.getMetaAccess(), builder.getGraph()));
       
    77             DeoptimizingFixedWithNextNode result = builder.append(type.isArray() ? new ResolveConstantNode(hub) : new InitializeKlassNode(hub));
       
    78             result.setStateBefore(frameState.get());
       
    79             if (classInit != null) {
       
    80                 classInit[0] = result;
       
    81             }
       
    82             return true;
       
    83         }
       
    84         return false;
       
    85     }
       
    86 
       
    87     @Override
       
    88     public boolean supportsLazyInitialization(ConstantPool cp) {
       
    89         // jdk.vm.ci.hotspot.HotSpotConstantPool is final, so we can
       
    90         // directly compare Classes.
       
    91         return (cp instanceof HotSpotConstantPool);
       
    92     }
       
    93 
       
    94     @Override
       
    95     public void loadReferencedType(GraphBuilderContext builder, ConstantPool cp, int cpi, int opcode) {
       
    96         if (cp instanceof HotSpotConstantPool) {
       
    97             ((HotSpotConstantPool) cp).loadReferencedType(cpi, opcode, false);
       
    98         } else {
       
    99             cp.loadReferencedType(cpi, opcode);
       
   100         }
       
   101     }
       
   102 
       
   103 }