< prev index next >

src/share/vm/runtime/safepoint.cpp

Print this page

        

*** 37,46 **** --- 37,47 ---- #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.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/interfaceSupport.hpp"
*** 1027,1055 **** // 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(result == NULL || result->is_oop(), "must be oop"); ! return_value = Handle(thread(), result); assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); } // Block the thread SafepointSynchronize::block(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 { --- 1028,1076 ---- // 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->is_returning_oop(); ! ! GrowableArray<Handle> return_values; ! ValueKlass* vk = NULL; ! if (!return_oop && method->is_returning_vt()) { ! // 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. ! vk = ValueKlass::returned_value_type(map); ! assert(vk == NULL || vk == method->returned_value_type(thread()) || ! method->returned_value_type(thread()) == SystemDictionary::___Value_klass(), "Bad value klass"); ! if (vk != NULL && !vk->save_oop_results(map, return_values)) { ! return_oop = true; ! vk = NULL; ! } ! } ! 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(result == NULL || result->is_oop(), "must be oop"); ! return_values.push(Handle(thread(), result)); assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); } // Block the thread SafepointSynchronize::block(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 >