/*
 * Copyright (c) 2015, 2017, 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 com.oracle.svm.core.code;

import org.graalvm.compiler.word.Word;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.function.CodePointer;
import org.graalvm.nativeimage.c.struct.SizeOf;
import org.graalvm.word.ComparableWord;
import org.graalvm.word.UnsignedWord;

import com.oracle.svm.core.MemoryWalker;
import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.annotate.UnknownObjectField;
import com.oracle.svm.core.annotate.UnknownPrimitiveField;
import com.oracle.svm.core.c.NonmovableArray;
import com.oracle.svm.core.c.NonmovableArrays;
import com.oracle.svm.core.c.NonmovableObjectArray;
import com.oracle.svm.core.util.VMError;

public class ImageCodeInfo {
    public static final String CODE_INFO_NAME = "image code";

    
Memory in the image heap to contain our CodeInfo structure at runtime.
/** Memory in the image heap to contain our {@link CodeInfo} structure at runtime. */
private final byte[] runtimeCodeInfoData; @Platforms(Platform.HOSTED_ONLY.class) // private final HostedImageCodeInfo hostedImageCodeInfo = new HostedImageCodeInfo(); @UnknownPrimitiveField private CodePointer codeStart; @UnknownPrimitiveField private UnsignedWord codeSize; @UnknownPrimitiveField private UnsignedWord dataOffset; @UnknownPrimitiveField private UnsignedWord dataSize; @UnknownPrimitiveField private UnsignedWord codeAndDataMemorySize; private final Object[] objectFields; @UnknownObjectField(types = {byte[].class}) byte[] codeInfoIndex; @UnknownObjectField(types = {byte[].class}) byte[] codeInfoEncodings; @UnknownObjectField(types = {byte[].class}) byte[] referenceMapEncoding; @UnknownObjectField(types = {byte[].class}) byte[] frameInfoEncodings; @UnknownObjectField(types = {Object[].class}) Object[] frameInfoObjectConstants; @UnknownObjectField(types = {Class[].class}) Class<?>[] frameInfoSourceClasses; @UnknownObjectField(types = {String[].class}) String[] frameInfoSourceMethodNames; @UnknownObjectField(types = {String[].class}) String[] frameInfoNames; @Platforms(Platform.HOSTED_ONLY.class) ImageCodeInfo() { NonmovableObjectArray<Object> objfields = NonmovableArrays.createObjectArray(Object[].class, CodeInfoImpl.OBJFIELDS_COUNT); NonmovableArrays.setObject(objfields, CodeInfoImpl.NAME_OBJFIELD, CODE_INFO_NAME); // The image code info is never invalidated, so we consider it as always tethered. NonmovableArrays.setObject(objfields, CodeInfoImpl.TETHER_OBJFIELD, new CodeInfoTether(true)); // no InstalledCode for image code objectFields = NonmovableArrays.getHostedArray(objfields); int runtimeInfoSize = SizeOf.get(CodeInfoImpl.class); runtimeCodeInfoData = new byte[runtimeInfoSize]; } @Uninterruptible(reason = "Executes during isolate creation.") CodeInfo prepareCodeInfo() { CodeInfoImpl info = NonmovableArrays.addressOf(NonmovableArrays.fromImageHeap(runtimeCodeInfoData), 0); assert info.getCodeStart().isNull() : "already initialized"; info.setObjectFields(NonmovableArrays.fromImageHeap(objectFields)); info.setCodeStart(codeStart); info.setCodeSize(codeSize); info.setDataOffset(dataOffset); info.setDataSize(dataSize); info.setCodeAndDataMemorySize(codeAndDataMemorySize); info.setCodeInfoIndex(NonmovableArrays.fromImageHeap(codeInfoIndex)); info.setCodeInfoEncodings(NonmovableArrays.fromImageHeap(codeInfoEncodings)); info.setStackReferenceMapEncoding(NonmovableArrays.fromImageHeap(referenceMapEncoding)); info.setFrameInfoEncodings(NonmovableArrays.fromImageHeap(frameInfoEncodings)); info.setFrameInfoObjectConstants(NonmovableArrays.fromImageHeap(frameInfoObjectConstants)); info.setFrameInfoSourceClasses(NonmovableArrays.fromImageHeap(frameInfoSourceClasses)); info.setFrameInfoSourceMethodNames(NonmovableArrays.fromImageHeap(frameInfoSourceMethodNames)); info.setFrameInfoNames(NonmovableArrays.fromImageHeap(frameInfoNames)); return info; } public boolean walkImageCode(MemoryWalker.Visitor visitor) { return visitor.visitCode(CodeInfoTable.getImageCodeInfo(), ImageSingletons.lookup(CodeInfoMemoryWalker.class)); } public HostedImageCodeInfo getHostedImageCodeInfo() { return hostedImageCodeInfo; }
Pure-hosted CodeInfo to collect and persist image code metadata in ImageCodeInfo and provide accesses during image generation.
/** * Pure-hosted {@link CodeInfo} to collect and persist image code metadata in * {@link ImageCodeInfo} and provide accesses during image generation. */
@Platforms(Platform.HOSTED_ONLY.class) public class HostedImageCodeInfo implements CodeInfoImpl { @Override public CodePointer getCodeStart() { return codeStart; } @Override public UnsignedWord getCodeSize() { return codeSize; } @Override public UnsignedWord getDataOffset() { return dataOffset; } @Override public UnsignedWord getDataSize() { return dataSize; } @Override public UnsignedWord getCodeAndDataMemorySize() { return codeAndDataMemorySize; } @Override public NonmovableArray<Byte> getStackReferenceMapEncoding() { return NonmovableArrays.fromImageHeap(referenceMapEncoding); } @Override public void setCodeStart(CodePointer value) { codeStart = value; } @Override public void setCodeSize(UnsignedWord value) { codeSize = value; } @Override public void setDataOffset(UnsignedWord value) { dataOffset = value; } @Override public void setDataSize(UnsignedWord value) { dataSize = value; } @Override public void setCodeAndDataMemorySize(UnsignedWord value) { codeAndDataMemorySize = value; } @Override public NonmovableArray<Byte> getCodeInfoIndex() { return NonmovableArrays.fromImageHeap(codeInfoIndex); } @Override public void setCodeInfoIndex(NonmovableArray<Byte> array) { codeInfoIndex = NonmovableArrays.getHostedArray(array); } @Override public NonmovableArray<Byte> getCodeInfoEncodings() { return NonmovableArrays.fromImageHeap(codeInfoEncodings); } @Override public void setCodeInfoEncodings(NonmovableArray<Byte> array) { codeInfoEncodings = NonmovableArrays.getHostedArray(array); } @Override public void setStackReferenceMapEncoding(NonmovableArray<Byte> array) { referenceMapEncoding = NonmovableArrays.getHostedArray(array); } @Override public NonmovableArray<Byte> getFrameInfoEncodings() { return NonmovableArrays.fromImageHeap(frameInfoEncodings); } @Override public void setFrameInfoEncodings(NonmovableArray<Byte> array) { frameInfoEncodings = NonmovableArrays.getHostedArray(array); } @Override public NonmovableObjectArray<Object> getFrameInfoObjectConstants() { return NonmovableArrays.fromImageHeap(frameInfoObjectConstants); } @Override public void setFrameInfoObjectConstants(NonmovableObjectArray<Object> array) { frameInfoObjectConstants = NonmovableArrays.getHostedArray(array); } @Override public NonmovableObjectArray<Class<?>> getFrameInfoSourceClasses() { return NonmovableArrays.fromImageHeap(frameInfoSourceClasses); } @Override public void setFrameInfoSourceClasses(NonmovableObjectArray<Class<?>> array) { frameInfoSourceClasses = NonmovableArrays.getHostedArray(array); } @Override public NonmovableObjectArray<String> getFrameInfoSourceMethodNames() { return NonmovableArrays.fromImageHeap(frameInfoSourceMethodNames); } @Override public void setFrameInfoSourceMethodNames(NonmovableObjectArray<String> array) { frameInfoSourceMethodNames = NonmovableArrays.getHostedArray(array); } @Override public NonmovableObjectArray<String> getFrameInfoNames() { return NonmovableArrays.fromImageHeap(frameInfoNames); } @Override public void setFrameInfoNames(NonmovableObjectArray<String> array) { frameInfoNames = NonmovableArrays.getHostedArray(array); } @Override public void setObjectFields(NonmovableObjectArray<Object> fields) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableObjectArray<Object> getObjectFields() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public int getTier() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setTier(int tier) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public int getState() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setState(int state) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableArray<Byte> getCodeConstantsReferenceMapEncoding() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setCodeConstantsReferenceMapEncoding(NonmovableArray<Byte> objectsReferenceMapEncoding) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public long getCodeConstantsReferenceMapIndex() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setCodeConstantsReferenceMapIndex(long objectsReferenceMapIndex) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableArray<Integer> getDeoptimizationStartOffsets() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setDeoptimizationStartOffsets(NonmovableArray<Integer> deoptimizationStartOffsets) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableArray<Byte> getDeoptimizationEncodings() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setDeoptimizationEncodings(NonmovableArray<Byte> deoptimizationEncodings) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableObjectArray<Object> getDeoptimizationObjectConstants() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setDeoptimizationObjectConstants(NonmovableObjectArray<Object> deoptimizationObjectConstants) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public NonmovableArray<InstalledCodeObserver.InstalledCodeObserverHandle> getCodeObserverHandles() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setCodeObserverHandles(NonmovableArray<InstalledCodeObserver.InstalledCodeObserverHandle> handles) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public Word getGCData() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public void setAllObjectsAreInImageHeap(boolean value) { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public boolean getAllObjectsAreInImageHeap() { throw VMError.shouldNotReachHere("not supported for image code"); } @Override public boolean isNull() { return false; } @Override public boolean isNonNull() { return !isNull(); } @Override public boolean equal(ComparableWord val) { throw VMError.shouldNotReachHere("not supported during image generation"); } @Override public boolean notEqual(ComparableWord val) { throw VMError.shouldNotReachHere("not supported during image generation"); } @Override public long rawValue() { throw VMError.shouldNotReachHere("not supported during image generation"); } } }