< prev index next >

src/share/vm/runtime/deoptimization.cpp

Print this page




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "code/pcDesc.hpp"
  31 #include "code/scopeDesc.hpp"
  32 #include "interpreter/bytecode.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "interpreter/oopMapCache.hpp"
  35 #include "memory/allocation.inline.hpp"
  36 #include "memory/oopFactory.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "oops/method.hpp"
  39 #include "oops/objArrayOop.inline.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "oops/fieldStreams.hpp"

  42 #include "oops/verifyOopClosure.hpp"
  43 #include "prims/jvmtiThreadState.hpp"
  44 #include "runtime/biasedLocking.hpp"
  45 #include "runtime/compilationPolicy.hpp"
  46 #include "runtime/deoptimization.hpp"
  47 #include "runtime/interfaceSupport.hpp"
  48 #include "runtime/sharedRuntime.hpp"
  49 #include "runtime/signature.hpp"
  50 #include "runtime/stubRoutines.hpp"
  51 #include "runtime/thread.hpp"
  52 #include "runtime/vframe.hpp"
  53 #include "runtime/vframeArray.hpp"
  54 #include "runtime/vframe_hp.hpp"
  55 #include "utilities/events.hpp"
  56 #include "utilities/xmlstream.hpp"
  57 
  58 #if INCLUDE_JVMCI
  59 #include "jvmci/jvmciRuntime.hpp"
  60 #include "jvmci/jvmciJavaClasses.hpp"
  61 #endif


 222       // by analyzing bytecode in deoptimized frames. This is why this flag
 223       // is set during method compilation (see Compile::Process_OopMap_Node()).
 224       // If the previous frame was popped, we don't have a result.
 225       bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution();
 226       Handle return_value;
 227       if (save_oop_result) {
 228         // Reallocation may trigger GC. If deoptimization happened on return from
 229         // call which returns oop we need to save it since it is not in oopmap.
 230         oop result = deoptee.saved_oop_result(&map);
 231         assert(result == NULL || result->is_oop(), "must be oop");
 232         return_value = Handle(thread, result);
 233         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 234         if (TraceDeoptimization) {
 235           ttyLocker ttyl;
 236           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 237         }
 238       }
 239       if (objects != NULL) {
 240         JRT_BLOCK
 241           realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);

 242         JRT_END
 243         reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal);
 244 #ifndef PRODUCT
 245         if (TraceDeoptimization) {
 246           ttyLocker ttyl;
 247           tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
 248           print_objects(objects, realloc_failures);
 249         }
 250 #endif
 251       }
 252       if (save_oop_result) {
 253         // Restore result.
 254         deoptee.set_saved_oop_result(&map, return_value());
 255       }
 256 #ifndef INCLUDE_JVMCI
 257     }
 258     if (EliminateLocks) {
 259 #endif // INCLUDE_JVMCI
 260 #ifndef PRODUCT
 261       bool first = true;
 262 #endif
 263       for (int i = 0; i < chunk->length(); i++) {


 914         ShouldNotReachHere();
 915     }
 916     index++;
 917   }
 918 }
 919 
 920 
 921 // restore fields of an eliminated object array
 922 void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) {
 923   for (int i = 0; i < sv->field_size(); i++) {
 924     StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
 925     assert(value->type() == T_OBJECT, "object element expected");
 926     obj->obj_at_put(i, value->get_obj()());
 927   }
 928 }
 929 
 930 class ReassignedField {
 931 public:
 932   int _offset;
 933   BasicType _type;

 934 public:
 935   ReassignedField() {
 936     _offset = 0;
 937     _type = T_ILLEGAL;

 938   }
 939 };
 940 
 941 int compare(ReassignedField* left, ReassignedField* right) {
 942   return left->_offset - right->_offset;
 943 }
 944 
 945 // Restore fields of an eliminated instance object using the same field order
 946 // returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
 947 static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal) {
 948   if (klass->superklass() != NULL) {
 949     svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal);
 950   }
 951 
 952   GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
 953   for (AllFieldStream fs(klass); !fs.done(); fs.next()) {
 954     if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) {
 955       ReassignedField field;
 956       field._offset = fs.offset();
 957       field._type = FieldType::basic_type(fs.signature());







 958       fields->append(field);
 959     }
 960   }
 961   fields->sort(compare);
 962   for (int i = 0; i < fields->length(); i++) {
 963     intptr_t val;
 964     ScopeValue* scope_field = sv->field_at(svIndex);
 965     StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
 966     int offset = fields->at(i)._offset;
 967     BasicType type = fields->at(i)._type;
 968     switch (type) {
 969       case T_OBJECT: case T_ARRAY:
 970         assert(value->type() == T_OBJECT, "Agreement.");
 971         obj->obj_field_put(offset, value->get_obj()());
 972         break;
 973 









 974       // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
 975       case T_INT: case T_FLOAT: { // 4 bytes.
 976         assert(value->type() == T_INT, "Agreement.");
 977         bool big_value = false;
 978         if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
 979           if (scope_field->is_location()) {
 980             Location::Type type = ((LocationValue*) scope_field)->location().type();
 981             if (type == Location::dbl || type == Location::lng) {
 982               big_value = true;
 983             }
 984           }
 985           if (scope_field->is_constant_int()) {
 986             ScopeValue* next_scope_field = sv->field_at(svIndex + 1);
 987             if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
 988               big_value = true;
 989             }
 990           }
 991         }
 992 
 993         if (big_value) {


1023         assert(value->type() == T_INT, "Agreement.");
1024         val = value->get_int();
1025         obj->short_field_put(offset, (jshort)*((jint*)&val));
1026         break;
1027 
1028       case T_BOOLEAN: case T_BYTE: // 1 byte
1029         assert(value->type() == T_INT, "Agreement.");
1030         val = value->get_int();
1031         obj->bool_field_put(offset, (jboolean)*((jint*)&val));
1032         break;
1033 
1034       default:
1035         ShouldNotReachHere();
1036     }
1037     svIndex++;
1038   }
1039   return svIndex;
1040 }
1041 
1042 // restore fields of all eliminated objects and arrays
1043 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal) {
1044   for (int i = 0; i < objects->length(); i++) {
1045     ObjectValue* sv = (ObjectValue*) objects->at(i);
1046     KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
1047     Handle obj = sv->value();
1048     assert(obj.not_null() || realloc_failures, "reallocation was missed");
1049     if (PrintDeoptimizationDetails) {
1050       tty->print_cr("reassign fields for object of type %s!", k->name()->as_C_string());
1051     }
1052     if (obj.is_null()) {
1053       continue;
1054     }
1055 
1056     if (k->is_instance_klass()) {
1057       InstanceKlass* ik = InstanceKlass::cast(k());
1058       reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal);
1059     } else if (k->is_typeArray_klass()) {
1060       TypeArrayKlass* ak = TypeArrayKlass::cast(k());
1061       reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
1062     } else if (k->is_objArray_klass()) {
1063       reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
1064     }
1065   }
1066 }
1067 
1068 
1069 // relock objects for which synchronization was eliminated
1070 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures) {
1071   for (int i = 0; i < monitors->length(); i++) {
1072     MonitorInfo* mon_info = monitors->at(i);
1073     if (mon_info->eliminated()) {
1074       assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed");
1075       if (!mon_info->owner_is_scalar_replaced()) {
1076         Handle obj = Handle(mon_info->owner());
1077         markOop mark = obj->mark();
1078         if (UseBiasedLocking && mark->has_bias_pattern()) {




  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "code/pcDesc.hpp"
  31 #include "code/scopeDesc.hpp"
  32 #include "interpreter/bytecode.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "interpreter/oopMapCache.hpp"
  35 #include "memory/allocation.inline.hpp"
  36 #include "memory/oopFactory.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "oops/method.hpp"
  39 #include "oops/objArrayOop.inline.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "oops/fieldStreams.hpp"
  42 #include "oops/valueKlass.hpp"
  43 #include "oops/verifyOopClosure.hpp"
  44 #include "prims/jvmtiThreadState.hpp"
  45 #include "runtime/biasedLocking.hpp"
  46 #include "runtime/compilationPolicy.hpp"
  47 #include "runtime/deoptimization.hpp"
  48 #include "runtime/interfaceSupport.hpp"
  49 #include "runtime/sharedRuntime.hpp"
  50 #include "runtime/signature.hpp"
  51 #include "runtime/stubRoutines.hpp"
  52 #include "runtime/thread.hpp"
  53 #include "runtime/vframe.hpp"
  54 #include "runtime/vframeArray.hpp"
  55 #include "runtime/vframe_hp.hpp"
  56 #include "utilities/events.hpp"
  57 #include "utilities/xmlstream.hpp"
  58 
  59 #if INCLUDE_JVMCI
  60 #include "jvmci/jvmciRuntime.hpp"
  61 #include "jvmci/jvmciJavaClasses.hpp"
  62 #endif


 223       // by analyzing bytecode in deoptimized frames. This is why this flag
 224       // is set during method compilation (see Compile::Process_OopMap_Node()).
 225       // If the previous frame was popped, we don't have a result.
 226       bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution();
 227       Handle return_value;
 228       if (save_oop_result) {
 229         // Reallocation may trigger GC. If deoptimization happened on return from
 230         // call which returns oop we need to save it since it is not in oopmap.
 231         oop result = deoptee.saved_oop_result(&map);
 232         assert(result == NULL || result->is_oop(), "must be oop");
 233         return_value = Handle(thread, result);
 234         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
 235         if (TraceDeoptimization) {
 236           ttyLocker ttyl;
 237           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread));
 238         }
 239       }
 240       if (objects != NULL) {
 241         JRT_BLOCK
 242           realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD);
 243           reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal, THREAD);
 244         JRT_END

 245 #ifndef PRODUCT
 246         if (TraceDeoptimization) {
 247           ttyLocker ttyl;
 248           tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread));
 249           print_objects(objects, realloc_failures);
 250         }
 251 #endif
 252       }
 253       if (save_oop_result) {
 254         // Restore result.
 255         deoptee.set_saved_oop_result(&map, return_value());
 256       }
 257 #ifndef INCLUDE_JVMCI
 258     }
 259     if (EliminateLocks) {
 260 #endif // INCLUDE_JVMCI
 261 #ifndef PRODUCT
 262       bool first = true;
 263 #endif
 264       for (int i = 0; i < chunk->length(); i++) {


 915         ShouldNotReachHere();
 916     }
 917     index++;
 918   }
 919 }
 920 
 921 
 922 // restore fields of an eliminated object array
 923 void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) {
 924   for (int i = 0; i < sv->field_size(); i++) {
 925     StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i));
 926     assert(value->type() == T_OBJECT, "object element expected");
 927     obj->obj_at_put(i, value->get_obj()());
 928   }
 929 }
 930 
 931 class ReassignedField {
 932 public:
 933   int _offset;
 934   BasicType _type;
 935   InstanceKlass* _klass;
 936 public:
 937   ReassignedField() {
 938     _offset = 0;
 939     _type = T_ILLEGAL;
 940     _klass = NULL;
 941   }
 942 };
 943 
 944 int compare(ReassignedField* left, ReassignedField* right) {
 945   return left->_offset - right->_offset;
 946 }
 947 
 948 // Restore fields of an eliminated instance object using the same field order
 949 // returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
 950 static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal, int base_offset, TRAPS) {
 951   if (klass->superklass() != NULL) {
 952     svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal, 0, CHECK_0);
 953   }
 954 
 955   GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>();
 956   for (AllFieldStream fs(klass); !fs.done(); fs.next()) {
 957     if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) {
 958       ReassignedField field;
 959       field._offset = fs.offset();
 960       field._type = FieldType::basic_type(fs.signature());
 961       if (field._type == T_VALUETYPE) {
 962         // Resolve klass of flattened value type field
 963         SignatureStream ss(fs.signature(), false);
 964         Klass* vk = ss.as_klass(Handle(klass->class_loader()), Handle(klass->protection_domain()), SignatureStream::NCDFError, CHECK_0);
 965         assert(vk->is_value(), "must be a ValueKlass");
 966         field._klass = InstanceKlass::cast(vk);
 967       }
 968       fields->append(field);
 969     }
 970   }
 971   fields->sort(compare);
 972   for (int i = 0; i < fields->length(); i++) {
 973     intptr_t val;
 974     ScopeValue* scope_field = sv->field_at(svIndex);
 975     StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
 976     int offset = base_offset + fields->at(i)._offset;
 977     BasicType type = fields->at(i)._type;
 978     switch (type) {
 979       case T_OBJECT: case T_ARRAY:
 980         assert(value->type() == T_OBJECT, "Agreement.");
 981         obj->obj_field_put(offset, value->get_obj()());
 982         break;
 983 
 984       case T_VALUETYPE: {
 985         // Recursively re-assign flattened value type fields
 986         InstanceKlass* vk = fields->at(i)._klass;
 987         assert(vk != NULL, "must be resolved");
 988         offset -= ValueKlass::cast(vk)->first_field_offset(); // Adjust offset to omit oop header
 989         svIndex = reassign_fields_by_klass(vk, fr, reg_map, sv, svIndex, obj, skip_internal, offset, CHECK_0);
 990         continue; // Continue because we don't need to increment svIndex
 991       }
 992 
 993       // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
 994       case T_INT: case T_FLOAT: { // 4 bytes.
 995         assert(value->type() == T_INT, "Agreement.");
 996         bool big_value = false;
 997         if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
 998           if (scope_field->is_location()) {
 999             Location::Type type = ((LocationValue*) scope_field)->location().type();
1000             if (type == Location::dbl || type == Location::lng) {
1001               big_value = true;
1002             }
1003           }
1004           if (scope_field->is_constant_int()) {
1005             ScopeValue* next_scope_field = sv->field_at(svIndex + 1);
1006             if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
1007               big_value = true;
1008             }
1009           }
1010         }
1011 
1012         if (big_value) {


1042         assert(value->type() == T_INT, "Agreement.");
1043         val = value->get_int();
1044         obj->short_field_put(offset, (jshort)*((jint*)&val));
1045         break;
1046 
1047       case T_BOOLEAN: case T_BYTE: // 1 byte
1048         assert(value->type() == T_INT, "Agreement.");
1049         val = value->get_int();
1050         obj->bool_field_put(offset, (jboolean)*((jint*)&val));
1051         break;
1052 
1053       default:
1054         ShouldNotReachHere();
1055     }
1056     svIndex++;
1057   }
1058   return svIndex;
1059 }
1060 
1061 // restore fields of all eliminated objects and arrays
1062 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal, TRAPS) {
1063   for (int i = 0; i < objects->length(); i++) {
1064     ObjectValue* sv = (ObjectValue*) objects->at(i);
1065     KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
1066     Handle obj = sv->value();
1067     assert(obj.not_null() || realloc_failures, "reallocation was missed");
1068     if (PrintDeoptimizationDetails) {
1069       tty->print_cr("reassign fields for object of type %s!", k->name()->as_C_string());
1070     }
1071     if (obj.is_null()) {
1072       continue;
1073     }
1074 
1075     if (k->is_instance_klass()) {
1076       InstanceKlass* ik = InstanceKlass::cast(k());
1077       reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal, 0, CHECK);
1078     } else if (k->is_typeArray_klass()) {
1079       TypeArrayKlass* ak = TypeArrayKlass::cast(k());
1080       reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
1081     } else if (k->is_objArray_klass()) {
1082       reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
1083     }
1084   }
1085 }
1086 
1087 
1088 // relock objects for which synchronization was eliminated
1089 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures) {
1090   for (int i = 0; i < monitors->length(); i++) {
1091     MonitorInfo* mon_info = monitors->at(i);
1092     if (mon_info->eliminated()) {
1093       assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed");
1094       if (!mon_info->owner_is_scalar_replaced()) {
1095         Handle obj = Handle(mon_info->owner());
1096         markOop mark = obj->mark();
1097         if (UseBiasedLocking && mark->has_bias_pattern()) {


< prev index next >