< prev index next >

src/hotspot/share/runtime/frame.cpp

Print this page
rev 50307 : [mq]: cont

*** 36,45 **** --- 36,46 ---- #include "oops/method.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" #include "oops/verifyOopClosure.hpp" #include "prims/methodHandles.hpp" + #include "runtime/continuation.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" #include "runtime/monitorChunk.hpp" #include "runtime/os.hpp"
*** 50,64 **** #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" #include "utilities/decoder.hpp" #include "utilities/formatBuffer.hpp" ! RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { _thread = thread; _update_map = update_map; clear(); debug_only(_update_for_id = NULL;) #ifndef PRODUCT for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL; #endif /* PRODUCT */ } --- 51,66 ---- #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" #include "utilities/decoder.hpp" #include "utilities/formatBuffer.hpp" ! RegisterMap::RegisterMap(JavaThread *thread, bool update_map, bool validate_oops) { _thread = thread; _update_map = update_map; clear(); debug_only(_update_for_id = NULL;) + _validate_oops = validate_oops; #ifndef PRODUCT for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL; #endif /* PRODUCT */ }
*** 67,76 **** --- 69,79 ---- assert(map != NULL, "RegisterMap must be present"); _thread = map->thread(); _update_map = map->update_map(); _include_argument_oops = map->include_argument_oops(); debug_only(_update_for_id = map->_update_for_id;) + _validate_oops = map->_validate_oops; pd_initialize_from(map); if (update_map()) { for(int i = 0; i < location_valid_size; i++) { LocationValidType bits = !update_map() ? 0 : map->_location_valid[i]; _location_valid[i] = bits;
*** 131,140 **** --- 134,146 ---- // that happens for deoptimized frames. In addition it makes the value the // hardware would want to see in the native frame. The only user (at this point) // is deoptimization. It likely no one else should ever use it. address frame::raw_pc() const { + // if (Continuation::is_continuation_entry_frame(*this)) { + // return StubRoutines::cont_returnBarrier(); + // } if (is_deoptimized_frame()) { CompiledMethod* cm = cb()->as_compiled_method_or_null(); if (cm->is_method_handle_return(pc())) return cm->deopt_mh_handler_begin() - pc_return_offset; else
*** 159,168 **** --- 165,185 ---- _pc = newpc; _cb = CodeCache::find_blob_unsafe(_pc); } + void frame::set_pc_preserve_deopt(address newpc) { + #ifdef ASSERT + if (_cb != NULL && _cb->is_nmethod()) { + assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation"); + } + #endif // ASSERT + + _pc = newpc; + _cb = CodeCache::find_blob_unsafe(_pc); + } + // type testers bool frame::is_ignored_frame() const { return false; // FIXME: some LambdaForm frames should be ignored } bool frame::is_deoptimized_frame() const {
*** 264,273 **** --- 281,299 ---- CompiledMethod* nm = (CompiledMethod*)_cb; if( !nm->can_be_deoptimized() ) return false; + address* pc_addr = &(((address*) sp())[-1]); // TODO: PLATFORM + if (Continuation::is_return_barrier_entry(*pc_addr)) { + log_trace(jvmcont)("Can't deopt entry:"); + if (log_is_enabled(Trace, jvmcont)) { + print_value_on(tty, NULL); + } + return false; + } + return !nm->is_at_poll_return(pc()); } void frame::deoptimize(JavaThread* thread) { // Schedule deoptimization of an nmethod activation with this frame.
*** 334,355 **** address deopt = cm->is_method_handle_return(pc()) ? cm->deopt_mh_handler_begin() : cm->deopt_handler_begin(); // Save the original pc before we patch in the new one cm->set_original_pc(this, pc()); patch_pc(thread, deopt); #ifdef ASSERT { - RegisterMap map(thread, false); frame check = thread->last_frame(); while (id() != check.id()) { check = check.sender(&map); } assert(check.is_deoptimized_frame(), "missed deopt"); } #endif // ASSERT } frame frame::java_sender() const { RegisterMap map(JavaThread::current(), false); --- 360,398 ---- address deopt = cm->is_method_handle_return(pc()) ? cm->deopt_mh_handler_begin() : cm->deopt_handler_begin(); // Save the original pc before we patch in the new one + // address xpc = pc(); cm->set_original_pc(this, pc()); patch_pc(thread, deopt); #ifdef ASSERT { frame check = thread->last_frame(); + if (is_older(check.id())) { + RegisterMap map(thread, false); while (id() != check.id()) { check = check.sender(&map); } + // if (!check.is_deoptimized_frame()) { + // tty->print_cr("Deopt failure:"); + // tty->print_cr("deopt: %p pc: %p", deopt, xpc); + // tty->print_cr("me:"); + // print_on(tty); + // tty->print_cr("---- %d", is_younger(check.id())); + // check = thread->last_frame(); + // check.print_on(tty); + // while (id() != check.id()) { + // check = check.sender(&map); + // tty->print_cr("---- %d", is_younger(check.id())); + // check.print_on(tty); + // } + // } assert(check.is_deoptimized_frame(), "missed deopt"); } + } #endif // ASSERT } frame frame::java_sender() const { RegisterMap map(JavaThread::current(), false);
*** 951,973 **** if (query_oop_map_cache) { m->mask_for(bci, &mask); } else { OopMapCache::compute_one_oop_map(m, bci, &mask); } mask.iterate_oop(&blk); } void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); finder.oops_do(); } ! void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) { assert(_cb != NULL, "sanity check"); if (_cb->oop_maps() != NULL) { ! OopMapSet::oops_do(this, reg_map, f); // Preserve potential arguments for a callee. We handle this by dispatching // on the codeblob. For c2i, we do if (reg_map->include_argument_oops()) { _cb->preserve_callee_argument_oops(*this, reg_map, f); --- 994,1017 ---- if (query_oop_map_cache) { m->mask_for(bci, &mask); } else { OopMapCache::compute_one_oop_map(m, bci, &mask); } + // mask.print(); mask.iterate_oop(&blk); } void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); finder.oops_do(); } ! void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, const RegisterMap* reg_map) { assert(_cb != NULL, "sanity check"); if (_cb->oop_maps() != NULL) { ! OopMapSet::oops_do(this, reg_map, f, df); // Preserve potential arguments for a callee. We handle this by dispatching // on the codeblob. For c2i, we do if (reg_map->include_argument_oops()) { _cb->preserve_callee_argument_oops(*this, reg_map, f);
*** 1001,1010 **** --- 1045,1061 ---- virtual void handle_oop_offset() { // Extract low order register number from register array. // In LP64-land, the high-order bits are valid but unhelpful. VMReg reg = _regs[_offset].first(); oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); + #ifdef ASSERT + if (loc == NULL) { + tty->print_cr("Error walking frame oops:"); + _fr.print_on(tty); + assert (loc != NULL, "reg: %ld %s loc: %p", reg->value(), reg->name(), loc); + } + #endif _f->do_oop(loc); } public: CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
*** 1099,1109 **** // Traverse the Handle Block saved in the entry frame entry_frame_call_wrapper()->oops_do(f); } ! void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) { #ifndef PRODUCT #if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 #pragma error_messages(off, SEC_NULL_PTR_DEREF) #endif // simulate GC crash here to dump java thread in error report --- 1150,1160 ---- // Traverse the Handle Block saved in the entry frame entry_frame_call_wrapper()->oops_do(f); } ! void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, RegisterMap* map, bool use_interpreter_oop_map_cache) { #ifndef PRODUCT #if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 #pragma error_messages(off, SEC_NULL_PTR_DEREF) #endif // simulate GC crash here to dump java thread in error report
*** 1115,1125 **** if (is_interpreted_frame()) { oops_interpreted_do(f, map, use_interpreter_oop_map_cache); } else if (is_entry_frame()) { oops_entry_do(f, map); } else if (CodeCache::contains(pc())) { ! oops_code_blob_do(f, cf, map); } else { ShouldNotReachHere(); } } --- 1166,1176 ---- if (is_interpreted_frame()) { oops_interpreted_do(f, map, use_interpreter_oop_map_cache); } else if (is_entry_frame()) { oops_entry_do(f, map); } else if (CodeCache::contains(pc())) { ! oops_code_blob_do(f, cf, df, map); } else { ShouldNotReachHere(); } }
*** 1139,1148 **** --- 1190,1206 ---- f(m); } } void frame::verify(const RegisterMap* map) { + #ifndef PRODUCT + if (TraceCodeBlobStacks) { + tty->print_cr("*** verify"); + print_on(tty); + } + #endif + // for now make sure receiver type is correct if (is_interpreted_frame()) { Method* method = interpreter_frame_method(); guarantee(method->is_method(), "method is wrong in frame::verify"); if (!method->is_static()) {
*** 1152,1162 **** } } #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "must be empty before verify"); #endif ! oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false); } #ifdef ASSERT bool frame::verify_return_pc(address x) { --- 1210,1220 ---- } } #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_empty(), "must be empty before verify"); #endif ! oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false); } #ifdef ASSERT bool frame::verify_return_pc(address x) {
< prev index next >