111 112 void JNIHandles::destroy_weak_global(jobject handle) { 113 if (handle != NULL) { 114 assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle"); 115 *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 116 } 117 } 118 119 120 void JNIHandles::oops_do(OopClosure* f) { 121 f->do_oop(&_deleted_handle); 122 _global_handles->oops_do(f); 123 } 124 125 126 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 127 _weak_global_handles->weak_oops_do(is_alive, f); 128 } 129 130 131 void JNIHandles::initialize() { 132 _global_handles = JNIHandleBlock::allocate_block(); 133 _weak_global_handles = JNIHandleBlock::allocate_block(); 134 EXCEPTION_MARK; 135 // We will never reach the CATCH below since Exceptions::_throw will cause 136 // the VM to exit if an exception is thrown during initialization 137 Klass* k = SystemDictionary::Object_klass(); 138 _deleted_handle = InstanceKlass::cast(k)->allocate_instance(CATCH); 139 } 140 141 142 bool JNIHandles::is_local_handle(Thread* thread, jobject handle) { 143 JNIHandleBlock* block = thread->active_handles(); 144 145 // Look back past possible native calls to jni_PushLocalFrame. 146 while (block != NULL) { 147 if (block->chain_contains(handle)) { 148 return true; 149 } 150 block = block->pop_frame_link(); 168 169 170 bool JNIHandles::is_global_handle(jobject handle) { 171 return _global_handles->chain_contains(handle); 172 } 173 174 175 bool JNIHandles::is_weak_global_handle(jobject handle) { 176 return _weak_global_handles->chain_contains(handle); 177 } 178 179 long JNIHandles::global_handle_memory_usage() { 180 return _global_handles->memory_usage(); 181 } 182 183 long JNIHandles::weak_global_handle_memory_usage() { 184 return _weak_global_handles->memory_usage(); 185 } 186 187 188 class AlwaysAliveClosure: public BoolObjectClosure { 189 public: 190 bool do_object_b(oop obj) { return true; } 191 }; 192 193 class CountHandleClosure: public OopClosure { 194 private: 195 int _count; 196 public: 197 CountHandleClosure(): _count(0) {} 198 virtual void do_oop(oop* ooph) { 199 if (*ooph != JNIHandles::deleted_handle()) { 200 _count++; 201 } 202 } 203 virtual void do_oop(narrowOop* unused) { ShouldNotReachHere(); } 204 int count() { return _count; } 205 }; 206 207 // We assume this is called at a safepoint: no lock is needed. 208 void JNIHandles::print_on(outputStream* st) { 209 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 210 assert(_global_handles != NULL && _weak_global_handles != NULL, 211 "JNIHandles not initialized"); 212 213 CountHandleClosure global_handle_count; 214 AlwaysAliveClosure always_alive; 215 oops_do(&global_handle_count); 216 weak_oops_do(&always_alive, &global_handle_count); 217 218 st->print_cr("JNI global references: %d", global_handle_count.count()); 219 st->cr(); 220 st->flush(); 221 } 222 223 class VerifyHandleClosure: public OopClosure { 224 public: 225 virtual void do_oop(oop* root) { 226 (*root)->verify(); 227 } 228 virtual void do_oop(narrowOop* root) { ShouldNotReachHere(); } 229 }; 230 231 void JNIHandles::verify() { 232 VerifyHandleClosure verify_handle; 233 AlwaysAliveClosure always_alive; 234 235 oops_do(&verify_handle); 236 weak_oops_do(&always_alive, &verify_handle); 237 } 238 239 240 241 void jni_handles_init() { 242 JNIHandles::initialize(); 243 } 244 245 246 int JNIHandleBlock::_blocks_allocated = 0; 247 JNIHandleBlock* JNIHandleBlock::_block_free_list = NULL; 248 #ifndef PRODUCT 249 JNIHandleBlock* JNIHandleBlock::_block_list = NULL; 250 #endif 251 252 253 void JNIHandleBlock::zap() { 254 // Zap block values 255 _top = 0; 256 for (int index = 0; index < block_size_in_oops; index++) { | 111 112 void JNIHandles::destroy_weak_global(jobject handle) { 113 if (handle != NULL) { 114 assert(!CheckJNICalls || is_weak_global_handle(handle), "Invalid delete of weak global JNI handle"); 115 *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it 116 } 117 } 118 119 120 void JNIHandles::oops_do(OopClosure* f) { 121 f->do_oop(&_deleted_handle); 122 _global_handles->oops_do(f); 123 } 124 125 126 void JNIHandles::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 127 _weak_global_handles->weak_oops_do(is_alive, f); 128 } 129 130 131 void JNIHandles::weak_oops_do(OopClosure* f) { 132 class AlwaysTrueClosure: public BoolObjectClosure { 133 public: 134 bool do_object_b(oop p) { return true; } 135 }; 136 static AlwaysTrueClosure always_true; 137 138 weak_oops_do(&always_true, f); 139 } 140 141 142 void JNIHandles::initialize() { 143 _global_handles = JNIHandleBlock::allocate_block(); 144 _weak_global_handles = JNIHandleBlock::allocate_block(); 145 EXCEPTION_MARK; 146 // We will never reach the CATCH below since Exceptions::_throw will cause 147 // the VM to exit if an exception is thrown during initialization 148 Klass* k = SystemDictionary::Object_klass(); 149 _deleted_handle = InstanceKlass::cast(k)->allocate_instance(CATCH); 150 } 151 152 153 bool JNIHandles::is_local_handle(Thread* thread, jobject handle) { 154 JNIHandleBlock* block = thread->active_handles(); 155 156 // Look back past possible native calls to jni_PushLocalFrame. 157 while (block != NULL) { 158 if (block->chain_contains(handle)) { 159 return true; 160 } 161 block = block->pop_frame_link(); 179 180 181 bool JNIHandles::is_global_handle(jobject handle) { 182 return _global_handles->chain_contains(handle); 183 } 184 185 186 bool JNIHandles::is_weak_global_handle(jobject handle) { 187 return _weak_global_handles->chain_contains(handle); 188 } 189 190 long JNIHandles::global_handle_memory_usage() { 191 return _global_handles->memory_usage(); 192 } 193 194 long JNIHandles::weak_global_handle_memory_usage() { 195 return _weak_global_handles->memory_usage(); 196 } 197 198 199 class CountHandleClosure: public OopClosure { 200 private: 201 int _count; 202 public: 203 CountHandleClosure(): _count(0) {} 204 virtual void do_oop(oop* ooph) { 205 if (*ooph != JNIHandles::deleted_handle()) { 206 _count++; 207 } 208 } 209 virtual void do_oop(narrowOop* unused) { ShouldNotReachHere(); } 210 int count() { return _count; } 211 }; 212 213 // We assume this is called at a safepoint: no lock is needed. 214 void JNIHandles::print_on(outputStream* st) { 215 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 216 assert(_global_handles != NULL && _weak_global_handles != NULL, 217 "JNIHandles not initialized"); 218 219 CountHandleClosure global_handle_count; 220 oops_do(&global_handle_count); 221 weak_oops_do(&global_handle_count); 222 223 st->print_cr("JNI global references: %d", global_handle_count.count()); 224 st->cr(); 225 st->flush(); 226 } 227 228 class VerifyHandleClosure: public OopClosure { 229 public: 230 virtual void do_oop(oop* root) { 231 (*root)->verify(); 232 } 233 virtual void do_oop(narrowOop* root) { ShouldNotReachHere(); } 234 }; 235 236 void JNIHandles::verify() { 237 VerifyHandleClosure verify_handle; 238 239 oops_do(&verify_handle); 240 weak_oops_do(&verify_handle); 241 } 242 243 244 245 void jni_handles_init() { 246 JNIHandles::initialize(); 247 } 248 249 250 int JNIHandleBlock::_blocks_allocated = 0; 251 JNIHandleBlock* JNIHandleBlock::_block_free_list = NULL; 252 #ifndef PRODUCT 253 JNIHandleBlock* JNIHandleBlock::_block_list = NULL; 254 #endif 255 256 257 void JNIHandleBlock::zap() { 258 // Zap block values 259 _top = 0; 260 for (int index = 0; index < block_size_in_oops; index++) { |