< prev index next >

src/share/vm/runtime/deoptimization.cpp

Print this page




 196 
 197 #if defined(COMPILER2) || INCLUDE_JVMCI
 198   // Reallocate the non-escaping objects and restore their fields. Then
 199   // relock objects if synchronization on them was eliminated.
 200 #ifndef INCLUDE_JVMCI
 201   if (DoEscapeAnalysis || EliminateNestedLocks) {
 202     if (EliminateAllocations) {
 203 #endif // INCLUDE_JVMCI
 204       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
 205       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 206 
 207       // The flag return_oop() indicates call sites which return oop
 208       // in compiled code. Such sites include java method calls,
 209       // runtime calls (for example, used to allocate new objects/arrays
 210       // on slow code path) and any other calls generated in compiled code.
 211       // It is not guaranteed that we can get such information here only
 212       // by analyzing bytecode in deoptimized frames. This is why this flag
 213       // is set during method compilation (see Compile::Process_OopMap_Node()).
 214       // If the previous frame was popped or if we are dispatching an exception,
 215       // we don't have an oop result.
 216       bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Unpack_deopt);
 217       Handle return_value;
















 218       if (save_oop_result) {
 219         // Reallocation may trigger GC. If deoptimization happened on return from
 220         // call which returns oop we need to save it since it is not in oopmap.
 221         oop result = deoptee.saved_oop_result(&map);
 222         assert(result == NULL || result->is_oop(), "must be oop");
 223         return_value = Handle(thread, result);
 224         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 225         if (TraceDeoptimization) {
 226           ttyLocker ttyl;
 227           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 228         }
 229       }
 230       if (objects != NULL) {
 231         bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
 232         JRT_BLOCK
 233           realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);




 234           reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal, THREAD);

 235         JRT_END
 236 #ifndef PRODUCT
 237         if (TraceDeoptimization) {
 238           ttyLocker ttyl;
 239           tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
 240           print_objects(objects, realloc_failures);
 241         }
 242 #endif
 243       }
 244       if (save_oop_result) {
 245         // Restore result.
 246         deoptee.set_saved_oop_result(&map, return_value());

 247       }
 248 #ifndef INCLUDE_JVMCI
 249     }
 250     if (EliminateLocks) {
 251 #endif // INCLUDE_JVMCI
 252 #ifndef PRODUCT
 253       bool first = true;
 254 #endif
 255       for (int i = 0; i < chunk->length(); i++) {
 256         compiledVFrame* cvf = chunk->at(i);
 257         assert (cvf->scope() != NULL,"expect only compiled java frames");
 258         GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
 259         if (monitors->is_nonempty()) {
 260           relock_objects(monitors, thread, realloc_failures);
 261 #ifndef PRODUCT
 262           if (PrintDeoptimizationDetails) {
 263             ttyLocker ttyl;
 264             for (int j = 0; j < monitors->length(); j++) {
 265               MonitorInfo* mi = monitors->at(j);
 266               if (mi->eliminated()) {


 833       obj = ak->allocate(sv->field_size(), THREAD);
 834     }
 835 
 836     if (obj == NULL) {
 837       failures = true;
 838     }
 839 
 840     assert(sv->value().is_null(), "redundant reallocation");
 841     assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception");
 842     CLEAR_PENDING_EXCEPTION;
 843     sv->set_value(obj);
 844   }
 845 
 846   if (failures) {
 847     THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures);
 848   } else if (pending_exception.not_null()) {
 849     thread->set_pending_exception(pending_exception(), exception_file, exception_line);
 850   }
 851 
 852   return failures;




















 853 }
 854 
 855 // restore elements of an eliminated type array
 856 void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
 857   int index = 0;
 858   intptr_t val;
 859 
 860   for (int i = 0; i < sv->field_size(); i++) {
 861     StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
 862     switch(type) {
 863     case T_LONG: case T_DOUBLE: {
 864       assert(value->type() == T_INT, "Agreement.");
 865       StackValue* low =
 866         StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
 867 #ifdef _LP64
 868       jlong res = (jlong)low->get_int();
 869 #else
 870 #ifdef SPARC
 871       // For SPARC we have to swap high and low words.
 872       jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());




 196 
 197 #if defined(COMPILER2) || INCLUDE_JVMCI
 198   // Reallocate the non-escaping objects and restore their fields. Then
 199   // relock objects if synchronization on them was eliminated.
 200 #ifndef INCLUDE_JVMCI
 201   if (DoEscapeAnalysis || EliminateNestedLocks) {
 202     if (EliminateAllocations) {
 203 #endif // INCLUDE_JVMCI
 204       assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
 205       GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
 206 
 207       // The flag return_oop() indicates call sites which return oop
 208       // in compiled code. Such sites include java method calls,
 209       // runtime calls (for example, used to allocate new objects/arrays
 210       // on slow code path) and any other calls generated in compiled code.
 211       // It is not guaranteed that we can get such information here only
 212       // by analyzing bytecode in deoptimized frames. This is why this flag
 213       // is set during method compilation (see Compile::Process_OopMap_Node()).
 214       // If the previous frame was popped or if we are dispatching an exception,
 215       // we don't have an oop result.
 216       ScopeDesc* scope = chunk->at(0)->scope();
 217       bool save_oop_result = scope->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Unpack_deopt);
 218       // In case of the return of multiple values, we must take care
 219       // of all oop return values.
 220       GrowableArray<Handle> return_oops;
 221       ValueKlass* vk = NULL;
 222       if (save_oop_result) {
 223         if (scope->return_vt()) {
 224           vk = ValueKlass::returned_value_type(map);
 225           if (vk != NULL) {
 226             bool success = vk->save_oop_results(map, return_oops);
 227             assert(success, "found klass ptr being returned: saving oops can't fail");
 228             save_oop_result = false;
 229           } else {
 230             vk = NULL;
 231           }
 232         }
 233       }      
 234       if (save_oop_result) {
 235         // Reallocation may trigger GC. If deoptimization happened on return from
 236         // call which returns oop we need to save it since it is not in oopmap.
 237         oop result = deoptee.saved_oop_result(&map);
 238         assert(result == NULL || result->is_oop(), "must be oop");
 239         return_oops.push(Handle(thread, result));
 240         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 241         if (TraceDeoptimization) {
 242           ttyLocker ttyl;
 243           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 244         }
 245       }
 246       if (objects != NULL || vk != NULL) {
 247         bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
 248         JRT_BLOCK
 249           if (vk != NULL) {
 250             realloc_failures = realloc_value_type_result(vk, map, return_oops, THREAD);
 251           }
 252           if (objects != NULL) {
 253             realloc_failures = realloc_failures || realloc_objects(thread, &deoptee, objects, THREAD);
 254             reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal, THREAD);
 255           }
 256         JRT_END
 257 #ifndef PRODUCT
 258         if (TraceDeoptimization) {
 259           ttyLocker ttyl;
 260           tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
 261           print_objects(objects, realloc_failures);
 262         }
 263 #endif
 264       }
 265       if (save_oop_result || vk != NULL) {
 266         // Restore result.
 267         assert(return_oops.length() == 1, "no value type");
 268         deoptee.set_saved_oop_result(&map, return_oops.pop()());
 269       }
 270 #ifndef INCLUDE_JVMCI
 271     }
 272     if (EliminateLocks) {
 273 #endif // INCLUDE_JVMCI
 274 #ifndef PRODUCT
 275       bool first = true;
 276 #endif
 277       for (int i = 0; i < chunk->length(); i++) {
 278         compiledVFrame* cvf = chunk->at(i);
 279         assert (cvf->scope() != NULL,"expect only compiled java frames");
 280         GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
 281         if (monitors->is_nonempty()) {
 282           relock_objects(monitors, thread, realloc_failures);
 283 #ifndef PRODUCT
 284           if (PrintDeoptimizationDetails) {
 285             ttyLocker ttyl;
 286             for (int j = 0; j < monitors->length(); j++) {
 287               MonitorInfo* mi = monitors->at(j);
 288               if (mi->eliminated()) {


 855       obj = ak->allocate(sv->field_size(), THREAD);
 856     }
 857 
 858     if (obj == NULL) {
 859       failures = true;
 860     }
 861 
 862     assert(sv->value().is_null(), "redundant reallocation");
 863     assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception");
 864     CLEAR_PENDING_EXCEPTION;
 865     sv->set_value(obj);
 866   }
 867 
 868   if (failures) {
 869     THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures);
 870   } else if (pending_exception.not_null()) {
 871     thread->set_pending_exception(pending_exception(), exception_file, exception_line);
 872   }
 873 
 874   return failures;
 875 }
 876 
 877 // We're deoptimizing at the return of a call, value type fields are
 878 // in registers. When we go back to the interpreter, it will expect a
 879 // reference to a value type instance. Allocate and initialize it from
 880 // the register values here.
 881 bool Deoptimization::realloc_value_type_result(ValueKlass* vk, const RegisterMap& map, GrowableArray<Handle>& return_oops, TRAPS) {
 882   VMRegPair* regs;
 883   int nb_fields;
 884   const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
 885   regs++;
 886   nb_fields--;
 887   oop new_vt = vk->realloc_result(sig_vk, map, regs, return_oops, nb_fields, THREAD);
 888   if (new_vt == NULL) {
 889     CLEAR_PENDING_EXCEPTION;
 890     THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), true);
 891   }
 892   return_oops.clear();
 893   return_oops.push(Handle(THREAD, new_vt));
 894   return false;
 895 }
 896 
 897 // restore elements of an eliminated type array
 898 void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) {
 899   int index = 0;
 900   intptr_t val;
 901 
 902   for (int i = 0; i < sv->field_size(); i++) {
 903     StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
 904     switch(type) {
 905     case T_LONG: case T_DOUBLE: {
 906       assert(value->type() == T_INT, "Agreement.");
 907       StackValue* low =
 908         StackValue::create_stack_value(fr, reg_map, sv->field_at(++i));
 909 #ifdef _LP64
 910       jlong res = (jlong)low->get_int();
 911 #else
 912 #ifdef SPARC
 913       // For SPARC we have to swap high and low words.
 914       jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int());


< prev index next >