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