fix System.loadLibrary for OpenJDK tails=true build

This commit is contained in:
Joel Dice 2013-03-05 15:43:49 -07:00
parent 585186f7d3
commit ca84dd26f1
5 changed files with 56 additions and 4 deletions

View File

@ -1583,6 +1583,10 @@ class Classpath {
virtual int64_t
getDirectBufferCapacity(Thread* t, object buffer) = 0;
virtual bool
canTailCall(Thread* t, object caller, object calleeClassName,
object calleeMethodName, object calleeMethodSpec) = 0;
virtual void
dispose() = 0;
};

View File

@ -439,6 +439,12 @@ class MyClasspath : public Classpath {
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual bool
canTailCall(Thread*, object, object, object, object)
{
return true;
}
virtual void
dispose()
{

View File

@ -174,6 +174,12 @@ class MyClasspath : public Classpath {
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual bool
canTailCall(Thread*, object, object, object, object)
{
return true;
}
virtual void
dispose()
{

View File

@ -842,6 +842,30 @@ class MyClasspath : public Classpath {
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual bool
canTailCall(Thread* t, object, object calleeClassName,
object calleeMethodName, object)
{
// we can't tail call System.loadLibrary or Runtime.loadLibrary
// due to their use of System.getCallerClass, which gets confused
// if we elide stack frames.
return (strcmp("loadLibrary", reinterpret_cast<char*>
(&byteArrayBody(t, calleeMethodName, 0)))
or (strcmp("java/lang/System", reinterpret_cast<char*>
(&byteArrayBody(t, calleeClassName, 0)))
and strcmp("java/lang/Runtime", reinterpret_cast<char*>
(&byteArrayBody(t, calleeClassName, 0)))))
// and we can't tail call Reflection.getCallerClass because the
// number of stack frames will be wrong
and (strcmp("getCallerClass", reinterpret_cast<char*>
(&byteArrayBody(t, calleeMethodName, 0)))
or strcmp("sun/reflect/Reflection", reinterpret_cast<char*>
(&byteArrayBody(t, calleeClassName, 0))));
}
virtual void
dispose()
{

View File

@ -3730,7 +3730,8 @@ returnsNext(MyThread* t, object code, unsigned ip)
bool
isTailCall(MyThread* t, object code, unsigned ip, object caller,
int calleeReturnCode)
int calleeReturnCode, object calleeClassName,
object calleeMethodName, object calleeMethodSpec)
{
return avian::codegen::TailCalls
and ((methodFlags(t, caller) & ACC_SYNCHRONIZED) == 0)
@ -3738,21 +3739,32 @@ isTailCall(MyThread* t, object code, unsigned ip, object caller,
and (not needsReturnBarrier(t, caller))
and (methodReturnCode(t, caller) == VoidField
or methodReturnCode(t, caller) == calleeReturnCode)
and returnsNext(t, code, ip);
and returnsNext(t, code, ip)
and t->m->classpath->canTailCall
(t, caller, calleeClassName, calleeMethodName, calleeMethodSpec);
}
bool
isTailCall(MyThread* t, object code, unsigned ip, object caller, object callee)
{
return isTailCall(t, code, ip, caller, methodReturnCode(t, callee));
return isTailCall
(t, code, ip, caller, methodReturnCode(t, callee),
className(t, methodClass(t, callee)), methodName(t, callee),
methodSpec(t, callee));
}
bool
isReferenceTailCall(MyThread* t, object code, unsigned ip, object caller,
object calleeReference)
{
object c = referenceClass(t, calleeReference);
if (objectClass(t, c) == type(t, Machine::ClassType)) {
c = className(t, c);
}
return isTailCall
(t, code, ip, caller, methodReferenceReturnCode(t, calleeReference));
(t, code, ip, caller, methodReferenceReturnCode(t, calleeReference),
c, referenceName(t, calleeReference), referenceSpec(t, calleeReference));
}
bool