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