JavaVMExt* const vm = Runtime::Current()->GetJavaVM();
for (jweak weak_root : class_loaders_) {
auto* const class_loader = down_cast<mirror::ClassLoader*>(
- vm->DecodeWeakGlobal(self, weak_root));
+ vm->DecodeWeakGlobalDuringShutdown(self, weak_root));
if (class_loader != nullptr) {
delete class_loader->GetClassTable();
}
}
inline bool JavaVMExt::MayAccessWeakGlobalsUnlocked(Thread* self) const {
- if (kUseReadBarrier) {
- // self can be null during a runtime shutdown. ~Runtime()->~ClassLinker()->DecodeWeakGlobal().
- return self != nullptr ? self->GetWeakRefAccessEnabled() : true;
- } else {
- return allow_accessing_weak_globals_.LoadSequentiallyConsistent();
- }
+ DCHECK(self != nullptr);
+ return kUseReadBarrier ?
+ self->GetWeakRefAccessEnabled() :
+ allow_accessing_weak_globals_.LoadSequentiallyConsistent();
}
mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
return weak_globals_.Get(ref);
}
+mirror::Object* JavaVMExt::DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref) {
+ DCHECK_EQ(GetIndirectRefKind(ref), kWeakGlobal);
+ DCHECK(Runtime::Current()->IsShuttingDown(self));
+ if (self != nullptr) {
+ return DecodeWeakGlobal(self, ref);
+ }
+ // self can be null during a runtime shutdown. ~Runtime()->~ClassLinker()->DecodeWeakGlobal().
+ if (!kUseReadBarrier) {
+ DCHECK(allow_accessing_weak_globals_.LoadSequentiallyConsistent());
+ }
+ return weak_globals_.SynchronizedGet(ref);
+}
+
void JavaVMExt::UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result) {
MutexLock mu(self, weak_globals_lock_);
weak_globals_.Update(ref, result);
SHARED_REQUIRES(Locks::mutator_lock_)
REQUIRES(weak_globals_lock_);
+ // Like DecodeWeakGlobal() but to be used only during a runtime shutdown where self may be
+ // null.
+ mirror::Object* DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref)
+ SHARED_REQUIRES(Locks::mutator_lock_)
+ REQUIRES(!weak_globals_lock_);
+
Mutex& WeakGlobalsLock() RETURN_CAPABILITY(weak_globals_lock_) {
return weak_globals_lock_;
}