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;