corda/src/jnienv.cpp

2635 lines
63 KiB
C++
Raw Normal View History

2010-12-06 03:21:09 +00:00
/* Copyright (c) 2008-2010 Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
2007-07-06 23:50:26 +00:00
#include "jnienv.h"
#include "machine.h"
2007-11-26 23:15:53 +00:00
#include "util.h"
#include "processor.h"
2007-09-07 23:20:21 +00:00
#include "constants.h"
using namespace vm;
namespace {
2010-04-15 17:11:10 +00:00
namespace local {
2007-09-07 23:20:21 +00:00
const uintptr_t InterfaceMethodID
= (static_cast<uintptr_t>(1) << (BitsPerWord - 1));
const uintptr_t NonVirtualMethodID
= (static_cast<uintptr_t>(1) << (BitsPerWord - 2));
jint JNICALL
AttachCurrentThread(Machine* m, Thread** t, void*)
{
*t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) {
*t = attachThread(m, false);
}
return 0;
}
jint JNICALL
AttachCurrentThreadAsDaemon(Machine* m, Thread** t, void*)
{
*t = static_cast<Thread*>(m->localThread->get());
if (*t == 0) {
*t = attachThread(m, true);
}
return 0;
}
jint JNICALL
DetachCurrentThread(Machine* m)
{
Thread* t = static_cast<Thread*>(m->localThread->get());
if (t) {
expect(t, t != m->rootThread);
m->localThread->set(0);
ACQUIRE_RAW(t, t->m->stateLock);
enter(t, Thread::ActiveState);
threadPeer(t, t->javaThread) = 0;
enter(t, Thread::ZombieState);
t->state = Thread::JoinedState;
return 0;
} else {
return -1;
}
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
destroyJavaVM(Thread* t, uintptr_t*)
{
// wait for other non-daemon threads to exit
{ ACQUIRE(t, t->m->stateLock);
while (t->m->liveCount - t->m->daemonCount > 1) {
t->m->stateLock->wait(t->systemThread, 0);
}
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
shutDown(t);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return 1;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jint JNICALL
DestroyJavaVM(Machine* m)
{
Thread* t; AttachCurrentThread(m, &t, 0);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
if (run(t, destroyJavaVM, 0)) {
t->exit();
return 0;
} else {
return -1;
}
}
jint JNICALL
GetEnv(Machine* m, Thread** t, jint version)
{
*t = static_cast<Thread*>(m->localThread->get());
if (*t) {
if (version <= JNI_VERSION_1_4) {
return JNI_OK;
} else {
return JNI_EVERSION;
}
} else {
return JNI_EDETACHED;
}
}
2010-04-15 17:11:10 +00:00
jint JNICALL
2009-06-22 22:25:13 +00:00
GetVersion(Thread* t)
{
ENTER(t, Thread::ActiveState);
return JNI_VERSION_1_6;
}
jsize JNICALL
GetStringLength(Thread* t, jstring s)
{
ENTER(t, Thread::ActiveState);
return stringLength(t, *s);
}
const jchar* JNICALL
GetStringChars(Thread* t, jstring s, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
jchar* chars = static_cast<jchar*>
2008-04-13 18:15:04 +00:00
(t->m->heap->allocate((stringLength(t, *s) + 1) * sizeof(jchar)));
2008-04-02 12:57:25 +00:00
stringChars(t, *s, chars);
if (isCopy) *isCopy = true;
return chars;
}
void JNICALL
ReleaseStringChars(Thread* t, jstring s, const jchar* chars)
{
ENTER(t, Thread::ActiveState);
2008-04-13 18:15:04 +00:00
t->m->heap->free(chars, (stringLength(t, *s) + 1) * sizeof(jchar));
}
void JNICALL
GetStringRegion(Thread* t, jstring s, jsize start, jsize length, jchar* dst)
{
ENTER(t, Thread::ActiveState);
stringChars(t, *s, start, length, dst);
}
const jchar* JNICALL
GetStringCritical(Thread* t, jstring s, jboolean* isCopy)
{
if ((t->criticalLevel ++) == 0) {
enter(t, Thread::ActiveState);
}
if (isCopy) {
*isCopy = true;
}
object data = stringData(t, *s);
if (objectClass(t, data) == type(t, Machine::ByteArrayType)) {
return GetStringChars(t, s, isCopy);
} else {
return &charArrayBody(t, data, stringOffset(t, *s));
}
}
void JNICALL
ReleaseStringCritical(Thread* t, jstring s, const jchar* chars)
{
if (objectClass(t, stringData(t, *s)) == type(t, Machine::ByteArrayType)) {
ReleaseStringChars(t, s, chars);
}
if ((-- t->criticalLevel) == 0) {
enter(t, Thread::IdleState);
}
}
jsize JNICALL
2007-07-06 23:18:40 +00:00
GetStringUTFLength(Thread* t, jstring s)
{
ENTER(t, Thread::ActiveState);
return stringUTFLength(t, *s);
}
const char* JNICALL
2007-07-06 23:18:40 +00:00
GetStringUTFChars(Thread* t, jstring s, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
int length = stringUTFLength(t, *s);
2007-07-06 23:18:40 +00:00
char* chars = static_cast<char*>
(t->m->heap->allocate(length + 1));
stringUTFChars(t, *s, chars, length);
if (isCopy) *isCopy = true;
return chars;
}
void JNICALL
ReleaseStringUTFChars(Thread* t, jstring s, const char* chars)
{
ENTER(t, Thread::ActiveState);
2008-04-13 18:15:04 +00:00
t->m->heap->free(chars, stringLength(t, *s) + 1);
}
void JNICALL
GetStringUTFRegion(Thread* t, jstring s, jsize start, jsize length, char* dst)
{
ENTER(t, Thread::ActiveState);
stringUTFChars
(t, *s, start, length, dst, stringUTFLength(t, *s, start, length));
}
jsize JNICALL
GetArrayLength(Thread* t, jarray array)
{
ENTER(t, Thread::ActiveState);
return cast<uintptr_t>(*array, BytesPerWord);
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
newString(Thread* t, uintptr_t* arguments)
2007-10-26 21:23:54 +00:00
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
const jchar* chars = reinterpret_cast<const jchar*>(arguments[0]);
jsize size = arguments[1];
2007-10-26 21:23:54 +00:00
object a = 0;
if (size) {
a = makeCharArray(t, size);
memcpy(&charArrayBody(t, a, 0), chars, size * sizeof(jchar));
2007-10-26 21:23:54 +00:00
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<uint64_t>
(makeLocalReference(t, t->m->classpath->makeString(t, a, 0, size)));
2007-10-26 21:23:54 +00:00
}
jstring JNICALL
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
NewString(Thread* t, const jchar* chars, jsize size)
2007-07-07 23:47:35 +00:00
{
if (chars == 0) return 0;
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars), size };
return reinterpret_cast<jstring>(run(t, newString, arguments));
}
uint64_t
newStringUTF(Thread* t, uintptr_t* arguments)
{
const char* chars = reinterpret_cast<const char*>(arguments[0]);
2007-07-07 23:47:35 +00:00
object array = parseUtf8(t, chars, strlen(chars));
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, t->m->classpath->makeString
(t, array, 0, cast<uintptr_t>(array, BytesPerWord) - 1)));
}
jstring JNICALL
NewStringUTF(Thread* t, const char* chars)
{
if (chars == 0) return 0;
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars) };
return reinterpret_cast<jstring>(run(t, newStringUTF, arguments));
2007-07-07 23:47:35 +00:00
}
void
replace(int a, int b, const char* in, int8_t* out)
{
while (*in) {
*out = (*in == a ? b : *in);
++ in;
++ out;
}
*out = 0;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
defineClass(Thread* t, uintptr_t* arguments)
{
jobject loader = reinterpret_cast<jobject>(arguments[0]);
const uint8_t* buffer = reinterpret_cast<const uint8_t*>(arguments[1]);
jsize length = arguments[2];
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, getJClass
(t, defineClass
(t, loader ? *loader : root(t, Machine::BootLoader), buffer, length))));
}
jclass JNICALL
DefineClass(Thread* t, const char*, jobject loader, const jbyte* buffer,
jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(loader),
reinterpret_cast<uintptr_t>(buffer),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jclass>(run(t, defineClass, arguments));
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
findClass(Thread* t, uintptr_t* arguments)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
const char* name = reinterpret_cast<const char*>(arguments[0]);
object n = makeByteArray(t, strlen(name) + 1);
replace('.', '/', name, &byteArrayBody(t, n, 0));
object caller = getCaller(t, 0);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, getJClass
(t, resolveClass
(t, caller ? classLoader(t, methodClass(t, caller))
: root(t, Machine::AppLoader), n))));
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jclass JNICALL
FindClass(Thread* t, const char* name)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(name) };
return reinterpret_cast<jclass>(run(t, findClass, arguments));
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
throwNew(Thread* t, uintptr_t* arguments)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jclass c = reinterpret_cast<jclass>(arguments[0]);
const char* message = reinterpret_cast<const char*>(arguments[1]);
object m = 0;
PROTECT(t, m);
if (message) {
m = makeString(t, "%s", message);
}
object trace = makeTrace(t);
PROTECT(t, trace);
t->exception = make(t, jclassVmClass(t, *c));
set(t, t->exception, ThrowableMessage, m);
set(t, t->exception, ThrowableTrace, trace);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return 1;
}
jint JNICALL
ThrowNew(Thread* t, jclass c, const char* message)
{
if (t->exception) {
return -1;
}
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(message) };
return run(t, throwNew, arguments) ? 0 : -1;
}
jint JNICALL
Throw(Thread* t, jthrowable throwable)
{
if (t->exception) {
return -1;
}
ENTER(t, Thread::ActiveState);
t->exception = *throwable;
return 0;
}
void JNICALL
DeleteLocalRef(Thread* t, jobject r)
2007-08-14 13:27:10 +00:00
{
2007-11-29 15:04:07 +00:00
ENTER(t, Thread::ActiveState);
disposeLocalReference(t, r);
2007-08-14 13:27:10 +00:00
}
jboolean JNICALL
ExceptionCheck(Thread* t)
{
return t->exception != 0;
}
jobject JNICALL
NewDirectByteBuffer(Thread*, void*, jlong)
{
return 0;
}
void* JNICALL
GetDirectBufferAddress(Thread*, jobject)
{
return 0;
}
jlong JNICALL
GetDirectBufferCapacity(Thread*, jobject)
{
return -1;
}
jclass JNICALL
GetObjectClass(Thread* t, jobject o)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
return makeLocalReference(t, getJClass(t, objectClass(t, *o)));
}
jboolean JNICALL
IsInstanceOf(Thread* t, jobject o, jclass c)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
return instanceOf(t, jclassVmClass(t, *c), *o);
}
jboolean JNICALL
IsAssignableFrom(Thread* t, jclass b, jclass a)
{
ENTER(t, Thread::ActiveState);
return isAssignableFrom(t, jclassVmClass(t, *a), jclassVmClass(t, *b));
}
object
findMethod(Thread* t, jclass c, const char* name, const char* spec)
{
object n = makeByteArray(t, "%s", name);
PROTECT(t, n);
object s = makeByteArray(t, "%s", spec);
return vm::findMethod(t, jclassVmClass(t, *c), n, s);
}
jint
methodID(Thread* t, object method)
{
if (methodNativeID(t, method) == 0) {
PROTECT(t, method);
ACQUIRE(t, t->m->referenceLock);
if (methodNativeID(t, method) == 0) {
setRoot(t, Machine::JNIMethodTable, vectorAppend
(t, root(t, Machine::JNIMethodTable), method));
methodNativeID(t, method) = vectorSize
(t, root(t, Machine::JNIMethodTable));
}
}
return methodNativeID(t, method);
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
getMethodID(Thread* t, uintptr_t* arguments)
2007-09-07 23:20:21 +00:00
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jclass c = reinterpret_cast<jclass>(arguments[0]);
const char* name = reinterpret_cast<const char*>(arguments[1]);
const char* spec = reinterpret_cast<const char*>(arguments[2]);
2007-09-07 23:20:21 +00:00
object method = findMethod(t, c, name, spec);
assert(t, (methodFlags(t, method) & ACC_STATIC) == 0);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return methodID(t, method);
2007-09-07 23:20:21 +00:00
}
2007-09-07 23:20:21 +00:00
jmethodID JNICALL
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
GetMethodID(Thread* t, jclass c, const char* name, const char* spec)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(name),
reinterpret_cast<uintptr_t>(spec) };
return run(t, getMethodID, arguments);
}
uint64_t
getStaticMethodID(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jclass>(arguments[0]);
const char* name = reinterpret_cast<const char*>(arguments[1]);
const char* spec = reinterpret_cast<const char*>(arguments[2]);
object method = findMethod(t, c, name, spec);
2007-09-07 23:20:21 +00:00
assert(t, methodFlags(t, method) & ACC_STATIC);
return methodID(t, method);
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jmethodID JNICALL
GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(name),
reinterpret_cast<uintptr_t>(spec) };
return run(t, getStaticMethodID, arguments);
}
2007-09-07 23:20:21 +00:00
inline object
getMethod(Thread* t, jmethodID m)
{
object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1);
2008-04-01 17:37:59 +00:00
assert(t, (methodFlags(t, method) & ACC_STATIC) == 0);
2008-04-01 17:37:59 +00:00
return method;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
newObjectV(Thread* t, uintptr_t* arguments)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jclass c = reinterpret_cast<jclass>(arguments[0]);
jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
object o = make(t, jclassVmClass(t, *c));
PROTECT(t, o);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
t->m->processor->invokeList(t, getMethod(t, m), o, true, *a);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<uint64_t>(makeLocalReference(t, o));
}
jobject JNICALL
NewObjectV(Thread* t, jclass c, jmethodID m, va_list a)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
m,
reinterpret_cast<uintptr_t>(a) };
return reinterpret_cast<jobject>(run(t, newObjectV, arguments));
}
jobject JNICALL
NewObject(Thread* t, jclass c, jmethodID m, ...)
{
va_list a;
va_start(a, m);
2007-11-29 15:04:07 +00:00
jobject r = NewObjectV(t, c, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callObjectMethodV(Thread* t, uintptr_t* arguments)
{
jobject o = reinterpret_cast<jclass>(arguments[0]);
jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
object method = getMethod(t, m);
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, t->m->processor->invokeList(t, method, *o, true, *a)));
}
2007-09-07 23:20:21 +00:00
jobject JNICALL
CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jobject>(run(t, callObjectMethodV, arguments));
}
jobject JNICALL
2007-09-07 23:20:21 +00:00
CallObjectMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jobject r = CallObjectMethodV(t, o, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callIntMethodV(Thread* t, uintptr_t* arguments)
{
jobject o = reinterpret_cast<jclass>(arguments[0]);
jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
object method = getMethod(t, m);
return intValue(t, t->m->processor->invokeList(t, method, *o, true, *a));
}
jboolean JNICALL
2007-09-07 23:20:21 +00:00
CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callIntMethodV, arguments) != 0;
2007-09-07 23:20:21 +00:00
}
jboolean JNICALL
CallBooleanMethod(Thread* t, jobject o, jmethodID m, ...)
{
va_list a;
va_start(a, m);
jboolean r = CallBooleanMethodV(t, o, m, a);
va_end(a);
return r;
}
jbyte JNICALL
2007-09-07 23:20:21 +00:00
CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callIntMethodV, arguments);
2007-09-07 23:20:21 +00:00
}
jbyte JNICALL
CallByteMethod(Thread* t, jobject o, jmethodID m, ...)
{
va_list a;
va_start(a, m);
jbyte r = CallByteMethodV(t, o, m, a);
va_end(a);
return r;
}
jchar JNICALL
2007-09-07 23:20:21 +00:00
CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callIntMethodV, arguments);
2007-09-07 23:20:21 +00:00
}
jchar JNICALL
CallCharMethod(Thread* t, jobject o, jmethodID m, ...)
{
va_list a;
va_start(a, m);
jchar r = CallCharMethodV(t, o, m, a);
va_end(a);
return r;
}
jshort JNICALL
2007-09-07 23:20:21 +00:00
CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jshort JNICALL
CallShortMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jshort r = CallShortMethodV(t, o, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jint JNICALL
CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jint JNICALL
CallIntMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jint r = CallIntMethodV(t, o, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callLongMethodV(Thread* t, uintptr_t* arguments)
{
jobject o = reinterpret_cast<jclass>(arguments[0]);
jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
object method = getMethod(t, m);
return longValue(t, t->m->processor->invokeList(t, method, *o, true, *a));
}
2007-09-07 23:20:21 +00:00
jlong JNICALL
CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callLongMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jlong JNICALL
CallLongMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jlong r = CallLongMethodV(t, o, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jfloat JNICALL
CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return bitsToFloat(run(t, callIntMethodV, arguments));
}
2007-09-07 23:20:21 +00:00
jfloat JNICALL
CallFloatMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jfloat r = CallFloatMethodV(t, o, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jdouble JNICALL
CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return bitsToDouble(run(t, callLongMethodV, arguments));
}
2007-09-07 23:20:21 +00:00
jdouble JNICALL
CallDoubleMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jdouble r = CallDoubleMethodV(t, o, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callVoidMethodV(Thread* t, uintptr_t* arguments)
{
jobject o = reinterpret_cast<jclass>(arguments[0]);
jmethodID m = arguments[1];
va_list* a = reinterpret_cast<va_list*>(arguments[2]);
object method = getMethod(t, m);
t->m->processor->invokeList(t, method, *o, true, *a);
return 0;
}
void JNICALL
2007-09-07 23:20:21 +00:00
CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
m,
reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
run(t, callVoidMethodV, arguments);
}
void JNICALL
2007-09-07 23:20:21 +00:00
CallVoidMethod(Thread* t, jobject o, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
CallVoidMethodV(t, o, m, a);
va_end(a);
}
2007-09-07 23:20:21 +00:00
inline object
getStaticMethod(Thread* t, jmethodID m)
{
object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1);
2008-04-01 17:37:59 +00:00
assert(t, methodFlags(t, method) & ACC_STATIC);
2008-04-01 17:37:59 +00:00
return method;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callStaticObjectMethodV(Thread* t, uintptr_t* arguments)
{
jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a)));
}
2007-09-07 23:20:21 +00:00
jobject JNICALL
CallStaticObjectMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jobject>(run(t, callStaticObjectMethodV, arguments));
}
jobject JNICALL
2007-09-07 23:20:21 +00:00
CallStaticObjectMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jobject r = CallStaticObjectMethodV(t, c, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callStaticIntMethodV(Thread* t, uintptr_t* arguments)
{
jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
return intValue
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a));
}
jboolean JNICALL
CallStaticBooleanMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticIntMethodV, arguments) != 0;
}
2007-09-07 23:20:21 +00:00
jboolean JNICALL
CallStaticBooleanMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jboolean r = CallStaticBooleanMethodV(t, c, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jbyte JNICALL
CallStaticByteMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jbyte JNICALL
CallStaticByteMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jbyte r = CallStaticByteMethodV(t, c, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jchar JNICALL
CallStaticCharMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jchar JNICALL
CallStaticCharMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jchar r = CallStaticCharMethodV(t, c, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jshort JNICALL
CallStaticShortMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jshort JNICALL
CallStaticShortMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jshort r = CallStaticShortMethodV(t, c, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jint JNICALL
CallStaticIntMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticIntMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jint JNICALL
CallStaticIntMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jint r = CallStaticIntMethodV(t, c, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callStaticLongMethodV(Thread* t, uintptr_t* arguments)
{
jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
return longValue
(t, t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a));
}
2007-09-07 23:20:21 +00:00
jlong JNICALL
CallStaticLongMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, callStaticLongMethodV, arguments);
}
2007-09-07 23:20:21 +00:00
jlong JNICALL
CallStaticLongMethod(Thread* t, jclass c, jmethodID m, ...)
{
2007-09-07 23:20:21 +00:00
va_list a;
va_start(a, m);
jlong r = CallStaticLongMethodV(t, c, m, a);
va_end(a);
return r;
}
2007-09-07 23:20:21 +00:00
jfloat JNICALL
CallStaticFloatMethodV(Thread* t, jclass, jmethodID m, va_list a)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return bitsToFloat(run(t, callStaticIntMethodV, arguments));
}
2007-09-07 23:20:21 +00:00
jfloat JNICALL
CallStaticFloatMethod(Thread* t, jclass c, jmethodID m, ...)
{
va_list a;
va_start(a, m);
jfloat r = CallStaticFloatMethodV(t, c, m, a);
va_end(a);
return r;
}
jdouble JNICALL
CallStaticDoubleMethodV(Thread* t, jclass, jmethodID m, va_list a)
2007-09-07 23:20:21 +00:00
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return bitsToDouble(run(t, callStaticLongMethodV, arguments));
2007-09-07 23:20:21 +00:00
}
jdouble JNICALL
CallStaticDoubleMethod(Thread* t, jclass c, jmethodID m, ...)
{
va_list a;
va_start(a, m);
jdouble r = CallStaticDoubleMethodV(t, c, m, a);
va_end(a);
return r;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
callStaticVoidMethodV(Thread* t, uintptr_t* arguments)
{
jmethodID m = arguments[0];
va_list* a = reinterpret_cast<va_list*>(arguments[1]);
t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, *a);
return 0;
}
2007-09-07 23:20:21 +00:00
void JNICALL
CallStaticVoidMethodV(Thread* t, jclass, jmethodID m, va_list a)
2007-09-07 23:20:21 +00:00
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { m, reinterpret_cast<uintptr_t>(a) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
run(t, callStaticVoidMethodV, arguments);
2007-09-07 23:20:21 +00:00
}
void JNICALL
CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...)
{
va_list a;
va_start(a, m);
CallStaticVoidMethodV(t, c, m, a);
va_end(a);
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
getFieldID(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jclass>(arguments[0]);
const char* name = reinterpret_cast<const char*>(arguments[1]);
const char* spec = reinterpret_cast<const char*>(arguments[2]);
return fieldOffset(t, resolveField(t, jclassVmClass(t, *c), name, spec));
}
2007-09-07 23:20:21 +00:00
jfieldID JNICALL
GetFieldID(Thread* t, jclass c, const char* name, const char* spec)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(name),
reinterpret_cast<uintptr_t>(spec) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, getFieldID, arguments);
2007-09-07 23:20:21 +00:00
}
jfieldID JNICALL
GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(name),
reinterpret_cast<uintptr_t>(spec) };
2007-09-07 23:20:21 +00:00
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, getFieldID, arguments);
2007-09-07 23:20:21 +00:00
}
jobject JNICALL
GetObjectField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return makeLocalReference(t, cast<object>(*o, field));
2007-09-07 23:20:21 +00:00
}
jboolean JNICALL
GetBooleanField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jboolean>(*o, field);
}
jbyte JNICALL
GetByteField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jbyte>(*o, field);
}
jchar JNICALL
GetCharField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jchar>(*o, field);
}
jshort JNICALL
GetShortField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jshort>(*o, field);
}
jint JNICALL
GetIntField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jint>(*o, field);
}
jlong JNICALL
GetLongField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jlong>(*o, field);
}
jfloat JNICALL
GetFloatField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jfloat>(*o, field);
}
jdouble JNICALL
GetDoubleField(Thread* t, jobject o, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<jdouble>(*o, field);
}
void JNICALL
SetObjectField(Thread* t, jobject o, jfieldID field, jobject v)
{
ENTER(t, Thread::ActiveState);
set(t, *o, field, (v ? *v : 0));
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetBooleanField(Thread* t, jobject o, jfieldID field, jboolean v)
{
ENTER(t, Thread::ActiveState);
cast<jboolean>(*o, field) = v;
}
void JNICALL
SetByteField(Thread* t, jobject o, jfieldID field, jbyte v)
{
ENTER(t, Thread::ActiveState);
cast<jbyte>(*o, field) = v;
}
void JNICALL
SetCharField(Thread* t, jobject o, jfieldID field, jchar v)
{
ENTER(t, Thread::ActiveState);
cast<jchar>(*o, field) = v;
}
void JNICALL
SetShortField(Thread* t, jobject o, jfieldID field, jshort v)
{
ENTER(t, Thread::ActiveState);
cast<jshort>(*o, field) = v;
}
void JNICALL
SetIntField(Thread* t, jobject o, jfieldID field, jint v)
{
ENTER(t, Thread::ActiveState);
cast<jint>(*o, field) = v;
}
void JNICALL
SetLongField(Thread* t, jobject o, jfieldID field, jlong v)
{
ENTER(t, Thread::ActiveState);
cast<jlong>(*o, field) = v;
}
void JNICALL
SetFloatField(Thread* t, jobject o, jfieldID field, jfloat v)
{
ENTER(t, Thread::ActiveState);
cast<jfloat>(*o, field) = v;
}
void JNICALL
SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v)
{
ENTER(t, Thread::ActiveState);
cast<jdouble>(*o, field) = v;
}
jobject JNICALL
GetStaticObjectField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return makeLocalReference
(t, cast<object>(classStaticTable(t, jclassVmClass(t, *c)), field));
2007-09-07 23:20:21 +00:00
}
jboolean JNICALL
GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jbyte JNICALL
GetStaticByteField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jchar JNICALL
GetStaticCharField(Thread* t, jclass c, jfieldID field)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
return cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jshort JNICALL
GetStaticShortField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jint JNICALL
GetStaticIntField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jlong JNICALL
GetStaticLongField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jfloat JNICALL
GetStaticFloatField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
jdouble JNICALL
GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
{
ENTER(t, Thread::ActiveState);
return cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field);
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v)
{
ENTER(t, Thread::ActiveState);
set(t, classStaticTable(t, jclassVmClass(t, *c)), field, (v ? *v : 0));
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v)
{
ENTER(t, Thread::ActiveState);
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
{
ENTER(t, Thread::ActiveState);
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
{
ENTER(t, Thread::ActiveState);
cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
{
ENTER(t, Thread::ActiveState);
cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
2007-09-07 23:20:21 +00:00
}
void JNICALL
SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
{
ENTER(t, Thread::ActiveState);
cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
}
void JNICALL
SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
}
void JNICALL
SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
}
void JNICALL
SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v)
{
2007-09-07 23:20:21 +00:00
ENTER(t, Thread::ActiveState);
cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
}
2007-09-07 23:20:21 +00:00
jobject JNICALL
NewGlobalRef(Thread* t, jobject o)
{
ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->m->referenceLock);
2007-09-07 23:20:21 +00:00
if (o) {
for (Reference* r = t->m->jniReferences; r; r = r->next) {
if (r->target == *o) {
acquire(t, r);
return &(r->target);
}
}
2008-04-13 18:15:04 +00:00
Reference* r = new (t->m->heap->allocate(sizeof(Reference)))
Reference(*o, &(t->m->jniReferences));
2007-09-07 23:20:21 +00:00
acquire(t, r);
return &(r->target);
} else {
return 0;
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
DeleteGlobalRef(Thread* t, jobject r)
2007-09-07 23:20:21 +00:00
{
ENTER(t, Thread::ActiveState);
ACQUIRE(t, t->m->referenceLock);
2007-09-07 23:20:21 +00:00
if (r) {
release(t, reinterpret_cast<Reference*>(r));
2007-09-07 23:20:21 +00:00
}
}
jint JNICALL
EnsureLocalCapacity(Thread*, jint)
{
return 0;
}
2007-09-07 23:20:21 +00:00
jthrowable JNICALL
ExceptionOccurred(Thread* t)
{
ENTER(t, Thread::ActiveState);
return makeLocalReference(t, t->exception);
2007-09-07 23:20:21 +00:00
}
void JNICALL
ExceptionDescribe(Thread* t)
{
ENTER(t, Thread::ActiveState);
return printTrace(t, t->exception);
}
void JNICALL
ExceptionClear(Thread* t)
{
ENTER(t, Thread::ActiveState);
t->exception = 0;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
newObjectArray(Thread* t, uintptr_t* arguments)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jsize length = arguments[0];
jclass class_ = reinterpret_cast<jclass>(arguments[1]);
jobject init = reinterpret_cast<jobject>(arguments[2]);
object a = makeObjectArray(t, jclassVmClass(t, *class_), length);
object value = (init ? *init : 0);
for (jsize i = 0; i < length; ++i) {
set(t, a, ArrayBody + (i * BytesPerWord), value);
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<uint64_t>(makeLocalReference(t, a));
}
jobjectArray JNICALL
NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
{
uintptr_t arguments[] = { length,
reinterpret_cast<uintptr_t>(class_),
reinterpret_cast<uintptr_t>(init) };
return reinterpret_cast<jobjectArray>(run(t, newObjectArray, arguments));
}
jobject JNICALL
GetObjectArrayElement(Thread* t, jobjectArray array, jsize index)
{
ENTER(t, Thread::ActiveState);
return makeLocalReference(t, objectArrayBody(t, *array, index));
}
void JNICALL
SetObjectArrayElement(Thread* t, jobjectArray array, jsize index,
jobject value)
{
ENTER(t, Thread::ActiveState);
set(t, *array, ArrayBody + (index * BytesPerWord), (value ? *value : 0));
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
newArray(Thread* t, uintptr_t* arguments)
{
object (*constructor)(Thread*, unsigned)
= reinterpret_cast<object (*)(Thread*, unsigned)>(arguments[0]);
jsize length = arguments[1];
return reinterpret_cast<uint64_t>
(makeLocalReference(t, constructor(t, length)));
}
jbooleanArray JNICALL
NewBooleanArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeBooleanArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jbooleanArray>(run(t, newArray, arguments));
}
object
makeByteArray0(Thread* t, unsigned length)
{
return makeByteArray(t, length);
}
jbyteArray JNICALL
NewByteArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeByteArray0)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jbyteArray>(run(t, newArray, arguments));
}
jcharArray JNICALL
NewCharArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeCharArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jcharArray>(run(t, newArray, arguments));
}
jshortArray JNICALL
NewShortArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeShortArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jshortArray>(run(t, newArray, arguments));
}
jintArray JNICALL
NewIntArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeIntArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jintArray>(run(t, newArray, arguments));
}
jlongArray JNICALL
NewLongArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeLongArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jlongArray>(run(t, newArray, arguments));
}
jfloatArray JNICALL
NewFloatArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeFloatArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jfloatArray>(run(t, newArray, arguments));
}
jdoubleArray JNICALL
NewDoubleArray(Thread* t, jsize length)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeDoubleArray)),
length };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return reinterpret_cast<jdoubleArray>(run(t, newArray, arguments));
}
2007-09-07 23:20:21 +00:00
jboolean* JNICALL
GetBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
2008-04-13 18:15:04 +00:00
jboolean* p = static_cast<jboolean*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &booleanArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jbyte* JNICALL
GetByteArrayElements(Thread* t, jbyteArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
2008-04-13 18:15:04 +00:00
jbyte* p = static_cast<jbyte*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &byteArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jchar* JNICALL
GetCharArrayElements(Thread* t, jcharArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
2008-04-13 18:15:04 +00:00
jchar* p = static_cast<jchar*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &charArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jshort* JNICALL
GetShortArrayElements(Thread* t, jshortArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
2008-04-13 18:15:04 +00:00
jshort* p = static_cast<jshort*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &shortArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jint* JNICALL
GetIntArrayElements(Thread* t, jintArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = intArrayLength(t, *array) * sizeof(jint);
2008-04-13 18:15:04 +00:00
jint* p = static_cast<jint*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &intArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jlong* JNICALL
GetLongArrayElements(Thread* t, jlongArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
2008-04-13 18:15:04 +00:00
jlong* p = static_cast<jlong*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &longArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jfloat* JNICALL
GetFloatArrayElements(Thread* t, jfloatArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
2008-04-13 18:15:04 +00:00
jfloat* p = static_cast<jfloat*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &floatArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
jdouble* JNICALL
GetDoubleArrayElements(Thread* t, jdoubleArray array, jboolean* isCopy)
{
ENTER(t, Thread::ActiveState);
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
2008-04-13 18:15:04 +00:00
jdouble* p = static_cast<jdouble*>(t->m->heap->allocate(size));
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(p, &doubleArrayBody(t, *array, 0), size);
}
if (isCopy) {
*isCopy = true;
}
return p;
}
void JNICALL
ReleaseBooleanArrayElements(Thread* t, jbooleanArray array, jboolean* p,
jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = booleanArrayLength(t, *array) * sizeof(jboolean);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&booleanArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseByteArrayElements(Thread* t, jbyteArray array, jbyte* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = byteArrayLength(t, *array) * sizeof(jbyte);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&byteArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseCharArrayElements(Thread* t, jcharArray array, jchar* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = charArrayLength(t, *array) * sizeof(jchar);
if (mode == 0 or mode == JNI_COMMIT) {
2007-09-07 23:20:21 +00:00
if (size) {
memcpy(&charArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseShortArrayElements(Thread* t, jshortArray array, jshort* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = shortArrayLength(t, *array) * sizeof(jshort);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&shortArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseIntArrayElements(Thread* t, jintArray array, jint* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = intArrayLength(t, *array) * sizeof(jint);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&intArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseLongArrayElements(Thread* t, jlongArray array, jlong* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = longArrayLength(t, *array) * sizeof(jlong);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&longArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseFloatArrayElements(Thread* t, jfloatArray array, jfloat* p, jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = floatArrayLength(t, *array) * sizeof(jfloat);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&floatArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
ReleaseDoubleArrayElements(Thread* t, jdoubleArray array, jdouble* p,
jint mode)
{
ENTER(t, Thread::ActiveState);
unsigned size = doubleArrayLength(t, *array) * sizeof(jdouble);
2007-09-07 23:20:21 +00:00
if (mode == 0 or mode == JNI_COMMIT) {
if (size) {
memcpy(&doubleArrayBody(t, *array, 0), p, size);
}
}
if (mode == 0 or mode == JNI_ABORT) {
2008-04-13 18:15:04 +00:00
t->m->heap->free(p, size);
2007-09-07 23:20:21 +00:00
}
}
void JNICALL
GetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
jboolean* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &booleanArrayBody(t, *array, offset),
length * sizeof(jboolean));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length,
jbyte* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &byteArrayBody(t, *array, offset), length * sizeof(jbyte));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length,
jchar* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &charArrayBody(t, *array, offset), length * sizeof(jchar));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length,
jshort* dst)
2007-09-07 23:20:21 +00:00
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &shortArrayBody(t, *array, offset), length * sizeof(jshort));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length,
jint* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &intArrayBody(t, *array, offset), length * sizeof(jint));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length,
jlong* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &longArrayBody(t, *array, offset), length * sizeof(jlong));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length,
jfloat* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &floatArrayBody(t, *array, offset), length * sizeof(jfloat));
}
2007-09-07 23:20:21 +00:00
}
void JNICALL
GetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length,
jdouble* dst)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(dst, &doubleArrayBody(t, *array, offset), length * sizeof(jdouble));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetBooleanArrayRegion(Thread* t, jbooleanArray array, jint offset, jint length,
const jboolean* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&booleanArrayBody(t, *array, offset), src,
length * sizeof(jboolean));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length,
const jbyte* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&byteArrayBody(t, *array, offset), src, length * sizeof(jbyte));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetCharArrayRegion(Thread* t, jcharArray array, jint offset, jint length,
const jchar* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&charArrayBody(t, *array, offset), src, length * sizeof(jchar));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetShortArrayRegion(Thread* t, jshortArray array, jint offset, jint length,
const jshort* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&shortArrayBody(t, *array, offset), src, length * sizeof(jshort));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetIntArrayRegion(Thread* t, jintArray array, jint offset, jint length,
const jint* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&intArrayBody(t, *array, offset), src, length * sizeof(jint));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetLongArrayRegion(Thread* t, jlongArray array, jint offset, jint length,
const jlong* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&longArrayBody(t, *array, offset), src, length * sizeof(jlong));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetFloatArrayRegion(Thread* t, jfloatArray array, jint offset, jint length,
const jfloat* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&floatArrayBody(t, *array, offset), src, length * sizeof(jfloat));
}
2007-09-17 22:15:42 +00:00
}
void JNICALL
SetDoubleArrayRegion(Thread* t, jdoubleArray array, jint offset, jint length,
const jdouble* src)
{
ENTER(t, Thread::ActiveState);
if (length) {
memcpy(&doubleArrayBody(t, *array, offset), src, length * sizeof(jdouble));
}
2007-09-07 23:20:21 +00:00
}
void* JNICALL
GetPrimitiveArrayCritical(Thread* t, jarray array, jboolean* isCopy)
{
if ((t->criticalLevel ++) == 0) {
enter(t, Thread::ActiveState);
}
if (isCopy) {
*isCopy = true;
}
return reinterpret_cast<uintptr_t*>(*array) + 2;
}
void JNICALL
ReleasePrimitiveArrayCritical(Thread* t, jarray, void*, jint)
{
if ((-- t->criticalLevel) == 0) {
enter(t, Thread::IdleState);
}
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
registerNatives(Thread* t, uintptr_t* arguments)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
jclass c = reinterpret_cast<jclass>(arguments[0]);
const JNINativeMethod* methods
= reinterpret_cast<const JNINativeMethod*>(arguments[1]);
jint methodCount = arguments[2];
for (int i = 0; i < methodCount; ++i) {
if (methods[i].function) {
object method = findMethodOrNull
(t, jclassVmClass(t, *c), methods[i].name, methods[i].signature);
if (method == 0 or (methodFlags(t, method) & ACC_NATIVE) == 0) {
// The JNI spec says we must throw a NoSuchMethodError in this
// case, but that would prevent using a code shrinker like
// ProGuard effectively. Instead, we just ignore it.
} else {
registerNative(t, method, methods[i].function);
}
}
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return 1;
}
jint JNICALL
RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
jint methodCount)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(methods),
methodCount };
return run(t, registerNatives, arguments) ? 0 : -1;
}
jint JNICALL
UnregisterNatives(Thread* t, jclass c)
{
ENTER(t, Thread::ActiveState);
unregisterNatives(t, *c);
return 0;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uint64_t
monitorOp(Thread* t, uintptr_t* arguments)
{
void (*op)(Thread*, object)
= reinterpret_cast<void (*)(Thread*, object)>(arguments[0]);
jobject o = reinterpret_cast<jobject>(arguments[1]);
op(t, *o);
return 1;
}
void
acquire0(Thread* t, object o)
{
return acquire(t, o);
}
jint JNICALL
MonitorEnter(Thread* t, jobject o)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(acquire0)),
reinterpret_cast<uintptr_t>(o) };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, monitorOp, arguments) ? 0 : -1;
}
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
void
release0(Thread* t, object o)
{
return acquire(t, o);
}
jint JNICALL
MonitorExit(Thread* t, jobject o)
{
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(release0)),
reinterpret_cast<uintptr_t>(o) };
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
return run(t, monitorOp, arguments) ? 0 : -1;
}
2007-09-07 23:20:21 +00:00
jint JNICALL
GetJavaVM(Thread* t, Machine** m)
2007-09-07 23:20:21 +00:00
{
*m = t->m;
return 0;
2007-09-07 23:20:21 +00:00
}
jboolean JNICALL
IsSameObject(Thread* t, jobject a, jobject b)
{
2008-04-01 22:40:53 +00:00
if (a and b) {
ENTER(t, Thread::ActiveState);
2007-09-07 23:20:21 +00:00
2008-04-01 22:40:53 +00:00
return *a == *b;
} else {
return a == b;
}
2007-09-07 23:20:21 +00:00
}
struct JavaVMOption {
char* optionString;
void* extraInfo;
};
struct JavaVMInitArgs {
jint version;
jint nOptions;
JavaVMOption* options;
jboolean ignoreUnrecognized;
};
int
parseSize(const char* s)
{
unsigned length = strlen(s);
RUNTIME_ARRAY(char, buffer, length + 1);
if (length == 0) {
return 0;
} else if (s[length - 1] == 'k') {
memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
RUNTIME_ARRAY_BODY(buffer)[length - 1] = 0;
return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024;
} else if (s[length - 1] == 'm') {
memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
RUNTIME_ARRAY_BODY(buffer)[length - 1] = 0;
return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024 * 1024;
} else {
return atoi(s);
}
}
void
append(char** p, const char* value, unsigned length, char tail)
{
if (length) {
memcpy(*p, value, length);
*p += length;
*((*p)++) = tail;
}
}
void
boot(Thread* t)
{
enter(t, Thread::ActiveState);
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
t->javaThread = t->m->classpath->makeThread(t, 0);
setRoot(t, Machine::NullPointerException, makeThrowable
(t, Machine::NullPointerExceptionType));
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
setRoot(t, Machine::ArithmeticException,
makeThrowable(t, Machine::ArithmeticExceptionType));
rework VM exception handling; throw OOMEs when appropriate This rather large commit modifies the VM to use non-local returns to throw exceptions instead of simply setting Thread::exception and returning frame-by-frame as it used to. This has several benefits: * Functions no longer need to check Thread::exception after each call which might throw an exception (which would be especially tedious and error-prone now that any function which allocates objects directly or indirectly might throw an OutOfMemoryError) * There's no need to audit the code for calls to functions which previously did not throw exceptions but later do * Performance should be improved slightly due to both the reduced need for conditionals and because undwinding now occurs in a single jump instead of a series of returns The main disadvantages are: * Slightly higher overhead for entering and leaving the VM via the JNI and JDK methods * Non-local returns can make the code harder to read * We must be careful to register destructors for stack-allocated resources with the Thread so they can be called prior to a non-local return The non-local return implementation is similar to setjmp/longjmp, except it uses continuation-passing style to avoid the need for cooperation from the C/C++ compiler. Native C++ exceptions would have also been an option, but that would introduce a dependence on libstdc++, which we're trying to avoid for portability reasons. Finally, this commit ensures that the VM throws an OutOfMemoryError instead of aborting when it reaches its memory ceiling. Currently, we treat the ceiling as a soft limit and temporarily exceed it as necessary to allow garbage collection and certain internal allocations to succeed, but refuse to allocate any Java objects until the heap size drops back below the ceiling.
2010-12-27 22:55:23 +00:00
setRoot(t, Machine::ArrayIndexOutOfBoundsException,
makeThrowable(t, Machine::ArrayIndexOutOfBoundsExceptionType));
setRoot(t, Machine::OutOfMemoryError,
makeThrowable(t, Machine::OutOfMemoryErrorType));
setRoot(t, Machine::FinalizerThread, t->m->classpath->makeThread(t, t));
threadDaemon(t, root(t, Machine::FinalizerThread)) = true;
t->m->classpath->boot(t);
enter(t, Thread::IdleState);
}
2010-04-15 17:11:10 +00:00
} // namespace local
} // namespace
namespace vm {
void
populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
{
memset(vmTable, 0, sizeof(JavaVMVTable));
2010-04-15 17:11:10 +00:00
vmTable->DestroyJavaVM = local::DestroyJavaVM;
vmTable->AttachCurrentThread = local::AttachCurrentThread;
vmTable->AttachCurrentThreadAsDaemon = local::AttachCurrentThreadAsDaemon;
vmTable->DetachCurrentThread = local::DetachCurrentThread;
vmTable->GetEnv = local::GetEnv;
memset(envTable, 0, sizeof(JNIEnvVTable));
2010-04-15 17:11:10 +00:00
envTable->GetVersion = local::GetVersion;
envTable->GetStringLength = local::GetStringLength;
envTable->GetStringChars = local::GetStringChars;
envTable->ReleaseStringChars = local::ReleaseStringChars;
envTable->GetStringRegion = local::GetStringRegion;
envTable->GetStringCritical = local::GetStringCritical;
envTable->ReleaseStringCritical = local::ReleaseStringCritical;
2010-04-15 17:11:10 +00:00
envTable->GetStringUTFLength = local::GetStringUTFLength;
envTable->GetStringUTFChars = local::GetStringUTFChars;
envTable->ReleaseStringUTFChars = local::ReleaseStringUTFChars;
envTable->GetStringUTFRegion = local::GetStringUTFRegion;
2010-04-15 17:11:10 +00:00
envTable->GetArrayLength = local::GetArrayLength;
envTable->NewString = local::NewString;
envTable->NewStringUTF = local::NewStringUTF;
envTable->DefineClass = local::DefineClass;
2010-04-15 17:11:10 +00:00
envTable->FindClass = local::FindClass;
envTable->ThrowNew = local::ThrowNew;
envTable->Throw = local::Throw;
2010-04-15 17:11:10 +00:00
envTable->ExceptionCheck = local::ExceptionCheck;
envTable->NewDirectByteBuffer = local::NewDirectByteBuffer;
envTable->GetDirectBufferAddress = local::GetDirectBufferAddress;
envTable->GetDirectBufferCapacity = local::GetDirectBufferCapacity;
envTable->DeleteLocalRef = local::DeleteLocalRef;
envTable->GetObjectClass = local::GetObjectClass;
envTable->IsInstanceOf = local::IsInstanceOf;
envTable->IsAssignableFrom = local::IsAssignableFrom;
2010-04-15 17:11:10 +00:00
envTable->GetFieldID = local::GetFieldID;
envTable->GetMethodID = local::GetMethodID;
envTable->GetStaticMethodID = local::GetStaticMethodID;
envTable->NewObject = local::NewObject;
envTable->NewObjectV = local::NewObjectV;
envTable->CallObjectMethodV = local::CallObjectMethodV;
envTable->CallObjectMethod = local::CallObjectMethod;
envTable->CallBooleanMethodV = local::CallBooleanMethodV;
envTable->CallBooleanMethod = local::CallBooleanMethod;
envTable->CallByteMethodV = local::CallByteMethodV;
envTable->CallByteMethod = local::CallByteMethod;
envTable->CallCharMethodV = local::CallCharMethodV;
envTable->CallCharMethod = local::CallCharMethod;
envTable->CallShortMethodV = local::CallShortMethodV;
envTable->CallShortMethod = local::CallShortMethod;
envTable->CallIntMethodV = local::CallIntMethodV;
envTable->CallIntMethod = local::CallIntMethod;
envTable->CallLongMethodV = local::CallLongMethodV;
envTable->CallLongMethod = local::CallLongMethod;
envTable->CallFloatMethodV = local::CallFloatMethodV;
envTable->CallFloatMethod = local::CallFloatMethod;
envTable->CallDoubleMethodV = local::CallDoubleMethodV;
envTable->CallDoubleMethod = local::CallDoubleMethod;
envTable->CallVoidMethodV = local::CallVoidMethodV;
envTable->CallVoidMethod = local::CallVoidMethod;
envTable->CallStaticObjectMethodV = local::CallStaticObjectMethodV;
envTable->CallStaticObjectMethod = local::CallStaticObjectMethod;
envTable->CallStaticBooleanMethodV = local::CallStaticBooleanMethodV;
envTable->CallStaticBooleanMethod = local::CallStaticBooleanMethod;
envTable->CallStaticByteMethodV = local::CallStaticByteMethodV;
envTable->CallStaticByteMethod = local::CallStaticByteMethod;
envTable->CallStaticCharMethodV = local::CallStaticCharMethodV;
envTable->CallStaticCharMethod = local::CallStaticCharMethod;
envTable->CallStaticShortMethodV = local::CallStaticShortMethodV;
envTable->CallStaticShortMethod = local::CallStaticShortMethod;
envTable->CallStaticIntMethodV = local::CallStaticIntMethodV;
envTable->CallStaticIntMethod = local::CallStaticIntMethod;
envTable->CallStaticLongMethodV = local::CallStaticLongMethodV;
envTable->CallStaticLongMethod = local::CallStaticLongMethod;
envTable->CallStaticFloatMethodV = local::CallStaticFloatMethodV;
envTable->CallStaticFloatMethod = local::CallStaticFloatMethod;
envTable->CallStaticDoubleMethodV = local::CallStaticDoubleMethodV;
envTable->CallStaticDoubleMethod = local::CallStaticDoubleMethod;
envTable->CallStaticVoidMethodV = local::CallStaticVoidMethodV;
envTable->CallStaticVoidMethod = local::CallStaticVoidMethod;
envTable->GetStaticFieldID = local::GetStaticFieldID;
envTable->GetObjectField = local::GetObjectField;
envTable->GetBooleanField = local::GetBooleanField;
envTable->GetByteField = local::GetByteField;
envTable->GetCharField = local::GetCharField;
envTable->GetShortField = local::GetShortField;
envTable->GetIntField = local::GetIntField;
envTable->GetLongField = local::GetLongField;
envTable->GetFloatField = local::GetFloatField;
envTable->GetDoubleField = local::GetDoubleField;
envTable->SetObjectField = local::SetObjectField;
envTable->SetBooleanField = local::SetBooleanField;
envTable->SetByteField = local::SetByteField;
envTable->SetCharField = local::SetCharField;
envTable->SetShortField = local::SetShortField;
envTable->SetIntField = local::SetIntField;
envTable->SetLongField = local::SetLongField;
envTable->SetFloatField = local::SetFloatField;
envTable->SetDoubleField = local::SetDoubleField;
envTable->GetStaticObjectField = local::GetStaticObjectField;
envTable->GetStaticBooleanField = local::GetStaticBooleanField;
envTable->GetStaticByteField = local::GetStaticByteField;
envTable->GetStaticCharField = local::GetStaticCharField;
envTable->GetStaticShortField = local::GetStaticShortField;
envTable->GetStaticIntField = local::GetStaticIntField;
envTable->GetStaticLongField = local::GetStaticLongField;
envTable->GetStaticFloatField = local::GetStaticFloatField;
envTable->GetStaticDoubleField = local::GetStaticDoubleField;
envTable->SetStaticObjectField = local::SetStaticObjectField;
envTable->SetStaticBooleanField = local::SetStaticBooleanField;
envTable->SetStaticByteField = local::SetStaticByteField;
envTable->SetStaticCharField = local::SetStaticCharField;
envTable->SetStaticShortField = local::SetStaticShortField;
envTable->SetStaticIntField = local::SetStaticIntField;
envTable->SetStaticLongField = local::SetStaticLongField;
envTable->SetStaticFloatField = local::SetStaticFloatField;
envTable->SetStaticDoubleField = local::SetStaticDoubleField;
envTable->NewGlobalRef = local::NewGlobalRef;
envTable->NewWeakGlobalRef = local::NewGlobalRef;
envTable->DeleteGlobalRef = local::DeleteGlobalRef;
envTable->EnsureLocalCapacity = local::EnsureLocalCapacity;
2010-04-15 17:11:10 +00:00
envTable->ExceptionOccurred = local::ExceptionOccurred;
envTable->ExceptionDescribe = local::ExceptionDescribe;
envTable->ExceptionClear = local::ExceptionClear;
envTable->NewObjectArray = local::NewObjectArray;
envTable->GetObjectArrayElement = local::GetObjectArrayElement;
envTable->SetObjectArrayElement = local::SetObjectArrayElement;
envTable->NewBooleanArray = local::NewBooleanArray;
envTable->NewByteArray = local::NewByteArray;
envTable->NewCharArray = local::NewCharArray;
envTable->NewShortArray = local::NewShortArray;
envTable->NewIntArray = local::NewIntArray;
envTable->NewLongArray = local::NewLongArray;
envTable->NewFloatArray = local::NewFloatArray;
envTable->NewDoubleArray = local::NewDoubleArray;
envTable->GetBooleanArrayElements = local::GetBooleanArrayElements;
envTable->GetByteArrayElements = local::GetByteArrayElements;
envTable->GetCharArrayElements = local::GetCharArrayElements;
envTable->GetShortArrayElements = local::GetShortArrayElements;
envTable->GetIntArrayElements = local::GetIntArrayElements;
envTable->GetLongArrayElements = local::GetLongArrayElements;
envTable->GetFloatArrayElements = local::GetFloatArrayElements;
envTable->GetDoubleArrayElements = local::GetDoubleArrayElements;
envTable->ReleaseBooleanArrayElements = local::ReleaseBooleanArrayElements;
envTable->ReleaseByteArrayElements = local::ReleaseByteArrayElements;
envTable->ReleaseCharArrayElements = local::ReleaseCharArrayElements;
envTable->ReleaseShortArrayElements = local::ReleaseShortArrayElements;
envTable->ReleaseIntArrayElements = local::ReleaseIntArrayElements;
envTable->ReleaseLongArrayElements = local::ReleaseLongArrayElements;
envTable->ReleaseFloatArrayElements = local::ReleaseFloatArrayElements;
envTable->ReleaseDoubleArrayElements = local::ReleaseDoubleArrayElements;
envTable->GetBooleanArrayRegion = local::GetBooleanArrayRegion;
envTable->GetByteArrayRegion = local::GetByteArrayRegion;
envTable->GetCharArrayRegion = local::GetCharArrayRegion;
envTable->GetShortArrayRegion = local::GetShortArrayRegion;
envTable->GetIntArrayRegion = local::GetIntArrayRegion;
envTable->GetLongArrayRegion = local::GetLongArrayRegion;
envTable->GetFloatArrayRegion = local::GetFloatArrayRegion;
envTable->GetDoubleArrayRegion = local::GetDoubleArrayRegion;
envTable->SetBooleanArrayRegion = local::SetBooleanArrayRegion;
envTable->SetByteArrayRegion = local::SetByteArrayRegion;
envTable->SetCharArrayRegion = local::SetCharArrayRegion;
envTable->SetShortArrayRegion = local::SetShortArrayRegion;
envTable->SetIntArrayRegion = local::SetIntArrayRegion;
envTable->SetLongArrayRegion = local::SetLongArrayRegion;
envTable->SetFloatArrayRegion = local::SetFloatArrayRegion;
envTable->SetDoubleArrayRegion = local::SetDoubleArrayRegion;
envTable->GetPrimitiveArrayCritical = local::GetPrimitiveArrayCritical;
envTable->ReleasePrimitiveArrayCritical
= local::ReleasePrimitiveArrayCritical;
envTable->RegisterNatives = local::RegisterNatives;
envTable->UnregisterNatives = local::UnregisterNatives;
2010-04-15 17:11:10 +00:00
envTable->MonitorEnter = local::MonitorEnter;
envTable->MonitorExit = local::MonitorExit;
envTable->GetJavaVM = local::GetJavaVM;
envTable->IsSameObject = local::IsSameObject;
}
} // namespace vm
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
#define CRASHDIR_PROPERTY "avian.crash.dir"
#define EMBED_PREFIX_PROPERTY "avian.embed.prefix"
#define CLASSPATH_PROPERTY "java.class.path"
2010-09-21 00:38:38 +00:00
#define JAVA_HOME_PROPERTY "java.home"
#define BOOTCLASSPATH_PREPEND_OPTION "bootclasspath/p"
#define BOOTCLASSPATH_OPTION "bootclasspath"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
#define BOOTCLASSPATH_APPEND_OPTION "bootclasspath/a"
extern "C" JNIEXPORT jint JNICALL
JNI_GetDefaultJavaVMInitArgs(void*)
{
return 0;
}
extern "C" JNIEXPORT jint JNICALL
JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
{
2010-04-15 17:11:10 +00:00
local::JavaVMInitArgs* a = static_cast<local::JavaVMInitArgs*>(args);
unsigned heapLimit = 0;
const char* bootLibrary = 0;
const char* classpath = 0;
2010-09-21 00:38:38 +00:00
const char* javaHome = AVIAN_JAVA_HOME;
const char* embedPrefix = AVIAN_EMBED_PREFIX;
const char* bootClasspathPrepend = "";
const char* bootClasspath = 0;
const char* bootClasspathAppend = "";
const char* crashDumpDirectory = 0;
unsigned propertyCount = 0;
for (int i = 0; i < a->nOptions; ++i) {
if (strncmp(a->options[i].optionString, "-X", 2) == 0) {
const char* p = a->options[i].optionString + 2;
if (strncmp(p, "mx", 2) == 0) {
2010-04-15 17:11:10 +00:00
heapLimit = local::parseSize(p + 2);
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
{
bootClasspathPrepend = p + sizeof(BOOTCLASSPATH_PREPEND_OPTION);
} else if (strncmp(p, BOOTCLASSPATH_OPTION ":",
sizeof(BOOTCLASSPATH_OPTION)) == 0)
{
bootClasspath = p + sizeof(BOOTCLASSPATH_OPTION);
} else if (strncmp(p, BOOTCLASSPATH_APPEND_OPTION ":",
sizeof(BOOTCLASSPATH_APPEND_OPTION)) == 0)
{
bootClasspathAppend = p + sizeof(BOOTCLASSPATH_APPEND_OPTION);
}
} else if (strncmp(a->options[i].optionString, "-D", 2) == 0) {
const char* p = a->options[i].optionString + 2;
if (strncmp(p, BOOTSTRAP_PROPERTY "=",
sizeof(BOOTSTRAP_PROPERTY)) == 0)
{
bootLibrary = p + sizeof(BOOTSTRAP_PROPERTY);
} else if (strncmp(p, CRASHDIR_PROPERTY "=",
sizeof(CRASHDIR_PROPERTY)) == 0)
{
crashDumpDirectory = p + sizeof(CRASHDIR_PROPERTY);
} else if (strncmp(p, CLASSPATH_PROPERTY "=",
sizeof(CLASSPATH_PROPERTY)) == 0)
{
classpath = p + sizeof(CLASSPATH_PROPERTY);
2010-09-21 00:38:38 +00:00
} else if (strncmp(p, JAVA_HOME_PROPERTY "=",
sizeof(JAVA_HOME_PROPERTY)) == 0)
{
javaHome = p + sizeof(JAVA_HOME_PROPERTY);
} else if (strncmp(p, EMBED_PREFIX_PROPERTY "=",
sizeof(EMBED_PREFIX_PROPERTY)) == 0)
{
embedPrefix = p + sizeof(EMBED_PREFIX_PROPERTY);
}
++ propertyCount;
}
}
if (heapLimit == 0) heapLimit = 128 * 1024 * 1024;
if (classpath == 0) classpath = ".";
System* s = makeSystem(crashDumpDirectory);
Heap* h = makeHeap(s, heapLimit);
Classpath* c = makeClasspath(s, h, javaHome, embedPrefix);
if (bootClasspath == 0) {
bootClasspath = c->bootClasspath();
}
unsigned bcppl = strlen(bootClasspathPrepend);
unsigned bcpl = strlen(bootClasspath);
unsigned bcpal = strlen(bootClasspathAppend);
unsigned bootClasspathBufferSize = bcppl + bcpl + bcpal + 3;
RUNTIME_ARRAY(char, bootClasspathBuffer, bootClasspathBufferSize);
char* bootClasspathPointer = RUNTIME_ARRAY_BODY(bootClasspathBuffer);
local::append(&bootClasspathPointer, bootClasspathPrepend, bcppl,
bcpl + bcpal ? PATH_SEPARATOR : 0);
local::append(&bootClasspathPointer, bootClasspath, bcpl,
bcpal ? PATH_SEPARATOR : 0);
local::append(&bootClasspathPointer, bootClasspathAppend, bcpal, 0);
Finder* bf = makeFinder
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
Finder* af = makeFinder(s, h, classpath, bootLibrary);
Processor* p = makeProcessor(s, h, true);
const char** properties = static_cast<const char**>
(h->allocate(sizeof(const char*) * propertyCount));
const char** propertyPointer = properties;
for (int i = 0; i < a->nOptions; ++i) {
if (strncmp(a->options[i].optionString, "-D", 2) == 0) {
*(propertyPointer++) = a->options[i].optionString + 2;
}
}
2008-04-13 18:15:04 +00:00
*m = new (h->allocate(sizeof(Machine)))
Machine(s, h, bf, af, p, c, properties, propertyCount);
*t = p->makeThread(*m, 0, 0);
local::boot(*t);
return 0;
}