< prev index next >
src/hotspot/share/runtime/safepoint.cpp
Print this page
*** 42,51 ****
--- 42,52 ----
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
+ #include "oops/valueKlass.hpp"
#include "runtime/atomic.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
*** 1051,1079 ****
// has already had the effect of causing the return to occur, so the execution
// will continue immediately after the call. In addition, the oopmap at the
// return point does not mark the return value as an oop (if it is), so
// it needs a handle here to be updated.
if( nm->is_at_poll_return(real_return_addr) ) {
// See if return type is an oop.
! bool return_oop = nm->method()->is_returning_oop();
! Handle return_value;
if (return_oop) {
// The oop result has been saved on the stack together with all
// the other registers. In order to preserve it over GCs we need
// to keep it in a handle.
oop result = caller_fr.saved_oop_result(&map);
assert(oopDesc::is_oop_or_null(result), "must be oop");
! return_value = Handle(thread(), result);
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// Block the thread
SafepointMechanism::block_if_requested(thread());
// restore oop result, if any
if (return_oop) {
! caller_fr.set_saved_oop_result(&map, return_value());
}
}
// This is a safepoint poll. Verify the return address and block.
else {
--- 1052,1107 ----
// has already had the effect of causing the return to occur, so the execution
// will continue immediately after the call. In addition, the oopmap at the
// return point does not mark the return value as an oop (if it is), so
// it needs a handle here to be updated.
if( nm->is_at_poll_return(real_return_addr) ) {
+ ResourceMark rm;
// See if return type is an oop.
! Method* method = nm->method();
! bool return_oop = method->may_return_oop();
!
! GrowableArray<Handle> return_values;
! ValueKlass* vk = NULL;
!
! if (return_oop && ValueTypeReturnedAsFields) {
! SignatureStream ss(method->signature());
! while (!ss.at_return_type()) {
! ss.next();
! }
! if (ss.type() == T_VALUETYPE) {
! // Check if value type is returned as fields
! vk = ValueKlass::returned_value_klass(map);
! if (vk != NULL) {
! // We're at a safepoint at the return of a method that returns
! // multiple values. We must make sure we preserve the oop values
! // across the safepoint.
! assert(vk == method->returned_value_type(thread()), "bad value klass");
! vk->save_oop_fields(map, return_values);
! return_oop = false;
! }
! }
! }
!
if (return_oop) {
// The oop result has been saved on the stack together with all
// the other registers. In order to preserve it over GCs we need
// to keep it in a handle.
oop result = caller_fr.saved_oop_result(&map);
assert(oopDesc::is_oop_or_null(result), "must be oop");
! return_values.push(Handle(thread(), result));
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// Block the thread
SafepointMechanism::block_if_requested(thread());
// restore oop result, if any
if (return_oop) {
! assert(return_values.length() == 1, "only one return value");
! caller_fr.set_saved_oop_result(&map, return_values.pop()());
! } else if (vk != NULL) {
! vk->restore_oop_results(map, return_values);
}
}
// This is a safepoint poll. Verify the return address and block.
else {
< prev index next >