/*
* Copyright (c) 2012, 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.ext.jvmti;
import static com.sun.max.vm.ext.jvmti.JVMTIConstants.*;
import static com.sun.max.vm.ext.jvmti.JVMTIEnvNativeStruct.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import com.sun.max.annotate.*;
import com.sun.max.io.*;
import com.sun.max.memory.*;
import com.sun.max.platform.*;
import com.sun.max.program.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
import com.sun.max.vm.ext.jvmti.JVMTI.*;
import com.sun.max.vm.hosted.*;
import com.sun.max.vm.jni.*;
import com.sun.max.vm.runtime.*;
import com.sun.max.vm.thread.*;
/**
* The template for the implementations of the JVMTI functions.
* This is transformed by {@link JVMTIFunctionsGenerator} into the actual
* implementation in {@link JVMTIFunctions}. The transformation includes
* phase checks, null {@link Pointer} checks, JNI handle type checks,
* capability checks, MemberID checks, jvmtiEnv checks and exception handling.
* Essentially the goal is to automate as much error checking as possible
* so that the real implementations can just focus on the logic.
*
* Null {@link Pointer} checks are indicated by:
* // NULLCHECK: arg1,arg2,...
*
* Phase checks are indicated by:
* // PHASES: phase1,phase2,...
*
* JNI handle type checks are indicated by:
*
* // HANDLECHECK: handleVar1=ClassName,...
*
* or
*
* // HANDLECHECK_NULLOK: handleVar1=ClassName,...
*
* in the (unusual) case that a null handle is acceptable.
*
* Capability checks are indicated by:
* // CAPABILITIES: cap1, cap2,...
*
* MemberID checks are indicated by:
* // MEMBERID: var1=T1,var2=T2,...
* where Ti are one of Member,Method,Field and SomeActor is the appropriate {@link Actor} subclass
*
* By default, all arguments are logged, but this can be customized via:
*
* // LOGARGS: arg1,arg2,...
*
* N.B. LOGARGS must be the last entry before the method body proper.
* The "env" arg is omitted in a customization but it is always logged.
*
* Generally, the method implementations are delegated to other classes, unless the
* implementation is completely trivial.
*/
@HOSTED_ONLY
@SuppressWarnings("null")
public class JVMTIFunctionsSource {
static {
JavaPrototype.registerGeneratedCodeCheckerCallback(new GeneratedCodeCheckerCallback());
}
@HOSTED_ONLY
private static class GeneratedCodeCheckerCallback implements JavaPrototype.GeneratedCodeCheckerCallback {
@Override
public void checkGeneratedCode() {
NativeInterfaces.checkGenerateSourcesInSync("com.oracle.max.vm.ext.jvmti", JVMTIFunctionsSource.class, JVMTIFunctions.class, new JVMTIFunctionsGenerator.JVMTICustomizer());
}
}
static StaticMethodActor[] checkAgainstJvmtiHeaderFile(StaticMethodActor[] jvmtiFunctionActors) {
String jniHeaderFilePath = System.getProperty("max.jni.headerFile");
if (jniHeaderFilePath == null) {
jniHeaderFilePath = Platform.jniHeaderFilePath();
}
File jvmtiHeaderFile = new File(new File(jniHeaderFilePath).getParentFile(), "jvmti.h");
ProgramError.check(jvmtiHeaderFile.isFile(), "JVMTI header file " + jvmtiHeaderFile + " does not exist or is not a file");
List<String> jvmtiFunctionNames = new ArrayList<String>();
parseJvmtiFunctions(jvmtiHeaderFile, jvmtiFunctionNames);
for (int i = 0; i != jvmtiFunctionNames.size(); ++i) {
final String jvmtiFunctionName = jvmtiFunctionNames.get(i);
final String jvmtiFunctionActorName = jvmtiFunctionActors[i].name.toString();
ProgramError.check(jvmtiFunctionName.equals(jvmtiFunctionActorName), "JVMTI function " + jvmtiFunctionName + " at index " + i + " does not match JVMTI function actor " + jvmtiFunctionActorName);
}
if (jvmtiFunctionNames.size() < jvmtiFunctionActors.length) {
// This means that an older version of jvmti.h is being used that does not
// define functions added in later versions.
jvmtiFunctionActors = Arrays.copyOf(jvmtiFunctionActors, jvmtiFunctionNames.size());
} else {
ProgramError.check(jvmtiFunctionNames.size() == jvmtiFunctionActors.length);
}
return jvmtiFunctionActors;
}
/**
* Parses a given file for declarations of functions in a VM native interface.
* The declaration of such functions match this pattern:
*
* (JNICALL *<function name>)
*
* @param nativeHeaderFile the C header file to parse
* @param jvmtiFunctionNames the list to which the matched function names are added
*/
private static void parseJvmtiFunctions(File nativeHeaderFile, List<String> jvmtiFunctionNames) {
final Pattern structDeclPattern = Pattern.compile(".*typedef struct jvmtiInterface_1_ \\{(.*)\\} jvmtiInterface_1;.*", Pattern.DOTALL);
try {
String content = new String(Files.toChars(nativeHeaderFile));
Matcher m = structDeclPattern.matcher(content);
if (m.matches()) {
Pattern functionDeclPattern = Pattern.compile("(?:void \\*(reserved\\d+))|(?:\\(JNICALL \\*([^\\)]+)\\)\\s*\\(jvmtiEnv\\s*\\*)", Pattern.DOTALL);
String structDecl = m.group(1);
m = functionDeclPattern.matcher(structDecl);
while (m.find()) {
String functionName = m.group(1);
if (functionName == null) {
functionName = m.group(2);
assert functionName != null;
}
jvmtiFunctionNames.add(functionName);
}
} else {
FatalError.unexpected("Could not find JVMTI function table decl");
}
} catch (IOException ioException) {
throw ProgramError.unexpected("Error reading native header file " + nativeHeaderFile.getPath(), ioException);
}
}
// Checkstyle: stop method name check
// These exist solely to avoid compilation errors in the this code. The transformed
// code defines them as locals in the method as part of the above error checks
private static final MethodActor methodActor = null;
private static final ClassMethodActor classMethodActor = null;
private static final FieldActor fieldActor = null;
private static final Thread handleAsThread = null;
private static final ThreadGroup handleAsThreadGroup = null;
private static final Class<?> handleAsClass = null;
private static final ClassLoader handleAsClassLoader = null;
private static final Env jvmtiEnv = null;
@VM_ENTRY_POINT
private static native void reserved1();
@VM_ENTRY_POINT
private static int SetEventNotificationMode(Pointer env, int mode, int event_type, JniHandle event_thread) {
// PHASES: ONLOAD,LIVE
// HANDLECHECK_NULLOK: event_thread=Thread
// LOGARGS: Address.fromInt(mode),Address.fromInt(event_type),event_thread
return JVMTIEvents.setEventNotificationMode(jvmtiEnv, mode, event_type, handleAsThread);
}
@VM_ENTRY_POINT
private static native void reserved3();
@VM_ENTRY_POINT
private static int GetAllThreads(Pointer env, Pointer threads_count_ptr, Pointer threads_ptr) {
// PHASES: LIVE
// NULLCHECK: threads_count_ptr,threads_ptr
return JVMTIThreadFunctions.getAllThreads(threads_count_ptr, threads_ptr);
}
@VM_ENTRY_POINT
private static int SuspendThread(Pointer env, JniHandle thread) {
// PHASES: LIVE
// CAPABILITIES: CAN_SUSPEND
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.suspendThread(jvmtiEnv, handleAsThread);
}
@VM_ENTRY_POINT
private static int ResumeThread(Pointer env, JniHandle thread) {
// PHASES: LIVE
// CAPABILITIES: CAN_SUSPEND
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.resumeThread(jvmtiEnv, handleAsThread);
}
@VM_ENTRY_POINT
private static int StopThread(Pointer env, JniHandle thread, JniHandle exception) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int InterruptThread(Pointer env, JniHandle thread) {
// PHASES: LIVE
// CAPABILITIES: CAN_SIGNAL_THREAD
// HANDLECHECK: thread=Thread
return JVMTIThreadFunctions.interruptThread(handleAsThread);
}
@VM_ENTRY_POINT
private static int GetThreadInfo(Pointer env, JniHandle thread, Pointer info_ptr) {
// PHASES: LIVE
// NULLCHECK: info_ptr
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.getThreadInfo(handleAsThread, info_ptr);
}
@VM_ENTRY_POINT
private static int GetOwnedMonitorInfo(Pointer env, JniHandle thread, Pointer owned_monitor_count_ptr, Pointer owned_monitors_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetCurrentContendedMonitor(Pointer env, JniHandle thread, Pointer monitor_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int RunAgentThread(Pointer env, JniHandle jthread, Address proc, Pointer arg, int priority) {
// PHASES: LIVE
// NULLCHECK: proc
return JVMTI.runAgentThread(env, jthread, proc, arg, priority);
}
@VM_ENTRY_POINT
private static int GetTopThreadGroups(Pointer env, Pointer group_count_ptr, Pointer groups_ptr) {
// PHASES: LIVE
// NULLCHECK: group_count_ptr,groups_ptr
return JVMTIThreadFunctions.getTopThreadGroups(group_count_ptr, groups_ptr);
}
@VM_ENTRY_POINT
private static int GetThreadGroupInfo(Pointer env, JniHandle group, Pointer info_ptr) {
// PHASES: LIVE
// HANDLECHECK: group=ThreadGroup
// NULLCHECK: info_ptr
return JVMTIThreadFunctions.getThreadGroupInfo(handleAsThreadGroup, info_ptr);
}
@VM_ENTRY_POINT
private static int GetThreadGroupChildren(Pointer env, JniHandle group, Pointer thread_count_ptr, Pointer threads_ptr, Pointer group_count_ptr, Pointer groups_ptr) {
// PHASES: LIVE
// NULLCHECK: thread_count_ptr,thread_count_ptr,group_count_ptr,groups_ptr
// HANDLECHECK: group=ThreadGroup
return JVMTIThreadFunctions.getThreadGroupChildren(handleAsThreadGroup, thread_count_ptr,
threads_ptr, group_count_ptr, groups_ptr);
}
@VM_ENTRY_POINT
private static int GetFrameCount(Pointer env, JniHandle thread, Pointer count_ptr) {
// PHASES: LIVE
// NULLCHECK: count_ptr
// HANDLECHECK_NULLOK: thread=Thread
// LOGARGS: JVMTIFunctionsLogger.threadArg(thread)
return JVMTIThreadFunctions.getFrameCount(handleAsThread, count_ptr);
}
@VM_ENTRY_POINT
private static int GetThreadState(Pointer env, JniHandle thread, Pointer thread_state_ptr) {
// PHASES: LIVE
// NULLCHECK: thread_state_ptr
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.getThreadState(handleAsThread, thread_state_ptr);
}
@VM_ENTRY_POINT
private static int GetCurrentThread(Pointer env, Pointer thread_ptr) {
// PHASES: START,LIVE
// NULLCHECK: thread_ptr
thread_ptr.setWord(JniHandles.createLocalHandle(VmThread.current().javaThread()));
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetFrameLocation(Pointer env, JniHandle thread, int depth, Pointer method_ptr, Pointer location_ptr) {
// PHASES: LIVE
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: method_ptr, location_ptr
// LOGARGS: JVMTIFunctionsLogger.threadArg(thread)
return JVMTIThreadFunctions.getFrameLocation(handleAsThread, depth, method_ptr, location_ptr);
}
@VM_ENTRY_POINT
private static int NotifyFramePop(Pointer env, JniHandle thread, int depth) {
// PHASES: LIVE
// HANDLECHECK_NULLOK: thread=Thread
// LOGARGS: Address.fromInt(depth)
return JVMTIThreadFunctions.notifyFramePop(jvmtiEnv, handleAsThread, depth);
}
@VM_ENTRY_POINT
private static int GetLocalObject(Pointer env, JniHandle thread, int depth, int slot, Pointer value_ptr) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: value_ptr
return JVMTIThreadFunctions.getLocalValue(handleAsThread, depth, slot, value_ptr, 'L');
}
@VM_ENTRY_POINT
private static int GetLocalInt(Pointer env, JniHandle thread, int depth, int slot, Pointer value_ptr) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: value_ptr
return JVMTIThreadFunctions.getLocalValue(handleAsThread, depth, slot, value_ptr, 'I');
}
@VM_ENTRY_POINT
private static int GetLocalLong(Pointer env, JniHandle thread, int depth, int slot, Pointer value_ptr) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: value_ptr
return JVMTIThreadFunctions.getLocalValue(handleAsThread, depth, slot, value_ptr, 'J');
}
@VM_ENTRY_POINT
private static int GetLocalFloat(Pointer env, JniHandle thread, int depth, int slot, Pointer value_ptr) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: value_ptr
return JVMTIThreadFunctions.getLocalValue(handleAsThread, depth, slot, value_ptr, 'F');
}
@VM_ENTRY_POINT
private static int GetLocalDouble(Pointer env, JniHandle thread, int depth, int slot, Pointer value_ptr) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: value_ptr
return JVMTIThreadFunctions.getLocalValue(handleAsThread, depth, slot, value_ptr, 'D');
}
@VM_ENTRY_POINT
private static int SetLocalObject(Pointer env, JniHandle thread, int depth, int slot, JniHandle value) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.setLocalObject(handleAsThread, depth, slot, value.unhand());
}
@VM_ENTRY_POINT
private static int SetLocalInt(Pointer env, JniHandle thread, int depth, int slot, int value) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.setLocalInt(handleAsThread, depth, slot, value);
}
@VM_ENTRY_POINT
private static int SetLocalLong(Pointer env, JniHandle thread, int depth, int slot, long value) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.setLocalLong(handleAsThread, depth, slot, value);
}
@VM_ENTRY_POINT
private static int SetLocalFloat(Pointer env, JniHandle thread, int depth, int slot, float value) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.setLocalFloat(handleAsThread, depth, slot, value);
}
@VM_ENTRY_POINT
private static int SetLocalDouble(Pointer env, JniHandle thread, int depth, int slot, double value) {
// PHASES: LIVE
// CAPABILITIES: CAN_ACCESS_LOCAL_VARIABLES
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIThreadFunctions.setLocalDouble(handleAsThread, depth, slot, value);
}
@VM_ENTRY_POINT
private static int CreateRawMonitor(Pointer env, Pointer name, Pointer monitor_ptr) {
// PHASES: ONLOAD,LIVE
// NULLCHECK: name,monitor_ptr
return JVMTIRawMonitor.create(name, monitor_ptr);
}
@VM_ENTRY_POINT
private static int DestroyRawMonitor(Pointer env, Word rawMonitor) {
// PHASES: ONLOAD,LIVE
return JVMTIRawMonitor.destroy(rawMonitor);
}
@VM_ENTRY_POINT
private static int RawMonitorEnter(Pointer env, Word rawMonitor) {
// PHASES: ANY
return JVMTIRawMonitor.enter(rawMonitor);
}
@VM_ENTRY_POINT
private static int RawMonitorExit(Pointer env, Word rawMonitor) {
// PHASES: ANY
return JVMTIRawMonitor.exit(rawMonitor);
}
@VM_ENTRY_POINT
private static int RawMonitorWait(Pointer env, Word rawMonitor, long millis) {
// PHASES: ANY
return JVMTIRawMonitor.wait(rawMonitor, millis);
}
@VM_ENTRY_POINT
private static int RawMonitorNotify(Pointer env, Word rawMonitor) {
// PHASES: ANY
return JVMTIRawMonitor.notify(rawMonitor);
}
@VM_ENTRY_POINT
private static int RawMonitorNotifyAll(Pointer env, Word rawMonitor) {
// PHASES: ANY
return JVMTIRawMonitor.notifyAll(rawMonitor);
}
@VM_ENTRY_POINT
private static int SetBreakpoint(Pointer env, MethodID method, long location) {
// PHASES: LIVE
// MEMBERID: method=Class:Method
return JVMTIBreakpoints.setBreakpoint(classMethodActor, method, location);
}
@VM_ENTRY_POINT
private static int ClearBreakpoint(Pointer env, MethodID method, long location) {
// PHASES: LIVE
// MEMBERID: method=Class:Method
return JVMTIBreakpoints.clearBreakpoint(classMethodActor, method, location);
}
@VM_ENTRY_POINT
private static native void reserved40();
@VM_ENTRY_POINT
private static int SetFieldAccessWatch(Pointer env, JniHandle klass, FieldID field) {
// PHASES: LIVE
// HANDLECHECK: klass=Class
// MEMBERID: field=Field
// CAPABILITIES: CAN_GENERATE_FIELD_ACCESS_EVENTS
return JVMTIFieldWatch.setAccessWatch(handleAsClass, fieldActor);
}
@VM_ENTRY_POINT
private static int ClearFieldAccessWatch(Pointer env, JniHandle klass, FieldID field) {
// PHASES: LIVE
// HANDLECHECK: klass=Class
// MEMBERID: field=Field
// CAPABILITIES: CAN_GENERATE_FIELD_ACCESS_EVENTS
return JVMTIFieldWatch.clearAccessWatch(handleAsClass, fieldActor);
}
@VM_ENTRY_POINT
private static int SetFieldModificationWatch(Pointer env, JniHandle klass, FieldID field) {
// PHASES: LIVE
// HANDLECHECK: klass=Class
// MEMBERID: field=Field
// CAPABILITIES: CAN_GENERATE_FIELD_MODIFICATION_EVENTS
return JVMTIFieldWatch.setModificationWatch(handleAsClass, fieldActor);
}
@VM_ENTRY_POINT
private static int ClearFieldModificationWatch(Pointer env, JniHandle klass, FieldID field) {
// PHASES: LIVE
// HANDLECHECK: klass=Class
// MEMBERID: field=Field
// CAPABILITIES: CAN_GENERATE_FIELD_MODIFICATION_EVENTS
return JVMTIFieldWatch.clearModificationWatch(handleAsClass, fieldActor);
}
@VM_ENTRY_POINT
private static int IsModifiableClass(Pointer env, JniHandle klass, Pointer is_modifiable_class_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int Allocate(Pointer env, long size, Pointer mem_ptr) {
// PHASES: ANY
// NULLCHECK: mem_ptr
if (size < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
if (size == 0) {
mem_ptr.setWord(Word.zero());
} else {
Pointer mem = Memory.allocate(Size.fromLong(size));
if (mem.isZero()) {
return JVMTI_ERROR_OUT_OF_MEMORY;
}
mem_ptr.setWord(mem);
}
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int Deallocate(Pointer env, Pointer mem) {
// PHASES: ANY
Memory.deallocate(mem);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetClassSignature(Pointer env, JniHandle klass, Pointer signature_ptr, Pointer generic_ptr) {
// PHASES: START,LIVE
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getClassSignature(handleAsClass, signature_ptr, generic_ptr);
}
@VM_ENTRY_POINT
private static int GetClassStatus(Pointer env, JniHandle klass, Pointer status_ptr) {
// PHASES: START,LIVE
// HANDLECHECK: klass=Class
// NULLCHECK: status_ptr
return JVMTIClassFunctions.getClassStatus(handleAsClass, status_ptr);
}
@VM_ENTRY_POINT
private static int GetSourceFileName(Pointer env, JniHandle klass, Pointer source_name_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_SOURCE_FILE_NAME
// NULLCHECK: source_name_ptr
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getSourceFileName(handleAsClass, source_name_ptr);
}
@VM_ENTRY_POINT
private static int GetClassModifiers(Pointer env, JniHandle klass, Pointer modifiers_ptr) {
// PHASES: START,LIVE
// NULLCHECK: modifiers_ptr
// HANDLECHECK: klass=Class
modifiers_ptr.setInt(ClassActor.fromJava(handleAsClass).accessFlags());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetClassMethods(Pointer env, JniHandle klass, Pointer method_count_ptr, Pointer methods_ptr) {
// PHASES: START,LIVE
// NULLCHECK: method_count_ptr,methods_ptr
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getClassMethods(handleAsClass, method_count_ptr, methods_ptr);
}
@VM_ENTRY_POINT
private static int GetClassFields(Pointer env, JniHandle klass, Pointer field_count_ptr, Pointer fields_ptr) {
// PHASES: START,LIVE
// NULLCHECK: field_count_ptr,fields_ptr
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getClassFields(handleAsClass, field_count_ptr, fields_ptr);
}
@VM_ENTRY_POINT
private static int GetImplementedInterfaces(Pointer env, JniHandle klass, Pointer interface_count_ptr, Pointer interfaces_ptr) {
// PHASES: START,LIVE
// NULLCHECK: interface_count_ptr,interfaces_ptr
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getImplementedInterfaces(handleAsClass, interface_count_ptr, interfaces_ptr);
}
@VM_ENTRY_POINT
private static int IsInterface(Pointer env, JniHandle klass, Pointer is_interface_ptr) {
// PHASES LIVE
// NULLCHECK: is_interface_ptr
// HANDLECHECK: klass=Class
boolean is = ClassActor.isInterface(ClassActor.fromJava(handleAsClass).flags());
is_interface_ptr.setBoolean(is);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int IsArrayClass(Pointer env, JniHandle klass, Pointer is_array_class_ptr) {
// PHASES LIVE
// NULLCHECK: is_array_class_ptr
// HANDLECHECK: klass=Class
boolean is = ClassActor.fromJava(handleAsClass).isArrayClass();
is_array_class_ptr.setBoolean(is);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetClassLoader(Pointer env, JniHandle klass, Pointer classloader_ptr) {
// PHASES START,LIVE
// NULLCHECK: classloader_ptr
// HANDLECHECK: klass=Class
classloader_ptr.setWord(JniHandles.createLocalHandle(handleAsClass.getClassLoader()));
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetObjectHashCode(Pointer env, JniHandle handle, Pointer hash_code_ptr) {
// PHASES: START,LIVE
// NULLCHECK: hash_code_ptr
Object object = handle.unhand();
if (object == null) {
return JVMTI_ERROR_INVALID_OBJECT;
}
hash_code_ptr.setInt(System.identityHashCode(object));
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetObjectMonitorUsage(Pointer env, JniHandle object, Pointer info_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetFieldName(Pointer env, JniHandle klass, FieldID field, Pointer name_ptr, Pointer signature_ptr, Pointer generic_ptr) {
// PHASES: START,LIVE
// HANDLECHECK: klass=Class
// MEMBERID: field=Field
return JVMTIClassFunctions.getFieldName(fieldActor, name_ptr, signature_ptr, generic_ptr);
}
@VM_ENTRY_POINT
private static int GetFieldDeclaringClass(Pointer env, JniHandle klass, FieldID field, Pointer declaring_class_ptr) {
// PHASES: START,LIVE
// NULLCHECK: declaring_class_ptr
// MEMBERID: field=Field
return JVMTIClassFunctions.getFieldDeclaringClass(fieldActor, declaring_class_ptr);
}
@VM_ENTRY_POINT
private static int GetFieldModifiers(Pointer env, JniHandle klass, FieldID field, Pointer modifiers_ptr) {
// PHASES: START,LIVE
// NULLCHECK: modifiers_ptr
// MEMBERID: field=Field
modifiers_ptr.setInt(fieldActor.accessFlags());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int IsFieldSynthetic(Pointer env, JniHandle klass, FieldID field, Pointer is_synthetic_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_SYNTHETIC_ATTRIBUTE
// NULLCHECK: is_synthetic_ptr
// MEMBERID: field=Field
boolean result = (fieldActor.flags() & Actor.ACC_SYNTHETIC) != 0;
is_synthetic_ptr.setBoolean(result);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetMethodName(Pointer env, MethodID method, Pointer name_ptr, Pointer signature_ptr, Pointer generic_ptr) {
// PHASES: START,LIVE
// MEMBERID: method=Method
return JVMTIClassFunctions.getMethodName(methodActor, name_ptr, signature_ptr, generic_ptr);
}
@VM_ENTRY_POINT
private static int GetMethodDeclaringClass(Pointer env, MethodID method, Pointer declaring_class_ptr) {
// PHASES: START,LIVE
// NULLCHECK: declaring_class_ptr
// MEMBERID: method=Method
return JVMTIClassFunctions.getMethodDeclaringClass(methodActor, declaring_class_ptr);
}
@VM_ENTRY_POINT
private static int GetMethodModifiers(Pointer env, MethodID method, Pointer modifiers_ptr) {
// PHASES: START,LIVE
// NULLCHECK: modifiers_ptr
// MEMBERID: method=Method
modifiers_ptr.setInt(methodActor.flags());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static native void reserved67();
@VM_ENTRY_POINT
private static int GetMaxLocals(Pointer env, MethodID method, Pointer max_ptr) {
// PHASES: START,LIVE
// NULLCHECK: max_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getMaxLocals(classMethodActor, max_ptr);
}
@VM_ENTRY_POINT
private static int GetArgumentsSize(Pointer env, MethodID method, Pointer size_ptr) {
// PHASES: START,LIVE
// NULLCHECK: size_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getArgumentsSize(classMethodActor, size_ptr);
}
@VM_ENTRY_POINT
private static int GetLineNumberTable(Pointer env, MethodID method, Pointer entry_count_ptr, Pointer table_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_LINE_NUMBERS
// NULLCHECK: entry_count_ptr,table_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getLineNumberTable(classMethodActor, entry_count_ptr, table_ptr);
}
@VM_ENTRY_POINT
private static int GetMethodLocation(Pointer env, MethodID method, Pointer start_location_ptr, Pointer end_location_ptr) {
// PHASES: START,LIVE
// NULLCHECK: start_location_ptr,end_location_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getMethodLocation(classMethodActor, start_location_ptr, end_location_ptr);
}
@VM_ENTRY_POINT
private static int GetLocalVariableTable(Pointer env, MethodID method, Pointer entry_count_ptr, Pointer table_ptr) {
// PHASES: LIVE
// NULLCHECK: entry_count_ptr, table_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getLocalVariableTable(classMethodActor, entry_count_ptr, table_ptr);
}
@VM_ENTRY_POINT
private static int SetNativeMethodPrefix(Pointer env, Pointer prefix) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int SetNativeMethodPrefixes(Pointer env, int prefix_count, Pointer prefixes) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetBytecodes(Pointer env, MethodID method, Pointer bytecode_count_ptr, Pointer bytecodes_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_BYTECODES
// NULLCHECK: bytecode_count_ptr,bytecodes_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.getByteCodes(classMethodActor, bytecode_count_ptr, bytecodes_ptr);
}
@VM_ENTRY_POINT
private static int IsMethodNative(Pointer env, MethodID method, Pointer is_native_ptr) {
// PHASES: START,LIVE
// NULLCHECK: is_native_ptr
// MEMBERID: method=Method
is_native_ptr.setBoolean(methodActor.isNative());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int IsMethodSynthetic(Pointer env, MethodID method, Pointer is_synthetic_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_SYNTHETIC_ATTRIBUTE
// NULLCHECK: is_synthetic_ptr
// MEMBERID: method=Method
boolean result = (methodActor.flags() & Actor.ACC_SYNTHETIC) != 0;
is_synthetic_ptr.setBoolean(result);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetLoadedClasses(Pointer env, Pointer class_count_ptr, Pointer classes_ptr) {
// PHASES: LIVE
// NULLCHECK: class_count_ptr,classes_ptr
return JVMTIClassFunctions.getLoadedClasses(class_count_ptr, classes_ptr);
}
@VM_ENTRY_POINT
private static int GetClassLoaderClasses(Pointer env, JniHandle initiatingLoader, Pointer class_count_ptr, Pointer classes_ptr) {
// PHASES: LIVE
// NULLCHECK: class_count_ptr,classes_ptr
// HANDLECHECK: initiatingLoader=ClassLoader
return JVMTIClassFunctions.getClassLoaderClasses(handleAsClassLoader, class_count_ptr, classes_ptr);
}
@VM_ENTRY_POINT
private static int PopFrame(Pointer env, JniHandle thread) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnObject(Pointer env, JniHandle thread, JniHandle value) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnInt(Pointer env, JniHandle thread, int value) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnLong(Pointer env, JniHandle thread, long value) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnFloat(Pointer env, JniHandle thread, float value) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnDouble(Pointer env, JniHandle thread, double value) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int ForceEarlyReturnVoid(Pointer env, JniHandle thread) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int RedefineClasses(Pointer env, int class_count, Pointer class_definitions) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetVersionNumber(Pointer env, Pointer version_ptr) {
// PHASES: ANY
// NULLCHECK: version_ptr
version_ptr.setInt(JVMTI_VERSION);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetCapabilities(Pointer env, Pointer capabilities_ptr) {
// PHASES: ANY
// NULLCHECK: capabilities_ptr
capabilities_ptr.setLong(0, CAPABILITIES.getPtr(env).readLong(0));
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetSourceDebugExtension(Pointer env, JniHandle klass, Pointer source_debug_extension_ptr) {
// PHASES: START,LIVE
// CAPABILITIES: CAN_GET_SOURCE_DEBUG_EXTENSION
// NULLCHECK: source_debug_extension_ptr
// HANDLECHECK: klass=Class
return JVMTIClassFunctions.getSourceDebugExtension(handleAsClass, source_debug_extension_ptr);
}
@VM_ENTRY_POINT
private static int IsMethodObsolete(Pointer env, MethodID method, Pointer is_obsolete_ptr) {
// PHASES: START,LIVE
// NULLCHECK: is_obsolete_ptr
// MEMBERID: method=Class:Method
return JVMTIClassFunctions.isMethodObsolete(classMethodActor, is_obsolete_ptr);
}
@VM_ENTRY_POINT
private static int SuspendThreadList(Pointer env, int request_count, Pointer request_list, Pointer results) {
// PHASES: LIVE
// CAPABILITIES: CAN_SUSPEND
// NULLCHECK: request_list,results
// LOGARGS: Address.fromInt(request_count)
if (request_count < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTIThreadFunctions.suspendThreadList(jvmtiEnv, request_count, request_list, results);
}
@VM_ENTRY_POINT
private static int ResumeThreadList(Pointer env, int request_count, Pointer request_list, Pointer results) {
// PHASES: LIVE
// CAPABILITIES: CAN_SUSPEND
// NULLCHECK: request_list,results
// LOGARGS: Address.fromInt(request_count)
if (request_count < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTIThreadFunctions.resumeThreadList(jvmtiEnv, request_count, request_list, results);
}
@VM_ENTRY_POINT
private static native void reserved94();
@VM_ENTRY_POINT
private static native void reserved95();
@VM_ENTRY_POINT
private static native void reserved96();
@VM_ENTRY_POINT
private static native void reserved97();
@VM_ENTRY_POINT
private static native void reserved98();
@VM_ENTRY_POINT
private static native void reserved99();
@VM_ENTRY_POINT
private static int GetAllStackTraces(Pointer env, int max_frame_count, Pointer stack_info_ptr, Pointer thread_count_ptr) {
// PHASES: LIVE
// NULLCHECK: stack_info_ptr,thread_count_ptr
if (max_frame_count < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTIThreadFunctions.getAllStackTraces(max_frame_count, stack_info_ptr, thread_count_ptr);
}
@VM_ENTRY_POINT
private static int GetThreadListStackTraces(Pointer env, int thread_count, Pointer thread_list, int max_frame_count, Pointer stack_info_ptr) {
// PHASES: LIVE
// NULLCHECK: thread_list,stack_info_ptr
if (thread_count < 0 || max_frame_count < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTIThreadFunctions.getThreadListStackTraces(thread_count, thread_list, max_frame_count, stack_info_ptr);
}
@VM_ENTRY_POINT
private static int GetThreadLocalStorage(Pointer env, JniHandle thread, Pointer data_ptr) {
// PHASES: START,LIVE
// HANDLECHECK_NULLOK: thread=Thread
// NULLCHECK: data_ptr
return JVMTIVmThreadLocal.getThreadLocalStorage(handleAsThread, data_ptr);
}
@VM_ENTRY_POINT
private static int SetThreadLocalStorage(Pointer env, JniHandle thread, Pointer data) {
// PHASES: START,LIVE
// HANDLECHECK_NULLOK: thread=Thread
return JVMTIVmThreadLocal.setThreadLocalStorage(handleAsThread, data);
}
@VM_ENTRY_POINT
private static int GetStackTrace(Pointer env, JniHandle thread, int start_depth, int max_frame_count, Pointer frame_buffer, Pointer count_ptr) {
// PHASES: LIVE
// NULLCHECK: frame_buffer,count_ptr
// HANDLECHECK_NULLOK: thread=Thread
if (max_frame_count < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
return JVMTIThreadFunctions.getStackTrace(handleAsThread, start_depth, max_frame_count, frame_buffer, count_ptr);
}
@VM_ENTRY_POINT
private static native void reserved105();
@VM_ENTRY_POINT
private static int GetTag(Pointer env, JniHandle object, Pointer tag_ptr) {
// PHASES: START,LIVE
// NULLCHECK: tag_ptr
return jvmtiEnv.tags.getTag(object.unhand(), tag_ptr);
}
@VM_ENTRY_POINT
private static int SetTag(Pointer env, JniHandle object, long tag) {
// PHASES: START,LIVE
return jvmtiEnv.tags.setTag(object.unhand(), tag);
}
@VM_ENTRY_POINT
private static int ForceGarbageCollection(Pointer env) {
System.gc();
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int IterateOverObjectsReachableFromObject(Pointer env, JniHandle object, Address object_reference_callback, Pointer user_data) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int IterateOverReachableObjects(Pointer env, Address heap_root_callback, Address stack_ref_callback, Address object_ref_callback, Pointer user_data) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int IterateOverHeap(Pointer env, int object_filter, Address heap_object_callback, Pointer user_data) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int IterateOverInstancesOfClass(Pointer env, JniHandle klass, int object_filter, Address heap_object_callback, Pointer user_data) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static native void reserved113();
@VM_ENTRY_POINT
private static int GetObjectsWithTags(Pointer env, int tag_count, Pointer tags, Pointer count_ptr, Pointer object_result_ptr, Pointer tag_result_ptr) {
// CAPABILITIES: CAN_TAG_OBJECTS
// NULLCHECK: tags,count_ptr
return JVMTI.getEnv(env).tags.getObjectsWithTags(tag_count, tags, count_ptr, object_result_ptr, tag_result_ptr);
}
@VM_ENTRY_POINT
private static int FollowReferences(Pointer env, int heap_filter, JniHandle klass, JniHandle initial_object, Pointer callbacks, Pointer user_data) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int IterateThroughHeap(Pointer env, int heap_filter, JniHandle klass, Pointer callbacks, Pointer user_data) {
// PHASES: LIVE
// CAPABILITIES: CAN_TAG_OBJECTS
// NULLCHECK: callbacks
// HANDLECHECK_NULLOK: klass=Class
return JVMTIHeapFunctions.iterateThroughHeap(jvmtiEnv, heap_filter, handleAsClass, callbacks, user_data);
}
@VM_ENTRY_POINT
private static native void reserved117();
@VM_ENTRY_POINT
private static native void reserved118();
@VM_ENTRY_POINT
private static native void reserved119();
@VM_ENTRY_POINT
private static int SetJNIFunctionTable(Pointer env, Pointer function_table) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetJNIFunctionTable(Pointer env, Pointer function_table) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int SetEventCallbacks(Pointer env, Pointer callbacks, int size_of_callbacks) {
// PHASES: ONLOAD,LIVE
Pointer envCallbacks = CALLBACKS.get(env).asPointer();
Memory.copyBytes(callbacks, envCallbacks, Size.fromInt(size_of_callbacks));
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GenerateEvents(Pointer env, int event_type) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetExtensionFunctions(Pointer env, Pointer extension_count_ptr, Pointer extensions) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetExtensionEvents(Pointer env, Pointer extension_count_ptr, Pointer extensions) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int SetExtensionEventCallback(Pointer env, int extension_event_index, Address callback) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int DisposeEnvironment(Pointer env) {
// PHASES: ANY
return JVMTI.disposeEnv(env);
}
@VM_ENTRY_POINT
private static int GetErrorName(Pointer env, int error, Pointer name_ptr) {
// PHASES: ANY
// NULLCHECK: name_ptr
if (error < 0 || error > JVMTI_ERROR_MAX) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
}
byte[] nameBytes = JVMTIError.nameBytes[error];
Pointer cstring = Memory.allocate(Size.fromInt(nameBytes.length + 1));
CString.writeBytes(nameBytes, 0, nameBytes.length, cstring, nameBytes.length + 1);
name_ptr.setWord(0, cstring);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetJLocationFormat(Pointer env, Pointer format_ptr) {
format_ptr.setInt(JVMTIConstants.JVMTI_JLOCATION_JVMBCI);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetSystemProperties(Pointer env, Pointer count_ptr, Pointer property_ptr) {
return JVMTISystem.getSystemProperties(env, count_ptr, property_ptr);
}
@VM_ENTRY_POINT
private static int GetSystemProperty(Pointer env, Pointer property, Pointer value_ptr) {
// PHASES: ONLOAD,LIVE
// NULLCHECK: property,value_ptr
return JVMTISystem.getSystemProperty(env, property, value_ptr);
}
@VM_ENTRY_POINT
private static int SetSystemProperty(Pointer env, Pointer property, Pointer value) {
// PHASES: ONLOAD
// NULLCHECK: property
return JVMTISystem.setSystemProperty(env, property, value); // value may be null, writeable enquiry
}
@VM_ENTRY_POINT
private static int GetPhase(Pointer env, Pointer phase_ptr) {
// PHASES: ANY
// NULLCHECK: phase_ptr
return JVMTI.getPhase(phase_ptr);
}
@VM_ENTRY_POINT
private static int GetCurrentThreadCpuTimerInfo(Pointer env, Pointer info_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetCurrentThreadCpuTime(Pointer env, Pointer nanos_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetThreadCpuTimerInfo(Pointer env, Pointer info_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetThreadCpuTime(Pointer env, JniHandle thread, Pointer nanos_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetTimerInfo(Pointer env, Pointer info_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetTime(Pointer env, Pointer nanos_ptr) {
// PHASES: ANY
// NULLCHECK: nanos_ptr
nanos_ptr.setLong(System.nanoTime());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetPotentialCapabilities(Pointer env, Pointer capabilities_ptr) {
// PHASES: ONLOAD,LIVE
// NULLCHECK: capabilities_ptr
// Currently we don't have any phase-limited or ownership limitations
JVMTICapabilities.E.setAll(capabilities_ptr);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static native void reserved141();
@VM_ENTRY_POINT
private static int AddCapabilities(Pointer env, Pointer capabilities_ptr) {
// PHASES: ONLOAD,LIVE
// NULLCHECK: capabilities_ptr
return JVMTICapabilities.addCapabilities(env, capabilities_ptr);
}
@VM_ENTRY_POINT
private static int RelinquishCapabilities(Pointer env, Pointer capabilities_ptr) {
// PHASES: ONLOAD,LIVE
// NULLCHECK: capabilities_ptr
return JVMTICapabilities.relinquishCapabilities(env, capabilities_ptr);
}
@VM_ENTRY_POINT
private static int GetAvailableProcessors(Pointer env, Pointer processor_count_ptr) {
// PHASES: ANY
// NULLCHECK: processor_count_ptr
processor_count_ptr.setInt(Runtime.getRuntime().availableProcessors());
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetClassVersionNumbers(Pointer env, JniHandle klass, Pointer minor_version_ptr, Pointer major_version_ptr) {
// PHASES: START,LIVE
// NULLCHECK: minor_version_ptr, minor_version_ptr
// HANDLECHECK: klass=Class
ClassActor classActor = ClassActor.fromJava(handleAsClass);
major_version_ptr.setInt(classActor.majorVersion);
minor_version_ptr.setInt(classActor.minorVersion);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int GetConstantPool(Pointer env, JniHandle klass, Pointer constant_pool_count_ptr, Pointer constant_pool_byte_count_ptr, Pointer constant_pool_bytes_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetEnvironmentLocalStorage(Pointer env, Pointer data_ptr) {
// PHASES: ANY
// NULLCHECK data_ptr
data_ptr.setWord(((JVMTI.NativeEnv) jvmtiEnv).envStorage);
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int SetEnvironmentLocalStorage(Pointer env, Pointer data) {
// PHASES: ANY
((JVMTI.NativeEnv) jvmtiEnv).envStorage = data;
return JVMTI_ERROR_NONE;
}
@VM_ENTRY_POINT
private static int AddToBootstrapClassLoaderSearch(Pointer env, Pointer segment) {
// PHASES ONLOAD,LIVE
// NULLCHECK: segment
return JVMTIClassFunctions.addToBootstrapClassLoaderSearch(env, segment);
}
@VM_ENTRY_POINT
private static int SetVerboseFlag(Pointer env, int flag, boolean value) {
// PHASES: ANY
return JVMTISystem.setVerboseFlag(flag, value);
}
@VM_ENTRY_POINT
private static int AddToSystemClassLoaderSearch(Pointer env, Pointer segment) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int RetransformClasses(Pointer env, int class_count, Pointer classes) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetOwnedMonitorStackDepthInfo(Pointer env, JniHandle thread, Pointer monitor_info_count_ptr, Pointer monitor_info_ptr) {
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
@VM_ENTRY_POINT
private static int GetObjectSize(Pointer env, JniHandle object, Pointer size_ptr) {
// PHASES: START,LIVE
// NULLCHECK: size_ptr
return JVMTIClassFunctions.getObjectSize(object.unhand(), size_ptr);
}
@VM_ENTRY_POINT
private static int GetLocalInstance(Pointer env, JniHandle thread, int depth, Pointer value_ptr) {
// PHASES: START,LIVE
// NULLCHECK: value_ptr
return JVMTI_ERROR_NOT_AVAILABLE; // TODO
}
}