< prev index next >

src/share/vm/opto/escape.cpp

Print this page

        

@@ -2050,12 +2050,13 @@
   dst->set_arraycopy_dst();
 }
 
 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
   const Type* adr_type = n->as_AddP()->bottom_type();
+  int field_offset = adr_type->isa_aryptr() ? adr_type->isa_aryptr()->field_offset().get() : Type::OffsetBot;
   BasicType bt = T_INT;
-  if (offset == Type::OffsetBot) {
+  if (offset == Type::OffsetBot && field_offset == Type::OffsetBot) {
     // Check only oop fields.
     if (!adr_type->isa_aryptr() ||
         (adr_type->isa_aryptr()->klass() == NULL) ||
          adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
       // OffsetBot is used to reference array's element. Ignore first AddP.

@@ -2080,12 +2081,19 @@
         // Ignore array length load.
       } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
         // Ignore first AddP.
       } else {
         const Type* elemtype = adr_type->isa_aryptr()->elem();
+        if (elemtype->isa_valuetype()) {
+          assert(field_offset != Type::OffsetBot, "invalid field offset");
+          ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
+          field_offset += vk->first_field_offset();
+          bt = vk->get_field_by_offset(field_offset, false)->layout_type();
+        } else {
         bt = elemtype->array_element_basic_type();
       }
+      }
     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
       // Allocation initialization, ThreadLocal field access, unsafe access
       if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
         bt = T_OBJECT;
       }

@@ -2403,11 +2411,11 @@
   }
   const TypePtr* tinst = base_t->add_offset(t->offset());
   if (tinst->isa_aryptr() && t->isa_aryptr()) {
     // In the case of a flattened value type array, each field has its
     // own slice so we need to keep track of the field being accessed.
-    tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset());
+    tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset().get());
   }
 
   // Do NOT remove the next line: ensure a new alias index is allocated
   // for the instance type. Note: C++ will not remove it since the call
   // has side effect.
< prev index next >