/*
* Copyright (c) 2007, 2011, 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 com.sun.max.vm.runtime;
import com.sun.max.annotate.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
import com.sun.max.vm.classfile.constant.*;
import com.sun.max.vm.compiler.*;
import com.sun.max.vm.compiler.target.*;
import com.sun.max.vm.type.*;
/**
* This class represents a method that is a critical entrypoint in the virtual machine, which means
* that it is typically used by very low-level subsystems that must have the method compiled to
* target code at image build time and must have the address of the machine code readily available.
* This is typically needed for subsystems that interact closely with the substrate at startup.
*/
public class CriticalMethod {
public final ClassMethodActor classMethodActor;
private final CallEntryPoint callEntryPoint;
protected Address address;
/**
* Create a new critical entrypoint for the method specified by the java class and its name
* as a string. This constructor uses the default {link CallEntryPoint optimized} entrypoint.
*
* @param javaClass the class in which the method was declared
* @param methodName the name of the method as a string
* @param methodSignature the signature of the method
* @throws NoSuchMethodError if a method with the specified name could not be found in the specified class
*/
@HOSTED_ONLY
public CriticalMethod(Class javaClass, String methodName, SignatureDescriptor methodSignature) {
this(javaClass, methodName, methodSignature, CallEntryPoint.OPTIMIZED_ENTRY_POINT);
}
/**
* Create a new critical entrypoint for the method specified by the java class and its name
* as a string.
*
* @param javaClass the class in which the method was declared
* @param methodName the name of the method as a string
* @param methodSignature the signature of the method to find. If this value is {@code null}, then the first method found
* based on {@code name} is returned.
* @param callEntryPoint the entrypoint in the method that is desired
* @throws NoSuchMethodError if a method with the specified name could not be found in the specified class
*/
@HOSTED_ONLY
public CriticalMethod(Class javaClass, String methodName, SignatureDescriptor methodSignature, CallEntryPoint callEntryPoint) {
final ClassActor classActor = ClassActor.fromJava(javaClass);
final Utf8Constant name = SymbolTable.makeSymbol(methodName);
ClassMethodActor classMethodActor = classActor.findLocalClassMethodActor(name, methodSignature);
if (classMethodActor == null) {
classMethodActor = classActor.findLocalStaticMethodActor(name);
}
if (classMethodActor == null) {
throw new NoSuchMethodError(methodName);
}
this.classMethodActor = classMethodActor;
this.callEntryPoint = callEntryPoint;
MaxineVM.registerCriticalMethod(this);
}
/**
* Create a new critical entrypoint for the specified class method actor.
*
* @param classMethodActor the method for which to create an entrypoint
* @param callEntryPoint the call entrypoint of the method that is desired
*/
@HOSTED_ONLY
public CriticalMethod(ClassMethodActor classMethodActor, CallEntryPoint callEntryPoint) {
this.classMethodActor = classMethodActor;
this.callEntryPoint = callEntryPoint;
MaxineVM.registerCriticalMethod(this);
}
/**
* Gets the address of the entrypoint to the compiled code of the method.
*
* @return the address of the first instruction of the compiled code of this method
*/
public Address address() {
if (address.isZero()) {
address = classMethodActor.currentTargetMethod().getEntryPoint(callEntryPoint).toAddress();
}
return address;
}
/**
* Gets the target method compiled for this critical method.
*
* @return {@code null} if this critical method has not been compiled.
*/
public TargetMethod targetMethod() {
return classMethodActor.currentTargetMethod();
}
}