JDK14/Java14源码在线阅读

/*
 * Copyright (c) 2016, 2018, 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.
 */



package jdk.tools.jaotc;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashMap;
import java.util.HashSet;

import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
import org.graalvm.compiler.code.CompilationResult;

import jdk.vm.ci.code.site.Mark;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;

final class CompiledMethodInfo {

    static final String archStr = System.getProperty("os.arch").toLowerCase();

    private static final int UNINITIALIZED_OFFSET = -1;

    private static class AOTMethodOffsets {
        /**
         * Offset in metaspace names section.
         */
        private int nameOffset;

        /**
         * Offset in the text section at which compiled code starts.
         */
        private int textSectionOffset;

        /**
         * Offset in the metadata section.
         */
        private int metadataOffset;

        /**
         * Offset to the metadata in the GOT table.
         */
        private int metadataGotOffset;

        /**
         * Size of the metadata.
         */
        private int metadataGotSize;

        /**
         * The sequential number corresponding to the order of methods code in code buffer.
         */
        private int codeId;

        AOTMethodOffsets() {
            this.nameOffset = UNINITIALIZED_OFFSET;
            this.textSectionOffset = UNINITIALIZED_OFFSET;
            this.metadataOffset = UNINITIALIZED_OFFSET;
            this.metadataGotOffset = UNINITIALIZED_OFFSET;
            this.metadataGotSize = -1;
            this.codeId = -1;
        }

        void addMethodOffsets(ReadOnlyDataContainer container, String name) {
            verify(name);
            // @formatter:off
            /*
             * The offsets layout should match AOTMethodOffsets structure in AOT JVM runtime
             */
                      // Add the offset to the name in the .metaspace.names section
            container.appendInt(nameOffset).
                      // Add the offset to the code in the .text section
                      appendInt(textSectionOffset).
                      // Add the offset to the metadata in the .method.metadata section
                      appendInt(metadataOffset).
                      // Add the offset to the metadata in the .metadata.got section
                      appendInt(metadataGotOffset).
                      // Add the size of the metadata
                      appendInt(metadataGotSize).
                      // Add code ID.
                      appendInt(codeId);
            // @formatter:on
        }

        private void verify(String name) {
            assert nameOffset >= 0 : "incorrect nameOffset: " + nameOffset + " for method: " + name;
            assert textSectionOffset > 0 : "incorrect textSectionOffset: " + textSectionOffset + " for method: " + name;
            assert metadataOffset >= 0 : "incorrect metadataOffset: " + metadataOffset + " for method: " + name;
            assert metadataGotOffset >= 0 : "incorrect metadataGotOffset: " + metadataGotOffset + " for method: " + name;
            assert metadataGotSize >= 0 : "incorrect metadataGotSize: " + metadataGotSize + " for method: " + name;
            assert codeId >= 0 : "incorrect codeId: " + codeId + " for method: " + name;
        }

        protected void setNameOffset(int offset) {
            nameOffset = offset;
        }

        protected void setTextSectionOffset(int textSectionOffset) {
            this.textSectionOffset = textSectionOffset;
        }

        protected int getTextSectionOffset() {
            return textSectionOffset;
        }

        protected void setCodeId(int codeId) {
            this.codeId = codeId;
        }

        protected int getCodeId() {
            return codeId;
        }

        protected void setMetadataOffset(int offset) {
            metadataOffset = offset;
        }

        protected void setMetadataGotOffset(int metadataGotOffset) {
            this.metadataGotOffset = metadataGotOffset;
        }

        protected void setMetadataGotSize(int length) {
            this.metadataGotSize = length;
        }
    }

    /**
     * Method name.
     */
    private String name;

    /**
     * Result of graal compilation.
     */
    private CompilationResult compilationResult;

    /**
     * HotSpotResolvedJavaMethod or Stub corresponding to the compilation result.
     */
    private JavaMethodInfo methodInfo;

    /**
     * Compiled code from installation.
     */
    private HotSpotCompiledCode code;

    /**
     * Offset to stubs.
     */
    private int stubsOffset;

    /**
     * The total size in bytes of the stub section.
     */
    private int totalStubSize;

    /**
     * Method's offsets.
     */
    private AOTMethodOffsets methodOffsets;

    /**
     * List of stubs (PLT trampoline).
     */
    private HashMap<String, StubInformation> stubs = new HashMap<>();

    /**
     * List of referenced classes.
     */
    private HashSet<AOTKlassData> dependentKlasses = new HashSet<>();

    /**
     * Methods count used to generate unique global method id.
     */
    private static final AtomicInteger methodsCount = new AtomicInteger();

    CompiledMethodInfo(CompilationResult compilationResult, JavaMethodInfo methodInfo) {
        this.name = methodInfo.getNameAndSignature();
        this.compilationResult = compilationResult;
        this.methodInfo = methodInfo;
        this.stubsOffset = UNINITIALIZED_OFFSET;
        this.methodOffsets = new AOTMethodOffsets();
    }

    String name() {
        return name;
    }

    void addMethodOffsets(BinaryContainer binaryContainer, ReadOnlyDataContainer container) {
        this.methodOffsets.setNameOffset(binaryContainer.addMetaspaceName(name));
        this.methodOffsets.addMethodOffsets(container, name);
        for (AOTKlassData data : dependentKlasses) {
            data.addDependentMethod(this);
        }
    }

    CompilationResult getCompilationResult() {
        return compilationResult;
    }

    JavaMethodInfo getMethodInfo() {
        return methodInfo;
    }

    void setTextSectionOffset(int textSectionOffset) {
        methodOffsets.setTextSectionOffset(textSectionOffset);
    }

    public int getTextSectionOffset() {
        return methodOffsets.getTextSectionOffset();
    }

    void setCodeId() {
        methodOffsets.setCodeId(CompiledMethodInfo.getNextCodeId());
    }

    int getCodeId() {
        return this.methodOffsets.getCodeId();
    }

    static int getMethodsCount() {
        return methodsCount.get();
    }

    static int getNextCodeId() {
        return methodsCount.getAndIncrement();
    }

    int getCodeSize() {
        return stubsOffset + getStubCodeSize();
    }

    int getStubCodeSize() {
        return totalStubSize;
    }

    void setMetadataOffset(int offset) {
        this.methodOffsets.setMetadataOffset(offset);
    }

    /**
     * Offset into the code of this method where the stub section starts.
     */
    void setStubsOffset(int offset) {
        stubsOffset = offset;
    }

    int getStubsOffset() {
        return stubsOffset;
    }

    void setMetadataGotOffset(int metadataGotOffset) {
        this.methodOffsets.setMetadataGotOffset(metadataGotOffset);
    }

    void setMetadataGotSize(int length) {
        this.methodOffsets.setMetadataGotSize(length);
    }

    void addStubCode(String call, StubInformation stub) {
        stubs.put(call, stub);
        totalStubSize += stub.getSize();
    }

    StubInformation getStubFor(String call) {
        StubInformation stub = stubs.get(call);
        assert stub != null : "missing stub for call " + call;
        stub.verify();
        return stub;
    }

    void addDependentKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
        AOTKlassData klassData = AOTCompiledClass.addFingerprintKlassData(binaryContainer, type);
        dependentKlasses.add(klassData);
    }

    AOTKlassData getDependentKlassData(HotSpotResolvedObjectType type) {
        AOTKlassData klassData = AOTCompiledClass.getAOTKlassData(type);
        if (dependentKlasses.contains(klassData)) {
            return klassData;
        }
        return null;
    }

    boolean hasMark(Site call, MarkId id) {
        for (Mark m : compilationResult.getMarks()) {
            int adjOffset = m.pcOffset;
            if (archStr.equals("aarch64")) {

/**代码未完, 请加载全部代码(NowJava.com).**/
展开阅读全文

关注时代Java

关注时代Java