object_registry.cc revision a032870e19e4a6c8d62b7dab806261006fa711ee
164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes/* 264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * Copyright (C) 2013 The Android Open Source Project 364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * 464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * you may not use this file except in compliance with the License. 664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * You may obtain a copy of the License at 764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * 864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * 1064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * Unless required by applicable law or agreed to in writing, software 1164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * See the License for the specific language governing permissions and 1464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes * limitations under the License. 1564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes */ 1664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 1764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes#include "object_registry.h" 1864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 1964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes#include "scoped_thread_state_change.h" 2064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 2164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesnamespace art { 2264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 2364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesmirror::Object* const ObjectRegistry::kInvalidObject = reinterpret_cast<mirror::Object*>(1); 2464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 2564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesstd::ostream& operator<<(std::ostream& os, const ObjectRegistryEntry& rhs) { 2664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes os << "ObjectRegistryEntry[" << rhs.jni_reference_type 2764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes << ",reference=" << rhs.jni_reference 2864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes << ",count=" << rhs.reference_count 2964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes << ",id=" << rhs.id << "]"; 3064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return os; 3164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 3264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 330f827169742aad6209d830db773a101849c32a83Elliott HughesObjectRegistry::ObjectRegistry() 34b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi : lock_("ObjectRegistry lock", kJdwpObjectRegistryLock), next_id_(1) { 3564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 3664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 3764f574f474aa77c72778640ab21f8cfa72546812Elliott HughesJDWP::RefTypeId ObjectRegistry::AddRefType(mirror::Class* c) { 3864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return InternalAdd(c); 3964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 4064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 4164f574f474aa77c72778640ab21f8cfa72546812Elliott HughesJDWP::ObjectId ObjectRegistry::Add(mirror::Object* o) { 4264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return InternalAdd(o); 4364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 4464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 4564f574f474aa77c72778640ab21f8cfa72546812Elliott HughesJDWP::ObjectId ObjectRegistry::InternalAdd(mirror::Object* o) { 46b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (o == nullptr) { 4764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return 0; 4864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 4964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 50b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi // Call IdentityHashCode here to avoid a lock level violation between lock_ and monitor_lock. 51b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi int32_t identity_hash_code = o->IdentityHashCode(); 5264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes ScopedObjectAccessUnchecked soa(Thread::Current()); 5364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(soa.Self(), lock_); 54b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi ObjectRegistryEntry* entry = nullptr; 55b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (ContainsLocked(soa.Self(), o, identity_hash_code, &entry)) { 56412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier // This object was already in our map. 57412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier ++entry->reference_count; 58412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier } else { 59412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry = new ObjectRegistryEntry; 60412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->jni_reference_type = JNIWeakGlobalRefType; 61412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->jni_reference = nullptr; 62412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->reference_count = 0; 63412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->id = 0; 64b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi entry->identity_hash_code = identity_hash_code; 65b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi object_to_entry_.insert(std::make_pair(identity_hash_code, entry)); 6664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 67412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier // This object isn't in the registry yet, so add it. 68412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier JNIEnv* env = soa.Env(); 6964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 70412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier jobject local_reference = soa.AddLocalReference<jobject>(o); 7164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 72412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->jni_reference_type = JNIWeakGlobalRefType; 73412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->jni_reference = env->NewWeakGlobalRef(local_reference); 74412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->reference_count = 1; 75412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->id = next_id_++; 7664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 77412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier id_to_entry_.Put(entry->id, entry); 7864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 79412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier env->DeleteLocalRef(local_reference); 80412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier } 81412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier return entry->id; 8264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 8364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 84b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchibool ObjectRegistry::Contains(mirror::Object* o, ObjectRegistryEntry** out_entry) { 85b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (o == nullptr) { 86b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi return false; 87b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 88b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi // Call IdentityHashCode here to avoid a lock level violation between lock_ and monitor_lock. 89b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi int32_t identity_hash_code = o->IdentityHashCode(); 90b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi Thread* self = Thread::Current(); 91b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi MutexLock mu(self, lock_); 92b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi return ContainsLocked(self, o, identity_hash_code, out_entry); 93b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi} 94b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi 95b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchibool ObjectRegistry::ContainsLocked(Thread* self, mirror::Object* o, int32_t identity_hash_code, 96b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi ObjectRegistryEntry** out_entry) { 97b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi DCHECK(o != nullptr); 98b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi for (auto it = object_to_entry_.lower_bound(identity_hash_code), end = object_to_entry_.end(); 99b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi it != end && it->first == identity_hash_code; ++it) { 100b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi ObjectRegistryEntry* entry = it->second; 101b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (o == self->DecodeJObject(entry->jni_reference)) { 102b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (out_entry != nullptr) { 103b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi *out_entry = entry; 104b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 105b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi return true; 106b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 107b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 108b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi return false; 10964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 11064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 11164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::Clear() { 11264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 11364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 11464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes VLOG(jdwp) << "Object registry contained " << object_to_entry_.size() << " entries"; 11564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes // Delete all the JNI references. 11664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes JNIEnv* env = self->GetJniEnv(); 117412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier for (const auto& pair : object_to_entry_) { 118a032870e19e4a6c8d62b7dab806261006fa711eeSebastien Hertz const ObjectRegistryEntry* entry = pair.second; 119a032870e19e4a6c8d62b7dab806261006fa711eeSebastien Hertz if (entry->jni_reference_type == JNIWeakGlobalRefType) { 120a032870e19e4a6c8d62b7dab806261006fa711eeSebastien Hertz env->DeleteWeakGlobalRef(entry->jni_reference); 12164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } else { 122a032870e19e4a6c8d62b7dab806261006fa711eeSebastien Hertz env->DeleteGlobalRef(entry->jni_reference); 12364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 124a032870e19e4a6c8d62b7dab806261006fa711eeSebastien Hertz delete entry; 12564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 12664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes // Clear the maps. 12764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes object_to_entry_.clear(); 12864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes id_to_entry_.clear(); 12964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 13064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 13164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesmirror::Object* ObjectRegistry::InternalGet(JDWP::ObjectId id) { 13264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 13364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 134412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 13564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes if (it == id_to_entry_.end()) { 13664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return kInvalidObject; 13764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 138412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier ObjectRegistryEntry& entry = *it->second; 13964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return self->DecodeJObject(entry.jni_reference); 14064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 14164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 142449db33fafa29578df60e8a323f78d5eb6247e76Jeff Haojobject ObjectRegistry::GetJObject(JDWP::ObjectId id) { 1430630ab5239a7d7be24dedbc3f66c822332446fc3Sebastien Hertz if (id == 0) { 1440630ab5239a7d7be24dedbc3f66c822332446fc3Sebastien Hertz return NULL; 1450630ab5239a7d7be24dedbc3f66c822332446fc3Sebastien Hertz } 146449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao Thread* self = Thread::Current(); 147449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao MutexLock mu(self, lock_); 148412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 149449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao CHECK(it != id_to_entry_.end()) << id; 150412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier ObjectRegistryEntry& entry = *it->second; 151449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao return entry.jni_reference; 152449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao} 153449db33fafa29578df60e8a323f78d5eb6247e76Jeff Hao 15464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::DisableCollection(JDWP::ObjectId id) { 15564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 15664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 157412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 158e96060aa2483529d087031f7cdcc0405f1ef9218Sebastien Hertz CHECK(it != id_to_entry_.end()); 159412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier Promote(*it->second); 16064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 16164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 16264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::EnableCollection(JDWP::ObjectId id) { 16364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 16464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 165412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 166e96060aa2483529d087031f7cdcc0405f1ef9218Sebastien Hertz CHECK(it != id_to_entry_.end()); 167412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier Demote(*it->second); 16864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 16964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 17064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::Demote(ObjectRegistryEntry& entry) { 17164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes if (entry.jni_reference_type == JNIGlobalRefType) { 17264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 17364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes JNIEnv* env = self->GetJniEnv(); 17464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes jobject global = entry.jni_reference; 17564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes entry.jni_reference = env->NewWeakGlobalRef(entry.jni_reference); 17664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes entry.jni_reference_type = JNIWeakGlobalRefType; 17764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes env->DeleteGlobalRef(global); 17864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 17964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 18064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 18164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::Promote(ObjectRegistryEntry& entry) { 18264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes if (entry.jni_reference_type == JNIWeakGlobalRefType) { 18364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 18464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes JNIEnv* env = self->GetJniEnv(); 18564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes jobject weak = entry.jni_reference; 18664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes entry.jni_reference = env->NewGlobalRef(entry.jni_reference); 18764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes entry.jni_reference_type = JNIGlobalRefType; 18864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes env->DeleteWeakGlobalRef(weak); 18964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 19064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 19164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 19264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesbool ObjectRegistry::IsCollected(JDWP::ObjectId id) { 19364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 19464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 195412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 196e96060aa2483529d087031f7cdcc0405f1ef9218Sebastien Hertz CHECK(it != id_to_entry_.end()); 197412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier ObjectRegistryEntry& entry = *it->second; 19864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes if (entry.jni_reference_type == JNIWeakGlobalRefType) { 19964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes JNIEnv* env = self->GetJniEnv(); 2007934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return env->IsSameObject(entry.jni_reference, NULL); // Has the jweak been collected? 20164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } else { 2027934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return false; // We hold a strong reference, so we know this is live. 20364f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 20464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 20564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 20664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughesvoid ObjectRegistry::DisposeObject(JDWP::ObjectId id, uint32_t reference_count) { 20764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes Thread* self = Thread::Current(); 20864f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes MutexLock mu(self, lock_); 209412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier auto it = id_to_entry_.find(id); 21064f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes if (it == id_to_entry_.end()) { 21164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes return; 21264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 213412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier ObjectRegistryEntry* entry = it->second; 214412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier entry->reference_count -= reference_count; 215412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier if (entry->reference_count <= 0) { 21664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes JNIEnv* env = self->GetJniEnv(); 217b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi // Erase the object from the maps. Note object may be null if it's 218b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi // a weak ref and the GC has cleared it. 219b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi int32_t hash_code = entry->identity_hash_code; 220b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi for (auto it = object_to_entry_.lower_bound(hash_code), end = object_to_entry_.end(); 221b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi it != end && it->first == hash_code; ++it) { 222b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi if (entry == it->second) { 223b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi object_to_entry_.erase(it); 224b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi break; 225b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 226b5a9e3d1cc1fd66683e43e365afc8c900e2800c4Hiroshi Yamauchi } 227412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier if (entry->jni_reference_type == JNIWeakGlobalRefType) { 228412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier env->DeleteWeakGlobalRef(entry->jni_reference); 22964f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } else { 230412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier env->DeleteGlobalRef(entry->jni_reference); 23164f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 23264f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes id_to_entry_.erase(id); 233412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier delete entry; 23464f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes } 23564f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} 23664f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes 23764f574f474aa77c72778640ab21f8cfa72546812Elliott Hughes} // namespace art 238