HotSpotClassInitializationPlugin.java revision 13190:3c91140c49a7
164382Skbyanc/*
264382Skbyanc * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
364382Skbyanc * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
464382Skbyanc *
539214Sgibbs * This code is free software; you can redistribute it and/or modify it
639214Sgibbs * under the terms of the GNU General Public License version 2 only, as
739214Sgibbs * published by the Free Software Foundation.
839214Sgibbs *
939214Sgibbs * This code is distributed in the hope that it will be useful, but WITHOUT
1039214Sgibbs * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1164382Skbyanc * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1264382Skbyanc * version 2 for more details (a copy is included in the LICENSE file that
1339214Sgibbs * accompanied this code).
1439214Sgibbs *
1564382Skbyanc * You should have received a copy of the GNU General Public License version
1664382Skbyanc * 2 along with this work; if not, write to the Free Software Foundation,
1764382Skbyanc * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1864382Skbyanc *
1964382Skbyanc * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2064382Skbyanc * or visit www.oracle.com if you need additional information or have any
2164382Skbyanc * questions.
2264382Skbyanc */
2364382Skbyancpackage org.graalvm.compiler.hotspot.meta;
2464382Skbyanc
2564382Skbyancimport org.graalvm.compiler.core.common.type.ObjectStamp;
2664382Skbyancimport org.graalvm.compiler.core.common.type.Stamp;
2739214Sgibbsimport org.graalvm.compiler.core.common.type.StampFactory;
2864382Skbyancimport org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
29114513Sobrienimport org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
30114513Sobrienimport org.graalvm.compiler.nodes.ConstantNode;
3139214Sgibbsimport org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
3264382Skbyancimport org.graalvm.compiler.nodes.FrameState;
3364382Skbyancimport org.graalvm.compiler.nodes.ValueNode;
3464382Skbyancimport org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
3564382Skbyancimport org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
3639214Sgibbs
3739214Sgibbsimport jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
3839214Sgibbsimport jdk.vm.ci.meta.ResolvedJavaMethod;
3964382Skbyancimport jdk.vm.ci.meta.ResolvedJavaType;
4039214Sgibbs
4139214Sgibbspublic final class HotSpotClassInitializationPlugin implements ClassInitializationPlugin {
4264382Skbyanc    @Override
4339214Sgibbs    public boolean shouldApply(GraphBuilderContext builder, ResolvedJavaType type) {
4439214Sgibbs        if (!builder.parsingIntrinsic()) {
4564382Skbyanc            if (!type.isArray()) {
4639214Sgibbs                ResolvedJavaMethod method = builder.getGraph().method();
4739214Sgibbs                ResolvedJavaType methodHolder = method.getDeclaringClass();
4839214Sgibbs                // We can elide initialization nodes if type >=: methodHolder.
4939214Sgibbs                // The type is already initialized by either "new" or "invokestatic".
5039214Sgibbs
5164382Skbyanc                // Emit initialization node if type is an interface since:
5264382Skbyanc                // JLS 12.4: Before a class is initialized, its direct superclass must be
5364382Skbyanc                // initialized, but interfaces implemented by the class are not
5464382Skbyanc                // initialized and a class or interface type T will be initialized
5564382Skbyanc                // immediately before the first occurrence of accesses listed
5664382Skbyanc                // in JLS 12.4.1.
5764382Skbyanc
5864382Skbyanc                return !type.isAssignableFrom(methodHolder) || type.isInterface();
5964382Skbyanc            } else if (!type.getComponentType().isPrimitive()) {
6064382Skbyanc                // Always apply to object array types
6164382Skbyanc                return true;
6264474Skbyanc            }
6364382Skbyanc        }
6464382Skbyanc        return false;
6564382Skbyanc    }
6664382Skbyanc
6764382Skbyanc    @Override
6864382Skbyanc    public ValueNode apply(GraphBuilderContext builder, ResolvedJavaType type, FrameState frameState) {
6964382Skbyanc        assert shouldApply(builder, type);
7064382Skbyanc        Stamp hubStamp = builder.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
7164382Skbyanc        ConstantNode hub = builder.append(ConstantNode.forConstant(hubStamp, ((HotSpotResolvedObjectType) type).klass(), builder.getMetaAccess(), builder.getGraph()));
7264382Skbyanc        DeoptimizingFixedWithNextNode result = builder.append(type.isArray() ? new ResolveConstantNode(hub) : new InitializeKlassNode(hub));
7364382Skbyanc        result.setStateBefore(frameState);
7464382Skbyanc        return result;
7564382Skbyanc    }
7664382Skbyanc}
7764382Skbyanc