< prev index next >
src/share/vm/runtime/deoptimization.cpp
Print this page
@@ -37,10 +37,11 @@
#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,12 +238,12 @@
}
}
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
- 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);
@@ -929,50 +930,68 @@
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) {
+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);
+ 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 = fields->at(i)._offset;
+ 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,11 +1057,11 @@
}
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) {
+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,11 +1072,11 @@
continue;
}
if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k());
- reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal);
+ 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 >