Merge "Quick compiler, fix wide bug" into ics-mr1-plus-art
diff --git a/src/class_linker.cc b/src/class_linker.cc
index dfed6f7..5bd69e8 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2851,19 +2851,22 @@
for (; j < actual_count; ++j) {
Method* super_method = vtable->Get(j);
super_mh.ChangeMethod(super_method);
- if (local_mh.HasSameNameAndSignature(&super_mh) &&
- klass->CanAccessMember(super_method->GetDeclaringClass(), super_method->GetAccessFlags())) {
- // Verify
- if (super_method->IsFinal()) {
- MethodHelper mh(local_method);
- ThrowLinkageError("Method %s.%s overrides final method in class %s",
- PrettyDescriptor(klass.get()).c_str(),
- mh.GetName(), mh.GetDeclaringClassDescriptor());
- return false;
+ if (local_mh.HasSameNameAndSignature(&super_mh)) {
+ if (klass->CanAccessMember(super_method->GetDeclaringClass(), super_method->GetAccessFlags())) {
+ if (super_method->IsFinal()) {
+ ThrowLinkageError("Method %s overrides final method in class %s",
+ PrettyMethod(local_method).c_str(),
+ super_mh.GetDeclaringClassDescriptor());
+ return false;
+ }
+ vtable->Set(j, local_method);
+ local_method->SetMethodIndex(j);
+ break;
+ } else {
+ LOG(WARNING) << "Before Android 4.1, method " << PrettyMethod(local_method)
+ << " would have incorrectly overridden the package-private method in "
+ << PrettyDescriptor(super_mh.GetDeclaringClassDescriptor());
}
- vtable->Set(j, local_method);
- local_method->SetMethodIndex(j);
- break;
}
}
if (j == actual_count) {
diff --git a/src/thread.cc b/src/thread.cc
index 0707c74..e5ade4d 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -269,7 +269,7 @@
InitTid();
InitStackHwm();
- CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach");
+ CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach self");
jni_env_ = new JNIEnvExt(this, runtime->GetJavaVM());
@@ -742,7 +742,13 @@
void Thread::ThreadExitCallback(void* arg) {
Thread* self = reinterpret_cast<Thread*>(arg);
- LOG(FATAL) << "Native thread exited without calling DetachCurrentThread: " << *self;
+ if (self->thread_exit_check_count_ == 0) {
+ LOG(WARNING) << "Native thread exiting without having called DetachCurrentThread (maybe it's going to use a pthread_key_create destructor?): " << *self;
+ CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, self), "reattach self");
+ self->thread_exit_check_count_ = 1;
+ } else {
+ LOG(FATAL) << "Native thread exited without calling DetachCurrentThread: " << *self;
+ }
}
void Thread::Startup() {
@@ -803,7 +809,8 @@
name_(new std::string(kThreadNameDuringStartup)),
daemon_(daemon),
no_thread_suspension_(0),
- last_no_thread_suspension_cause_(NULL) {
+ last_no_thread_suspension_cause_(NULL),
+ thread_exit_check_count_(0) {
CHECK_EQ((sizeof(Thread) % 4), 0U) << sizeof(Thread);
memset(&held_mutexes_[0], 0, sizeof(held_mutexes_));
}
diff --git a/src/thread.h b/src/thread.h
index 24c78ee..155c980 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -665,9 +665,13 @@
public:
// Runtime support function pointers
+ // TODO: move this near the top, since changing its offset requires all oats to be recompiled!
EntryPoints entrypoints_;
private:
+ // How many times has our pthread key's destructor been called?
+ uint32_t thread_exit_check_count_;
+
friend class ScopedThreadListLockReleaser;
DISALLOW_COPY_AND_ASSIGN(Thread);
};