Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Commit

Permalink
Add Thread entry to signal if the thread can call into java
Browse files Browse the repository at this point in the history
Compiler threads (AOT or JIT) should not call into Java as they have no
peers (which may lead to crashes, e.g. b/33067273)

(cherry picked from commit ccd56958eb46fbb00c1eb45c7a7b23d5bbfd7698)

Bug: 32602185
Bug: 33067273

Test: m test-art-host-run-test; m test-art-host-gtest
Change-Id: I97dda7a5444643db3c5d5318339a65a602f709e8
  • Loading branch information
Calin Juravle authored and agampe committed Feb 8, 2017
1 parent 3f3d4d6 commit f5f462b
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 1 deletion.
8 changes: 8 additions & 0 deletions runtime/class_linker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2409,6 +2409,14 @@ mirror::Class* ClassLinker::FindClass(Thread* self,

// We'll let the Java-side rediscover all this and throw the exception with the right stack
// trace.
if (!self->CanCallIntoJava()) {
// Oops, we can't call into java so we can't run actual class-loader code.
// This is true for e.g. for the compiler (jit or aot).
mirror::Throwable* pre_allocated =
Runtime::Current()->GetPreAllocatedNoClassDefFoundError();
self->SetException(pre_allocated);
return nullptr;
}
}

if (Runtime::Current()->IsAotCompiler()) {
Expand Down
2 changes: 2 additions & 0 deletions runtime/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,8 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
CHECK_EQ(self->GetThreadId(), ThreadList::kMainThreadId);
CHECK(self != nullptr);

self->SetCanCallIntoJava(!IsAotCompiler());

// Set us to runnable so tools using a runtime can allocate and GC by default
self->TransitionFromSuspendedToRunnable();

Expand Down
6 changes: 5 additions & 1 deletion runtime/thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,11 @@ void Thread::Shutdown() {
}
}

Thread::Thread(bool daemon) : tls32_(daemon), wait_monitor_(nullptr), interrupted_(false) {
Thread::Thread(bool daemon)
: tls32_(daemon),
wait_monitor_(nullptr),
interrupted_(false),
can_call_into_java_(true) {
wait_mutex_ = new Mutex("a thread wait mutex");
wait_cond_ = new ConditionVariable("a thread wait condition variable", *wait_mutex_);
tlsPtr_.instrumentation_stack = new std::deque<instrumentation::InstrumentationStackFrame>;
Expand Down
13 changes: 13 additions & 0 deletions runtime/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,15 @@ class Thread {
--tls32_.disable_thread_flip_count;
}

// Returns true if the thread is allowed to call into java.
bool CanCallIntoJava() const {
return can_call_into_java_;
}

void SetCanCallIntoJava(bool can_call_into_java) {
can_call_into_java_ = can_call_into_java;
}

// Activates single step control for debugging. The thread takes the
// ownership of the given SingleStepControl*. It is deleted by a call
// to DeactivateSingleStepControl or upon thread destruction.
Expand Down Expand Up @@ -1518,6 +1527,10 @@ class Thread {
// Debug disable read barrier count, only is checked for debug builds and only in the runtime.
uint8_t debug_disallow_read_barrier_ = 0;

// True if the thread is allowed to call back into java (for e.g. during class resolution).
// By default this is true.
bool can_call_into_java_;

friend class Dbg; // For SetStateUnsafe.
friend class gc::collector::SemiSpace; // For getting stack traces.
friend class Runtime; // For CreatePeer.
Expand Down
2 changes: 2 additions & 0 deletions runtime/thread_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ void* ThreadPoolWorker::Callback(void* arg) {
ThreadPoolWorker* worker = reinterpret_cast<ThreadPoolWorker*>(arg);
Runtime* runtime = Runtime::Current();
CHECK(runtime->AttachCurrentThread(worker->name_.c_str(), true, nullptr, false));
// Thread pool workers cannot call into java.
Thread::Current()->SetCanCallIntoJava(false);
// Do work until its time to shut down.
worker->Run();
runtime->DetachCurrentThread();
Expand Down
1 change: 1 addition & 0 deletions runtime/thread_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class ThreadPoolWorker {
DISALLOW_COPY_AND_ASSIGN(ThreadPoolWorker);
};

// Note that thread pool workers will set Thread#setCanCallIntoJava to false.
class ThreadPool {
public:
// Returns the number of threads in the thread pool.
Expand Down

0 comments on commit f5f462b

Please sign in to comment.