fix broken Android build due to 617bd85

617bd85 broke the Android build by creating an unresolvable
order-of-operations bug in classpath-android.cpp's
MyClasspath::preBoot method.

The problem is that, while JNIEnv::FindClass is supposed to initialize
the class that it finds, this causes JniConstants::init to indirectly
invoke native methods which are not registered until JNI_OnLoad is
called (which happens after JniConstants::init is called).  However,
if we call JNI_OnLoad first, that causes methods to be invoked which
rely on JniConstants::init having already been run.

I haven't checked to see how Dalvik handles this, but I don't see any
way around the problem besides disabling initialization by
JNIEnv::FindClass until the preBoot phase is complete.  Moreover, it's
dangerous to allow Java code to be invoked so early anyway, since the
VM is not yet fully initialized.
This commit is contained in:
Joel Dice 2014-04-11 19:38:11 -06:00
parent f7614bf8a7
commit f21f11efd6
5 changed files with 26 additions and 5 deletions

View File

@ -1571,6 +1571,8 @@ class Classpath {
virtual void
preBoot(Thread* t) = 0;
virtual bool mayInitClasses() = 0;
virtual void
boot(Thread* t) = 0;

View File

@ -228,9 +228,8 @@ translateStackTrace(Thread* t, object raw)
class MyClasspath : public Classpath {
public:
MyClasspath(Allocator* allocator):
allocator(allocator),
tzdata(0)
MyClasspath(Allocator* allocator)
: allocator(allocator), tzdata(0), mayInitClasses_(false)
{ }
virtual object
@ -493,6 +492,13 @@ class MyClasspath : public Classpath {
JniConstants::init(reinterpret_cast<_JNIEnv*>(t));
JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0);
mayInitClasses_ = true;
}
virtual bool mayInitClasses()
{
return mayInitClasses_;
}
virtual void
@ -579,6 +585,7 @@ class MyClasspath : public Classpath {
Allocator* allocator;
System::Region* tzdata;
bool mayInitClasses_;
};
int64_t JNICALL

View File

@ -121,6 +121,11 @@ class MyClasspath : public Classpath {
// ignore
}
virtual bool mayInitClasses()
{
return true;
}
virtual void
boot(Thread*)
{

View File

@ -681,6 +681,11 @@ class MyClasspath : public Classpath {
// ignore
}
virtual bool mayInitClasses()
{
return true;
}
virtual void
boot(Thread* t)
{

View File

@ -354,9 +354,11 @@ findClass(Thread* t, uintptr_t* arguments)
: root(t, Machine::AppLoader),
n);
if (t->m->classpath->mayInitClasses()) {
PROTECT(t, c);
initClass(t, c);
}
return reinterpret_cast<uint64_t>(makeLocalReference(t, getJClass(t, c)));
}