< prev index next >

src/share/vm/runtime/deoptimization.cpp

Print this page

        

*** 37,46 **** --- 37,47 ---- #include "memory/resourceArea.hpp" #include "oops/method.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" + #include "oops/valueKlass.hpp" #include "oops/verifyOopClosure.hpp" #include "prims/jvmtiThreadState.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp"
*** 237,248 **** } } if (objects != NULL) { JRT_BLOCK realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD); JRT_END - reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); print_objects(objects, realloc_failures); --- 238,249 ---- } } if (objects != NULL) { JRT_BLOCK realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD); + reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal, THREAD); JRT_END #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); print_objects(objects, realloc_failures);
*** 929,978 **** class ReassignedField { public: int _offset; BasicType _type; public: ReassignedField() { _offset = 0; _type = T_ILLEGAL; } }; int compare(ReassignedField* left, ReassignedField* right) { return left->_offset - right->_offset; } // Restore fields of an eliminated instance object using the same field order // returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true) ! static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj, bool skip_internal) { if (klass->superklass() != NULL) { ! svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal); } GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>(); for (AllFieldStream fs(klass); !fs.done(); fs.next()) { if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) { ReassignedField field; field._offset = fs.offset(); field._type = FieldType::basic_type(fs.signature()); fields->append(field); } } fields->sort(compare); for (int i = 0; i < fields->length(); i++) { intptr_t val; ScopeValue* scope_field = sv->field_at(svIndex); StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field); ! int offset = fields->at(i)._offset; BasicType type = fields->at(i)._type; switch (type) { case T_OBJECT: case T_ARRAY: assert(value->type() == T_OBJECT, "Agreement."); obj->obj_field_put(offset, value->get_obj()()); break; // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. case T_INT: case T_FLOAT: { // 4 bytes. assert(value->type() == T_INT, "Agreement."); bool big_value = false; if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) { --- 930,997 ---- class ReassignedField { public: int _offset; BasicType _type; + InstanceKlass* _klass; public: ReassignedField() { _offset = 0; _type = T_ILLEGAL; + _klass = NULL; } }; int compare(ReassignedField* left, ReassignedField* right) { return left->_offset - right->_offset; } // Restore fields of an eliminated instance object using the same field order // returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true) ! 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) { if (klass->superklass() != NULL) { ! svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj, skip_internal, 0, CHECK_0); } GrowableArray<ReassignedField>* fields = new GrowableArray<ReassignedField>(); for (AllFieldStream fs(klass); !fs.done(); fs.next()) { if (!fs.access_flags().is_static() && (!skip_internal || !fs.access_flags().is_internal())) { ReassignedField field; field._offset = fs.offset(); field._type = FieldType::basic_type(fs.signature()); + if (field._type == T_VALUETYPE) { + // Resolve klass of flattened value type field + SignatureStream ss(fs.signature(), false); + Klass* vk = ss.as_klass(Handle(klass->class_loader()), Handle(klass->protection_domain()), SignatureStream::NCDFError, CHECK_0); + assert(vk->is_value(), "must be a ValueKlass"); + field._klass = InstanceKlass::cast(vk); + } fields->append(field); } } fields->sort(compare); for (int i = 0; i < fields->length(); i++) { intptr_t val; ScopeValue* scope_field = sv->field_at(svIndex); StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field); ! int offset = base_offset + fields->at(i)._offset; BasicType type = fields->at(i)._type; switch (type) { case T_OBJECT: case T_ARRAY: assert(value->type() == T_OBJECT, "Agreement."); obj->obj_field_put(offset, value->get_obj()()); break; + case T_VALUETYPE: { + // Recursively re-assign flattened value type fields + InstanceKlass* vk = fields->at(i)._klass; + assert(vk != NULL, "must be resolved"); + offset -= ValueKlass::cast(vk)->first_field_offset(); // Adjust offset to omit oop header + svIndex = reassign_fields_by_klass(vk, fr, reg_map, sv, svIndex, obj, skip_internal, offset, CHECK_0); + continue; // Continue because we don't need to increment svIndex + } + // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. case T_INT: case T_FLOAT: { // 4 bytes. assert(value->type() == T_INT, "Agreement."); bool big_value = false; if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
*** 1038,1048 **** } return svIndex; } // restore fields of all eliminated objects and arrays ! void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal) { for (int i = 0; i < objects->length(); i++) { ObjectValue* sv = (ObjectValue*) objects->at(i); KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); Handle obj = sv->value(); assert(obj.not_null() || realloc_failures, "reallocation was missed"); --- 1057,1067 ---- } return svIndex; } // restore fields of all eliminated objects and arrays ! void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures, bool skip_internal, TRAPS) { for (int i = 0; i < objects->length(); i++) { ObjectValue* sv = (ObjectValue*) objects->at(i); KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); Handle obj = sv->value(); assert(obj.not_null() || realloc_failures, "reallocation was missed");
*** 1053,1063 **** continue; } if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k()); ! reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal); } else if (k->is_typeArray_klass()) { TypeArrayKlass* ak = TypeArrayKlass::cast(k()); reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); } else if (k->is_objArray_klass()) { reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj()); --- 1072,1082 ---- continue; } if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k()); ! reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal, 0, CHECK); } else if (k->is_typeArray_klass()) { TypeArrayKlass* ak = TypeArrayKlass::cast(k()); reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); } else if (k->is_objArray_klass()) { reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
< prev index next >