< prev index next >

src/share/vm/opto/escape.cpp

Print this page

        

@@ -882,11 +882,11 @@
         // it's fields will be marked as NoEscape at least.
         add_java_object(call, PointsToNode::NoEscape);
         ptnode_adr(call_idx)->set_scalar_replaceable(false);
       } else {
         // Determine whether any arguments are returned.
-        const TypeTuple* d = call->tf()->domain_sig();
+        const TypeTuple* d = call->tf()->domain_cc();
         bool ret_arg = false;
         for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
           if (d->field_at(i)->isa_ptr() != NULL &&
               call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
             ret_arg = true;

@@ -1057,20 +1057,15 @@
       }
       BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
       // fall-through if not a Java method or no analyzer information
       if (call_analyzer != NULL) {
         PointsToNode* call_ptn = ptnode_adr(call->_idx);
-        const TypeTuple* d = call->tf()->domain_sig();
-        int extra = 0;
+        const TypeTuple* d = call->tf()->domain_cc();
         for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
           const Type* at = d->field_at(i);
-          if (at->isa_valuetypeptr()) {
-            extra += at->is_valuetypeptr()->value_type()->value_klass()->field_count() - 1;
-            continue;
-          }
           int k = i - TypeFunc::Parms;
-          Node* arg = call->in(i + extra);
+          Node* arg = call->in(i);
           PointsToNode* arg_ptn = ptnode_adr(arg->_idx);
           if (at->isa_ptr() != NULL &&
               call_analyzer->is_arg_returned(k)) {
             // The call returns arguments.
             if (call_ptn != NULL) { // Is call's result used?

@@ -1106,11 +1101,11 @@
     }
     default: {
       // Fall-through here if not a Java method or no analyzer information
       // or some other type of call, assume the worst case: all arguments
       // globally escape.
-      const TypeTuple* d = call->tf()->domain_sig();
+      const TypeTuple* d = call->tf()->domain_cc();
       for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
         const Type* at = d->field_at(i);
         if (at->isa_oopptr() != NULL) {
           Node* arg = call->in(i);
           if (arg->is_AddP()) {

@@ -2052,12 +2047,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.

@@ -2084,12 +2080,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) ||
           n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
           n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {

@@ -2409,11 +2412,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 >