90 // start_index Start index to the user-supplied buffers. 91 // frames_array Buffer to store Class or StackFrame in, starting at start_index. 92 // frames array is a Class<?>[] array when only getting caller 93 // reference, and a StackFrameInfo[] array (or derivative) 94 // otherwise. It should never be null. 95 // end_index End index to the user-supplied buffers with unpacked frames. 96 // 97 // Returns the number of frames whose information was transferred into the buffers. 98 // 99 int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, 100 int max_nframes, int start_index, 101 objArrayHandle frames_array, 102 int& end_index, TRAPS) { 103 if (TraceStackWalk) { 104 tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d", 105 max_nframes, start_index, frames_array->length()); 106 } 107 assert(max_nframes > 0, "invalid max_nframes"); 108 assert(start_index + max_nframes <= frames_array->length(), "oob"); 109 110 int frames_decoded = 0; 111 for (; !stream.at_end(); stream.next()) { 112 Method* method = stream.method(); 113 int bci = stream.bci(); 114 115 if (method == NULL) continue; 116 if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) { 117 if (method->is_hidden()) { 118 if (TraceStackWalk) { 119 tty->print(" hidden method: "); method->print_short_name(); 120 tty->print("\n"); 121 } 122 continue; 123 } 124 } 125 126 int index = end_index++; 127 if (TraceStackWalk) { 128 tty->print(" %d: frame method: ", index); method->print_short_name(); 129 tty->print_cr(" bci=%d", bci); 130 } 131 132 // fill in StackFrameInfo and initialize MemberName 133 if (live_frame_info(mode)) { 134 assert (use_frames_array(mode), "Bad mode for get live frame"); 135 Handle stackFrame(frames_array->obj_at(index)); 136 fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0); 137 } else if (need_method_info(mode)) { 138 assert (use_frames_array(mode), "Bad mode for get stack frame"); 139 Handle stackFrame(frames_array->obj_at(index)); 140 fill_stackframe(stackFrame, method, bci); 141 } else { 142 assert (use_frames_array(mode) == false, "Bad mode for get caller class"); 143 frames_array->obj_at_put(index, method->method_holder()->java_mirror()); 144 } 145 if (++frames_decoded >= max_nframes) break; 146 } 147 return frames_decoded; 148 } 149 150 static oop create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) { 151 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_LiveStackFrameInfo(), CHECK_NULL); 152 instanceKlassHandle ik (THREAD, k); 153 154 JavaValue result(T_OBJECT); 155 JavaCallArguments args; 156 Symbol* signature = NULL; 157 158 // ## TODO: type is only available in LocalVariable table, if present. 159 // ## StackValue type is T_INT or T_OBJECT. 160 switch (values->at(i)->type()) { 161 case T_INT: 162 args.push_int(values->int_at(i)); 163 signature = vmSymbols::asPrimitive_int_signature(); | 90 // start_index Start index to the user-supplied buffers. 91 // frames_array Buffer to store Class or StackFrame in, starting at start_index. 92 // frames array is a Class<?>[] array when only getting caller 93 // reference, and a StackFrameInfo[] array (or derivative) 94 // otherwise. It should never be null. 95 // end_index End index to the user-supplied buffers with unpacked frames. 96 // 97 // Returns the number of frames whose information was transferred into the buffers. 98 // 99 int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream, 100 int max_nframes, int start_index, 101 objArrayHandle frames_array, 102 int& end_index, TRAPS) { 103 if (TraceStackWalk) { 104 tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d", 105 max_nframes, start_index, frames_array->length()); 106 } 107 assert(max_nframes > 0, "invalid max_nframes"); 108 assert(start_index + max_nframes <= frames_array->length(), "oob"); 109 110 Method* caller_sensitive_method = NULL; 111 112 int frames_decoded = 0; 113 for (; !stream.at_end(); stream.next()) { 114 Method* method = stream.method(); 115 int bci = stream.bci(); 116 117 if (method == NULL) continue; 118 119 if (caller_sensitive_method != NULL) { 120 // JVM_GetCallerClass may return a hidden method 121 // StackWalker::getCallerClass should return the same caller as JVM_GetCallerClass 122 // even the jdk implementation does not use it for performance reason 123 if (method->is_ignored_by_security_stack_walk()) continue; 124 } else { 125 // filter hidden frames 126 if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) { 127 if (method->is_hidden()) { 128 if (TraceStackWalk) { 129 tty->print(" hidden method: "); method->print_short_name(); 130 tty->print("\n"); 131 } 132 continue; 133 } 134 } 135 } 136 137 int index = end_index++; 138 if (TraceStackWalk) { 139 tty->print(" %d: frame method: ", index); method->print_short_name(); 140 tty->print_cr(" bci=%d", bci); 141 } 142 143 // fill in StackFrameInfo and initialize MemberName 144 if (live_frame_info(mode)) { 145 assert (use_frames_array(mode), "Bad mode for get live frame"); 146 Handle stackFrame(frames_array->obj_at(index)); 147 fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0); 148 } else if (need_method_info(mode)) { 149 assert (use_frames_array(mode), "Bad mode for get stack frame"); 150 Handle stackFrame(frames_array->obj_at(index)); 151 fill_stackframe(stackFrame, method, bci); 152 } else { 153 assert (use_frames_array(mode) == false, "Bad mode for get caller class"); 154 frames_array->obj_at_put(index, method->method_holder()->java_mirror()); 155 if (StackWalk::get_caller_class(mode) && 156 caller_sensitive_method == NULL && method->caller_sensitive()) { 157 caller_sensitive_method = method; 158 } 159 } 160 if (++frames_decoded >= max_nframes) break; 161 } 162 return frames_decoded; 163 } 164 165 static oop create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) { 166 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_LiveStackFrameInfo(), CHECK_NULL); 167 instanceKlassHandle ik (THREAD, k); 168 169 JavaValue result(T_OBJECT); 170 JavaCallArguments args; 171 Symbol* signature = NULL; 172 173 // ## TODO: type is only available in LocalVariable table, if present. 174 // ## StackValue type is T_INT or T_OBJECT. 175 switch (values->at(i)->type()) { 176 case T_INT: 177 args.push_int(values->int_at(i)); 178 signature = vmSymbols::asPrimitive_int_signature(); |