void Rewriter::relocate_and_link(instanceKlassHandle this_oop, objArrayHandle methods, TRAPS) { int len = methods->length(); for (int i = len-1; i >= 0; i--) { methodHandle m(THREAD, (methodOop)methods->obj_at(i)); if (m->has_jsrs()) { m = rewrite_jsrs(m, CHECK); // Method might have gotten rewritten. methods->obj_at_put(i, m()); } // Set up method entry points for compiler and interpreter . m->link_method(m, CHECK); // This is for JVMTI and unrelated to relocator but the last thing we do #ifdef ASSERT if (StressMethodComparator) { static int nmc = 0; for (int j = i; j >= 0 && j >= i-4; j--) { if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); bool z = MethodComparator::methods_EMCP(m(), (methodOop)methods->obj_at(j)); if (j == i && !z) { tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); assert(z, "method must compare equal to itself"); } } } #endif //ASSERT } }
// Fill in the StackFrameInfo at the given index in frames_array void JavaFrameStream::fill_frame(int index, objArrayHandle frames_array, const methodHandle& method, TRAPS) { if (_need_method_info) { Handle stackFrame(THREAD, frames_array->obj_at(index)); fill_stackframe(stackFrame, method); } else { frames_array->obj_at_put(index, method->method_holder()->java_mirror()); } }
// Unpacks one or more frames into user-supplied buffers. // Updates the end index, and returns the number of unpacked frames. // Always start with the existing vfst.method and bci. // Do not call vfst.next to advance over the last returned value. // In other words, do not leave any stale data in the vfst. // // Parameters: // mode Restrict which frames to be decoded. // JavaFrameStream stream of javaVFrames // max_nframes Maximum number of frames to be filled. // start_index Start index to the user-supplied buffers. // frames_array Buffer to store Class or StackFrame in, starting at start_index. // frames array is a Class<?>[] array when only getting caller // reference, and a StackFrameInfo[] array (or derivative) // otherwise. It should never be null. // end_index End index to the user-supplied buffers with unpacked frames. // // Returns the number of frames whose information was transferred into the buffers. // int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, int max_nframes, int start_index, objArrayHandle frames_array, int& end_index, TRAPS) { if (TraceStackWalk) { tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d", max_nframes, start_index, frames_array->length()); } assert(max_nframes > 0, "invalid max_nframes"); assert(start_index + max_nframes <= frames_array->length(), "oob"); int frames_decoded = 0; for (; !stream.at_end(); stream.next()) { Method* method = stream.method(); int bci = stream.bci(); if (method == NULL) continue; if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) { if (method->is_hidden()) { if (TraceStackWalk) { tty->print(" hidden method: "); method->print_short_name(); tty->print("\n"); } continue; } } int index = end_index++; if (TraceStackWalk) { tty->print(" %d: frame method: ", index); method->print_short_name(); tty->print_cr(" bci=%d", bci); } // fill in StackFrameInfo and initialize MemberName if (live_frame_info(mode)) { assert (use_frames_array(mode), "Bad mode for get live frame"); Handle stackFrame(frames_array->obj_at(index)); fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0); } else if (need_method_info(mode)) { assert (use_frames_array(mode), "Bad mode for get stack frame"); Handle stackFrame(frames_array->obj_at(index)); fill_stackframe(stackFrame, method, bci); } else { assert (use_frames_array(mode) == false, "Bad mode for get caller class"); frames_array->obj_at_put(index, method->method_holder()->java_mirror()); } if (++frames_decoded >= max_nframes) break; } return frames_decoded; }
void JavaAssertions::fillJavaArrays(const OptionList* p, int len, objArrayHandle names, typeArrayHandle enabled, TRAPS) { // Fill in the parallel names and enabled (boolean) arrays. Start at the end // of the array and work backwards, so the order of items in the arrays // matches the order on the command line (the list is in reverse order, since // it was created by prepending successive items from the command line). int index; for (index = len - 1; p != 0; p = p->next(), --index) { assert(index >= 0, "length does not match list"); Handle s = java_lang_String::create_from_str(p->name(), CHECK); s = java_lang_String::char_converter(s, '/', '.', CHECK); names->obj_at_put(index, s()); enabled->bool_at_put(index, p->enabled()); } assert(index == -1, "length does not match list"); }
bool BaseFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) { bool ok = check_magic(frames_array); frames_array->obj_at_put(magic_pos, NULL); _anchor = 0L; return ok; }
// setup and cleanup actions void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) { frames_array->obj_at_put(magic_pos, _thread->threadObj()); _anchor = address_value(); assert(check_magic(frames_array), "invalid magic"); }
bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) { bool ok = check_magic(classes_array); classes_array->obj_at_put(magic_pos, NULL); _anchor = 0L; return ok; }
// setup and cleanup actions void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) { classes_array->obj_at_put(magic_pos, _thread->threadObj()); _anchor = address_value(); assert(check_magic(classes_array), "invalid magic"); }