fix time==0 case in Unsafe.park and implement JVM_DumpThreads

Also, set name field on system threads for OpenJDK build to avoid NPEs
in Thread.getName.
This commit is contained in:
Joel Dice 2010-11-27 16:27:30 -07:00
parent 3cba6edf1f
commit 70a36c05b9
3 changed files with 99 additions and 47 deletions

View File

@ -313,6 +313,8 @@ class MyClasspath : public Classpath {
setObjectClass(t, group, type(t, Machine::ThreadGroupType));
threadGroupMaxPriority(t, group) = MaxPriority;
}
PROTECT(t, group);
object thread = allocate(t, FixedSizeOfThread, true);
setObjectClass(t, thread, type(t, Machine::ThreadType));
@ -320,6 +322,17 @@ class MyClasspath : public Classpath {
threadGroup(t, thread) = group;
threadContextClassLoader(t, thread) = root(t, Machine::BootLoader);
PROTECT(t, thread);
const unsigned BufferSize = 256;
char buffer[BufferSize];
unsigned length = vm::snprintf(buffer, BufferSize, "Thread-%p", thread);
object name = makeCharArray(t, length);
for (unsigned i = 0; i < length; ++i) {
charArrayBody(t, name, i) = buffer[i];
}
set(t, thread, ThreadName, name);
return thread;
}
@ -1708,10 +1721,9 @@ Avian_sun_misc_Unsafe_park
if (absolute) {
time -= t->m->system->now();
}
if (time <= 0) {
return;
if (time <= 0) {
return;
}
}
monitorAcquire(t, local::interruptLock(t, t->javaThread));
@ -2162,7 +2174,44 @@ extern "C" JNIEXPORT jobjectArray JNICALL
EXPORT(JVM_GetAllThreads)(Thread*, jclass) { abort(); }
extern "C" JNIEXPORT jobjectArray JNICALL
EXPORT(JVM_DumpThreads)(Thread*, jclass, jobjectArray) { abort(); }
EXPORT(JVM_DumpThreads)(Thread* t, jclass, jobjectArray threads)
{
ENTER(t, Thread::ActiveState);
unsigned threadsLength = objectArrayLength(t, *threads);
object arrayClass = resolveObjectArrayClass
(t, classLoader(t, type(t, Machine::StackTraceElementType)),
type(t, Machine::StackTraceElementType));
object result = makeObjectArray(t, arrayClass, threadsLength);
PROTECT(t, result);
for (unsigned threadsIndex = 0; threadsIndex < threadsLength;
++ threadsIndex)
{
Thread* peer = reinterpret_cast<Thread*>
(threadPeer(t, objectArrayBody(t, *threads, threadsIndex)));
if (peer) {
object trace = t->m->processor->getStackTrace(t, peer);
PROTECT(t, trace);
unsigned traceLength = objectArrayLength(t, trace);
object array = makeObjectArray
(t, type(t, Machine::StackTraceElementType), traceLength);
PROTECT(t, array);
for (unsigned traceIndex = 0; traceIndex < traceLength; ++ traceIndex) {
object ste = makeStackTraceElement
(t, objectArrayBody(t, trace, traceIndex));
set(t, array, ArrayBody + (traceIndex * BytesPerWord), ste);
}
set(t, result, ArrayBody + (threadsIndex * BytesPerWord), array);
}
}
return makeLocalReference(t, result);
}
extern "C" JNIEXPORT jclass JNICALL
EXPORT(JVM_CurrentLoadedClass)(Thread*) { abort(); }

View File

@ -1837,48 +1837,6 @@ resolveArrayClass(Thread* t, object loader, object spec, bool throw_)
}
}
object
resolveObjectArrayClass(Thread* t, object loader, object elementClass)
{
{ object arrayClass = classRuntimeDataArrayClass
(t, getClassRuntimeData(t, elementClass));
if (arrayClass) {
return arrayClass;
}
}
PROTECT(t, loader);
PROTECT(t, elementClass);
object elementSpec = className(t, elementClass);
PROTECT(t, elementSpec);
object spec;
if (byteArrayBody(t, elementSpec, 0) == '[') {
spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 1);
byteArrayBody(t, spec, 0) = '[';
memcpy(&byteArrayBody(t, spec, 1),
&byteArrayBody(t, elementSpec, 0),
byteArrayLength(t, elementSpec));
} else {
spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 3);
byteArrayBody(t, spec, 0) = '[';
byteArrayBody(t, spec, 1) = 'L';
memcpy(&byteArrayBody(t, spec, 2),
&byteArrayBody(t, elementSpec, 0),
byteArrayLength(t, elementSpec) - 1);
byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 1) = ';';
byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 2) = 0;
}
object arrayClass = resolveClass(t, loader, spec);
set(t, getClassRuntimeData(t, elementClass), ClassRuntimeDataArrayClass,
arrayClass);
return arrayClass;
}
void
removeMonitor(Thread* t, object o)
{
@ -3519,6 +3477,48 @@ initClass(Thread* t, object c)
}
}
object
resolveObjectArrayClass(Thread* t, object loader, object elementClass)
{
{ object arrayClass = classRuntimeDataArrayClass
(t, getClassRuntimeData(t, elementClass));
if (arrayClass) {
return arrayClass;
}
}
PROTECT(t, loader);
PROTECT(t, elementClass);
object elementSpec = className(t, elementClass);
PROTECT(t, elementSpec);
object spec;
if (byteArrayBody(t, elementSpec, 0) == '[') {
spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 1);
byteArrayBody(t, spec, 0) = '[';
memcpy(&byteArrayBody(t, spec, 1),
&byteArrayBody(t, elementSpec, 0),
byteArrayLength(t, elementSpec));
} else {
spec = makeByteArray(t, byteArrayLength(t, elementSpec) + 3);
byteArrayBody(t, spec, 0) = '[';
byteArrayBody(t, spec, 1) = 'L';
memcpy(&byteArrayBody(t, spec, 2),
&byteArrayBody(t, elementSpec, 0),
byteArrayLength(t, elementSpec) - 1);
byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 1) = ';';
byteArrayBody(t, spec, byteArrayLength(t, elementSpec) + 2) = 0;
}
object arrayClass = resolveClass(t, loader, spec);
set(t, getClassRuntimeData(t, elementClass), ClassRuntimeDataArrayClass,
arrayClass);
return arrayClass;
}
object
makeObjectArray(Thread* t, object elementClass, unsigned count)
{

View File

@ -2196,6 +2196,9 @@ postInitClass(Thread* t, object c);
void
initClass(Thread* t, object c);
object
resolveObjectArrayClass(Thread* t, object loader, object elementClass);
object
makeObjectArray(Thread* t, object elementClass, unsigned count);