Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/jvmtiImpl.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | d2a62e0f25eb |
children | e522a00b91aa 070d523b96a7 |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
233 // | 233 // |
234 | 234 |
235 JvmtiBreakpoint::JvmtiBreakpoint() { | 235 JvmtiBreakpoint::JvmtiBreakpoint() { |
236 _method = NULL; | 236 _method = NULL; |
237 _bci = 0; | 237 _bci = 0; |
238 _class_loader = NULL; | |
238 #ifdef CHECK_UNHANDLED_OOPS | 239 #ifdef CHECK_UNHANDLED_OOPS |
239 // This one is always allocated with new, but check it just in case. | 240 // This one is always allocated with new, but check it just in case. |
240 Thread *thread = Thread::current(); | 241 Thread *thread = Thread::current(); |
241 if (thread->is_in_stack((address)&_method)) { | 242 if (thread->is_in_stack((address)&_method)) { |
242 thread->allow_unhandled_oop((oop*)&_method); | 243 thread->allow_unhandled_oop((oop*)&_method); |
243 } | 244 } |
244 #endif // CHECK_UNHANDLED_OOPS | 245 #endif // CHECK_UNHANDLED_OOPS |
245 } | 246 } |
246 | 247 |
247 JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) { | 248 JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) { |
248 _method = m_method; | 249 _method = m_method; |
250 _class_loader = _method->method_holder()->class_loader_data()->class_loader(); | |
249 assert(_method != NULL, "_method != NULL"); | 251 assert(_method != NULL, "_method != NULL"); |
250 _bci = (int) location; | 252 _bci = (int) location; |
251 #ifdef CHECK_UNHANDLED_OOPS | |
252 // Could be allocated with new and wouldn't be on the unhandled oop list. | |
253 Thread *thread = Thread::current(); | |
254 if (thread->is_in_stack((address)&_method)) { | |
255 thread->allow_unhandled_oop(&_method); | |
256 } | |
257 #endif // CHECK_UNHANDLED_OOPS | |
258 | |
259 assert(_bci >= 0, "_bci >= 0"); | 253 assert(_bci >= 0, "_bci >= 0"); |
260 } | 254 } |
261 | 255 |
262 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { | 256 void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { |
263 _method = bp._method; | 257 _method = bp._method; |
264 _bci = bp._bci; | 258 _bci = bp._bci; |
259 _class_loader = bp._class_loader; | |
265 } | 260 } |
266 | 261 |
267 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { | 262 bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { |
268 Unimplemented(); | 263 Unimplemented(); |
269 return false; | 264 return false; |
273 return _method == bp._method | 268 return _method == bp._method |
274 && _bci == bp._bci; | 269 && _bci == bp._bci; |
275 } | 270 } |
276 | 271 |
277 bool JvmtiBreakpoint::is_valid() { | 272 bool JvmtiBreakpoint::is_valid() { |
273 // class loader can be NULL | |
278 return _method != NULL && | 274 return _method != NULL && |
279 _bci >= 0; | 275 _bci >= 0; |
280 } | 276 } |
281 | 277 |
282 address JvmtiBreakpoint::getBcp() { | 278 address JvmtiBreakpoint::getBcp() { |
283 return _method->bcp_from(_bci); | 279 return _method->bcp_from(_bci); |
284 } | 280 } |
285 | 281 |
286 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { | 282 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { |
287 ((methodOopDesc*)_method->*meth_act)(_bci); | 283 ((Method*)_method->*meth_act)(_bci); |
288 | 284 |
289 // add/remove breakpoint to/from versions of the method that | 285 // add/remove breakpoint to/from versions of the method that |
290 // are EMCP. Directly or transitively obsolete methods are | 286 // are EMCP. Directly or transitively obsolete methods are |
291 // not saved in the PreviousVersionInfo. | 287 // not saved in the PreviousVersionInfo. |
292 Thread *thread = Thread::current(); | 288 Thread *thread = Thread::current(); |
300 // contain a GrowableArray of handles. We have to clean up the | 296 // contain a GrowableArray of handles. We have to clean up the |
301 // GrowableArray _after_ the PreviousVersionWalker destructor | 297 // GrowableArray _after_ the PreviousVersionWalker destructor |
302 // has destroyed the handles. | 298 // has destroyed the handles. |
303 { | 299 { |
304 // search previous versions if they exist | 300 // search previous versions if they exist |
305 PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part()); | 301 PreviousVersionWalker pvw((InstanceKlass *)ikh()); |
306 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | 302 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); |
307 pv_info != NULL; pv_info = pvw.next_previous_version()) { | 303 pv_info != NULL; pv_info = pvw.next_previous_version()) { |
308 GrowableArray<methodHandle>* methods = | 304 GrowableArray<methodHandle>* methods = |
309 pv_info->prev_EMCP_method_handles(); | 305 pv_info->prev_EMCP_method_handles(); |
310 | 306 |
322 break; | 318 break; |
323 } | 319 } |
324 | 320 |
325 for (int i = methods->length() - 1; i >= 0; i--) { | 321 for (int i = methods->length() - 1; i >= 0; i--) { |
326 methodHandle method = methods->at(i); | 322 methodHandle method = methods->at(i); |
327 if (method->name() == m_name && method->signature() == m_signature) { | 323 // obsolete methods that are running are not deleted from |
324 // previous version array, but they are skipped here. | |
325 if (!method->is_obsolete() && | |
326 method->name() == m_name && | |
327 method->signature() == m_signature) { | |
328 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", | 328 RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", |
329 meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear", | 329 meth_act == &Method::set_breakpoint ? "sett" : "clear", |
330 method->name()->as_C_string(), | 330 method->name()->as_C_string(), |
331 method->signature()->as_C_string())); | 331 method->signature()->as_C_string())); |
332 assert(!method->is_obsolete(), "only EMCP methods here"); | 332 |
333 | 333 ((Method*)method()->*meth_act)(_bci); |
334 ((methodOopDesc*)method()->*meth_act)(_bci); | |
335 break; | 334 break; |
336 } | 335 } |
337 } | 336 } |
338 } | 337 } |
339 } // pvw is cleaned up | 338 } // pvw is cleaned up |
340 } // rm is cleaned up | 339 } // rm is cleaned up |
341 } | 340 } |
342 | 341 |
343 void JvmtiBreakpoint::set() { | 342 void JvmtiBreakpoint::set() { |
344 each_method_version_do(&methodOopDesc::set_breakpoint); | 343 each_method_version_do(&Method::set_breakpoint); |
345 } | 344 } |
346 | 345 |
347 void JvmtiBreakpoint::clear() { | 346 void JvmtiBreakpoint::clear() { |
348 each_method_version_do(&methodOopDesc::clear_breakpoint); | 347 each_method_version_do(&Method::clear_breakpoint); |
349 } | 348 } |
350 | 349 |
351 void JvmtiBreakpoint::print() { | 350 void JvmtiBreakpoint::print() { |
352 #ifndef PRODUCT | 351 #ifndef PRODUCT |
353 const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); | 352 const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); |
474 VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); | 473 VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); |
475 VMThread::execute(&clear_breakpoint); | 474 VMThread::execute(&clear_breakpoint); |
476 return JVMTI_ERROR_NONE; | 475 return JVMTI_ERROR_NONE; |
477 } | 476 } |
478 | 477 |
479 void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) { | 478 void JvmtiBreakpoints::clearall_in_class_at_safepoint(Klass* klass) { |
480 bool changed = true; | 479 bool changed = true; |
481 // We are going to run thru the list of bkpts | 480 // We are going to run thru the list of bkpts |
482 // and delete some. This deletion probably alters | 481 // and delete some. This deletion probably alters |
483 // the list in some implementation defined way such | 482 // the list in some implementation defined way such |
484 // that when we delete entry i, the next entry might | 483 // that when we delete entry i, the next entry might |
645 if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym) { | 644 if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym) { |
646 return true; | 645 return true; |
647 } | 646 } |
648 } | 647 } |
649 // Compare secondary supers | 648 // Compare secondary supers |
650 objArrayOop sec_supers = klass->secondary_supers(); | 649 Array<Klass*>* sec_supers = klass->secondary_supers(); |
651 for (idx = 0; idx < sec_supers->length(); idx++) { | 650 for (idx = 0; idx < sec_supers->length(); idx++) { |
652 if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym) { | 651 if (Klass::cast((Klass*) sec_supers->at(idx))->name() == ty_sym) { |
653 return true; | 652 return true; |
654 } | 653 } |
655 } | 654 } |
656 return false; | 655 return false; |
657 } | 656 } |
660 // JVMTI_ERROR_INVALID_SLOT | 659 // JVMTI_ERROR_INVALID_SLOT |
661 // JVMTI_ERROR_TYPE_MISMATCH | 660 // JVMTI_ERROR_TYPE_MISMATCH |
662 // Returns: 'true' - everything is Ok, 'false' - error code | 661 // Returns: 'true' - everything is Ok, 'false' - error code |
663 | 662 |
664 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { | 663 bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { |
665 methodOop method_oop = jvf->method(); | 664 Method* method_oop = jvf->method(); |
666 if (!method_oop->has_localvariable_table()) { | 665 if (!method_oop->has_localvariable_table()) { |
667 // Just to check index boundaries | 666 // Just to check index boundaries |
668 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; | 667 jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; |
669 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { | 668 if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { |
670 _result = JVMTI_ERROR_INVALID_SLOT; | 669 _result = JVMTI_ERROR_INVALID_SLOT; |