implement various JVM_* methods

This includes a proper implementation of JVM_ActiveProcessorCount, as
well as JVM_SetLength and JVM_NewMultiArray.  Also, we now accept up
to JNI_VERSION_1_6 in JVM_IsSupportedJNIVersion.
This commit is contained in:
Joel Dice 2011-03-26 11:15:52 -06:00
parent 3dd091c67a
commit ba0cc803a6
4 changed files with 118 additions and 60 deletions

View File

@ -2733,7 +2733,13 @@ EXPORT(JVM_MaxMemory)()
extern "C" JNIEXPORT jint JNICALL
EXPORT(JVM_ActiveProcessorCount)()
{
return 1;
#ifdef PLATFORM_WINDOWS
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwNumberOfProcessors;
#else
return sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
uint64_t
@ -2780,7 +2786,7 @@ EXPORT(JVM_FindLibraryEntry)(void* library, const char* name)
extern "C" JNIEXPORT jboolean JNICALL
EXPORT(JVM_IsSupportedJNIVersion)(jint version)
{
return version <= JNI_VERSION_1_4;
return version <= JNI_VERSION_1_6;
}
extern "C" JNIEXPORT jboolean JNICALL
@ -3165,14 +3171,9 @@ extern "C" JNIEXPORT void JNICALL
EXPORT(JVM_SetPrimitiveArrayElement)(Thread*, jobject, jint, jvalue,
unsigned char) { abort(); }
uint64_t
jvmNewArray(Thread* t, uintptr_t* arguments)
object
makeNewArray(Thread* t, object c, unsigned length)
{
jclass elementClass = reinterpret_cast<jclass>(arguments[0]);
jint length = arguments[1];
object c = jclassVmClass(t, *elementClass);
if (classVmFlags(t, c) & PrimitiveFlag) {
const char* name = reinterpret_cast<char*>
(&byteArrayBody(t, local::getClassName(t, c), 0));
@ -3180,32 +3181,34 @@ jvmNewArray(Thread* t, uintptr_t* arguments)
switch (*name) {
case 'b':
if (name[1] == 'o') {
return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeBooleanArray(t, length)));
return makeBooleanArray(t, length);
} else {
return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeByteArray(t, length)));
return makeByteArray(t, length);
}
case 'c': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeCharArray(t, length)));
case 'd': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeDoubleArray(t, length)));
case 'f': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeFloatArray(t, length)));
case 'i': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeIntArray(t, length)));
case 'l': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeLongArray(t, length)));
case 's': return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeShortArray(t, length)));
case 'c': return makeCharArray(t, length);
case 'd': return makeDoubleArray(t, length);
case 'f': return makeFloatArray(t, length);
case 'i': return makeIntArray(t, length);
case 'l': return makeLongArray(t, length);
case 's': return makeShortArray(t, length);
default: abort(t);
}
} else {
return reinterpret_cast<uint64_t>
(makeLocalReference(t, makeObjectArray(t, c, length)));
return makeObjectArray(t, c, length);
}
}
uint64_t
jvmNewArray(Thread* t, uintptr_t* arguments)
{
jclass elementClass = reinterpret_cast<jclass>(arguments[0]);
jint length = arguments[1];
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, makeNewArray(t, jclassVmClass(t, *elementClass), length)));
}
extern "C" JNIEXPORT jobject JNICALL
EXPORT(JVM_NewArray)(Thread* t, jclass elementClass, jint length)
{
@ -3215,8 +3218,41 @@ EXPORT(JVM_NewArray)(Thread* t, jclass elementClass, jint length)
return reinterpret_cast<jobject>(run(t, jvmNewArray, arguments));
}
uint64_t
jvmNewMultiArray(Thread* t, uintptr_t* arguments)
{
jclass elementClass = reinterpret_cast<jclass>(arguments[0]);
jintArray dimensions = reinterpret_cast<jintArray>(arguments[1]);
THREAD_RUNTIME_ARRAY(t, int32_t, counts, intArrayLength(t, *dimensions));
for (int i = intArrayLength(t, *dimensions) - 1; i >= 0; --i) {
RUNTIME_ARRAY_BODY(counts)[i] = intArrayBody(t, *dimensions, i);
if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
throwNew(t, Machine::NegativeArraySizeExceptionType, "%d",
RUNTIME_ARRAY_BODY(counts)[i]);
return 0;
}
}
object array = makeNewArray
(t, jclassVmClass(t, *elementClass), RUNTIME_ARRAY_BODY(counts)[0]);
PROTECT(t, array);
populateMultiArray(t, array, RUNTIME_ARRAY_BODY(counts), 0,
intArrayLength(t, *dimensions));
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
}
extern "C" JNIEXPORT jobject JNICALL
EXPORT(JVM_NewMultiArray)(Thread*, jclass, jintArray) { abort(); }
EXPORT(JVM_NewMultiArray)(Thread* t, jclass elementClass,
jintArray dimensions)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(elementClass),
reinterpret_cast<uintptr_t>(dimensions) };
return reinterpret_cast<jobject>(run(t, jvmNewMultiArray, arguments));
}
extern "C" JNIEXPORT jclass JNICALL
EXPORT(JVM_GetCallerClass)(Thread* t, int target)
@ -4338,7 +4374,25 @@ EXPORT(JVM_Lseek)(jint fd, jlong offset, jint seek)
}
extern "C" JNIEXPORT jint JNICALL
EXPORT(JVM_SetLength)(jint, jlong) { abort(); }
EXPORT(JVM_SetLength)(jint fd, jlong length)
{
#ifdef PLATFORM_WINDOWS
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (h == INVALID_HANDLE_VALUE) {
errno = EBADF;
return -1;
}
if (SetEndOfFile(h, length)) {
return 0;
} else {
errno = EIO;
return -1;
}
#else
return ftruncate(fd, length);
#endif
}
extern "C" JNIEXPORT jint JNICALL
EXPORT(JVM_Sync)(jint fd)

View File

@ -4210,6 +4210,37 @@ defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length)
return c;
}
void
populateMultiArray(Thread* t, object array, int32_t* counts,
unsigned index, unsigned dimensions)
{
if (index + 1 == dimensions or counts[index] == 0) {
return;
}
PROTECT(t, array);
object spec = className(t, objectClass(t, array));
PROTECT(t, spec);
object elementSpec = makeByteArray(t, byteArrayLength(t, spec) - 1);
memcpy(&byteArrayBody(t, elementSpec, 0),
&byteArrayBody(t, spec, 1),
byteArrayLength(t, spec) - 1);
object class_ = resolveClass
(t, classLoader(t, objectClass(t, array)), elementSpec);
PROTECT(t, class_);
for (int32_t i = 0; i < counts[index]; ++i) {
object a = makeArray(t, counts[index + 1]);
setObjectClass(t, a, class_);
set(t, array, ArrayBody + (i * BytesPerWord), a);
populateMultiArray(t, a, counts, index + 1, dimensions);
}
}
void
noop()
{ }

View File

@ -3701,6 +3701,10 @@ unregisterNatives(Thread* t, object c)
}
}
void
populateMultiArray(Thread* t, object array, int32_t* counts,
unsigned index, unsigned dimensions);
object
getCaller(Thread* t, unsigned target);

View File

@ -56,37 +56,6 @@ isSpecialMethod(Thread* t, object method, object class_)
and isSuperclass(t, methodClass(t, method), class_);
}
inline void
populateMultiArray(Thread* t, object array, int32_t* counts,
unsigned index, unsigned dimensions)
{
if (index + 1 == dimensions or counts[index] == 0) {
return;
}
PROTECT(t, array);
object spec = className(t, objectClass(t, array));
PROTECT(t, spec);
object elementSpec = makeByteArray(t, byteArrayLength(t, spec) - 1);
memcpy(&byteArrayBody(t, elementSpec, 0),
&byteArrayBody(t, spec, 1),
byteArrayLength(t, spec) - 1);
object class_ = resolveClass
(t, classLoader(t, objectClass(t, array)), elementSpec);
PROTECT(t, class_);
for (int32_t i = 0; i < counts[index]; ++i) {
object a = makeArray(t, counts[index + 1]);
setObjectClass(t, a, class_);
set(t, array, ArrayBody + (i * BytesPerWord), a);
populateMultiArray(t, a, counts, index + 1, dimensions);
}
}
void
resolveNative(Thread* t, object method);