2007-07-06 23:50:26 +00:00
|
|
|
#ifndef MACHINE_H
|
|
|
|
#define MACHINE_H
|
2007-06-25 01:34:07 +00:00
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
#include "common.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "heap.h"
|
|
|
|
#include "class-finder.h"
|
2007-06-25 01:34:07 +00:00
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
#define JNIEXPORT __attribute__ ((visibility("default")))
|
|
|
|
#define JNIIMPORT __attribute__ ((visibility("hidden")))
|
2007-06-25 01:34:07 +00:00
|
|
|
#define JNICALL
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
#define PROTECT(thread, name) \
|
|
|
|
Thread::Protector MAKE_NAME(protector_) (thread, &name);
|
|
|
|
|
|
|
|
#define ACQUIRE(t, x) MonitorResource MAKE_NAME(monitorResource_) (t, x)
|
|
|
|
|
|
|
|
#define ACQUIRE_RAW(t, x) RawMonitorResource MAKE_NAME(monitorResource_) (t, x)
|
|
|
|
|
|
|
|
#define ENTER(t, state) StateResource MAKE_NAME(stateResource_) (t, state)
|
|
|
|
|
2007-06-25 02:02:24 +00:00
|
|
|
namespace vm {
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
const bool Verbose = false;
|
2007-07-17 00:23:23 +00:00
|
|
|
const bool DebugRun = false;
|
2007-07-10 03:04:49 +00:00
|
|
|
const bool DebugStack = false;
|
2007-07-11 13:35:28 +00:00
|
|
|
const bool DebugMonitors = false;
|
2007-07-06 15:24:06 +00:00
|
|
|
|
|
|
|
const uintptr_t HashTakenMark = 1;
|
|
|
|
const uintptr_t ExtendedMark = 2;
|
|
|
|
|
|
|
|
const unsigned FrameBaseOffset = 0;
|
|
|
|
const unsigned FrameNextOffset = 1;
|
|
|
|
const unsigned FrameMethodOffset = 2;
|
|
|
|
const unsigned FrameIpOffset = 3;
|
|
|
|
const unsigned FrameFootprint = 4;
|
|
|
|
|
|
|
|
enum FieldCode {
|
|
|
|
VoidField,
|
|
|
|
ByteField,
|
|
|
|
CharField,
|
|
|
|
DoubleField,
|
|
|
|
FloatField,
|
|
|
|
IntField,
|
|
|
|
LongField,
|
|
|
|
ShortField,
|
|
|
|
BooleanField,
|
|
|
|
ObjectField
|
|
|
|
};
|
|
|
|
|
|
|
|
enum StackTag {
|
|
|
|
IntTag, // must be zero
|
|
|
|
ObjectTag
|
|
|
|
};
|
|
|
|
|
2007-07-14 17:31:01 +00:00
|
|
|
enum MapType {
|
|
|
|
NormalMap,
|
|
|
|
WeakMap
|
|
|
|
};
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
const int NativeLine = -1;
|
|
|
|
const int UnknownLine = -2;
|
|
|
|
|
2007-07-20 03:18:25 +00:00
|
|
|
const unsigned ReferenceFlag = 1 << 0;
|
|
|
|
const unsigned WeakReferenceFlag = 1 << 1;
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
class Thread;
|
|
|
|
|
|
|
|
typedef Thread JNIEnv;
|
|
|
|
|
2007-06-25 01:34:07 +00:00
|
|
|
typedef uint8_t jboolean;
|
|
|
|
typedef int8_t jbyte;
|
|
|
|
typedef uint16_t jchar;
|
|
|
|
typedef int16_t jshort;
|
|
|
|
typedef int32_t jint;
|
|
|
|
typedef int64_t jlong;
|
|
|
|
typedef float jfloat;
|
|
|
|
typedef double jdouble;
|
|
|
|
|
|
|
|
typedef jint jsize;
|
|
|
|
|
|
|
|
typedef void** jobject;
|
|
|
|
|
|
|
|
typedef jobject jclass;
|
|
|
|
typedef jobject jthrowable;
|
|
|
|
typedef jobject jstring;
|
|
|
|
typedef jobject jweak;
|
|
|
|
|
|
|
|
typedef jobject jarray;
|
|
|
|
typedef jarray jbooleanArray;
|
|
|
|
typedef jarray jbyteArray;
|
|
|
|
typedef jarray jcharArray;
|
|
|
|
typedef jarray jshortArray;
|
|
|
|
typedef jarray jintArray;
|
|
|
|
typedef jarray jlongArray;
|
|
|
|
typedef jarray jfloatArray;
|
|
|
|
typedef jarray jdoubleArray;
|
|
|
|
typedef jarray jobjectArray;
|
|
|
|
|
|
|
|
typedef void** jfieldID;
|
|
|
|
typedef void** jmethodID;
|
|
|
|
|
|
|
|
union jvalue {
|
|
|
|
jboolean z;
|
|
|
|
jbyte b;
|
|
|
|
jchar c;
|
|
|
|
jshort s;
|
|
|
|
jint i;
|
|
|
|
jlong j;
|
|
|
|
jfloat f;
|
|
|
|
jdouble d;
|
|
|
|
jobject l;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct JNINativeMethod {
|
|
|
|
char* name;
|
|
|
|
char* signature;
|
|
|
|
void* function;
|
|
|
|
};
|
|
|
|
|
2007-06-25 02:02:24 +00:00
|
|
|
struct JavaVMVTable;
|
|
|
|
|
2007-06-25 01:34:07 +00:00
|
|
|
struct JavaVM {
|
2007-06-25 02:02:24 +00:00
|
|
|
JavaVM(JavaVMVTable* vtable): vtable(vtable) { }
|
|
|
|
|
|
|
|
JavaVMVTable* vtable;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct JavaVMVTable {
|
2007-06-25 01:34:07 +00:00
|
|
|
void* reserved0;
|
|
|
|
void* reserved1;
|
|
|
|
void* reserved2;
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *DestroyJavaVM)
|
|
|
|
(JavaVM*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *AttachCurrentThread)
|
|
|
|
(JavaVM*, void**, void*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *DetachCurrentThread)
|
|
|
|
(JavaVM*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *GetEnv)
|
|
|
|
(JavaVM*, void**, jint);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *AttachCurrentThreadAsDaemon)
|
|
|
|
(JavaVM*, void**, void*);
|
|
|
|
};
|
|
|
|
|
2007-06-25 02:02:24 +00:00
|
|
|
struct JNIEnvVTable {
|
2007-06-25 01:34:07 +00:00
|
|
|
void* reserved0;
|
|
|
|
void* reserved1;
|
|
|
|
void* reserved2;
|
|
|
|
void* reserved3;
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *GetVersion)
|
|
|
|
(JNIEnv*);
|
|
|
|
|
|
|
|
jclass
|
|
|
|
(JNICALL *DefineClass)
|
|
|
|
(JNIEnv*, const char*, jobject, const jbyte*, jsize);
|
|
|
|
|
|
|
|
jclass
|
|
|
|
(JNICALL *FindClass)
|
|
|
|
(JNIEnv*, const char*);
|
|
|
|
|
|
|
|
jmethodID
|
|
|
|
(JNICALL *FromReflectedMethod)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jfieldID
|
|
|
|
(JNICALL *FromReflectedField)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *ToReflectedMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, jboolean);
|
|
|
|
|
|
|
|
jclass
|
|
|
|
(JNICALL *GetSuperclass)
|
|
|
|
(JNIEnv*, jclass);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *IsAssignableFrom)
|
|
|
|
(JNIEnv*, jclass, jclass);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *ToReflectedField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jboolean);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *Throw)
|
|
|
|
(JNIEnv*, jthrowable);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *ThrowNew)
|
|
|
|
(JNIEnv*, jclass, const char*);
|
|
|
|
|
|
|
|
jthrowable
|
|
|
|
(JNICALL *ExceptionOccurred)
|
|
|
|
(JNIEnv*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ExceptionDescribe)
|
|
|
|
(JNIEnv*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ExceptionClear)
|
|
|
|
(JNIEnv*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *FatalError)
|
|
|
|
(JNIEnv*, const char*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *PushLocalFrame)
|
|
|
|
(JNIEnv*, jint);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *PopLocalFrame)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewGlobalRef)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *DeleteGlobalRef)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *DeleteLocalRef)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *IsSameObject)
|
|
|
|
(JNIEnv*, jobject, jobject);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewLocalRef)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *EnsureLocalCapacity)
|
|
|
|
(JNIEnv*, jint);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *AllocObject)
|
|
|
|
(JNIEnv*, jclass);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewObject)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewObjectV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewObjectA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jclass
|
|
|
|
(JNICALL *GetObjectClass)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *IsInstanceOf)
|
|
|
|
(JNIEnv*, jobject, jclass);
|
|
|
|
|
|
|
|
jmethodID
|
|
|
|
(JNICALL *GetMethodID)
|
|
|
|
(JNIEnv*, jclass, const char*, const char*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallObjectMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallObjectMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallObjectMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallBooleanMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallBooleanMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallBooleanMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallByteMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallByteMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallByteMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallCharMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallCharMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallCharMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallShortMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallShortMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallShortMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallIntMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallIntMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallIntMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallLongMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallLongMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallLongMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallFloatMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallFloatMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallFloatMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallDoubleMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallDoubleMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallDoubleMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallVoidMethod)
|
|
|
|
(JNIEnv*, jobject, jmethodID, ...);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallVoidMethodV)
|
|
|
|
(JNIEnv*, jobject, jmethodID, va_list);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallVoidMethodA)
|
|
|
|
(JNIEnv*, jobject, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallNonvirtualObjectMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallNonvirtualObjectMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallNonvirtualObjectMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallNonvirtualBooleanMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallNonvirtualBooleanMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallNonvirtualBooleanMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallNonvirtualByteMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallNonvirtualByteMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallNonvirtualByteMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallNonvirtualCharMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallNonvirtualCharMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallNonvirtualCharMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallNonvirtualShortMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallNonvirtualShortMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID,
|
|
|
|
va_list);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallNonvirtualShortMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID,
|
|
|
|
const jvalue*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallNonvirtualIntMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallNonvirtualIntMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID,
|
|
|
|
va_list);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallNonvirtualIntMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID,
|
|
|
|
const jvalue*);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallNonvirtualLongMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallNonvirtualLongMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID,
|
|
|
|
va_list);
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallNonvirtualLongMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallNonvirtualFloatMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallNonvirtualFloatMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallNonvirtualFloatMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallNonvirtualDoubleMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallNonvirtualDoubleMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallNonvirtualDoubleMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallNonvirtualVoidMethod)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallNonvirtualVoidMethodV)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallNonvirtualVoidMethodA)
|
|
|
|
(JNIEnv*, jobject, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jfieldID
|
|
|
|
(JNICALL *GetFieldID)
|
|
|
|
(JNIEnv*, jclass, const char*, const char*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *GetObjectField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *GetBooleanField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *GetByteField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *GetCharField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *GetShortField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *GetIntField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *GetLongField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *GetFloatField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *GetDoubleField)
|
|
|
|
(JNIEnv*, jobject, jfieldID);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetObjectField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jobject);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetBooleanField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jboolean);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetByteField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jbyte);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetCharField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jchar);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetShortField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jshort);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetIntField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetLongField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jlong);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetFloatField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jfloat);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetDoubleField)
|
|
|
|
(JNIEnv*, jobject, jfieldID, jdouble);
|
|
|
|
|
|
|
|
jmethodID
|
|
|
|
(JNICALL *GetStaticMethodID)
|
|
|
|
(JNIEnv*, jclass, const char*, const char*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallStaticObjectMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallStaticObjectMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *CallStaticObjectMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallStaticBooleanMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallStaticBooleanMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *CallStaticBooleanMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallStaticByteMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallStaticByteMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *CallStaticByteMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallStaticCharMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallStaticCharMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *CallStaticCharMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallStaticShortMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallStaticShortMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *CallStaticShortMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallStaticIntMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallStaticIntMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *CallStaticIntMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallStaticLongMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallStaticLongMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *CallStaticLongMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallStaticFloatMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallStaticFloatMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *CallStaticFloatMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallStaticDoubleMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallStaticDoubleMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *CallStaticDoubleMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallStaticVoidMethod)
|
|
|
|
(JNIEnv*, jclass, jmethodID, ...);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallStaticVoidMethodV)
|
|
|
|
(JNIEnv*, jclass, jmethodID, va_list);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *CallStaticVoidMethodA)
|
|
|
|
(JNIEnv*, jclass, jmethodID, const jvalue*);
|
|
|
|
|
|
|
|
jfieldID
|
|
|
|
(JNICALL *GetStaticFieldID)
|
|
|
|
(JNIEnv*, jclass, const char*, const char*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *GetStaticObjectField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *GetStaticBooleanField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jbyte
|
|
|
|
(JNICALL *GetStaticByteField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jchar
|
|
|
|
(JNICALL *GetStaticCharField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jshort
|
|
|
|
(JNICALL *GetStaticShortField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *GetStaticIntField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *GetStaticLongField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jfloat
|
|
|
|
(JNICALL *GetStaticFloatField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
jdouble
|
|
|
|
(JNICALL *GetStaticDoubleField)
|
|
|
|
(JNIEnv*, jclass, jfieldID);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticObjectField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jobject);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticBooleanField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jboolean);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticByteField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jbyte);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticCharField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jchar);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticShortField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jshort);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticIntField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticLongField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jlong);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticFloatField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jfloat);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetStaticDoubleField)
|
|
|
|
(JNIEnv*, jclass, jfieldID, jdouble);
|
|
|
|
|
|
|
|
jstring
|
|
|
|
(JNICALL *NewString)
|
|
|
|
(JNIEnv*, const jchar*, jsize);
|
|
|
|
|
|
|
|
jsize
|
|
|
|
(JNICALL *GetStringLength)
|
|
|
|
(JNIEnv*, jstring);
|
|
|
|
|
|
|
|
const jchar*
|
|
|
|
(JNICALL *GetStringChars)
|
|
|
|
(JNIEnv*, jstring, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseStringChars)
|
|
|
|
(JNIEnv*, jstring, const jchar*);
|
|
|
|
|
|
|
|
jstring
|
|
|
|
(JNICALL *NewStringUTF)
|
|
|
|
(JNIEnv*, const char*);
|
|
|
|
|
|
|
|
jsize
|
|
|
|
(JNICALL *GetStringUTFLength)
|
|
|
|
(JNIEnv*, jstring);
|
|
|
|
|
|
|
|
const char*
|
|
|
|
(JNICALL *GetStringUTFChars)
|
|
|
|
(JNIEnv*, jstring, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseStringUTFChars)
|
|
|
|
(JNIEnv*, jstring, const char*);
|
|
|
|
|
|
|
|
jsize
|
|
|
|
(JNICALL *GetArrayLength)
|
|
|
|
(JNIEnv*, jarray);
|
|
|
|
|
|
|
|
jobjectArray
|
|
|
|
(JNICALL *NewObjectArray)
|
|
|
|
(JNIEnv*, jsize, jclass, jobject);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *GetObjectArrayElement)
|
|
|
|
(JNIEnv*, jobjectArray, jsize);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetObjectArrayElement)
|
|
|
|
(JNIEnv*, jobjectArray, jsize, jobject);
|
|
|
|
|
|
|
|
jbooleanArray
|
|
|
|
(JNICALL *NewBooleanArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jbyteArray
|
|
|
|
(JNICALL *NewByteArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jcharArray
|
|
|
|
(JNICALL *NewCharArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jshortArray
|
|
|
|
(JNICALL *NewShortArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jintArray
|
|
|
|
(JNICALL *NewIntArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jlongArray
|
|
|
|
(JNICALL *NewLongArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jfloatArray
|
|
|
|
(JNICALL *NewFloatArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jdoubleArray
|
|
|
|
(JNICALL *NewDoubleArray)
|
|
|
|
(JNIEnv*, jsize);
|
|
|
|
|
|
|
|
jboolean*
|
|
|
|
(JNICALL *GetBooleanArrayElements)
|
|
|
|
(JNIEnv*, jbooleanArray, jboolean*);
|
|
|
|
|
|
|
|
jbyte*
|
|
|
|
(JNICALL *GetByteArrayElements)
|
|
|
|
(JNIEnv*, jbyteArray, jboolean*);
|
|
|
|
|
|
|
|
jchar*
|
|
|
|
(JNICALL *GetCharArrayElements)
|
|
|
|
(JNIEnv*, jcharArray, jboolean*);
|
|
|
|
|
|
|
|
jshort*
|
|
|
|
(JNICALL *GetShortArrayElements)
|
|
|
|
(JNIEnv*, jshortArray, jboolean*);
|
|
|
|
|
|
|
|
jint*
|
|
|
|
(JNICALL *GetIntArrayElements)
|
|
|
|
(JNIEnv*, jintArray, jboolean*);
|
|
|
|
|
|
|
|
jlong*
|
|
|
|
(JNICALL *GetLongArrayElements)
|
|
|
|
(JNIEnv*, jlongArray, jboolean*);
|
|
|
|
|
|
|
|
jfloat*
|
|
|
|
(JNICALL *GetFloatArrayElements)
|
|
|
|
(JNIEnv*, jfloatArray, jboolean*);
|
|
|
|
|
|
|
|
jdouble*
|
|
|
|
(JNICALL *GetDoubleArrayElements)
|
|
|
|
(JNIEnv*, jdoubleArray, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseBooleanArrayElements)
|
|
|
|
(JNIEnv*, jbooleanArray, jboolean*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseByteArrayElements)
|
|
|
|
(JNIEnv*, jbyteArray, jbyte*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseCharArrayElements)
|
|
|
|
(JNIEnv*, jcharArray, jchar*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseShortArrayElements)
|
|
|
|
(JNIEnv*, jshortArray, jshort*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseIntArrayElements)
|
|
|
|
(JNIEnv*, jintArray, jint*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseLongArrayElements)
|
|
|
|
(JNIEnv*, jlongArray, jlong*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseFloatArrayElements)
|
|
|
|
(JNIEnv*, jfloatArray, jfloat*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseDoubleArrayElements)
|
|
|
|
(JNIEnv*, jdoubleArray, jdouble*, jint);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetBooleanArrayRegion)
|
|
|
|
(JNIEnv*, jbooleanArray, jsize, jsize, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetByteArrayRegion)
|
|
|
|
(JNIEnv*, jbyteArray, jsize, jsize, jbyte*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetCharArrayRegion)
|
|
|
|
(JNIEnv*, jcharArray, jsize, jsize, jchar*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetShortArrayRegion)
|
|
|
|
(JNIEnv*, jshortArray, jsize, jsize, jshort*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetIntArrayRegion)
|
|
|
|
(JNIEnv*, jintArray, jsize, jsize, jint*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetLongArrayRegion)
|
|
|
|
(JNIEnv*, jlongArray, jsize, jsize, jlong*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetFloatArrayRegion)
|
|
|
|
(JNIEnv*, jfloatArray, jsize, jsize, jfloat*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetDoubleArrayRegion)
|
|
|
|
(JNIEnv*, jdoubleArray, jsize, jsize, jdouble*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetBooleanArrayRegion)
|
|
|
|
(JNIEnv*, jbooleanArray, jsize, jsize, const jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetByteArrayRegion)
|
|
|
|
(JNIEnv*, jbyteArray, jsize, jsize, const jbyte*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetCharArrayRegion)
|
|
|
|
(JNIEnv*, jcharArray, jsize, jsize, const jchar*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetShortArrayRegion)
|
|
|
|
(JNIEnv*, jshortArray, jsize, jsize, const jshort*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetIntArrayRegion)
|
|
|
|
(JNIEnv*, jintArray, jsize, jsize, const jint*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetLongArrayRegion)
|
|
|
|
(JNIEnv*, jlongArray, jsize, jsize, const jlong*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetFloatArrayRegion)
|
|
|
|
(JNIEnv*, jfloatArray, jsize, jsize, const jfloat*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *SetDoubleArrayRegion)
|
|
|
|
(JNIEnv*, jdoubleArray, jsize, jsize, const jdouble*);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *RegisterNatives)
|
|
|
|
(JNIEnv*, jclass, const JNINativeMethod*, jint);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *UnregisterNatives)
|
|
|
|
(JNIEnv*, jclass);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *MonitorEnter)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *MonitorExit)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
jint
|
|
|
|
(JNICALL *GetJavaVM)
|
|
|
|
(JNIEnv*, JavaVM**);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetStringRegion)
|
|
|
|
(JNIEnv*, jstring, jsize, jsize, jchar*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *GetStringUTFRegion)
|
|
|
|
(JNIEnv*, jstring, jsize, jsize, char*);
|
|
|
|
|
|
|
|
void*
|
|
|
|
(JNICALL *GetPrimitiveArrayCritical)
|
|
|
|
(JNIEnv*, jarray, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleasePrimitiveArrayCritical)
|
|
|
|
(JNIEnv*, jarray, void*, jint);
|
|
|
|
|
|
|
|
const jchar*
|
|
|
|
(JNICALL *GetStringCritical)
|
|
|
|
(JNIEnv*, jstring, jboolean*);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *ReleaseStringCritical)
|
|
|
|
(JNIEnv*, jstring, const jchar*);
|
|
|
|
|
|
|
|
jweak
|
|
|
|
(JNICALL *NewWeakGlobalRef)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
|
|
|
|
void
|
|
|
|
(JNICALL *DeleteWeakGlobalRef)
|
|
|
|
(JNIEnv*, jweak);
|
|
|
|
|
|
|
|
jboolean
|
|
|
|
(JNICALL *ExceptionCheck)
|
|
|
|
(JNIEnv*);
|
|
|
|
|
|
|
|
jobject
|
|
|
|
(JNICALL *NewDirectByteBuffer)
|
|
|
|
(JNIEnv*, void*, jlong);
|
|
|
|
|
|
|
|
void*
|
|
|
|
(JNICALL *GetDirectBufferAddress)
|
|
|
|
(JNIEnv* env, jobject);
|
|
|
|
|
|
|
|
jlong
|
|
|
|
(JNICALL *GetDirectBufferCapacity)
|
|
|
|
(JNIEnv*, jobject);
|
|
|
|
};
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
inline int
|
|
|
|
strcmp(const int8_t* a, const int8_t* b)
|
|
|
|
{
|
|
|
|
return ::strcmp(reinterpret_cast<const char*>(a),
|
|
|
|
reinterpret_cast<const char*>(b));
|
|
|
|
}
|
|
|
|
|
2007-07-10 01:43:43 +00:00
|
|
|
void
|
|
|
|
noop();
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
class Machine {
|
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
#include "type-enums.cpp"
|
|
|
|
} Type;
|
|
|
|
|
|
|
|
Machine(System* system, Heap* heap, ClassFinder* classFinder);
|
|
|
|
|
|
|
|
~Machine() {
|
|
|
|
dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
void dispose();
|
|
|
|
|
|
|
|
System* system;
|
|
|
|
Heap* heap;
|
|
|
|
ClassFinder* classFinder;
|
|
|
|
Thread* rootThread;
|
|
|
|
Thread* exclusive;
|
|
|
|
unsigned activeCount;
|
|
|
|
unsigned liveCount;
|
|
|
|
System::Monitor* stateLock;
|
|
|
|
System::Monitor* heapLock;
|
|
|
|
System::Monitor* classLock;
|
2007-07-20 03:18:25 +00:00
|
|
|
System::Monitor* referenceLock;
|
2007-07-06 15:24:06 +00:00
|
|
|
System::Library* libraries;
|
|
|
|
object classMap;
|
|
|
|
object bootstrapClassMap;
|
|
|
|
object builtinMap;
|
|
|
|
object monitorMap;
|
|
|
|
object types;
|
|
|
|
object finalizers;
|
2007-07-10 01:43:43 +00:00
|
|
|
object tenuredFinalizers;
|
|
|
|
object finalizeQueue;
|
2007-07-06 15:24:06 +00:00
|
|
|
object weakReferences;
|
2007-07-10 01:43:43 +00:00
|
|
|
object tenuredWeakReferences;
|
2007-07-06 15:24:06 +00:00
|
|
|
bool unsafe;
|
|
|
|
JNIEnvVTable jniEnvVTable;
|
|
|
|
};
|
|
|
|
|
|
|
|
class Thread {
|
|
|
|
public:
|
|
|
|
enum State {
|
|
|
|
NoState,
|
|
|
|
ActiveState,
|
|
|
|
IdleState,
|
|
|
|
ZombieState,
|
2007-07-18 01:33:00 +00:00
|
|
|
JoinedState,
|
2007-07-06 15:24:06 +00:00
|
|
|
ExclusiveState,
|
|
|
|
ExitState
|
|
|
|
};
|
|
|
|
|
|
|
|
class Protector {
|
|
|
|
public:
|
|
|
|
Protector(Thread* t, object* p): t(t), p(p), next(t->protector) {
|
|
|
|
t->protector = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
~Protector() {
|
|
|
|
t->protector = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread* t;
|
|
|
|
object* p;
|
|
|
|
Protector* next;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const unsigned HeapSizeInBytes = 64 * 1024;
|
|
|
|
static const unsigned StackSizeInBytes = 64 * 1024;
|
|
|
|
|
|
|
|
static const unsigned HeapSizeInWords = HeapSizeInBytes / BytesPerWord;
|
|
|
|
static const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord;
|
|
|
|
|
2007-07-07 18:09:16 +00:00
|
|
|
Thread(Machine* m, Allocator* allocator, object javaThread, Thread* parent);
|
|
|
|
|
|
|
|
~Thread() {
|
|
|
|
exit();
|
|
|
|
}
|
2007-07-06 15:24:06 +00:00
|
|
|
|
2007-07-07 18:09:16 +00:00
|
|
|
void exit();
|
2007-07-06 15:24:06 +00:00
|
|
|
void dispose();
|
|
|
|
|
|
|
|
JNIEnvVTable* vtable;
|
|
|
|
Machine* vm;
|
2007-07-07 18:09:16 +00:00
|
|
|
Allocator* allocator;
|
|
|
|
Thread* parent;
|
|
|
|
Thread* peer;
|
2007-07-06 15:24:06 +00:00
|
|
|
Thread* child;
|
|
|
|
State state;
|
2007-07-07 18:09:16 +00:00
|
|
|
System::Thread* systemThread;
|
|
|
|
object javaThread;
|
2007-07-06 15:24:06 +00:00
|
|
|
object code;
|
|
|
|
object exception;
|
2007-07-07 18:09:16 +00:00
|
|
|
object large;
|
2007-07-06 15:24:06 +00:00
|
|
|
unsigned ip;
|
|
|
|
unsigned sp;
|
|
|
|
int frame;
|
|
|
|
unsigned heapIndex;
|
|
|
|
Protector* protector;
|
2007-07-16 23:58:37 +00:00
|
|
|
#ifdef VM_STRESS
|
|
|
|
bool stress;
|
|
|
|
object* heap;
|
|
|
|
#else // not VM_STRESS
|
2007-07-06 15:24:06 +00:00
|
|
|
object heap[HeapSizeInWords];
|
2007-07-16 23:58:37 +00:00
|
|
|
#endif // not VM_STRESS
|
|
|
|
uintptr_t stack[StackSizeInWords];
|
2007-07-06 15:24:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
inline object
|
|
|
|
objectClass(Thread*, object o)
|
|
|
|
{
|
|
|
|
return mask(cast<object>(o, 0));
|
|
|
|
}
|
|
|
|
|
2007-07-16 01:03:02 +00:00
|
|
|
void
|
|
|
|
enter(Thread* t, Thread::State state);
|
2007-07-06 15:24:06 +00:00
|
|
|
|
|
|
|
class StateResource {
|
|
|
|
public:
|
|
|
|
StateResource(Thread* t, Thread::State state): t(t), oldState(t->state) {
|
|
|
|
enter(t, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
~StateResource() { enter(t, oldState); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Thread* t;
|
|
|
|
Thread::State oldState;
|
|
|
|
};
|
|
|
|
|
2007-07-16 01:03:02 +00:00
|
|
|
void
|
|
|
|
collect(Thread* t, Heap::CollectionType type);
|
|
|
|
|
|
|
|
#ifdef VM_STRESS
|
|
|
|
|
|
|
|
inline void
|
|
|
|
stress(Thread* t)
|
|
|
|
{
|
2007-07-17 00:23:23 +00:00
|
|
|
if ((not t->stress)
|
|
|
|
and t->state != Thread::NoState
|
|
|
|
and t->state != Thread::IdleState)
|
|
|
|
{
|
2007-07-16 01:03:02 +00:00
|
|
|
t->stress = true;
|
2007-07-16 01:07:13 +00:00
|
|
|
{ ENTER(t, Thread::ExclusiveState);
|
2007-07-16 01:03:02 +00:00
|
|
|
|
|
|
|
# ifdef VM_STRESS_MAJOR
|
2007-07-16 01:07:13 +00:00
|
|
|
collect(t, Heap::MajorCollection);
|
2007-07-16 01:03:02 +00:00
|
|
|
# else // not VM_STRESS_MAJOR
|
2007-07-16 01:07:13 +00:00
|
|
|
collect(t, Heap::MinorCollection);
|
2007-07-16 01:03:02 +00:00
|
|
|
# endif // not VM_STRESS_MAJOR
|
2007-07-16 01:07:13 +00:00
|
|
|
}
|
2007-07-16 01:03:02 +00:00
|
|
|
|
|
|
|
t->stress = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else // not VM_STRESS
|
|
|
|
|
|
|
|
inline void
|
|
|
|
stress(Thread*)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
#endif // not VM_STRESS
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
class MonitorResource {
|
|
|
|
public:
|
|
|
|
MonitorResource(Thread* t, System::Monitor* m): t(t), m(m) {
|
2007-07-16 01:03:02 +00:00
|
|
|
stress(t);
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
if (not m->tryAcquire(t)) {
|
|
|
|
ENTER(t, Thread::IdleState);
|
|
|
|
m->acquire(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~MonitorResource() { m->release(t); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Thread* t;
|
|
|
|
System::Monitor* m;
|
|
|
|
};
|
|
|
|
|
|
|
|
class RawMonitorResource {
|
|
|
|
public:
|
|
|
|
RawMonitorResource(Thread* t, System::Monitor* m): t(t), m(m) {
|
|
|
|
m->acquire(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
~RawMonitorResource() { m->release(t); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Thread* t;
|
|
|
|
System::Monitor* m;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline void NO_RETURN
|
|
|
|
abort(Thread* t)
|
|
|
|
{
|
|
|
|
abort(t->vm->system);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
assert(Thread* t, bool v)
|
|
|
|
{
|
|
|
|
assert(t->vm->system, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
expect(Thread* t, bool v)
|
|
|
|
{
|
|
|
|
expect(t->vm->system, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
allocateLarge(Thread* t, unsigned sizeInBytes)
|
|
|
|
{
|
2007-07-07 18:09:16 +00:00
|
|
|
return t->large = t->vm->system->allocate(sizeInBytes);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
allocateSmall(Thread* t, unsigned sizeInBytes)
|
|
|
|
{
|
|
|
|
object o = t->heap + t->heapIndex;
|
|
|
|
t->heapIndex += divide(sizeInBytes, BytesPerWord);
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
|
|
|
object
|
|
|
|
allocate2(Thread* t, unsigned sizeInBytes);
|
|
|
|
|
|
|
|
inline object
|
|
|
|
allocate(Thread* t, unsigned sizeInBytes)
|
|
|
|
{
|
2007-07-16 01:03:02 +00:00
|
|
|
stress(t);
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
if (UNLIKELY(t->heapIndex + divide(sizeInBytes, BytesPerWord)
|
|
|
|
>= Thread::HeapSizeInWords
|
|
|
|
or t->vm->exclusive))
|
|
|
|
{
|
|
|
|
return allocate2(t, sizeInBytes);
|
|
|
|
} else {
|
|
|
|
return allocateSmall(t, sizeInBytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
2007-07-16 23:58:37 +00:00
|
|
|
mark(Thread* t, object& target)
|
2007-07-06 15:24:06 +00:00
|
|
|
{
|
|
|
|
if (t->vm->heap->needsMark(&target)) {
|
|
|
|
ACQUIRE_RAW(t, t->vm->heapLock);
|
|
|
|
t->vm->heap->mark(&target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-16 23:58:37 +00:00
|
|
|
inline void
|
|
|
|
set(Thread* t, object& target, object value)
|
|
|
|
{
|
|
|
|
target = value;
|
|
|
|
mark(t, target);
|
|
|
|
}
|
|
|
|
|
2007-07-14 17:31:01 +00:00
|
|
|
inline void
|
|
|
|
setObjectClass(Thread* t, object o, object value)
|
|
|
|
{
|
|
|
|
set(t, cast<object>(o, 0),
|
|
|
|
reinterpret_cast<object>
|
|
|
|
(reinterpret_cast<uintptr_t>(value)
|
|
|
|
| reinterpret_cast<uintptr_t>(cast<object>(o, 0)) & (~PointerMask)));
|
|
|
|
}
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
object&
|
|
|
|
arrayBodyUnsafe(Thread*, object, unsigned);
|
|
|
|
|
|
|
|
#include "type-declarations.cpp"
|
|
|
|
|
|
|
|
object
|
|
|
|
makeTrace(Thread* t, int frame);
|
|
|
|
|
|
|
|
object
|
|
|
|
makeTrace(Thread* t);
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeRuntimeException(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeRuntimeException(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
2007-07-07 18:09:16 +00:00
|
|
|
inline object
|
|
|
|
makeIllegalStateException(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeIllegalStateException(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
inline object
|
|
|
|
makeIllegalMonitorStateException(Thread* t)
|
|
|
|
{
|
|
|
|
return makeIllegalMonitorStateException(t, 0, makeTrace(t), 0);
|
|
|
|
}
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
inline object
|
|
|
|
makeArrayIndexOutOfBoundsException(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeArrayIndexOutOfBoundsException(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
2007-07-07 23:47:35 +00:00
|
|
|
makeArrayStoreException(Thread* t)
|
|
|
|
{
|
|
|
|
return makeArrayStoreException(t, 0, makeTrace(t), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeNegativeArraySizeException(Thread* t, object message)
|
2007-07-06 15:24:06 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
2007-07-07 23:47:35 +00:00
|
|
|
return makeNegativeArraySizeException(t, message, trace, 0);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeClassCastException(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeClassCastException(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeClassNotFoundException(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeClassNotFoundException(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeNullPointerException(Thread* t)
|
|
|
|
{
|
|
|
|
return makeNullPointerException(t, 0, makeTrace(t), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeStackOverflowError(Thread* t)
|
|
|
|
{
|
|
|
|
return makeStackOverflowError(t, 0, makeTrace(t), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeNoSuchFieldError(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeNoSuchFieldError(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeNoSuchMethodError(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeNoSuchMethodError(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
makeUnsatisfiedLinkError(Thread* t, object message)
|
|
|
|
{
|
|
|
|
PROTECT(t, message);
|
|
|
|
object trace = makeTrace(t);
|
|
|
|
return makeUnsatisfiedLinkError(t, message, trace, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
object
|
|
|
|
makeByteArray(Thread* t, const char* format, ...);
|
|
|
|
|
|
|
|
object
|
|
|
|
makeString(Thread* t, const char* format, ...);
|
|
|
|
|
2007-07-08 01:06:32 +00:00
|
|
|
void
|
|
|
|
stringChars(Thread* t, object string, char* chars);
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
inline void
|
|
|
|
pushObject(Thread* t, object o)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "push object %p at %d\n", o, t->sp);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
|
|
|
|
t->stack[(t->sp * 2) ] = ObjectTag;
|
|
|
|
t->stack[(t->sp * 2) + 1] = reinterpret_cast<uintptr_t>(o);
|
|
|
|
++ t->sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
pushInt(Thread* t, uint32_t v)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "push int %d at %d\n", v, t->sp);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
|
|
|
|
t->stack[(t->sp * 2) ] = IntTag;
|
|
|
|
t->stack[(t->sp * 2) + 1] = v;
|
|
|
|
++ t->sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
pushLong(Thread* t, uint64_t v)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "push long " LLD " at %d\n", v, t->sp);
|
|
|
|
}
|
|
|
|
|
|
|
|
pushInt(t, v >> 32);
|
2007-07-11 01:38:06 +00:00
|
|
|
pushInt(t, v & 0xFFFFFFFF);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
popObject(Thread* t)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "pop object %p at %d\n",
|
|
|
|
reinterpret_cast<object>(t->stack[((t->sp - 1) * 2) + 1]),
|
|
|
|
t->sp - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag);
|
|
|
|
return reinterpret_cast<object>(t->stack[((-- t->sp) * 2) + 1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
popInt(Thread* t)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "pop int " LD " at %d\n",
|
|
|
|
t->stack[((t->sp - 1) * 2) + 1],
|
|
|
|
t->sp - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, t->stack[(t->sp - 1) * 2] == IntTag);
|
|
|
|
return t->stack[((-- t->sp) * 2) + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint64_t
|
|
|
|
popLong(Thread* t)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "pop long " LLD " at %d\n",
|
|
|
|
(static_cast<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32)
|
|
|
|
| static_cast<uint64_t>(t->stack[((t->sp - 1) * 2) + 1]),
|
|
|
|
t->sp - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t a = popInt(t);
|
|
|
|
uint64_t b = popInt(t);
|
|
|
|
return (b << 32) | a;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
peekObject(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "peek object %p at %d\n",
|
|
|
|
reinterpret_cast<object>(t->stack[(index * 2) + 1]),
|
|
|
|
index);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, index < Thread::StackSizeInWords / 2);
|
|
|
|
assert(t, t->stack[index * 2] == ObjectTag);
|
|
|
|
return *reinterpret_cast<object*>(t->stack + (index * 2) + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
peekInt(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "peek int " LD " at %d\n",
|
|
|
|
t->stack[(index * 2) + 1],
|
|
|
|
index);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(t, index < Thread::StackSizeInWords / 2);
|
|
|
|
assert(t, t->stack[index * 2] == IntTag);
|
|
|
|
return t->stack[(index * 2) + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint64_t
|
|
|
|
peekLong(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "peek long " LLD " at %d\n",
|
|
|
|
(static_cast<uint64_t>(t->stack[(index * 2) + 1]) << 32)
|
|
|
|
| static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]),
|
|
|
|
index);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (static_cast<uint64_t>(peekInt(t, index)) << 32)
|
|
|
|
| static_cast<uint64_t>(peekInt(t, index + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
pokeObject(Thread* t, unsigned index, object value)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "poke object %p at %d\n", value, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
t->stack[index * 2] = ObjectTag;
|
|
|
|
t->stack[(index * 2) + 1] = reinterpret_cast<uintptr_t>(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
pokeInt(Thread* t, unsigned index, uint32_t value)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "poke int %d at %d\n", value, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
t->stack[index * 2] = IntTag;
|
|
|
|
t->stack[(index * 2) + 1] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
pokeLong(Thread* t, unsigned index, uint64_t value)
|
|
|
|
{
|
|
|
|
if (DebugStack) {
|
|
|
|
fprintf(stderr, "poke long " LLD " at %d\n", value, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
pokeInt(t, index, value >> 32);
|
2007-07-11 01:38:06 +00:00
|
|
|
pokeInt(t, index + 1, value & 0xFFFFFFFF);
|
2007-07-06 15:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline object*
|
|
|
|
pushReference(Thread* t, object o)
|
|
|
|
{
|
|
|
|
expect(t, t->sp + 1 < Thread::StackSizeInWords / 2);
|
|
|
|
pushObject(t, o);
|
|
|
|
return reinterpret_cast<object*>(t->stack + ((t->sp - 1) * 2) + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int
|
|
|
|
frameNext(Thread* t, int frame)
|
|
|
|
{
|
|
|
|
return peekInt(t, frame + FrameNextOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object
|
|
|
|
frameMethod(Thread* t, int frame)
|
|
|
|
{
|
|
|
|
return peekObject(t, frame + FrameMethodOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
frameIp(Thread* t, int frame)
|
|
|
|
{
|
|
|
|
return peekInt(t, frame + FrameIpOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
frameBase(Thread* t, int frame)
|
|
|
|
{
|
|
|
|
return peekInt(t, frame + FrameBaseOffset);
|
|
|
|
}
|
|
|
|
|
2007-07-06 23:50:26 +00:00
|
|
|
inline object
|
|
|
|
localObject(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
return peekObject(t, frameBase(t, t->frame) + index);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
localInt(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
return peekInt(t, frameBase(t, t->frame) + index);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint64_t
|
|
|
|
localLong(Thread* t, unsigned index)
|
|
|
|
{
|
|
|
|
return peekLong(t, frameBase(t, t->frame) + index);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
setLocalObject(Thread* t, unsigned index, object value)
|
|
|
|
{
|
|
|
|
pokeObject(t, frameBase(t, t->frame) + index, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
setLocalInt(Thread* t, unsigned index, uint32_t value)
|
|
|
|
{
|
|
|
|
pokeInt(t, frameBase(t, t->frame) + index, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
setLocalLong(Thread* t, unsigned index, uint64_t value)
|
|
|
|
{
|
|
|
|
pokeLong(t, frameBase(t, t->frame) + index, value);
|
|
|
|
}
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
inline object
|
|
|
|
makeTrace(Thread* t)
|
|
|
|
{
|
|
|
|
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
|
|
|
return makeTrace(t, t->frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
hash(const int8_t* s, unsigned length)
|
|
|
|
{
|
|
|
|
uint32_t h = 0;
|
|
|
|
for (unsigned i = 0; i < length; ++i) h = (h * 31) + s[i];
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
baseSize(Thread* t, object o, object class_)
|
|
|
|
{
|
|
|
|
return divide(classFixedSize(t, class_), BytesPerWord)
|
|
|
|
+ divide(classArrayElementSize(t, class_)
|
2007-07-10 01:43:43 +00:00
|
|
|
* cast<uintptr_t>(o, classFixedSize(t, class_) - BytesPerWord),
|
2007-07-06 15:24:06 +00:00
|
|
|
BytesPerWord);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
objectExtended(Thread*, object o)
|
|
|
|
{
|
|
|
|
return (cast<uintptr_t>(o, 0) & (~PointerMask)) == ExtendedMark;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uintptr_t&
|
|
|
|
extendedWord(Thread* t, object o, unsigned baseSize)
|
|
|
|
{
|
|
|
|
assert(t, objectExtended(t, o));
|
|
|
|
return cast<uintptr_t>(o, baseSize * BytesPerWord);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
extendedSize(Thread* t, object o, unsigned baseSize)
|
|
|
|
{
|
|
|
|
return baseSize + objectExtended(t, o);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
hashTaken(Thread*, object o)
|
|
|
|
{
|
|
|
|
return (cast<uintptr_t>(o, 0) & (~PointerMask)) == HashTakenMark;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
markHashTaken(Thread* t, object o)
|
|
|
|
{
|
|
|
|
assert(t, not objectExtended(t, o));
|
|
|
|
cast<uintptr_t>(o, 0) |= HashTakenMark;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
takeHash(Thread*, object o)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<uintptr_t>(o) / BytesPerWord;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
objectHash(Thread* t, object o)
|
|
|
|
{
|
|
|
|
if (objectExtended(t, o)) {
|
|
|
|
return extendedWord(t, o, baseSize(t, o, objectClass(t, o)));
|
|
|
|
} else {
|
|
|
|
markHashTaken(t, o);
|
|
|
|
return takeHash(t, o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
objectEqual(Thread*, object a, object b)
|
|
|
|
{
|
|
|
|
return a == b;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
byteArrayHash(Thread* t, object array)
|
|
|
|
{
|
|
|
|
return hash(&byteArrayBody(t, array, 0), byteArrayLength(t, array));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
byteArrayEqual(Thread* t, object a, object b)
|
|
|
|
{
|
|
|
|
return a == b or
|
|
|
|
((byteArrayLength(t, a) == byteArrayLength(t, b)) and
|
|
|
|
memcmp(&byteArrayBody(t, a, 0), &byteArrayBody(t, b, 0),
|
|
|
|
byteArrayLength(t, a)) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
intArrayEqual(Thread* t, object a, object b)
|
|
|
|
{
|
|
|
|
return a == b or
|
|
|
|
((intArrayLength(t, a) == intArrayLength(t, b)) and
|
|
|
|
memcmp(&intArrayBody(t, a, 0), &intArrayBody(t, b, 0),
|
|
|
|
intArrayLength(t, a) * 4) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t
|
|
|
|
methodHash(Thread* t, object method)
|
|
|
|
{
|
|
|
|
return byteArrayHash(t, methodName(t, method))
|
|
|
|
^ byteArrayHash(t, methodSpec(t, method));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
methodEqual(Thread* t, object a, object b)
|
|
|
|
{
|
|
|
|
return a == b or
|
|
|
|
(byteArrayEqual(t, methodName(t, a), methodName(t, b)) and
|
|
|
|
byteArrayEqual(t, methodSpec(t, a), methodSpec(t, b)));
|
|
|
|
}
|
|
|
|
|
|
|
|
object
|
|
|
|
hashMapFindNode(Thread* t, object map, object key,
|
|
|
|
uint32_t (*hash)(Thread*, object),
|
|
|
|
bool (*equal)(Thread*, object, object));
|
|
|
|
|
|
|
|
inline object
|
|
|
|
hashMapFind(Thread* t, object map, object key,
|
|
|
|
uint32_t (*hash)(Thread*, object),
|
|
|
|
bool (*equal)(Thread*, object, object))
|
|
|
|
{
|
|
|
|
object n = hashMapFindNode(t, map, key, hash, equal);
|
|
|
|
return (n ? tripleSecond(t, n) : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
|
|
|
|
unsigned size);
|
|
|
|
|
|
|
|
void
|
|
|
|
hashMapInsert(Thread* t, object map, object key, object value,
|
|
|
|
uint32_t (*hash)(Thread*, object));
|
|
|
|
|
|
|
|
inline bool
|
|
|
|
hashMapInsertOrReplace(Thread* t, object map, object key, object value,
|
|
|
|
uint32_t (*hash)(Thread*, object),
|
|
|
|
bool (*equal)(Thread*, object, object))
|
|
|
|
{
|
|
|
|
object n = hashMapFindNode(t, map, key, hash, equal);
|
|
|
|
if (n == 0) {
|
|
|
|
hashMapInsert(t, map, key, value, hash);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
set(t, tripleSecond(t, n), value);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-07 18:09:16 +00:00
|
|
|
inline bool
|
|
|
|
hashMapInsertMaybe(Thread* t, object map, object key, object value,
|
|
|
|
uint32_t (*hash)(Thread*, object),
|
|
|
|
bool (*equal)(Thread*, object, object))
|
|
|
|
{
|
|
|
|
object n = hashMapFindNode(t, map, key, hash, equal);
|
|
|
|
if (n == 0) {
|
|
|
|
hashMapInsert(t, map, key, value, hash);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-06 15:24:06 +00:00
|
|
|
object
|
|
|
|
hashMapRemove(Thread* t, object map, object key,
|
|
|
|
uint32_t (*hash)(Thread*, object),
|
|
|
|
bool (*equal)(Thread*, object, object));
|
|
|
|
|
2007-07-06 23:18:40 +00:00
|
|
|
object
|
|
|
|
hashMapIterator(Thread* t, object map);
|
|
|
|
|
|
|
|
object
|
|
|
|
hashMapIteratorNext(Thread* t, object it);
|
|
|
|
|
|
|
|
void
|
|
|
|
listAppend(Thread* t, object list, object value);
|
|
|
|
|
2007-07-14 17:31:01 +00:00
|
|
|
unsigned
|
|
|
|
fieldCode(Thread* t, unsigned javaCode);
|
|
|
|
|
|
|
|
unsigned
|
|
|
|
fieldType(Thread* t, unsigned code);
|
|
|
|
|
|
|
|
unsigned
|
|
|
|
primitiveSize(Thread* t, unsigned code);
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
fieldSize(Thread* t, object field)
|
|
|
|
{
|
|
|
|
unsigned code = fieldCode(t, field);
|
|
|
|
if (code == ObjectField) {
|
|
|
|
return BytesPerWord;
|
|
|
|
} else {
|
|
|
|
return primitiveSize(t, code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
object
|
|
|
|
resolveClass(Thread* t, object spec);
|
|
|
|
|
|
|
|
object
|
|
|
|
resolveObjectArrayClass(Thread* t, object elementSpec);
|
|
|
|
|
|
|
|
object
|
|
|
|
makeObjectArray(Thread* t, object elementClass, unsigned count, bool clear);
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
objectArrayLength(Thread* t, object array)
|
|
|
|
{
|
|
|
|
assert(t, classFixedSize(t, objectClass(t, array)) == BytesPerWord * 2);
|
|
|
|
assert(t, classArrayElementSize(t, objectClass(t, array)) == BytesPerWord);
|
|
|
|
return cast<uintptr_t>(array, BytesPerWord);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline object&
|
|
|
|
objectArrayBody(Thread* t, object array, unsigned index)
|
|
|
|
{
|
|
|
|
assert(t, classFixedSize(t, objectClass(t, array)) == BytesPerWord * 2);
|
|
|
|
assert(t, classArrayElementSize(t, objectClass(t, array)) == BytesPerWord);
|
|
|
|
assert(t, classObjectMask(t, objectClass(t, array))
|
|
|
|
== classObjectMask(t, arrayBody
|
|
|
|
(t, t->vm->types, Machine::ArrayType)));
|
2007-07-14 18:37:04 +00:00
|
|
|
return cast<object>(array, (2 + index) * BytesPerWord);
|
2007-07-14 17:31:01 +00:00
|
|
|
}
|
|
|
|
|
2007-07-16 23:58:37 +00:00
|
|
|
unsigned
|
|
|
|
parameterFootprint(const char* s);
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
parameterFootprint(Thread* t, object spec)
|
|
|
|
{
|
|
|
|
return parameterFootprint
|
|
|
|
(reinterpret_cast<const char*>(&byteArrayBody(t, spec, 0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned
|
|
|
|
parameterCount(const char* s);
|
|
|
|
|
|
|
|
inline unsigned
|
|
|
|
parameterCount(Thread* t, object spec)
|
|
|
|
{
|
|
|
|
return parameterCount
|
|
|
|
(reinterpret_cast<const char*>(&byteArrayBody(t, spec, 0)));
|
|
|
|
}
|
|
|
|
|
2007-07-14 18:37:04 +00:00
|
|
|
int
|
|
|
|
lineNumber(Thread* t, object method, unsigned ip);
|
|
|
|
|
2007-07-06 23:50:26 +00:00
|
|
|
void
|
|
|
|
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
|
|
|
|
|
|
|
|
System::Monitor*
|
|
|
|
objectMonitor(Thread* t, object o);
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
inline void
|
|
|
|
acquire(Thread* t, object o)
|
|
|
|
{
|
|
|
|
System::Monitor* m = objectMonitor(t, o);
|
2007-07-11 04:19:26 +00:00
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p acquires %p for %x\n",
|
|
|
|
t, m, objectHash(t, o));
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
if (not m->tryAcquire(t)) {
|
|
|
|
ENTER(t, Thread::IdleState);
|
|
|
|
m->acquire(t);
|
|
|
|
}
|
2007-07-19 23:45:44 +00:00
|
|
|
|
|
|
|
stress(t);
|
2007-07-07 23:47:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
release(Thread* t, object o)
|
|
|
|
{
|
2007-07-11 04:19:26 +00:00
|
|
|
System::Monitor* m = objectMonitor(t, o);
|
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p releases %p for %x\n",
|
|
|
|
t, m, objectHash(t, o));
|
|
|
|
}
|
|
|
|
|
|
|
|
m->release(t);
|
2007-07-07 23:47:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
wait(Thread* t, object o, int64_t milliseconds)
|
|
|
|
{
|
|
|
|
System::Monitor* m = objectMonitor(t, o);
|
2007-07-11 04:19:26 +00:00
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p waits " LLD " millis on %p for %x\n",
|
|
|
|
t, milliseconds, m, objectHash(t, o));
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
if (m->owner() == t) {
|
|
|
|
ENTER(t, Thread::IdleState);
|
|
|
|
m->wait(t, milliseconds);
|
|
|
|
} else {
|
|
|
|
t->exception = makeIllegalMonitorStateException(t);
|
|
|
|
}
|
2007-07-11 04:19:26 +00:00
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p wakes up on %p for %x\n",
|
|
|
|
t, m, objectHash(t, o));
|
|
|
|
}
|
2007-07-19 23:45:44 +00:00
|
|
|
|
|
|
|
stress(t);
|
2007-07-07 23:47:35 +00:00
|
|
|
}
|
|
|
|
|
2007-07-20 14:36:31 +00:00
|
|
|
inline void
|
|
|
|
vmWait(Thread* t, object o, int64_t milliseconds)
|
|
|
|
{
|
|
|
|
wait(t, o, milliseconds);
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
inline void
|
|
|
|
notify(Thread* t, object o)
|
|
|
|
{
|
|
|
|
System::Monitor* m = objectMonitor(t, o);
|
2007-07-11 04:19:26 +00:00
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p notifies on %p for %x\n",
|
|
|
|
t, m, objectHash(t, o));
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
if (m->owner() == t) {
|
|
|
|
m->notify(t);
|
|
|
|
} else {
|
|
|
|
t->exception = makeIllegalMonitorStateException(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-20 14:36:31 +00:00
|
|
|
inline void
|
|
|
|
vmNotify(Thread* t, object o)
|
|
|
|
{
|
|
|
|
notify(t, o);
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
inline void
|
|
|
|
notifyAll(Thread* t, object o)
|
|
|
|
{
|
|
|
|
System::Monitor* m = objectMonitor(t, o);
|
2007-07-11 04:19:26 +00:00
|
|
|
|
|
|
|
if (DebugMonitors) {
|
|
|
|
fprintf(stderr, "thread %p notifies all on %p for %x\n",
|
|
|
|
t, m, objectHash(t, o));
|
|
|
|
}
|
|
|
|
|
2007-07-07 23:47:35 +00:00
|
|
|
if (m->owner() == t) {
|
|
|
|
m->notifyAll(t);
|
|
|
|
} else {
|
|
|
|
t->exception = makeIllegalMonitorStateException(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-20 14:36:31 +00:00
|
|
|
inline void
|
|
|
|
vmNotifyAll(Thread* t, object o)
|
|
|
|
{
|
|
|
|
notifyAll(t, o);
|
|
|
|
}
|
|
|
|
|
2007-07-07 18:09:16 +00:00
|
|
|
void
|
|
|
|
exit(Thread* t);
|
|
|
|
|
2007-06-25 02:02:24 +00:00
|
|
|
} // namespace vm
|
|
|
|
|
2007-07-06 23:50:26 +00:00
|
|
|
#endif//MACHINE_H
|