Sun, 10 Feb 2013 22:35:38 -0800
8006430: TraceTypeProfile is a product flag while it should be a diagnostic flag
Summary: make sure all diagnostic and experimental flag kinds are checked in Flag::is_unlocked()
Reviewed-by: kvn
duke@435 | 1 | /* |
bdelsart@3433 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #include "precompiled.hpp" |
twisti@4318 | 26 | #include "compiler/disassembler.hpp" |
stefank@2314 | 27 | #include "gc_interface/collectedHeap.inline.hpp" |
stefank@2314 | 28 | #include "interpreter/interpreter.hpp" |
stefank@2314 | 29 | #include "interpreter/oopMapCache.hpp" |
stefank@2314 | 30 | #include "memory/resourceArea.hpp" |
stefank@2314 | 31 | #include "memory/universe.inline.hpp" |
stefank@2314 | 32 | #include "oops/markOop.hpp" |
coleenp@4037 | 33 | #include "oops/methodData.hpp" |
coleenp@4037 | 34 | #include "oops/method.hpp" |
stefank@2314 | 35 | #include "oops/oop.inline.hpp" |
stefank@2314 | 36 | #include "oops/oop.inline2.hpp" |
never@2895 | 37 | #include "prims/methodHandles.hpp" |
stefank@2314 | 38 | #include "runtime/frame.inline.hpp" |
stefank@2314 | 39 | #include "runtime/handles.inline.hpp" |
stefank@2314 | 40 | #include "runtime/javaCalls.hpp" |
stefank@2314 | 41 | #include "runtime/monitorChunk.hpp" |
stefank@2314 | 42 | #include "runtime/sharedRuntime.hpp" |
stefank@2314 | 43 | #include "runtime/signature.hpp" |
stefank@2314 | 44 | #include "runtime/stubCodeGenerator.hpp" |
stefank@2314 | 45 | #include "runtime/stubRoutines.hpp" |
zgu@2364 | 46 | #include "utilities/decoder.hpp" |
zgu@2364 | 47 | |
stefank@2314 | 48 | #ifdef TARGET_ARCH_x86 |
stefank@2314 | 49 | # include "nativeInst_x86.hpp" |
stefank@2314 | 50 | #endif |
stefank@2314 | 51 | #ifdef TARGET_ARCH_sparc |
stefank@2314 | 52 | # include "nativeInst_sparc.hpp" |
stefank@2314 | 53 | #endif |
stefank@2314 | 54 | #ifdef TARGET_ARCH_zero |
stefank@2314 | 55 | # include "nativeInst_zero.hpp" |
stefank@2314 | 56 | #endif |
bobv@2508 | 57 | #ifdef TARGET_ARCH_arm |
bobv@2508 | 58 | # include "nativeInst_arm.hpp" |
bobv@2508 | 59 | #endif |
bobv@2508 | 60 | #ifdef TARGET_ARCH_ppc |
bobv@2508 | 61 | # include "nativeInst_ppc.hpp" |
bobv@2508 | 62 | #endif |
duke@435 | 63 | |
duke@435 | 64 | RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { |
duke@435 | 65 | _thread = thread; |
duke@435 | 66 | _update_map = update_map; |
duke@435 | 67 | clear(); |
duke@435 | 68 | debug_only(_update_for_id = NULL;) |
duke@435 | 69 | #ifndef PRODUCT |
duke@435 | 70 | for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL; |
duke@435 | 71 | #endif /* PRODUCT */ |
duke@435 | 72 | } |
duke@435 | 73 | |
duke@435 | 74 | RegisterMap::RegisterMap(const RegisterMap* map) { |
duke@435 | 75 | assert(map != this, "bad initialization parameter"); |
duke@435 | 76 | assert(map != NULL, "RegisterMap must be present"); |
duke@435 | 77 | _thread = map->thread(); |
duke@435 | 78 | _update_map = map->update_map(); |
duke@435 | 79 | _include_argument_oops = map->include_argument_oops(); |
duke@435 | 80 | debug_only(_update_for_id = map->_update_for_id;) |
duke@435 | 81 | pd_initialize_from(map); |
duke@435 | 82 | if (update_map()) { |
duke@435 | 83 | for(int i = 0; i < location_valid_size; i++) { |
duke@435 | 84 | LocationValidType bits = !update_map() ? 0 : map->_location_valid[i]; |
duke@435 | 85 | _location_valid[i] = bits; |
duke@435 | 86 | // for whichever bits are set, pull in the corresponding map->_location |
duke@435 | 87 | int j = i*location_valid_type_size; |
duke@435 | 88 | while (bits != 0) { |
duke@435 | 89 | if ((bits & 1) != 0) { |
duke@435 | 90 | assert(0 <= j && j < reg_count, "range check"); |
duke@435 | 91 | _location[j] = map->_location[j]; |
duke@435 | 92 | } |
duke@435 | 93 | bits >>= 1; |
duke@435 | 94 | j += 1; |
duke@435 | 95 | } |
duke@435 | 96 | } |
duke@435 | 97 | } |
duke@435 | 98 | } |
duke@435 | 99 | |
duke@435 | 100 | void RegisterMap::clear() { |
duke@435 | 101 | set_include_argument_oops(true); |
duke@435 | 102 | if (_update_map) { |
duke@435 | 103 | for(int i = 0; i < location_valid_size; i++) { |
duke@435 | 104 | _location_valid[i] = 0; |
duke@435 | 105 | } |
duke@435 | 106 | pd_clear(); |
duke@435 | 107 | } else { |
duke@435 | 108 | pd_initialize(); |
duke@435 | 109 | } |
duke@435 | 110 | } |
duke@435 | 111 | |
duke@435 | 112 | #ifndef PRODUCT |
duke@435 | 113 | |
duke@435 | 114 | void RegisterMap::print_on(outputStream* st) const { |
duke@435 | 115 | st->print_cr("Register map"); |
duke@435 | 116 | for(int i = 0; i < reg_count; i++) { |
duke@435 | 117 | |
duke@435 | 118 | VMReg r = VMRegImpl::as_VMReg(i); |
duke@435 | 119 | intptr_t* src = (intptr_t*) location(r); |
duke@435 | 120 | if (src != NULL) { |
duke@435 | 121 | |
never@852 | 122 | r->print_on(st); |
never@852 | 123 | st->print(" [" INTPTR_FORMAT "] = ", src); |
duke@435 | 124 | if (((uintptr_t)src & (sizeof(*src)-1)) != 0) { |
never@852 | 125 | st->print_cr("<misaligned>"); |
duke@435 | 126 | } else { |
never@852 | 127 | st->print_cr(INTPTR_FORMAT, *src); |
duke@435 | 128 | } |
duke@435 | 129 | } |
duke@435 | 130 | } |
duke@435 | 131 | } |
duke@435 | 132 | |
duke@435 | 133 | void RegisterMap::print() const { |
duke@435 | 134 | print_on(tty); |
duke@435 | 135 | } |
duke@435 | 136 | |
duke@435 | 137 | #endif |
duke@435 | 138 | // This returns the pc that if you were in the debugger you'd see. Not |
duke@435 | 139 | // the idealized value in the frame object. This undoes the magic conversion |
duke@435 | 140 | // that happens for deoptimized frames. In addition it makes the value the |
duke@435 | 141 | // hardware would want to see in the native frame. The only user (at this point) |
duke@435 | 142 | // is deoptimization. It likely no one else should ever use it. |
duke@435 | 143 | |
duke@435 | 144 | address frame::raw_pc() const { |
duke@435 | 145 | if (is_deoptimized_frame()) { |
twisti@1639 | 146 | nmethod* nm = cb()->as_nmethod_or_null(); |
twisti@1639 | 147 | if (nm->is_method_handle_return(pc())) |
twisti@1639 | 148 | return nm->deopt_mh_handler_begin() - pc_return_offset; |
twisti@1639 | 149 | else |
twisti@1639 | 150 | return nm->deopt_handler_begin() - pc_return_offset; |
duke@435 | 151 | } else { |
duke@435 | 152 | return (pc() - pc_return_offset); |
duke@435 | 153 | } |
duke@435 | 154 | } |
duke@435 | 155 | |
duke@435 | 156 | // Change the pc in a frame object. This does not change the actual pc in |
duke@435 | 157 | // actual frame. To do that use patch_pc. |
duke@435 | 158 | // |
duke@435 | 159 | void frame::set_pc(address newpc ) { |
duke@435 | 160 | #ifdef ASSERT |
duke@435 | 161 | if (_cb != NULL && _cb->is_nmethod()) { |
duke@435 | 162 | assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation"); |
duke@435 | 163 | } |
duke@435 | 164 | #endif // ASSERT |
duke@435 | 165 | |
duke@435 | 166 | // Unsafe to use the is_deoptimzed tester after changing pc |
duke@435 | 167 | _deopt_state = unknown; |
duke@435 | 168 | _pc = newpc; |
duke@435 | 169 | _cb = CodeCache::find_blob_unsafe(_pc); |
duke@435 | 170 | |
duke@435 | 171 | } |
duke@435 | 172 | |
duke@435 | 173 | // type testers |
twisti@3969 | 174 | bool frame::is_ignored_frame() const { |
twisti@3969 | 175 | return false; // FIXME: some LambdaForm frames should be ignored |
never@2895 | 176 | } |
duke@435 | 177 | bool frame::is_deoptimized_frame() const { |
duke@435 | 178 | assert(_deopt_state != unknown, "not answerable"); |
duke@435 | 179 | return _deopt_state == is_deoptimized; |
duke@435 | 180 | } |
duke@435 | 181 | |
duke@435 | 182 | bool frame::is_native_frame() const { |
duke@435 | 183 | return (_cb != NULL && |
duke@435 | 184 | _cb->is_nmethod() && |
duke@435 | 185 | ((nmethod*)_cb)->is_native_method()); |
duke@435 | 186 | } |
duke@435 | 187 | |
duke@435 | 188 | bool frame::is_java_frame() const { |
duke@435 | 189 | if (is_interpreted_frame()) return true; |
duke@435 | 190 | if (is_compiled_frame()) return true; |
duke@435 | 191 | return false; |
duke@435 | 192 | } |
duke@435 | 193 | |
duke@435 | 194 | |
duke@435 | 195 | bool frame::is_compiled_frame() const { |
duke@435 | 196 | if (_cb != NULL && |
duke@435 | 197 | _cb->is_nmethod() && |
duke@435 | 198 | ((nmethod*)_cb)->is_java_method()) { |
duke@435 | 199 | return true; |
duke@435 | 200 | } |
duke@435 | 201 | return false; |
duke@435 | 202 | } |
duke@435 | 203 | |
duke@435 | 204 | |
duke@435 | 205 | bool frame::is_runtime_frame() const { |
duke@435 | 206 | return (_cb != NULL && _cb->is_runtime_stub()); |
duke@435 | 207 | } |
duke@435 | 208 | |
duke@435 | 209 | bool frame::is_safepoint_blob_frame() const { |
duke@435 | 210 | return (_cb != NULL && _cb->is_safepoint_stub()); |
duke@435 | 211 | } |
duke@435 | 212 | |
duke@435 | 213 | // testers |
duke@435 | 214 | |
duke@435 | 215 | bool frame::is_first_java_frame() const { |
duke@435 | 216 | RegisterMap map(JavaThread::current(), false); // No update |
duke@435 | 217 | frame s; |
duke@435 | 218 | for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)); |
duke@435 | 219 | return s.is_first_frame(); |
duke@435 | 220 | } |
duke@435 | 221 | |
duke@435 | 222 | |
duke@435 | 223 | bool frame::entry_frame_is_first() const { |
duke@435 | 224 | return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL; |
duke@435 | 225 | } |
duke@435 | 226 | |
duke@435 | 227 | |
duke@435 | 228 | bool frame::should_be_deoptimized() const { |
duke@435 | 229 | if (_deopt_state == is_deoptimized || |
duke@435 | 230 | !is_compiled_frame() ) return false; |
duke@435 | 231 | assert(_cb != NULL && _cb->is_nmethod(), "must be an nmethod"); |
duke@435 | 232 | nmethod* nm = (nmethod *)_cb; |
duke@435 | 233 | if (TraceDependencies) { |
duke@435 | 234 | tty->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false"); |
duke@435 | 235 | nm->print_value_on(tty); |
duke@435 | 236 | tty->cr(); |
duke@435 | 237 | } |
duke@435 | 238 | |
duke@435 | 239 | if( !nm->is_marked_for_deoptimization() ) |
duke@435 | 240 | return false; |
duke@435 | 241 | |
duke@435 | 242 | // If at the return point, then the frame has already been popped, and |
duke@435 | 243 | // only the return needs to be executed. Don't deoptimize here. |
duke@435 | 244 | return !nm->is_at_poll_return(pc()); |
duke@435 | 245 | } |
duke@435 | 246 | |
duke@435 | 247 | bool frame::can_be_deoptimized() const { |
duke@435 | 248 | if (!is_compiled_frame()) return false; |
duke@435 | 249 | nmethod* nm = (nmethod*)_cb; |
duke@435 | 250 | |
duke@435 | 251 | if( !nm->can_be_deoptimized() ) |
duke@435 | 252 | return false; |
duke@435 | 253 | |
duke@435 | 254 | return !nm->is_at_poll_return(pc()); |
duke@435 | 255 | } |
duke@435 | 256 | |
never@2082 | 257 | void frame::deoptimize(JavaThread* thread) { |
never@2082 | 258 | // Schedule deoptimization of an nmethod activation with this frame. |
duke@435 | 259 | assert(_cb != NULL && _cb->is_nmethod(), "must be"); |
duke@435 | 260 | nmethod* nm = (nmethod*)_cb; |
duke@435 | 261 | |
duke@435 | 262 | // This is a fix for register window patching race |
never@2082 | 263 | if (NeedsDeoptSuspend && Thread::current() != thread) { |
never@2082 | 264 | assert(SafepointSynchronize::is_at_safepoint(), |
never@2082 | 265 | "patching other threads for deopt may only occur at a safepoint"); |
duke@435 | 266 | |
duke@435 | 267 | // It is possible especially with DeoptimizeALot/DeoptimizeRandom that |
duke@435 | 268 | // we could see the frame again and ask for it to be deoptimized since |
duke@435 | 269 | // it might move for a long time. That is harmless and we just ignore it. |
duke@435 | 270 | if (id() == thread->must_deopt_id()) { |
duke@435 | 271 | assert(thread->is_deopt_suspend(), "lost suspension"); |
duke@435 | 272 | return; |
duke@435 | 273 | } |
duke@435 | 274 | |
duke@435 | 275 | // We are at a safepoint so the target thread can only be |
duke@435 | 276 | // in 4 states: |
duke@435 | 277 | // blocked - no problem |
duke@435 | 278 | // blocked_trans - no problem (i.e. could have woken up from blocked |
duke@435 | 279 | // during a safepoint). |
duke@435 | 280 | // native - register window pc patching race |
duke@435 | 281 | // native_trans - momentary state |
duke@435 | 282 | // |
duke@435 | 283 | // We could just wait out a thread in native_trans to block. |
duke@435 | 284 | // Then we'd have all the issues that the safepoint code has as to |
duke@435 | 285 | // whether to spin or block. It isn't worth it. Just treat it like |
duke@435 | 286 | // native and be done with it. |
duke@435 | 287 | // |
never@2082 | 288 | // Examine the state of the thread at the start of safepoint since |
never@2082 | 289 | // threads that were in native at the start of the safepoint could |
never@2082 | 290 | // come to a halt during the safepoint, changing the current value |
never@2082 | 291 | // of the safepoint_state. |
never@2082 | 292 | JavaThreadState state = thread->safepoint_state()->orig_thread_state(); |
duke@435 | 293 | if (state == _thread_in_native || state == _thread_in_native_trans) { |
duke@435 | 294 | // Since we are at a safepoint the target thread will stop itself |
duke@435 | 295 | // before it can return to java as long as we remain at the safepoint. |
duke@435 | 296 | // Therefore we can put an additional request for the thread to stop |
duke@435 | 297 | // no matter what no (like a suspend). This will cause the thread |
duke@435 | 298 | // to notice it needs to do the deopt on its own once it leaves native. |
duke@435 | 299 | // |
duke@435 | 300 | // The only reason we must do this is because on machine with register |
duke@435 | 301 | // windows we have a race with patching the return address and the |
duke@435 | 302 | // window coming live as the thread returns to the Java code (but still |
duke@435 | 303 | // in native mode) and then blocks. It is only this top most frame |
duke@435 | 304 | // that is at risk. So in truth we could add an additional check to |
duke@435 | 305 | // see if this frame is one that is at risk. |
duke@435 | 306 | RegisterMap map(thread, false); |
duke@435 | 307 | frame at_risk = thread->last_frame().sender(&map); |
duke@435 | 308 | if (id() == at_risk.id()) { |
duke@435 | 309 | thread->set_must_deopt_id(id()); |
duke@435 | 310 | thread->set_deopt_suspend(); |
duke@435 | 311 | return; |
duke@435 | 312 | } |
duke@435 | 313 | } |
duke@435 | 314 | } // NeedsDeoptSuspend |
duke@435 | 315 | |
duke@435 | 316 | |
twisti@1639 | 317 | // If the call site is a MethodHandle call site use the MH deopt |
twisti@1639 | 318 | // handler. |
twisti@1639 | 319 | address deopt = nm->is_method_handle_return(pc()) ? |
twisti@1639 | 320 | nm->deopt_mh_handler_begin() : |
twisti@1639 | 321 | nm->deopt_handler_begin(); |
twisti@1639 | 322 | |
duke@435 | 323 | // Save the original pc before we patch in the new one |
duke@435 | 324 | nm->set_original_pc(this, pc()); |
duke@435 | 325 | patch_pc(thread, deopt); |
twisti@1639 | 326 | |
duke@435 | 327 | #ifdef ASSERT |
duke@435 | 328 | { |
duke@435 | 329 | RegisterMap map(thread, false); |
duke@435 | 330 | frame check = thread->last_frame(); |
duke@435 | 331 | while (id() != check.id()) { |
duke@435 | 332 | check = check.sender(&map); |
duke@435 | 333 | } |
duke@435 | 334 | assert(check.is_deoptimized_frame(), "missed deopt"); |
duke@435 | 335 | } |
duke@435 | 336 | #endif // ASSERT |
duke@435 | 337 | } |
duke@435 | 338 | |
duke@435 | 339 | frame frame::java_sender() const { |
duke@435 | 340 | RegisterMap map(JavaThread::current(), false); |
duke@435 | 341 | frame s; |
duke@435 | 342 | for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)) ; |
duke@435 | 343 | guarantee(s.is_java_frame(), "tried to get caller of first java frame"); |
duke@435 | 344 | return s; |
duke@435 | 345 | } |
duke@435 | 346 | |
duke@435 | 347 | frame frame::real_sender(RegisterMap* map) const { |
duke@435 | 348 | frame result = sender(map); |
never@2895 | 349 | while (result.is_runtime_frame() || |
twisti@3969 | 350 | result.is_ignored_frame()) { |
duke@435 | 351 | result = result.sender(map); |
duke@435 | 352 | } |
duke@435 | 353 | return result; |
duke@435 | 354 | } |
duke@435 | 355 | |
duke@435 | 356 | // Note: called by profiler - NOT for current thread |
duke@435 | 357 | frame frame::profile_find_Java_sender_frame(JavaThread *thread) { |
duke@435 | 358 | // If we don't recognize this frame, walk back up the stack until we do |
duke@435 | 359 | RegisterMap map(thread, false); |
duke@435 | 360 | frame first_java_frame = frame(); |
duke@435 | 361 | |
duke@435 | 362 | // Find the first Java frame on the stack starting with input frame |
duke@435 | 363 | if (is_java_frame()) { |
duke@435 | 364 | // top frame is compiled frame or deoptimized frame |
duke@435 | 365 | first_java_frame = *this; |
duke@435 | 366 | } else if (safe_for_sender(thread)) { |
duke@435 | 367 | for (frame sender_frame = sender(&map); |
duke@435 | 368 | sender_frame.safe_for_sender(thread) && !sender_frame.is_first_frame(); |
duke@435 | 369 | sender_frame = sender_frame.sender(&map)) { |
duke@435 | 370 | if (sender_frame.is_java_frame()) { |
duke@435 | 371 | first_java_frame = sender_frame; |
duke@435 | 372 | break; |
duke@435 | 373 | } |
duke@435 | 374 | } |
duke@435 | 375 | } |
duke@435 | 376 | return first_java_frame; |
duke@435 | 377 | } |
duke@435 | 378 | |
duke@435 | 379 | // Interpreter frames |
duke@435 | 380 | |
duke@435 | 381 | |
duke@435 | 382 | void frame::interpreter_frame_set_locals(intptr_t* locs) { |
duke@435 | 383 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 384 | *interpreter_frame_locals_addr() = locs; |
duke@435 | 385 | } |
duke@435 | 386 | |
coleenp@4037 | 387 | Method* frame::interpreter_frame_method() const { |
duke@435 | 388 | assert(is_interpreted_frame(), "interpreted frame expected"); |
coleenp@4037 | 389 | Method* m = *interpreter_frame_method_addr(); |
coleenp@4037 | 390 | assert(m->is_metadata(), "bad Method* in interpreter frame"); |
coleenp@4037 | 391 | assert(m->is_method(), "not a Method*"); |
duke@435 | 392 | return m; |
duke@435 | 393 | } |
duke@435 | 394 | |
coleenp@4037 | 395 | void frame::interpreter_frame_set_method(Method* method) { |
duke@435 | 396 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 397 | *interpreter_frame_method_addr() = method; |
duke@435 | 398 | } |
duke@435 | 399 | |
duke@435 | 400 | void frame::interpreter_frame_set_bcx(intptr_t bcx) { |
duke@435 | 401 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 402 | if (ProfileInterpreter) { |
duke@435 | 403 | bool formerly_bci = is_bci(interpreter_frame_bcx()); |
duke@435 | 404 | bool is_now_bci = is_bci(bcx); |
duke@435 | 405 | *interpreter_frame_bcx_addr() = bcx; |
duke@435 | 406 | |
duke@435 | 407 | intptr_t mdx = interpreter_frame_mdx(); |
duke@435 | 408 | |
duke@435 | 409 | if (mdx != 0) { |
duke@435 | 410 | if (formerly_bci) { |
duke@435 | 411 | if (!is_now_bci) { |
duke@435 | 412 | // The bcx was just converted from bci to bcp. |
duke@435 | 413 | // Convert the mdx in parallel. |
coleenp@4037 | 414 | MethodData* mdo = interpreter_frame_method()->method_data(); |
duke@435 | 415 | assert(mdo != NULL, ""); |
duke@435 | 416 | int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one. |
duke@435 | 417 | address mdp = mdo->di_to_dp(mdi); |
duke@435 | 418 | interpreter_frame_set_mdx((intptr_t)mdp); |
duke@435 | 419 | } |
duke@435 | 420 | } else { |
duke@435 | 421 | if (is_now_bci) { |
duke@435 | 422 | // The bcx was just converted from bcp to bci. |
duke@435 | 423 | // Convert the mdx in parallel. |
coleenp@4037 | 424 | MethodData* mdo = interpreter_frame_method()->method_data(); |
duke@435 | 425 | assert(mdo != NULL, ""); |
duke@435 | 426 | int mdi = mdo->dp_to_di((address)mdx); |
duke@435 | 427 | interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0. |
duke@435 | 428 | } |
duke@435 | 429 | } |
duke@435 | 430 | } |
duke@435 | 431 | } else { |
duke@435 | 432 | *interpreter_frame_bcx_addr() = bcx; |
duke@435 | 433 | } |
duke@435 | 434 | } |
duke@435 | 435 | |
duke@435 | 436 | jint frame::interpreter_frame_bci() const { |
duke@435 | 437 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 438 | intptr_t bcx = interpreter_frame_bcx(); |
duke@435 | 439 | return is_bci(bcx) ? bcx : interpreter_frame_method()->bci_from((address)bcx); |
duke@435 | 440 | } |
duke@435 | 441 | |
duke@435 | 442 | void frame::interpreter_frame_set_bci(jint bci) { |
duke@435 | 443 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 444 | assert(!is_bci(interpreter_frame_bcx()), "should not set bci during GC"); |
duke@435 | 445 | interpreter_frame_set_bcx((intptr_t)interpreter_frame_method()->bcp_from(bci)); |
duke@435 | 446 | } |
duke@435 | 447 | |
duke@435 | 448 | address frame::interpreter_frame_bcp() const { |
duke@435 | 449 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 450 | intptr_t bcx = interpreter_frame_bcx(); |
duke@435 | 451 | return is_bci(bcx) ? interpreter_frame_method()->bcp_from(bcx) : (address)bcx; |
duke@435 | 452 | } |
duke@435 | 453 | |
duke@435 | 454 | void frame::interpreter_frame_set_bcp(address bcp) { |
duke@435 | 455 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 456 | assert(!is_bci(interpreter_frame_bcx()), "should not set bcp during GC"); |
duke@435 | 457 | interpreter_frame_set_bcx((intptr_t)bcp); |
duke@435 | 458 | } |
duke@435 | 459 | |
duke@435 | 460 | void frame::interpreter_frame_set_mdx(intptr_t mdx) { |
duke@435 | 461 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 462 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 463 | *interpreter_frame_mdx_addr() = mdx; |
duke@435 | 464 | } |
duke@435 | 465 | |
duke@435 | 466 | address frame::interpreter_frame_mdp() const { |
duke@435 | 467 | assert(ProfileInterpreter, "must be profiling interpreter"); |
duke@435 | 468 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 469 | intptr_t bcx = interpreter_frame_bcx(); |
duke@435 | 470 | intptr_t mdx = interpreter_frame_mdx(); |
duke@435 | 471 | |
duke@435 | 472 | assert(!is_bci(bcx), "should not access mdp during GC"); |
duke@435 | 473 | return (address)mdx; |
duke@435 | 474 | } |
duke@435 | 475 | |
duke@435 | 476 | void frame::interpreter_frame_set_mdp(address mdp) { |
duke@435 | 477 | assert(is_interpreted_frame(), "interpreted frame expected"); |
duke@435 | 478 | if (mdp == NULL) { |
duke@435 | 479 | // Always allow the mdp to be cleared. |
duke@435 | 480 | interpreter_frame_set_mdx((intptr_t)mdp); |
duke@435 | 481 | } |
duke@435 | 482 | intptr_t bcx = interpreter_frame_bcx(); |
duke@435 | 483 | assert(!is_bci(bcx), "should not set mdp during GC"); |
duke@435 | 484 | interpreter_frame_set_mdx((intptr_t)mdp); |
duke@435 | 485 | } |
duke@435 | 486 | |
duke@435 | 487 | BasicObjectLock* frame::next_monitor_in_interpreter_frame(BasicObjectLock* current) const { |
duke@435 | 488 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 489 | #ifdef ASSERT |
duke@435 | 490 | interpreter_frame_verify_monitor(current); |
duke@435 | 491 | #endif |
duke@435 | 492 | BasicObjectLock* next = (BasicObjectLock*) (((intptr_t*) current) + interpreter_frame_monitor_size()); |
duke@435 | 493 | return next; |
duke@435 | 494 | } |
duke@435 | 495 | |
duke@435 | 496 | BasicObjectLock* frame::previous_monitor_in_interpreter_frame(BasicObjectLock* current) const { |
duke@435 | 497 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 498 | #ifdef ASSERT |
duke@435 | 499 | // // This verification needs to be checked before being enabled |
duke@435 | 500 | // interpreter_frame_verify_monitor(current); |
duke@435 | 501 | #endif |
duke@435 | 502 | BasicObjectLock* previous = (BasicObjectLock*) (((intptr_t*) current) - interpreter_frame_monitor_size()); |
duke@435 | 503 | return previous; |
duke@435 | 504 | } |
duke@435 | 505 | |
duke@435 | 506 | // Interpreter locals and expression stack locations. |
duke@435 | 507 | |
duke@435 | 508 | intptr_t* frame::interpreter_frame_local_at(int index) const { |
duke@435 | 509 | const int n = Interpreter::local_offset_in_bytes(index)/wordSize; |
duke@435 | 510 | return &((*interpreter_frame_locals_addr())[n]); |
duke@435 | 511 | } |
duke@435 | 512 | |
duke@435 | 513 | intptr_t* frame::interpreter_frame_expression_stack_at(jint offset) const { |
duke@435 | 514 | const int i = offset * interpreter_frame_expression_stack_direction(); |
twisti@1861 | 515 | const int n = i * Interpreter::stackElementWords; |
duke@435 | 516 | return &(interpreter_frame_expression_stack()[n]); |
duke@435 | 517 | } |
duke@435 | 518 | |
duke@435 | 519 | jint frame::interpreter_frame_expression_stack_size() const { |
duke@435 | 520 | // Number of elements on the interpreter expression stack |
duke@435 | 521 | // Callers should span by stackElementWords |
twisti@1861 | 522 | int element_size = Interpreter::stackElementWords; |
duke@435 | 523 | if (frame::interpreter_frame_expression_stack_direction() < 0) { |
duke@435 | 524 | return (interpreter_frame_expression_stack() - |
duke@435 | 525 | interpreter_frame_tos_address() + 1)/element_size; |
duke@435 | 526 | } else { |
duke@435 | 527 | return (interpreter_frame_tos_address() - |
duke@435 | 528 | interpreter_frame_expression_stack() + 1)/element_size; |
duke@435 | 529 | } |
duke@435 | 530 | } |
duke@435 | 531 | |
duke@435 | 532 | |
duke@435 | 533 | // (frame::interpreter_frame_sender_sp accessor is in frame_<arch>.cpp) |
duke@435 | 534 | |
duke@435 | 535 | const char* frame::print_name() const { |
duke@435 | 536 | if (is_native_frame()) return "Native"; |
duke@435 | 537 | if (is_interpreted_frame()) return "Interpreted"; |
duke@435 | 538 | if (is_compiled_frame()) { |
duke@435 | 539 | if (is_deoptimized_frame()) return "Deoptimized"; |
duke@435 | 540 | return "Compiled"; |
duke@435 | 541 | } |
duke@435 | 542 | if (sp() == NULL) return "Empty"; |
duke@435 | 543 | return "C"; |
duke@435 | 544 | } |
duke@435 | 545 | |
duke@435 | 546 | void frame::print_value_on(outputStream* st, JavaThread *thread) const { |
duke@435 | 547 | NOT_PRODUCT(address begin = pc()-40;) |
duke@435 | 548 | NOT_PRODUCT(address end = NULL;) |
duke@435 | 549 | |
duke@435 | 550 | st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp()); |
duke@435 | 551 | if (sp() != NULL) |
duke@435 | 552 | st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc()); |
duke@435 | 553 | |
duke@435 | 554 | if (StubRoutines::contains(pc())) { |
duke@435 | 555 | st->print_cr(")"); |
duke@435 | 556 | st->print("("); |
duke@435 | 557 | StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); |
duke@435 | 558 | st->print("~Stub::%s", desc->name()); |
duke@435 | 559 | NOT_PRODUCT(begin = desc->begin(); end = desc->end();) |
duke@435 | 560 | } else if (Interpreter::contains(pc())) { |
duke@435 | 561 | st->print_cr(")"); |
duke@435 | 562 | st->print("("); |
duke@435 | 563 | InterpreterCodelet* desc = Interpreter::codelet_containing(pc()); |
duke@435 | 564 | if (desc != NULL) { |
duke@435 | 565 | st->print("~"); |
never@3499 | 566 | desc->print_on(st); |
duke@435 | 567 | NOT_PRODUCT(begin = desc->code_begin(); end = desc->code_end();) |
duke@435 | 568 | } else { |
duke@435 | 569 | st->print("~interpreter"); |
duke@435 | 570 | } |
duke@435 | 571 | } |
duke@435 | 572 | st->print_cr(")"); |
duke@435 | 573 | |
duke@435 | 574 | if (_cb != NULL) { |
duke@435 | 575 | st->print(" "); |
duke@435 | 576 | _cb->print_value_on(st); |
duke@435 | 577 | st->cr(); |
duke@435 | 578 | #ifndef PRODUCT |
duke@435 | 579 | if (end == NULL) { |
twisti@2103 | 580 | begin = _cb->code_begin(); |
twisti@2103 | 581 | end = _cb->code_end(); |
duke@435 | 582 | } |
duke@435 | 583 | #endif |
duke@435 | 584 | } |
duke@435 | 585 | NOT_PRODUCT(if (WizardMode && Verbose) Disassembler::decode(begin, end);) |
duke@435 | 586 | } |
duke@435 | 587 | |
duke@435 | 588 | |
duke@435 | 589 | void frame::print_on(outputStream* st) const { |
duke@435 | 590 | print_value_on(st,NULL); |
duke@435 | 591 | if (is_interpreted_frame()) { |
duke@435 | 592 | interpreter_frame_print_on(st); |
duke@435 | 593 | } |
duke@435 | 594 | } |
duke@435 | 595 | |
duke@435 | 596 | |
duke@435 | 597 | void frame::interpreter_frame_print_on(outputStream* st) const { |
duke@435 | 598 | #ifndef PRODUCT |
duke@435 | 599 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 600 | jint i; |
duke@435 | 601 | for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) { |
duke@435 | 602 | intptr_t x = *interpreter_frame_local_at(i); |
duke@435 | 603 | st->print(" - local [" INTPTR_FORMAT "]", x); |
duke@435 | 604 | st->fill_to(23); |
duke@435 | 605 | st->print_cr("; #%d", i); |
duke@435 | 606 | } |
duke@435 | 607 | for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) { |
duke@435 | 608 | intptr_t x = *interpreter_frame_expression_stack_at(i); |
duke@435 | 609 | st->print(" - stack [" INTPTR_FORMAT "]", x); |
duke@435 | 610 | st->fill_to(23); |
duke@435 | 611 | st->print_cr("; #%d", i); |
duke@435 | 612 | } |
duke@435 | 613 | // locks for synchronization |
duke@435 | 614 | for (BasicObjectLock* current = interpreter_frame_monitor_end(); |
duke@435 | 615 | current < interpreter_frame_monitor_begin(); |
duke@435 | 616 | current = next_monitor_in_interpreter_frame(current)) { |
kvn@1690 | 617 | st->print(" - obj ["); |
duke@435 | 618 | current->obj()->print_value_on(st); |
kvn@1690 | 619 | st->print_cr("]"); |
kvn@1690 | 620 | st->print(" - lock ["); |
duke@435 | 621 | current->lock()->print_on(st); |
kvn@1690 | 622 | st->print_cr("]"); |
duke@435 | 623 | } |
duke@435 | 624 | // monitor |
duke@435 | 625 | st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin()); |
duke@435 | 626 | // bcp |
duke@435 | 627 | st->print(" - bcp [" INTPTR_FORMAT "]", interpreter_frame_bcp()); |
duke@435 | 628 | st->fill_to(23); |
duke@435 | 629 | st->print_cr("; @%d", interpreter_frame_bci()); |
duke@435 | 630 | // locals |
duke@435 | 631 | st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0)); |
duke@435 | 632 | // method |
duke@435 | 633 | st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method()); |
duke@435 | 634 | st->fill_to(23); |
duke@435 | 635 | st->print("; "); |
duke@435 | 636 | interpreter_frame_method()->print_name(st); |
duke@435 | 637 | st->cr(); |
duke@435 | 638 | #endif |
duke@435 | 639 | } |
duke@435 | 640 | |
duke@435 | 641 | // Return whether the frame is in the VM or os indicating a Hotspot problem. |
duke@435 | 642 | // Otherwise, it's likely a bug in the native library that the Java code calls, |
duke@435 | 643 | // hopefully indicating where to submit bugs. |
duke@435 | 644 | static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) { |
duke@435 | 645 | // C/C++ frame |
duke@435 | 646 | bool in_vm = os::address_is_in_vm(pc); |
duke@435 | 647 | st->print(in_vm ? "V" : "C"); |
duke@435 | 648 | |
duke@435 | 649 | int offset; |
duke@435 | 650 | bool found; |
duke@435 | 651 | |
duke@435 | 652 | // libname |
duke@435 | 653 | found = os::dll_address_to_library_name(pc, buf, buflen, &offset); |
duke@435 | 654 | if (found) { |
duke@435 | 655 | // skip directory names |
duke@435 | 656 | const char *p1, *p2; |
duke@435 | 657 | p1 = buf; |
duke@435 | 658 | int len = (int)strlen(os::file_separator()); |
duke@435 | 659 | while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; |
duke@435 | 660 | st->print(" [%s+0x%x]", p1, offset); |
duke@435 | 661 | } else { |
duke@435 | 662 | st->print(" " PTR_FORMAT, pc); |
duke@435 | 663 | } |
duke@435 | 664 | |
duke@435 | 665 | // function name - os::dll_address_to_function_name() may return confusing |
duke@435 | 666 | // names if pc is within jvm.dll or libjvm.so, because JVM only has |
duke@435 | 667 | // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this |
duke@435 | 668 | // only for native libraries. |
zgu@2364 | 669 | if (!in_vm || Decoder::can_decode_C_frame_in_vm()) { |
duke@435 | 670 | found = os::dll_address_to_function_name(pc, buf, buflen, &offset); |
duke@435 | 671 | |
duke@435 | 672 | if (found) { |
duke@435 | 673 | st->print(" %s+0x%x", buf, offset); |
duke@435 | 674 | } |
duke@435 | 675 | } |
duke@435 | 676 | } |
duke@435 | 677 | |
duke@435 | 678 | // frame::print_on_error() is called by fatal error handler. Notice that we may |
duke@435 | 679 | // crash inside this function if stack frame is corrupted. The fatal error |
duke@435 | 680 | // handler can catch and handle the crash. Here we assume the frame is valid. |
duke@435 | 681 | // |
duke@435 | 682 | // First letter indicates type of the frame: |
duke@435 | 683 | // J: Java frame (compiled) |
duke@435 | 684 | // j: Java frame (interpreted) |
duke@435 | 685 | // V: VM frame (C/C++) |
duke@435 | 686 | // v: Other frames running VM generated code (e.g. stubs, adapters, etc.) |
duke@435 | 687 | // C: C/C++ frame |
duke@435 | 688 | // |
duke@435 | 689 | // We don't need detailed frame type as that in frame::print_name(). "C" |
duke@435 | 690 | // suggests the problem is in user lib; everything else is likely a VM bug. |
duke@435 | 691 | |
duke@435 | 692 | void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const { |
duke@435 | 693 | if (_cb != NULL) { |
duke@435 | 694 | if (Interpreter::contains(pc())) { |
coleenp@4037 | 695 | Method* m = this->interpreter_frame_method(); |
duke@435 | 696 | if (m != NULL) { |
duke@435 | 697 | m->name_and_sig_as_C_string(buf, buflen); |
duke@435 | 698 | st->print("j %s", buf); |
duke@435 | 699 | st->print("+%d", this->interpreter_frame_bci()); |
duke@435 | 700 | } else { |
duke@435 | 701 | st->print("j " PTR_FORMAT, pc()); |
duke@435 | 702 | } |
duke@435 | 703 | } else if (StubRoutines::contains(pc())) { |
duke@435 | 704 | StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); |
duke@435 | 705 | if (desc != NULL) { |
duke@435 | 706 | st->print("v ~StubRoutines::%s", desc->name()); |
duke@435 | 707 | } else { |
duke@435 | 708 | st->print("v ~StubRoutines::" PTR_FORMAT, pc()); |
duke@435 | 709 | } |
duke@435 | 710 | } else if (_cb->is_buffer_blob()) { |
duke@435 | 711 | st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); |
duke@435 | 712 | } else if (_cb->is_nmethod()) { |
coleenp@4037 | 713 | Method* m = ((nmethod *)_cb)->method(); |
duke@435 | 714 | if (m != NULL) { |
duke@435 | 715 | m->name_and_sig_as_C_string(buf, buflen); |
duke@435 | 716 | st->print("J %s", buf); |
duke@435 | 717 | } else { |
duke@435 | 718 | st->print("J " PTR_FORMAT, pc()); |
duke@435 | 719 | } |
duke@435 | 720 | } else if (_cb->is_runtime_stub()) { |
duke@435 | 721 | st->print("v ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name()); |
duke@435 | 722 | } else if (_cb->is_deoptimization_stub()) { |
duke@435 | 723 | st->print("v ~DeoptimizationBlob"); |
duke@435 | 724 | } else if (_cb->is_exception_stub()) { |
duke@435 | 725 | st->print("v ~ExceptionBlob"); |
duke@435 | 726 | } else if (_cb->is_safepoint_stub()) { |
duke@435 | 727 | st->print("v ~SafepointBlob"); |
duke@435 | 728 | } else { |
duke@435 | 729 | st->print("v blob " PTR_FORMAT, pc()); |
duke@435 | 730 | } |
duke@435 | 731 | } else { |
duke@435 | 732 | print_C_frame(st, buf, buflen, pc()); |
duke@435 | 733 | } |
duke@435 | 734 | } |
duke@435 | 735 | |
duke@435 | 736 | |
duke@435 | 737 | /* |
duke@435 | 738 | The interpreter_frame_expression_stack_at method in the case of SPARC needs the |
duke@435 | 739 | max_stack value of the method in order to compute the expression stack address. |
coleenp@4037 | 740 | It uses the Method* in order to get the max_stack value but during GC this |
coleenp@4037 | 741 | Method* value saved on the frame is changed by reverse_and_push and hence cannot |
duke@435 | 742 | be used. So we save the max_stack value in the FrameClosure object and pass it |
duke@435 | 743 | down to the interpreter_frame_expression_stack_at method |
duke@435 | 744 | */ |
duke@435 | 745 | class InterpreterFrameClosure : public OffsetClosure { |
duke@435 | 746 | private: |
duke@435 | 747 | frame* _fr; |
duke@435 | 748 | OopClosure* _f; |
duke@435 | 749 | int _max_locals; |
duke@435 | 750 | int _max_stack; |
duke@435 | 751 | |
duke@435 | 752 | public: |
duke@435 | 753 | InterpreterFrameClosure(frame* fr, int max_locals, int max_stack, |
duke@435 | 754 | OopClosure* f) { |
duke@435 | 755 | _fr = fr; |
duke@435 | 756 | _max_locals = max_locals; |
duke@435 | 757 | _max_stack = max_stack; |
duke@435 | 758 | _f = f; |
duke@435 | 759 | } |
duke@435 | 760 | |
duke@435 | 761 | void offset_do(int offset) { |
duke@435 | 762 | oop* addr; |
duke@435 | 763 | if (offset < _max_locals) { |
duke@435 | 764 | addr = (oop*) _fr->interpreter_frame_local_at(offset); |
duke@435 | 765 | assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame"); |
duke@435 | 766 | _f->do_oop(addr); |
duke@435 | 767 | } else { |
duke@435 | 768 | addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals)); |
duke@435 | 769 | // In case of exceptions, the expression stack is invalid and the esp will be reset to express |
duke@435 | 770 | // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel). |
duke@435 | 771 | bool in_stack; |
duke@435 | 772 | if (frame::interpreter_frame_expression_stack_direction() > 0) { |
duke@435 | 773 | in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address(); |
duke@435 | 774 | } else { |
duke@435 | 775 | in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address(); |
duke@435 | 776 | } |
duke@435 | 777 | if (in_stack) { |
duke@435 | 778 | _f->do_oop(addr); |
duke@435 | 779 | } |
duke@435 | 780 | } |
duke@435 | 781 | } |
duke@435 | 782 | |
duke@435 | 783 | int max_locals() { return _max_locals; } |
duke@435 | 784 | frame* fr() { return _fr; } |
duke@435 | 785 | }; |
duke@435 | 786 | |
duke@435 | 787 | |
duke@435 | 788 | class InterpretedArgumentOopFinder: public SignatureInfo { |
duke@435 | 789 | private: |
twisti@1573 | 790 | OopClosure* _f; // Closure to invoke |
twisti@1573 | 791 | int _offset; // TOS-relative offset, decremented with each argument |
twisti@1573 | 792 | bool _has_receiver; // true if the callee has a receiver |
duke@435 | 793 | frame* _fr; |
duke@435 | 794 | |
duke@435 | 795 | void set(int size, BasicType type) { |
duke@435 | 796 | _offset -= size; |
duke@435 | 797 | if (type == T_OBJECT || type == T_ARRAY) oop_offset_do(); |
duke@435 | 798 | } |
duke@435 | 799 | |
duke@435 | 800 | void oop_offset_do() { |
duke@435 | 801 | oop* addr; |
duke@435 | 802 | addr = (oop*)_fr->interpreter_frame_tos_at(_offset); |
duke@435 | 803 | _f->do_oop(addr); |
duke@435 | 804 | } |
duke@435 | 805 | |
duke@435 | 806 | public: |
coleenp@2497 | 807 | InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) { |
duke@435 | 808 | // compute size of arguments |
twisti@1573 | 809 | int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
duke@435 | 810 | assert(!fr->is_interpreted_frame() || |
duke@435 | 811 | args_size <= fr->interpreter_frame_expression_stack_size(), |
duke@435 | 812 | "args cannot be on stack anymore"); |
duke@435 | 813 | // initialize InterpretedArgumentOopFinder |
duke@435 | 814 | _f = f; |
duke@435 | 815 | _fr = fr; |
duke@435 | 816 | _offset = args_size; |
duke@435 | 817 | } |
duke@435 | 818 | |
duke@435 | 819 | void oops_do() { |
twisti@1573 | 820 | if (_has_receiver) { |
duke@435 | 821 | --_offset; |
duke@435 | 822 | oop_offset_do(); |
duke@435 | 823 | } |
duke@435 | 824 | iterate_parameters(); |
duke@435 | 825 | } |
duke@435 | 826 | }; |
duke@435 | 827 | |
duke@435 | 828 | |
duke@435 | 829 | // Entry frame has following form (n arguments) |
duke@435 | 830 | // +-----------+ |
duke@435 | 831 | // sp -> | last arg | |
duke@435 | 832 | // +-----------+ |
duke@435 | 833 | // : ::: : |
duke@435 | 834 | // +-----------+ |
duke@435 | 835 | // (sp+n)->| first arg| |
duke@435 | 836 | // +-----------+ |
duke@435 | 837 | |
duke@435 | 838 | |
duke@435 | 839 | |
duke@435 | 840 | // visits and GC's all the arguments in entry frame |
duke@435 | 841 | class EntryFrameOopFinder: public SignatureInfo { |
duke@435 | 842 | private: |
duke@435 | 843 | bool _is_static; |
duke@435 | 844 | int _offset; |
duke@435 | 845 | frame* _fr; |
duke@435 | 846 | OopClosure* _f; |
duke@435 | 847 | |
duke@435 | 848 | void set(int size, BasicType type) { |
duke@435 | 849 | assert (_offset >= 0, "illegal offset"); |
duke@435 | 850 | if (type == T_OBJECT || type == T_ARRAY) oop_at_offset_do(_offset); |
duke@435 | 851 | _offset -= size; |
duke@435 | 852 | } |
duke@435 | 853 | |
duke@435 | 854 | void oop_at_offset_do(int offset) { |
jcoomes@1844 | 855 | assert (offset >= 0, "illegal offset"); |
duke@435 | 856 | oop* addr = (oop*) _fr->entry_frame_argument_at(offset); |
duke@435 | 857 | _f->do_oop(addr); |
duke@435 | 858 | } |
duke@435 | 859 | |
duke@435 | 860 | public: |
coleenp@2497 | 861 | EntryFrameOopFinder(frame* frame, Symbol* signature, bool is_static) : SignatureInfo(signature) { |
duke@435 | 862 | _f = NULL; // will be set later |
duke@435 | 863 | _fr = frame; |
duke@435 | 864 | _is_static = is_static; |
duke@435 | 865 | _offset = ArgumentSizeComputer(signature).size() - 1; // last parameter is at index 0 |
duke@435 | 866 | } |
duke@435 | 867 | |
duke@435 | 868 | void arguments_do(OopClosure* f) { |
duke@435 | 869 | _f = f; |
duke@435 | 870 | if (!_is_static) oop_at_offset_do(_offset+1); // do the receiver |
duke@435 | 871 | iterate_parameters(); |
duke@435 | 872 | } |
duke@435 | 873 | |
duke@435 | 874 | }; |
duke@435 | 875 | |
coleenp@2497 | 876 | oop* frame::interpreter_callee_receiver_addr(Symbol* signature) { |
duke@435 | 877 | ArgumentSizeComputer asc(signature); |
duke@435 | 878 | int size = asc.size(); |
duke@435 | 879 | return (oop *)interpreter_frame_tos_at(size); |
duke@435 | 880 | } |
duke@435 | 881 | |
duke@435 | 882 | |
stefank@4298 | 883 | void frame::oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, |
stefank@4298 | 884 | const RegisterMap* map, bool query_oop_map_cache) { |
duke@435 | 885 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 886 | assert(map != NULL, "map must be set"); |
duke@435 | 887 | Thread *thread = Thread::current(); |
duke@435 | 888 | methodHandle m (thread, interpreter_frame_method()); |
duke@435 | 889 | jint bci = interpreter_frame_bci(); |
duke@435 | 890 | |
coleenp@4037 | 891 | assert(!Universe::heap()->is_in(m()), |
coleenp@4037 | 892 | "must be valid oop"); |
duke@435 | 893 | assert(m->is_method(), "checking frame value"); |
coleenp@4037 | 894 | assert((m->is_native() && bci == 0) || |
coleenp@4037 | 895 | (!m->is_native() && bci >= 0 && bci < m->code_size()), |
coleenp@4037 | 896 | "invalid bci value"); |
duke@435 | 897 | |
duke@435 | 898 | // Handle the monitor elements in the activation |
duke@435 | 899 | for ( |
duke@435 | 900 | BasicObjectLock* current = interpreter_frame_monitor_end(); |
duke@435 | 901 | current < interpreter_frame_monitor_begin(); |
duke@435 | 902 | current = next_monitor_in_interpreter_frame(current) |
duke@435 | 903 | ) { |
duke@435 | 904 | #ifdef ASSERT |
duke@435 | 905 | interpreter_frame_verify_monitor(current); |
duke@435 | 906 | #endif |
duke@435 | 907 | current->oops_do(f); |
duke@435 | 908 | } |
duke@435 | 909 | |
duke@435 | 910 | // process fixed part |
stefank@4298 | 911 | if (cld_f != NULL) { |
stefank@4298 | 912 | // The method pointer in the frame might be the only path to the method's |
stefank@4298 | 913 | // klass, and the klass needs to be kept alive while executing. The GCs |
stefank@4298 | 914 | // don't trace through method pointers, so typically in similar situations |
stefank@4298 | 915 | // the mirror or the class loader of the klass are installed as a GC root. |
stefank@4298 | 916 | // To minimze the overhead of doing that here, we ask the GC to pass down a |
stefank@4298 | 917 | // closure that knows how to keep klasses alive given a ClassLoaderData. |
stefank@4298 | 918 | cld_f->do_cld(m->method_holder()->class_loader_data()); |
stefank@4298 | 919 | } |
stefank@4298 | 920 | |
twisti@2263 | 921 | #if !defined(PPC) || defined(ZERO) |
duke@435 | 922 | if (m->is_native()) { |
duke@435 | 923 | #ifdef CC_INTERP |
coleenp@4037 | 924 | interpreterState istate = get_interpreterState(); |
duke@435 | 925 | f->do_oop((oop*)&istate->_oop_temp); |
duke@435 | 926 | #else |
duke@435 | 927 | f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset )); |
duke@435 | 928 | #endif /* CC_INTERP */ |
duke@435 | 929 | } |
bobv@2036 | 930 | #else // PPC |
bobv@2036 | 931 | if (m->is_native() && m->is_static()) { |
bobv@2036 | 932 | f->do_oop(interpreter_frame_mirror_addr()); |
bobv@2036 | 933 | } |
bobv@2036 | 934 | #endif // PPC |
duke@435 | 935 | |
duke@435 | 936 | int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); |
duke@435 | 937 | |
coleenp@2497 | 938 | Symbol* signature = NULL; |
twisti@1573 | 939 | bool has_receiver = false; |
duke@435 | 940 | |
duke@435 | 941 | // Process a callee's arguments if we are at a call site |
duke@435 | 942 | // (i.e., if we are at an invoke bytecode) |
duke@435 | 943 | // This is used sometimes for calling into the VM, not for another |
duke@435 | 944 | // interpreted or compiled frame. |
duke@435 | 945 | if (!m->is_native()) { |
never@2462 | 946 | Bytecode_invoke call = Bytecode_invoke_check(m, bci); |
never@2462 | 947 | if (call.is_valid()) { |
coleenp@2497 | 948 | signature = call.signature(); |
never@2462 | 949 | has_receiver = call.has_receiver(); |
duke@435 | 950 | if (map->include_argument_oops() && |
duke@435 | 951 | interpreter_frame_expression_stack_size() > 0) { |
duke@435 | 952 | ResourceMark rm(thread); // is this right ??? |
duke@435 | 953 | // we are at a call site & the expression stack is not empty |
duke@435 | 954 | // => process callee's arguments |
duke@435 | 955 | // |
duke@435 | 956 | // Note: The expression stack can be empty if an exception |
twisti@1040 | 957 | // occurred during method resolution/execution. In all |
duke@435 | 958 | // cases we empty the expression stack completely be- |
duke@435 | 959 | // fore handling the exception (the exception handling |
duke@435 | 960 | // code in the interpreter calls a blocking runtime |
duke@435 | 961 | // routine which can cause this code to be executed). |
duke@435 | 962 | // (was bug gri 7/27/98) |
twisti@1573 | 963 | oops_interpreted_arguments_do(signature, has_receiver, f); |
duke@435 | 964 | } |
duke@435 | 965 | } |
duke@435 | 966 | } |
duke@435 | 967 | |
twisti@1861 | 968 | InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); |
twisti@1861 | 969 | |
twisti@1861 | 970 | // process locals & expression stack |
twisti@1861 | 971 | InterpreterOopMap mask; |
twisti@1861 | 972 | if (query_oop_map_cache) { |
twisti@1861 | 973 | m->mask_for(bci, &mask); |
duke@435 | 974 | } else { |
twisti@1861 | 975 | OopMapCache::compute_one_oop_map(m, bci, &mask); |
duke@435 | 976 | } |
twisti@1861 | 977 | mask.iterate_oop(&blk); |
duke@435 | 978 | } |
duke@435 | 979 | |
duke@435 | 980 | |
coleenp@2497 | 981 | void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { |
twisti@1573 | 982 | InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); |
duke@435 | 983 | finder.oops_do(); |
duke@435 | 984 | } |
duke@435 | 985 | |
jrose@1424 | 986 | void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) { |
duke@435 | 987 | assert(_cb != NULL, "sanity check"); |
duke@435 | 988 | if (_cb->oop_maps() != NULL) { |
duke@435 | 989 | OopMapSet::oops_do(this, reg_map, f); |
duke@435 | 990 | |
duke@435 | 991 | // Preserve potential arguments for a callee. We handle this by dispatching |
duke@435 | 992 | // on the codeblob. For c2i, we do |
duke@435 | 993 | if (reg_map->include_argument_oops()) { |
duke@435 | 994 | _cb->preserve_callee_argument_oops(*this, reg_map, f); |
duke@435 | 995 | } |
duke@435 | 996 | } |
duke@435 | 997 | // In cases where perm gen is collected, GC will want to mark |
duke@435 | 998 | // oops referenced from nmethods active on thread stacks so as to |
duke@435 | 999 | // prevent them from being collected. However, this visit should be |
duke@435 | 1000 | // restricted to certain phases of the collection only. The |
jrose@1424 | 1001 | // closure decides how it wants nmethods to be traced. |
jrose@1424 | 1002 | if (cf != NULL) |
jrose@1424 | 1003 | cf->do_code_blob(_cb); |
duke@435 | 1004 | } |
duke@435 | 1005 | |
duke@435 | 1006 | class CompiledArgumentOopFinder: public SignatureInfo { |
duke@435 | 1007 | protected: |
duke@435 | 1008 | OopClosure* _f; |
twisti@1573 | 1009 | int _offset; // the current offset, incremented with each argument |
twisti@1573 | 1010 | bool _has_receiver; // true if the callee has a receiver |
duke@435 | 1011 | frame _fr; |
duke@435 | 1012 | RegisterMap* _reg_map; |
duke@435 | 1013 | int _arg_size; |
duke@435 | 1014 | VMRegPair* _regs; // VMReg list of arguments |
duke@435 | 1015 | |
duke@435 | 1016 | void set(int size, BasicType type) { |
duke@435 | 1017 | if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset(); |
duke@435 | 1018 | _offset += size; |
duke@435 | 1019 | } |
duke@435 | 1020 | |
duke@435 | 1021 | virtual void handle_oop_offset() { |
duke@435 | 1022 | // Extract low order register number from register array. |
duke@435 | 1023 | // In LP64-land, the high-order bits are valid but unhelpful. |
duke@435 | 1024 | VMReg reg = _regs[_offset].first(); |
duke@435 | 1025 | oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); |
duke@435 | 1026 | _f->do_oop(loc); |
duke@435 | 1027 | } |
duke@435 | 1028 | |
duke@435 | 1029 | public: |
coleenp@2497 | 1030 | CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map) |
duke@435 | 1031 | : SignatureInfo(signature) { |
duke@435 | 1032 | |
duke@435 | 1033 | // initialize CompiledArgumentOopFinder |
duke@435 | 1034 | _f = f; |
duke@435 | 1035 | _offset = 0; |
twisti@1573 | 1036 | _has_receiver = has_receiver; |
duke@435 | 1037 | _fr = fr; |
duke@435 | 1038 | _reg_map = (RegisterMap*)reg_map; |
twisti@1573 | 1039 | _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
duke@435 | 1040 | |
duke@435 | 1041 | int arg_size; |
coleenp@2497 | 1042 | _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size); |
duke@435 | 1043 | assert(arg_size == _arg_size, "wrong arg size"); |
duke@435 | 1044 | } |
duke@435 | 1045 | |
duke@435 | 1046 | void oops_do() { |
twisti@1573 | 1047 | if (_has_receiver) { |
duke@435 | 1048 | handle_oop_offset(); |
duke@435 | 1049 | _offset++; |
duke@435 | 1050 | } |
duke@435 | 1051 | iterate_parameters(); |
duke@435 | 1052 | } |
duke@435 | 1053 | }; |
duke@435 | 1054 | |
coleenp@2497 | 1055 | void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) { |
duke@435 | 1056 | ResourceMark rm; |
twisti@1573 | 1057 | CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map); |
duke@435 | 1058 | finder.oops_do(); |
duke@435 | 1059 | } |
duke@435 | 1060 | |
duke@435 | 1061 | |
duke@435 | 1062 | // Get receiver out of callers frame, i.e. find parameter 0 in callers |
duke@435 | 1063 | // frame. Consult ADLC for where parameter 0 is to be found. Then |
duke@435 | 1064 | // check local reg_map for it being a callee-save register or argument |
duke@435 | 1065 | // register, both of which are saved in the local frame. If not found |
duke@435 | 1066 | // there, it must be an in-stack argument of the caller. |
duke@435 | 1067 | // Note: caller.sp() points to callee-arguments |
duke@435 | 1068 | oop frame::retrieve_receiver(RegisterMap* reg_map) { |
duke@435 | 1069 | frame caller = *this; |
duke@435 | 1070 | |
duke@435 | 1071 | // First consult the ADLC on where it puts parameter 0 for this signature. |
duke@435 | 1072 | VMReg reg = SharedRuntime::name_for_receiver(); |
duke@435 | 1073 | oop r = *caller.oopmapreg_to_location(reg, reg_map); |
twisti@3969 | 1074 | assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r)); |
duke@435 | 1075 | return r; |
duke@435 | 1076 | } |
duke@435 | 1077 | |
duke@435 | 1078 | |
duke@435 | 1079 | oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const { |
duke@435 | 1080 | if(reg->is_reg()) { |
duke@435 | 1081 | // If it is passed in a register, it got spilled in the stub frame. |
duke@435 | 1082 | return (oop *)reg_map->location(reg); |
duke@435 | 1083 | } else { |
coleenp@548 | 1084 | int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size; |
coleenp@548 | 1085 | return (oop*)(((address)unextended_sp()) + sp_offset_in_bytes); |
duke@435 | 1086 | } |
duke@435 | 1087 | } |
duke@435 | 1088 | |
kamg@2361 | 1089 | BasicLock* frame::get_native_monitor() { |
kamg@2361 | 1090 | nmethod* nm = (nmethod*)_cb; |
kamg@2361 | 1091 | assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), |
kamg@2361 | 1092 | "Should not call this unless it's a native nmethod"); |
kamg@2361 | 1093 | int byte_offset = in_bytes(nm->native_basic_lock_sp_offset()); |
duke@435 | 1094 | assert(byte_offset >= 0, "should not see invalid offset"); |
duke@435 | 1095 | return (BasicLock*) &sp()[byte_offset / wordSize]; |
duke@435 | 1096 | } |
duke@435 | 1097 | |
kamg@2361 | 1098 | oop frame::get_native_receiver() { |
kamg@2361 | 1099 | nmethod* nm = (nmethod*)_cb; |
kamg@2361 | 1100 | assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), |
kamg@2361 | 1101 | "Should not call this unless it's a native nmethod"); |
kamg@2361 | 1102 | int byte_offset = in_bytes(nm->native_receiver_sp_offset()); |
duke@435 | 1103 | assert(byte_offset >= 0, "should not see invalid offset"); |
duke@435 | 1104 | oop owner = ((oop*) sp())[byte_offset / wordSize]; |
duke@435 | 1105 | assert( Universe::heap()->is_in(owner), "bad receiver" ); |
duke@435 | 1106 | return owner; |
duke@435 | 1107 | } |
duke@435 | 1108 | |
duke@435 | 1109 | void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) { |
duke@435 | 1110 | assert(map != NULL, "map must be set"); |
duke@435 | 1111 | if (map->include_argument_oops()) { |
duke@435 | 1112 | // must collect argument oops, as nobody else is doing it |
duke@435 | 1113 | Thread *thread = Thread::current(); |
duke@435 | 1114 | methodHandle m (thread, entry_frame_call_wrapper()->callee_method()); |
coleenp@2497 | 1115 | EntryFrameOopFinder finder(this, m->signature(), m->is_static()); |
duke@435 | 1116 | finder.arguments_do(f); |
duke@435 | 1117 | } |
duke@435 | 1118 | // Traverse the Handle Block saved in the entry frame |
duke@435 | 1119 | entry_frame_call_wrapper()->oops_do(f); |
duke@435 | 1120 | } |
duke@435 | 1121 | |
duke@435 | 1122 | |
stefank@4298 | 1123 | void frame::oops_do_internal(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) { |
minqi@1554 | 1124 | #ifndef PRODUCT |
minqi@1554 | 1125 | // simulate GC crash here to dump java thread in error report |
minqi@1554 | 1126 | if (CrashGCForDumpingJavaThread) { |
minqi@1554 | 1127 | char *t = NULL; |
minqi@1554 | 1128 | *t = 'c'; |
minqi@1554 | 1129 | } |
minqi@1554 | 1130 | #endif |
minqi@1554 | 1131 | if (is_interpreted_frame()) { |
stefank@4298 | 1132 | oops_interpreted_do(f, cld_f, map, use_interpreter_oop_map_cache); |
minqi@1554 | 1133 | } else if (is_entry_frame()) { |
minqi@1554 | 1134 | oops_entry_do(f, map); |
minqi@1554 | 1135 | } else if (CodeCache::contains(pc())) { |
minqi@1554 | 1136 | oops_code_blob_do(f, cf, map); |
twisti@2047 | 1137 | #ifdef SHARK |
twisti@2047 | 1138 | } else if (is_fake_stub_frame()) { |
twisti@2047 | 1139 | // nothing to do |
twisti@2047 | 1140 | #endif // SHARK |
duke@435 | 1141 | } else { |
duke@435 | 1142 | ShouldNotReachHere(); |
duke@435 | 1143 | } |
duke@435 | 1144 | } |
duke@435 | 1145 | |
jrose@1424 | 1146 | void frame::nmethods_do(CodeBlobClosure* cf) { |
duke@435 | 1147 | if (_cb != NULL && _cb->is_nmethod()) { |
jrose@1424 | 1148 | cf->do_code_blob(_cb); |
duke@435 | 1149 | } |
duke@435 | 1150 | } |
duke@435 | 1151 | |
duke@435 | 1152 | |
coleenp@4037 | 1153 | // call f() on the interpreted Method*s in the stack. |
coleenp@4037 | 1154 | // Have to walk the entire code cache for the compiled frames Yuck. |
coleenp@4037 | 1155 | void frame::metadata_do(void f(Metadata*)) { |
coleenp@4037 | 1156 | if (_cb != NULL && Interpreter::contains(pc())) { |
coleenp@4037 | 1157 | Method* m = this->interpreter_frame_method(); |
coleenp@4037 | 1158 | assert(m != NULL, "huh?"); |
coleenp@4037 | 1159 | f(m); |
coleenp@4037 | 1160 | } |
coleenp@4037 | 1161 | } |
coleenp@4037 | 1162 | |
duke@435 | 1163 | void frame::gc_prologue() { |
duke@435 | 1164 | if (is_interpreted_frame()) { |
coleenp@4037 | 1165 | // set bcx to bci to become Method* position independent during GC |
duke@435 | 1166 | interpreter_frame_set_bcx(interpreter_frame_bci()); |
duke@435 | 1167 | } |
duke@435 | 1168 | } |
duke@435 | 1169 | |
duke@435 | 1170 | |
duke@435 | 1171 | void frame::gc_epilogue() { |
duke@435 | 1172 | if (is_interpreted_frame()) { |
duke@435 | 1173 | // set bcx back to bcp for interpreter |
duke@435 | 1174 | interpreter_frame_set_bcx((intptr_t)interpreter_frame_bcp()); |
duke@435 | 1175 | } |
duke@435 | 1176 | // call processor specific epilog function |
duke@435 | 1177 | pd_gc_epilog(); |
duke@435 | 1178 | } |
duke@435 | 1179 | |
duke@435 | 1180 | |
duke@435 | 1181 | # ifdef ENABLE_ZAP_DEAD_LOCALS |
duke@435 | 1182 | |
duke@435 | 1183 | void frame::CheckValueClosure::do_oop(oop* p) { |
duke@435 | 1184 | if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) { |
duke@435 | 1185 | warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current()); |
duke@435 | 1186 | } |
duke@435 | 1187 | } |
duke@435 | 1188 | frame::CheckValueClosure frame::_check_value; |
duke@435 | 1189 | |
duke@435 | 1190 | |
duke@435 | 1191 | void frame::CheckOopClosure::do_oop(oop* p) { |
duke@435 | 1192 | if (*p != NULL && !(*p)->is_oop()) { |
duke@435 | 1193 | warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current()); |
duke@435 | 1194 | } |
duke@435 | 1195 | } |
duke@435 | 1196 | frame::CheckOopClosure frame::_check_oop; |
duke@435 | 1197 | |
duke@435 | 1198 | void frame::check_derived_oop(oop* base, oop* derived) { |
duke@435 | 1199 | _check_oop.do_oop(base); |
duke@435 | 1200 | } |
duke@435 | 1201 | |
duke@435 | 1202 | |
duke@435 | 1203 | void frame::ZapDeadClosure::do_oop(oop* p) { |
duke@435 | 1204 | if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p); |
duke@435 | 1205 | // Need cast because on _LP64 the conversion to oop is ambiguous. Constant |
duke@435 | 1206 | // can be either long or int. |
duke@435 | 1207 | *p = (oop)(int)0xbabebabe; |
duke@435 | 1208 | } |
duke@435 | 1209 | frame::ZapDeadClosure frame::_zap_dead; |
duke@435 | 1210 | |
duke@435 | 1211 | void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) { |
duke@435 | 1212 | assert(thread == Thread::current(), "need to synchronize to do this to another thread"); |
duke@435 | 1213 | // Tracing - part 1 |
duke@435 | 1214 | if (TraceZapDeadLocals) { |
duke@435 | 1215 | ResourceMark rm(thread); |
duke@435 | 1216 | tty->print_cr("--------------------------------------------------------------------------------"); |
duke@435 | 1217 | tty->print("Zapping dead locals in "); |
duke@435 | 1218 | print_on(tty); |
duke@435 | 1219 | tty->cr(); |
duke@435 | 1220 | } |
duke@435 | 1221 | // Zapping |
duke@435 | 1222 | if (is_entry_frame ()) zap_dead_entry_locals (thread, map); |
duke@435 | 1223 | else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map); |
duke@435 | 1224 | else if (is_compiled_frame()) zap_dead_compiled_locals (thread, map); |
duke@435 | 1225 | |
duke@435 | 1226 | else |
duke@435 | 1227 | // could be is_runtime_frame |
duke@435 | 1228 | // so remove error: ShouldNotReachHere(); |
duke@435 | 1229 | ; |
duke@435 | 1230 | // Tracing - part 2 |
duke@435 | 1231 | if (TraceZapDeadLocals) { |
duke@435 | 1232 | tty->cr(); |
duke@435 | 1233 | } |
duke@435 | 1234 | } |
duke@435 | 1235 | |
duke@435 | 1236 | |
duke@435 | 1237 | void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) { |
duke@435 | 1238 | // get current interpreter 'pc' |
duke@435 | 1239 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
coleenp@4037 | 1240 | Method* m = interpreter_frame_method(); |
duke@435 | 1241 | int bci = interpreter_frame_bci(); |
duke@435 | 1242 | |
duke@435 | 1243 | int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); |
duke@435 | 1244 | |
twisti@1861 | 1245 | // process dynamic part |
twisti@1861 | 1246 | InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(), |
twisti@1861 | 1247 | &_check_value); |
twisti@1861 | 1248 | InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(), |
twisti@1861 | 1249 | &_check_oop ); |
twisti@1861 | 1250 | InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(), |
twisti@1861 | 1251 | &_zap_dead ); |
duke@435 | 1252 | |
twisti@1861 | 1253 | // get frame map |
twisti@1861 | 1254 | InterpreterOopMap mask; |
twisti@1861 | 1255 | m->mask_for(bci, &mask); |
twisti@1861 | 1256 | mask.iterate_all( &oop_blk, &value_blk, &dead_blk); |
duke@435 | 1257 | } |
duke@435 | 1258 | |
duke@435 | 1259 | |
duke@435 | 1260 | void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) { |
duke@435 | 1261 | |
duke@435 | 1262 | ResourceMark rm(thread); |
duke@435 | 1263 | assert(_cb != NULL, "sanity check"); |
duke@435 | 1264 | if (_cb->oop_maps() != NULL) { |
coleenp@548 | 1265 | OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop, &_check_value); |
duke@435 | 1266 | } |
duke@435 | 1267 | } |
duke@435 | 1268 | |
duke@435 | 1269 | |
duke@435 | 1270 | void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) { |
duke@435 | 1271 | if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented"); |
duke@435 | 1272 | } |
duke@435 | 1273 | |
duke@435 | 1274 | |
duke@435 | 1275 | void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) { |
duke@435 | 1276 | if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented"); |
duke@435 | 1277 | } |
duke@435 | 1278 | |
duke@435 | 1279 | # endif // ENABLE_ZAP_DEAD_LOCALS |
duke@435 | 1280 | |
duke@435 | 1281 | void frame::verify(const RegisterMap* map) { |
duke@435 | 1282 | // for now make sure receiver type is correct |
duke@435 | 1283 | if (is_interpreted_frame()) { |
coleenp@4037 | 1284 | Method* method = interpreter_frame_method(); |
duke@435 | 1285 | guarantee(method->is_method(), "method is wrong in frame::verify"); |
duke@435 | 1286 | if (!method->is_static()) { |
duke@435 | 1287 | // fetch the receiver |
duke@435 | 1288 | oop* p = (oop*) interpreter_frame_local_at(0); |
duke@435 | 1289 | // make sure we have the right receiver type |
duke@435 | 1290 | } |
duke@435 | 1291 | } |
duke@435 | 1292 | COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");) |
stefank@4298 | 1293 | oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false); |
duke@435 | 1294 | } |
duke@435 | 1295 | |
duke@435 | 1296 | |
duke@435 | 1297 | #ifdef ASSERT |
duke@435 | 1298 | bool frame::verify_return_pc(address x) { |
duke@435 | 1299 | if (StubRoutines::returns_to_call_stub(x)) { |
duke@435 | 1300 | return true; |
duke@435 | 1301 | } |
duke@435 | 1302 | if (CodeCache::contains(x)) { |
duke@435 | 1303 | return true; |
duke@435 | 1304 | } |
duke@435 | 1305 | if (Interpreter::contains(x)) { |
duke@435 | 1306 | return true; |
duke@435 | 1307 | } |
duke@435 | 1308 | return false; |
duke@435 | 1309 | } |
duke@435 | 1310 | #endif |
duke@435 | 1311 | |
duke@435 | 1312 | #ifdef ASSERT |
duke@435 | 1313 | void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const { |
duke@435 | 1314 | assert(is_interpreted_frame(), "Not an interpreted frame"); |
duke@435 | 1315 | // verify that the value is in the right part of the frame |
duke@435 | 1316 | address low_mark = (address) interpreter_frame_monitor_end(); |
duke@435 | 1317 | address high_mark = (address) interpreter_frame_monitor_begin(); |
duke@435 | 1318 | address current = (address) value; |
duke@435 | 1319 | |
duke@435 | 1320 | const int monitor_size = frame::interpreter_frame_monitor_size(); |
duke@435 | 1321 | guarantee((high_mark - current) % monitor_size == 0 , "Misaligned top of BasicObjectLock*"); |
duke@435 | 1322 | guarantee( high_mark > current , "Current BasicObjectLock* higher than high_mark"); |
duke@435 | 1323 | |
duke@435 | 1324 | guarantee((current - low_mark) % monitor_size == 0 , "Misaligned bottom of BasicObjectLock*"); |
duke@435 | 1325 | guarantee( current >= low_mark , "Current BasicObjectLock* below than low_mark"); |
duke@435 | 1326 | } |
bdelsart@3451 | 1327 | #endif |
never@2868 | 1328 | |
bdelsart@3451 | 1329 | #ifndef PRODUCT |
never@2868 | 1330 | void frame::describe(FrameValues& values, int frame_no) { |
bdelsart@3445 | 1331 | // boundaries: sp and the 'real' frame pointer |
bdelsart@3445 | 1332 | values.describe(-1, sp(), err_msg("sp for #%d", frame_no), 1); |
bdelsart@3445 | 1333 | intptr_t* frame_pointer = real_fp(); // Note: may differ from fp() |
bdelsart@3445 | 1334 | |
bdelsart@3445 | 1335 | // print frame info at the highest boundary |
bdelsart@3445 | 1336 | intptr_t* info_address = MAX2(sp(), frame_pointer); |
bdelsart@3445 | 1337 | |
bdelsart@3445 | 1338 | if (info_address != frame_pointer) { |
bdelsart@3445 | 1339 | // print frame_pointer explicitly if not marked by the frame info |
bdelsart@3445 | 1340 | values.describe(-1, frame_pointer, err_msg("frame pointer for #%d", frame_no), 1); |
bdelsart@3445 | 1341 | } |
bdelsart@3445 | 1342 | |
never@2868 | 1343 | if (is_entry_frame() || is_compiled_frame() || is_interpreted_frame() || is_native_frame()) { |
never@2868 | 1344 | // Label values common to most frames |
never@2868 | 1345 | values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no)); |
never@2868 | 1346 | } |
bdelsart@3445 | 1347 | |
never@2868 | 1348 | if (is_interpreted_frame()) { |
coleenp@4037 | 1349 | Method* m = interpreter_frame_method(); |
never@2868 | 1350 | int bci = interpreter_frame_bci(); |
never@2868 | 1351 | |
never@2868 | 1352 | // Label the method and current bci |
bdelsart@3445 | 1353 | values.describe(-1, info_address, |
never@2868 | 1354 | FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2); |
bdelsart@3445 | 1355 | values.describe(-1, info_address, |
never@2868 | 1356 | err_msg("- %d locals %d max stack", m->max_locals(), m->max_stack()), 1); |
never@2868 | 1357 | if (m->max_locals() > 0) { |
never@2868 | 1358 | intptr_t* l0 = interpreter_frame_local_at(0); |
never@2868 | 1359 | intptr_t* ln = interpreter_frame_local_at(m->max_locals() - 1); |
never@2868 | 1360 | values.describe(-1, MAX2(l0, ln), err_msg("locals for #%d", frame_no), 1); |
never@2868 | 1361 | // Report each local and mark as owned by this frame |
never@2868 | 1362 | for (int l = 0; l < m->max_locals(); l++) { |
never@2868 | 1363 | intptr_t* l0 = interpreter_frame_local_at(l); |
never@2868 | 1364 | values.describe(frame_no, l0, err_msg("local %d", l)); |
never@2868 | 1365 | } |
never@2868 | 1366 | } |
never@2868 | 1367 | |
never@2868 | 1368 | // Compute the actual expression stack size |
never@2868 | 1369 | InterpreterOopMap mask; |
never@2868 | 1370 | OopMapCache::compute_one_oop_map(m, bci, &mask); |
never@2868 | 1371 | intptr_t* tos = NULL; |
never@2868 | 1372 | // Report each stack element and mark as owned by this frame |
never@2868 | 1373 | for (int e = 0; e < mask.expression_stack_size(); e++) { |
never@2868 | 1374 | tos = MAX2(tos, interpreter_frame_expression_stack_at(e)); |
never@2868 | 1375 | values.describe(frame_no, interpreter_frame_expression_stack_at(e), |
never@2868 | 1376 | err_msg("stack %d", e)); |
never@2868 | 1377 | } |
never@2868 | 1378 | if (tos != NULL) { |
never@2868 | 1379 | values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 1); |
never@2868 | 1380 | } |
never@2868 | 1381 | if (interpreter_frame_monitor_begin() != interpreter_frame_monitor_end()) { |
never@2868 | 1382 | values.describe(frame_no, (intptr_t*)interpreter_frame_monitor_begin(), "monitors begin"); |
never@2868 | 1383 | values.describe(frame_no, (intptr_t*)interpreter_frame_monitor_end(), "monitors end"); |
never@2868 | 1384 | } |
never@2868 | 1385 | } else if (is_entry_frame()) { |
never@2868 | 1386 | // For now just label the frame |
bdelsart@3445 | 1387 | values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2); |
never@2868 | 1388 | } else if (is_compiled_frame()) { |
never@2868 | 1389 | // For now just label the frame |
never@2868 | 1390 | nmethod* nm = cb()->as_nmethod_or_null(); |
bdelsart@3445 | 1391 | values.describe(-1, info_address, |
never@2868 | 1392 | FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no, |
never@2868 | 1393 | nm, nm->method()->name_and_sig_as_C_string(), |
bdelsart@3445 | 1394 | (_deopt_state == is_deoptimized) ? |
bdelsart@3445 | 1395 | " (deoptimized)" : |
bdelsart@3445 | 1396 | ((_deopt_state == unknown) ? " (state unknown)" : "")), |
bdelsart@3445 | 1397 | 2); |
never@2868 | 1398 | } else if (is_native_frame()) { |
never@2868 | 1399 | // For now just label the frame |
never@2868 | 1400 | nmethod* nm = cb()->as_nmethod_or_null(); |
bdelsart@3445 | 1401 | values.describe(-1, info_address, |
never@2868 | 1402 | FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no, |
never@2868 | 1403 | nm, nm->method()->name_and_sig_as_C_string()), 2); |
bdelsart@3445 | 1404 | } else { |
bdelsart@3445 | 1405 | // provide default info if not handled before |
bdelsart@3445 | 1406 | char *info = (char *) "special frame"; |
bdelsart@3445 | 1407 | if ((_cb != NULL) && |
bdelsart@3445 | 1408 | (_cb->name() != NULL)) { |
bdelsart@3445 | 1409 | info = (char *)_cb->name(); |
bdelsart@3445 | 1410 | } |
bdelsart@3445 | 1411 | values.describe(-1, info_address, err_msg("#%d <%s>", frame_no, info), 2); |
never@2868 | 1412 | } |
bdelsart@3445 | 1413 | |
bdelsart@3445 | 1414 | // platform dependent additional data |
never@2868 | 1415 | describe_pd(values, frame_no); |
never@2868 | 1416 | } |
never@2868 | 1417 | |
duke@435 | 1418 | #endif |
duke@435 | 1419 | |
duke@435 | 1420 | |
duke@435 | 1421 | //----------------------------------------------------------------------------------- |
duke@435 | 1422 | // StackFrameStream implementation |
duke@435 | 1423 | |
duke@435 | 1424 | StackFrameStream::StackFrameStream(JavaThread *thread, bool update) : _reg_map(thread, update) { |
duke@435 | 1425 | assert(thread->has_last_Java_frame(), "sanity check"); |
duke@435 | 1426 | _fr = thread->last_frame(); |
duke@435 | 1427 | _is_done = false; |
duke@435 | 1428 | } |
never@2868 | 1429 | |
never@2868 | 1430 | |
bdelsart@3451 | 1431 | #ifndef PRODUCT |
never@2868 | 1432 | |
never@2868 | 1433 | void FrameValues::describe(int owner, intptr_t* location, const char* description, int priority) { |
never@2868 | 1434 | FrameValue fv; |
never@2868 | 1435 | fv.location = location; |
never@2868 | 1436 | fv.owner = owner; |
never@2868 | 1437 | fv.priority = priority; |
never@2868 | 1438 | fv.description = NEW_RESOURCE_ARRAY(char, strlen(description) + 1); |
never@2868 | 1439 | strcpy(fv.description, description); |
never@2868 | 1440 | _values.append(fv); |
never@2868 | 1441 | } |
never@2868 | 1442 | |
never@2868 | 1443 | |
bdelsart@3451 | 1444 | #ifdef ASSERT |
never@2897 | 1445 | void FrameValues::validate() { |
never@2868 | 1446 | _values.sort(compare); |
never@2868 | 1447 | bool error = false; |
never@2868 | 1448 | FrameValue prev; |
never@2868 | 1449 | prev.owner = -1; |
never@2868 | 1450 | for (int i = _values.length() - 1; i >= 0; i--) { |
never@2868 | 1451 | FrameValue fv = _values.at(i); |
never@2868 | 1452 | if (fv.owner == -1) continue; |
never@2868 | 1453 | if (prev.owner == -1) { |
never@2868 | 1454 | prev = fv; |
never@2868 | 1455 | continue; |
never@2868 | 1456 | } |
never@2868 | 1457 | if (prev.location == fv.location) { |
never@2868 | 1458 | if (fv.owner != prev.owner) { |
never@2868 | 1459 | tty->print_cr("overlapping storage"); |
never@2868 | 1460 | tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", prev.location, *prev.location, prev.description); |
never@2868 | 1461 | tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description); |
never@2868 | 1462 | error = true; |
never@2868 | 1463 | } |
never@2868 | 1464 | } else { |
never@2868 | 1465 | prev = fv; |
never@2868 | 1466 | } |
never@2868 | 1467 | } |
never@2897 | 1468 | assert(!error, "invalid layout"); |
never@2868 | 1469 | } |
bdelsart@3451 | 1470 | #endif // ASSERT |
never@2868 | 1471 | |
twisti@3238 | 1472 | void FrameValues::print(JavaThread* thread) { |
never@2868 | 1473 | _values.sort(compare); |
never@2901 | 1474 | |
never@2901 | 1475 | // Sometimes values like the fp can be invalid values if the |
never@2901 | 1476 | // register map wasn't updated during the walk. Trim out values |
never@2901 | 1477 | // that aren't actually in the stack of the thread. |
never@2901 | 1478 | int min_index = 0; |
never@2901 | 1479 | int max_index = _values.length() - 1; |
never@2901 | 1480 | intptr_t* v0 = _values.at(min_index).location; |
never@2901 | 1481 | intptr_t* v1 = _values.at(max_index).location; |
twisti@3238 | 1482 | |
twisti@3238 | 1483 | if (thread == Thread::current()) { |
twisti@3238 | 1484 | while (!thread->is_in_stack((address)v0)) { |
twisti@3238 | 1485 | v0 = _values.at(++min_index).location; |
twisti@3238 | 1486 | } |
twisti@3238 | 1487 | while (!thread->is_in_stack((address)v1)) { |
twisti@3238 | 1488 | v1 = _values.at(--max_index).location; |
twisti@3238 | 1489 | } |
twisti@3238 | 1490 | } else { |
twisti@3238 | 1491 | while (!thread->on_local_stack((address)v0)) { |
twisti@3238 | 1492 | v0 = _values.at(++min_index).location; |
twisti@3238 | 1493 | } |
twisti@3238 | 1494 | while (!thread->on_local_stack((address)v1)) { |
twisti@3238 | 1495 | v1 = _values.at(--max_index).location; |
twisti@3238 | 1496 | } |
never@2901 | 1497 | } |
never@2868 | 1498 | intptr_t* min = MIN2(v0, v1); |
never@2868 | 1499 | intptr_t* max = MAX2(v0, v1); |
never@2868 | 1500 | intptr_t* cur = max; |
never@2868 | 1501 | intptr_t* last = NULL; |
never@2901 | 1502 | for (int i = max_index; i >= min_index; i--) { |
never@2868 | 1503 | FrameValue fv = _values.at(i); |
never@2868 | 1504 | while (cur > fv.location) { |
never@2868 | 1505 | tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur); |
never@2868 | 1506 | cur--; |
never@2868 | 1507 | } |
never@2868 | 1508 | if (last == fv.location) { |
never@2868 | 1509 | const char* spacer = " " LP64_ONLY(" "); |
never@2868 | 1510 | tty->print_cr(" %s %s %s", spacer, spacer, fv.description); |
never@2868 | 1511 | } else { |
never@2868 | 1512 | tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description); |
never@2868 | 1513 | last = fv.location; |
never@2868 | 1514 | cur--; |
never@2868 | 1515 | } |
never@2868 | 1516 | } |
never@2868 | 1517 | } |
never@2868 | 1518 | |
bdelsart@3451 | 1519 | #endif // ndef PRODUCT |