< prev index next >

src/share/vm/interpreter/interpreterRuntime.cpp

Print this page

        

@@ -264,18 +264,24 @@
   if (field_type == T_OBJECT || field_type == T_ARRAY) {
     oop aoop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
     assert(aoop == NULL || (oopDesc::is_oop(aoop) && (!aoop->is_value())),"argument must be a reference type");
     new_value_h()->obj_field_put(fd.offset(), aoop);
   } else if (field_type == T_VALUETYPE) {
+    if (fd.is_flatten()) {
     Klass* field_k = vklass->get_value_field_klass(fd.index());
     ValueKlass* field_vk = ValueKlass::cast(field_k);
     oop vt_oop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
     assert(vt_oop != NULL && oopDesc::is_oop(vt_oop) && vt_oop->is_value(),"argument must be a value type");
     assert(field_vk == vt_oop->klass(), "Must match");
     field_vk->value_store(field_vk->data_for_oop(vt_oop),
         ((char*)(oopDesc*)new_value_h()) + fd.offset(), true, false);
   } else {
+      oop voop = *(oop*)f.interpreter_frame_expression_stack_at(tos_idx);
+      assert(voop != NULL || (oopDesc::is_oop(voop) && (voop->is_value())),"argument must be a value type");
+      new_value_h()->obj_field_put(fd.offset(), voop);
+    }
+  } else {
     intptr_t* addr = f.interpreter_frame_expression_stack_at(tos_idx);
     copy_primitive_argument(addr, new_value_h, fd.offset(), field_type);
   }
 
   // returning result

@@ -328,28 +334,37 @@
                                                 InstanceKlass::cast(target_klass),
                                                 CHECK);
   thread->set_vm_result(value);
 IRT_END
 
-IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* value, int offset))
-  Handle value_h(THREAD, value);
-  InstanceKlass* klass = InstanceKlass::cast(value->klass());
+IRT_ENTRY(void, InterpreterRuntime::qgetfield(JavaThread* thread, oopDesc* obj, int offset))
+  Handle value_h(THREAD, obj);
+  InstanceKlass* klass = InstanceKlass::cast(obj->klass());
 
   fieldDescriptor fd;
   klass->find_field_from_offset(offset, false, &fd);
   Klass* field_k = klass->get_value_field_klass(fd.index());
   ValueKlass* field_vklass = ValueKlass::cast(field_k);
   field_vklass->initialize(THREAD);
 
-  // allocate instance
+  instanceOop res;
   bool in_heap;
-  instanceOop res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
+  if (fd.is_flatten()) {
+    // allocate instance
+    res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
   instanceHandle res_h(THREAD, res);
   // copy value
   field_vklass->value_store(((char*)(oopDesc*)value_h()) + offset,
                             field_vklass->data_for_oop(res), in_heap, false);
   thread->set_vm_result(res_h());
+  } else {
+    oop res = value_h()->obj_field_acquire(offset);
+    if (res == NULL) {
+      res = field_vklass->allocate_buffered_or_heap_instance(&in_heap, CHECK);
+    }
+    thread->set_vm_result(res);
+  }
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::initialize_static_value_field(JavaThread* thread, oopDesc* mirror, int offset))
   instanceHandle mirror_h(THREAD, (instanceOop)mirror);
   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));

@@ -377,13 +392,29 @@
   fieldDescriptor fd;
   klass->find_field_from_offset(offset, false, &fd);
   Klass* field_k = klass->get_value_field_klass(fd.index());
   ValueKlass* field_vklass = ValueKlass::cast(value->klass());
   assert(field_k == field_vklass, "Field descriptor and argument must match");
+  if (fd.is_flatten()) {
   // copy value
   field_vklass->value_store(field_vklass->data_for_oop(value_h()),
                             ((char*)(oopDesc*)obj_h()) + offset, true, false);
+  } else {
+    if (Universe::heap()->is_in_reserved(value_h())) {
+      obj_h()->obj_field_put(offset, value_h());
+    } else {
+      // allocate heap instance
+      instanceOop val = field_vklass->allocate_instance(CHECK);
+      instanceHandle res_h(THREAD, val);
+      // copy value
+      field_vklass->value_store(field_vklass->data_for_oop(value_h()),
+                                field_vklass->data_for_oop(res_h()), true, false);
+
+
+      obj_h()->obj_field_put(offset, res_h());
+    }
+  }
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::qputstatic(JavaThread* thread, oopDesc* value))
   instanceHandle value_h(THREAD, (instanceOop)value);
   assert(value_h()->is_value(), "qputstatic only deals with value arguments");

@@ -993,10 +1024,11 @@
     info.index(),
     info.offset(),
     state,
     info.access_flags().is_final(),
     info.access_flags().is_volatile(),
+    info.is_flatten(),
     pool->pool_holder()
   );
 }
 
 
< prev index next >