< 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 >