< prev index next >

src/hotspot/share/runtime/deoptimization.cpp

Print this page




 203     if (EliminateAllocations) {
 204 #endif // INCLUDE_JVMCI
 205       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
 206       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 207 
 208       // The flag return_oop() indicates call sites which return oop
 209       // in compiled code. Such sites include java method calls,
 210       // runtime calls (for example, used to allocate new objects/arrays
 211       // on slow code path) and any other calls generated in compiled code.
 212       // It is not guaranteed that we can get such information here only
 213       // by analyzing bytecode in deoptimized frames. This is why this flag
 214       // is set during method compilation (see Compile::Process_OopMap_Node()).
 215       // If the previous frame was popped or if we are dispatching an exception,
 216       // we don't have an oop result.
 217       ScopeDesc* scope = chunk->at(0)->scope();
 218       bool save_oop_result = scope->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Unpack_deopt);
 219       // In case of the return of multiple values, we must take care
 220       // of all oop return values.
 221       GrowableArray<Handle> return_oops;
 222       ValueKlass* vk = NULL;
 223       if (save_oop_result) {
 224         if (scope->return_vt()) {
 225           vk = ValueKlass::returned_value_type(map);
 226           if (vk != NULL) {
 227             bool success = vk->save_oop_results(map, return_oops);
 228             assert(success, "found klass ptr being returned: saving oops can't fail");
 229             save_oop_result = false;
 230           } else {
 231             vk = NULL;
 232           }
 233         }
 234       }
 235       if (save_oop_result) {
 236         // Reallocation may trigger GC. If deoptimization happened on return from
 237         // call which returns oop we need to save it since it is not in oopmap.
 238         oop result = deoptee.saved_oop_result(&map);
 239         assert(oopDesc::is_oop_or_null(result), "must be oop");
 240         return_oops.push(Handle(thread, result));
 241         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 242         if (TraceDeoptimization) {
 243           ttyLocker ttyl;
 244           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 245         }
 246       }
 247       if (objects != NULL || vk != NULL) {
 248         bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
 249         JRT_BLOCK
 250           if (vk != NULL) {
 251             realloc_failures = realloc_value_type_result(vk, map, return_oops, THREAD);
 252           }




 203     if (EliminateAllocations) {
 204 #endif // INCLUDE_JVMCI
 205       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
 206       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 207 
 208       // The flag return_oop() indicates call sites which return oop
 209       // in compiled code. Such sites include java method calls,
 210       // runtime calls (for example, used to allocate new objects/arrays
 211       // on slow code path) and any other calls generated in compiled code.
 212       // It is not guaranteed that we can get such information here only
 213       // by analyzing bytecode in deoptimized frames. This is why this flag
 214       // is set during method compilation (see Compile::Process_OopMap_Node()).
 215       // If the previous frame was popped or if we are dispatching an exception,
 216       // we don't have an oop result.
 217       ScopeDesc* scope = chunk->at(0)->scope();
 218       bool save_oop_result = scope->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Unpack_deopt);
 219       // In case of the return of multiple values, we must take care
 220       // of all oop return values.
 221       GrowableArray<Handle> return_oops;
 222       ValueKlass* vk = NULL;
 223       if (save_oop_result && scope->return_vt()) {
 224         vk = ValueKlass::returned_value_klass(map);

 225         if (vk != NULL) {
 226           vk->save_oop_fields(map, return_oops);

 227           save_oop_result = false;



 228         }
 229       }
 230       if (save_oop_result) {
 231         // Reallocation may trigger GC. If deoptimization happened on return from
 232         // call which returns oop we need to save it since it is not in oopmap.
 233         oop result = deoptee.saved_oop_result(&map);
 234         assert(oopDesc::is_oop_or_null(result), "must be oop");
 235         return_oops.push(Handle(thread, result));
 236         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 237         if (TraceDeoptimization) {
 238           ttyLocker ttyl;
 239           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 240         }
 241       }
 242       if (objects != NULL || vk != NULL) {
 243         bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
 244         JRT_BLOCK
 245           if (vk != NULL) {
 246             realloc_failures = realloc_value_type_result(vk, map, return_oops, THREAD);
 247           }


< prev index next >