1 /*
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.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
112 // a shared class. We do the remap during the doit() phase of
113 // the safepoint to be safer.
114 if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
115 RC_TRACE_WITH_THREAD(0x00000001, thread,
116 ("failed to remap shared readonly space to readwrite, private"));
117 _res = JVMTI_ERROR_INTERNAL;
118 return;
119 }
120 }
121
122 for (int i = 0; i < _class_count; i++) {
123 redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
124 }
125 // Disable any dependent concurrent compilations
126 SystemDictionary::notice_modification();
127
128 // Set flag indicating that some invariants are no longer true.
129 // See jvmtiExport.hpp for detailed explanation.
130 JvmtiExport::set_has_redefined_a_class();
131
132 #ifdef ASSERT
133 SystemDictionary::classes_do(check_class, thread);
134 #endif
135 }
136
137 void VM_RedefineClasses::doit_epilogue() {
138 // Free os::malloc allocated memory.
139 // The memory allocated in redefine will be free'ed in next VM operation.
140 os::free(_scratch_classes);
141
142 if (RC_TRACE_ENABLED(0x00000004)) {
143 // Used to have separate timers for "doit" and "all", but the timer
144 // overhead skewed the measurements.
145 jlong doit_time = _timer_rsc_phase1.milliseconds() +
146 _timer_rsc_phase2.milliseconds();
147 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
148
149 RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
150 " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time,
151 _timer_vm_op_prologue.milliseconds(), doit_time));
152 RC_TRACE(0x00000004,
153 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT,
3351 int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3352 java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3353
3354 if (class_oop != _the_class_oop) {
3355 // _the_class_oop count is printed at end of redefine_single_class()
3356 RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3357 ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3358 }
3359
3360 for (Klass *subk = ik->subklass(); subk != NULL;
3361 subk = subk->next_sibling()) {
3362 if (subk->oop_is_instance()) {
3363 // Only update instanceKlasses
3364 instanceKlass *subik = (instanceKlass*)subk;
3365 // recursively do subclasses of the current subclass
3366 increment_class_counter(subik, THREAD);
3367 }
3368 }
3369 }
3370
3371 #ifndef PRODUCT
3372 void VM_RedefineClasses::check_class(klassOop k_oop,
3373 oop initiating_loader, TRAPS) {
3374 Klass *k = k_oop->klass_part();
3375 if (k->oop_is_instance()) {
3376 HandleMark hm(THREAD);
3377 instanceKlass *ik = (instanceKlass *) k;
3378
3379 if (ik->vtable_length() > 0) {
3380 ResourceMark rm(THREAD);
3381 if (!ik->vtable()->check_no_old_entries()) {
3382 tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name());
3383 ik->vtable()->dump_vtable();
3384 dump_methods();
3385 assert(false, "OLD method found");
3386 }
3387 }
3388 }
3389 }
3390
3391 void VM_RedefineClasses::dump_methods() {
3392 int j;
3393 tty->print_cr("_old_methods --");
3394 for (j = 0; j < _old_methods->length(); ++j) {
3395 methodOop m = (methodOop) _old_methods->obj_at(j);
3396 tty->print("%4d (%5d) ", j, m->vtable_index());
3397 m->access_flags().print_on(tty);
3398 tty->print(" -- ");
3399 m->print_name(tty);
3400 tty->cr();
3401 }
3402 tty->print_cr("_new_methods --");
3403 for (j = 0; j < _new_methods->length(); ++j) {
3404 methodOop m = (methodOop) _new_methods->obj_at(j);
3405 tty->print("%4d (%5d) ", j, m->vtable_index());
3406 m->access_flags().print_on(tty);
3407 tty->print(" -- ");
3408 m->print_name(tty);
3409 tty->cr();
3410 }
3411 tty->print_cr("_matching_(old/new)_methods --");
3412 for (j = 0; j < _matching_methods_length; ++j) {
3413 methodOop m = _matching_old_methods[j];
3414 tty->print("%4d (%5d) ", j, m->vtable_index());
3415 m->access_flags().print_on(tty);
3416 tty->print(" -- ");
3417 m->print_name(tty);
3418 tty->cr();
3419 m = _matching_new_methods[j];
3420 tty->print(" (%5d) ", m->vtable_index());
3421 m->access_flags().print_on(tty);
3422 tty->cr();
3423 }
3424 tty->print_cr("_deleted_methods --");
3425 for (j = 0; j < _deleted_methods_length; ++j) {
3426 methodOop m = _deleted_methods[j];
3427 tty->print("%4d (%5d) ", j, m->vtable_index());
3428 m->access_flags().print_on(tty);
3429 tty->print(" -- ");
3430 m->print_name(tty);
3431 tty->cr();
3432 }
3433 tty->print_cr("_added_methods --");
3434 for (j = 0; j < _added_methods_length; ++j) {
3435 methodOop m = _added_methods[j];
3436 tty->print("%4d (%5d) ", j, m->vtable_index());
3437 m->access_flags().print_on(tty);
3438 tty->print(" -- ");
3439 m->print_name(tty);
3440 tty->cr();
3441 }
3442 }
3443 #endif
|
1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
112 // a shared class. We do the remap during the doit() phase of
113 // the safepoint to be safer.
114 if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
115 RC_TRACE_WITH_THREAD(0x00000001, thread,
116 ("failed to remap shared readonly space to readwrite, private"));
117 _res = JVMTI_ERROR_INTERNAL;
118 return;
119 }
120 }
121
122 for (int i = 0; i < _class_count; i++) {
123 redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
124 }
125 // Disable any dependent concurrent compilations
126 SystemDictionary::notice_modification();
127
128 // Set flag indicating that some invariants are no longer true.
129 // See jvmtiExport.hpp for detailed explanation.
130 JvmtiExport::set_has_redefined_a_class();
131
132 // check_class() is optionally called for product bits, but is
133 // always called for non-product bits.
134 #ifdef PRODUCT
135 if (RC_TRACE_ENABLED(0x00004000)) {
136 #endif
137 RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class"));
138 SystemDictionary::classes_do(check_class, thread);
139 #ifdef PRODUCT
140 }
141 #endif
142 }
143
144 void VM_RedefineClasses::doit_epilogue() {
145 // Free os::malloc allocated memory.
146 // The memory allocated in redefine will be free'ed in next VM operation.
147 os::free(_scratch_classes);
148
149 if (RC_TRACE_ENABLED(0x00000004)) {
150 // Used to have separate timers for "doit" and "all", but the timer
151 // overhead skewed the measurements.
152 jlong doit_time = _timer_rsc_phase1.milliseconds() +
153 _timer_rsc_phase2.milliseconds();
154 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
155
156 RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
157 " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time,
158 _timer_vm_op_prologue.milliseconds(), doit_time));
159 RC_TRACE(0x00000004,
160 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT,
3358 int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
3359 java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
3360
3361 if (class_oop != _the_class_oop) {
3362 // _the_class_oop count is printed at end of redefine_single_class()
3363 RC_TRACE_WITH_THREAD(0x00000008, THREAD,
3364 ("updated count in subclass=%s to %d", ik->external_name(), new_count));
3365 }
3366
3367 for (Klass *subk = ik->subklass(); subk != NULL;
3368 subk = subk->next_sibling()) {
3369 if (subk->oop_is_instance()) {
3370 // Only update instanceKlasses
3371 instanceKlass *subik = (instanceKlass*)subk;
3372 // recursively do subclasses of the current subclass
3373 increment_class_counter(subik, THREAD);
3374 }
3375 }
3376 }
3377
3378 void VM_RedefineClasses::check_class(klassOop k_oop,
3379 oop initiating_loader, TRAPS) {
3380 Klass *k = k_oop->klass_part();
3381 if (k->oop_is_instance()) {
3382 HandleMark hm(THREAD);
3383 instanceKlass *ik = (instanceKlass *) k;
3384 bool no_old_methods = true; // be optimistic
3385 ResourceMark rm(THREAD);
3386
3387 // a vtable should never contain old or obsolete methods
3388 if (ik->vtable_length() > 0 &&
3389 !ik->vtable()->check_no_old_or_obsolete_entries()) {
3390 if (RC_TRACE_ENABLED(0x00004000)) {
3391 RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3392 ("klassVtable::check_no_old_or_obsolete_entries failure"
3393 " -- OLD or OBSOLETE method found -- class: %s",
3394 ik->signature_name()));
3395 ik->vtable()->dump_vtable();
3396 }
3397 no_old_methods = false;
3398 }
3399
3400 // an itable should never contain old or obsolete methods
3401 if (ik->itable_length() > 0 &&
3402 !ik->itable()->check_no_old_or_obsolete_entries()) {
3403 if (RC_TRACE_ENABLED(0x00004000)) {
3404 RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3405 ("klassItable::check_no_old_or_obsolete_entries failure"
3406 " -- OLD or OBSOLETE method found -- class: %s",
3407 ik->signature_name()));
3408 ik->itable()->dump_itable();
3409 }
3410 no_old_methods = false;
3411 }
3412
3413 // the constant pool cache should never contain old or obsolete methods
3414 if (ik->constants() != NULL &&
3415 ik->constants()->cache() != NULL &&
3416 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
3417 if (RC_TRACE_ENABLED(0x00004000)) {
3418 RC_TRACE_WITH_THREAD(0x00004000, THREAD,
3419 ("cp-cache::check_no_old_or_obsolete_entries failure"
3420 " -- OLD or OBSOLETE method found -- class: %s",
3421 ik->signature_name()));
3422 ik->constants()->cache()->dump_cache();
3423 }
3424 no_old_methods = false;
3425 }
3426
3427 if (!no_old_methods) {
3428 if (RC_TRACE_ENABLED(0x00004000)) {
3429 dump_methods();
3430 } else {
3431 tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option "
3432 "to see more info about the following guarantee() failure.");
3433 }
3434 guarantee(false, "OLD and/or OBSOLETE method(s) found");
3435 }
3436 }
3437 }
3438
3439 void VM_RedefineClasses::dump_methods() {
3440 int j;
3441 RC_TRACE(0x00004000, ("_old_methods --"));
3442 for (j = 0; j < _old_methods->length(); ++j) {
3443 methodOop m = (methodOop) _old_methods->obj_at(j);
3444 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
3445 m->access_flags().print_on(tty);
3446 tty->print(" -- ");
3447 m->print_name(tty);
3448 tty->cr();
3449 }
3450 RC_TRACE(0x00004000, ("_new_methods --"));
3451 for (j = 0; j < _new_methods->length(); ++j) {
3452 methodOop m = (methodOop) _new_methods->obj_at(j);
3453 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
3454 m->access_flags().print_on(tty);
3455 tty->print(" -- ");
3456 m->print_name(tty);
3457 tty->cr();
3458 }
3459 RC_TRACE(0x00004000, ("_matching_(old/new)_methods --"));
3460 for (j = 0; j < _matching_methods_length; ++j) {
3461 methodOop m = _matching_old_methods[j];
3462 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
3463 m->access_flags().print_on(tty);
3464 tty->print(" -- ");
3465 m->print_name(tty);
3466 tty->cr();
3467 m = _matching_new_methods[j];
3468 RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index()));
3469 m->access_flags().print_on(tty);
3470 tty->cr();
3471 }
3472 RC_TRACE(0x00004000, ("_deleted_methods --"));
3473 for (j = 0; j < _deleted_methods_length; ++j) {
3474 methodOop m = _deleted_methods[j];
3475 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
3476 m->access_flags().print_on(tty);
3477 tty->print(" -- ");
3478 m->print_name(tty);
3479 tty->cr();
3480 }
3481 RC_TRACE(0x00004000, ("_added_methods --"));
3482 for (j = 0; j < _added_methods_length; ++j) {
3483 methodOop m = _added_methods[j];
3484 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index()));
3485 m->access_flags().print_on(tty);
3486 tty->print(" -- ");
3487 m->print_name(tty);
3488 tty->cr();
3489 }
3490 }
|