src/share/vm/opto/escape.cpp

changeset 4255
f3da5ff1514c
parent 4206
006174cfe979
child 4315
2aff40cb4703
     1.1 --- a/src/share/vm/opto/escape.cpp	Tue Nov 06 09:22:55 2012 -0800
     1.2 +++ b/src/share/vm/opto/escape.cpp	Tue Nov 06 15:16:32 2012 -0800
     1.3 @@ -1386,12 +1386,12 @@
     1.4      // Non-escaped allocation returned from Java or runtime call have
     1.5      // unknown values in fields.
     1.6      for (EdgeIterator i(pta); i.has_next(); i.next()) {
     1.7 -      PointsToNode* ptn = i.get();
     1.8 -      if (ptn->is_Field() && ptn->as_Field()->is_oop()) {
     1.9 -        if (add_edge(ptn, phantom_obj)) {
    1.10 +      PointsToNode* field = i.get();
    1.11 +      if (field->is_Field() && field->as_Field()->is_oop()) {
    1.12 +        if (add_edge(field, phantom_obj)) {
    1.13            // New edge was added
    1.14            new_edges++;
    1.15 -          add_field_uses_to_worklist(ptn->as_Field());
    1.16 +          add_field_uses_to_worklist(field->as_Field());
    1.17          }
    1.18        }
    1.19      }
    1.20 @@ -1413,30 +1413,30 @@
    1.21    // captured by Initialize node.
    1.22    //
    1.23    for (EdgeIterator i(pta); i.has_next(); i.next()) {
    1.24 -    PointsToNode* ptn = i.get(); // Field (AddP)
    1.25 -    if (!ptn->is_Field() || !ptn->as_Field()->is_oop())
    1.26 +    PointsToNode* field = i.get(); // Field (AddP)
    1.27 +    if (!field->is_Field() || !field->as_Field()->is_oop())
    1.28        continue; // Not oop field
    1.29 -    int offset = ptn->as_Field()->offset();
    1.30 +    int offset = field->as_Field()->offset();
    1.31      if (offset == Type::OffsetBot) {
    1.32        if (!visited_bottom_offset) {
    1.33          // OffsetBot is used to reference array's element,
    1.34          // always add reference to NULL to all Field nodes since we don't
    1.35          // known which element is referenced.
    1.36 -        if (add_edge(ptn, null_obj)) {
    1.37 +        if (add_edge(field, null_obj)) {
    1.38            // New edge was added
    1.39            new_edges++;
    1.40 -          add_field_uses_to_worklist(ptn->as_Field());
    1.41 +          add_field_uses_to_worklist(field->as_Field());
    1.42            visited_bottom_offset = true;
    1.43          }
    1.44        }
    1.45      } else {
    1.46        // Check only oop fields.
    1.47 -      const Type* adr_type = ptn->ideal_node()->as_AddP()->bottom_type();
    1.48 +      const Type* adr_type = field->ideal_node()->as_AddP()->bottom_type();
    1.49        if (adr_type->isa_rawptr()) {
    1.50  #ifdef ASSERT
    1.51          // Raw pointers are used for initializing stores so skip it
    1.52          // since it should be recorded already
    1.53 -        Node* base = get_addp_base(ptn->ideal_node());
    1.54 +        Node* base = get_addp_base(field->ideal_node());
    1.55          assert(adr_type->isa_rawptr() && base->is_Proj() &&
    1.56                 (base->in(0) == alloc),"unexpected pointer type");
    1.57  #endif
    1.58 @@ -1446,10 +1446,54 @@
    1.59          offsets_worklist.append(offset);
    1.60          Node* value = NULL;
    1.61          if (ini != NULL) {
    1.62 -          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
    1.63 -          Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
    1.64 -          if (store != NULL && store->is_Store()) {
    1.65 +          // StoreP::memory_type() == T_ADDRESS
    1.66 +          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_ADDRESS;
    1.67 +          Node* store = ini->find_captured_store(offset, type2aelembytes(ft, true), phase);
    1.68 +          // Make sure initializing store has the same type as this AddP.
    1.69 +          // This AddP may reference non existing field because it is on a
    1.70 +          // dead branch of bimorphic call which is not eliminated yet.
    1.71 +          if (store != NULL && store->is_Store() &&
    1.72 +              store->as_Store()->memory_type() == ft) {
    1.73              value = store->in(MemNode::ValueIn);
    1.74 +#ifdef ASSERT
    1.75 +            if (VerifyConnectionGraph) {
    1.76 +              // Verify that AddP already points to all objects the value points to.
    1.77 +              PointsToNode* val = ptnode_adr(value->_idx);
    1.78 +              assert((val != NULL), "should be processed already");
    1.79 +              PointsToNode* missed_obj = NULL;
    1.80 +              if (val->is_JavaObject()) {
    1.81 +                if (!field->points_to(val->as_JavaObject())) {
    1.82 +                  missed_obj = val;
    1.83 +                }
    1.84 +              } else {
    1.85 +                if (!val->is_LocalVar() || (val->edge_count() == 0)) {
    1.86 +                  tty->print_cr("----------init store has invalid value -----");
    1.87 +                  store->dump();
    1.88 +                  val->dump();
    1.89 +                  assert(val->is_LocalVar() && (val->edge_count() > 0), "should be processed already");
    1.90 +                }
    1.91 +                for (EdgeIterator j(val); j.has_next(); j.next()) {
    1.92 +                  PointsToNode* obj = j.get();
    1.93 +                  if (obj->is_JavaObject()) {
    1.94 +                    if (!field->points_to(obj->as_JavaObject())) {
    1.95 +                      missed_obj = obj;
    1.96 +                      break;
    1.97 +                    }
    1.98 +                  }
    1.99 +                }
   1.100 +              }
   1.101 +              if (missed_obj != NULL) {
   1.102 +                tty->print_cr("----------field---------------------------------");
   1.103 +                field->dump();
   1.104 +                tty->print_cr("----------missed referernce to object-----------");
   1.105 +                missed_obj->dump();
   1.106 +                tty->print_cr("----------object referernced by init store -----");
   1.107 +                store->dump();
   1.108 +                val->dump();
   1.109 +                assert(!field->points_to(missed_obj->as_JavaObject()), "missed JavaObject reference");
   1.110 +              }
   1.111 +            }
   1.112 +#endif
   1.113            } else {
   1.114              // There could be initializing stores which follow allocation.
   1.115              // For example, a volatile field store is not collected
   1.116 @@ -1462,10 +1506,10 @@
   1.117          }
   1.118          if (value == NULL) {
   1.119            // A field's initializing value was not recorded. Add NULL.
   1.120 -          if (add_edge(ptn, null_obj)) {
   1.121 +          if (add_edge(field, null_obj)) {
   1.122              // New edge was added
   1.123              new_edges++;
   1.124 -            add_field_uses_to_worklist(ptn->as_Field());
   1.125 +            add_field_uses_to_worklist(field->as_Field());
   1.126            }
   1.127          }
   1.128        }
   1.129 @@ -1607,7 +1651,26 @@
   1.130        }
   1.131        // Verify that all fields have initializing values.
   1.132        if (field->edge_count() == 0) {
   1.133 +        tty->print_cr("----------field does not have references----------");
   1.134          field->dump();
   1.135 +        for (BaseIterator i(field); i.has_next(); i.next()) {
   1.136 +          PointsToNode* base = i.get();
   1.137 +          tty->print_cr("----------field has next base---------------------");
   1.138 +          base->dump();
   1.139 +          if (base->is_JavaObject() && (base != phantom_obj) && (base != null_obj)) {
   1.140 +            tty->print_cr("----------base has fields-------------------------");
   1.141 +            for (EdgeIterator j(base); j.has_next(); j.next()) {
   1.142 +              j.get()->dump();
   1.143 +            }
   1.144 +            tty->print_cr("----------base has references---------------------");
   1.145 +            for (UseIterator j(base); j.has_next(); j.next()) {
   1.146 +              j.get()->dump();
   1.147 +            }
   1.148 +          }
   1.149 +        }
   1.150 +        for (UseIterator i(field); i.has_next(); i.next()) {
   1.151 +          i.get()->dump();
   1.152 +        }
   1.153          assert(field->edge_count() > 0, "sanity");
   1.154        }
   1.155      }
   1.156 @@ -1967,7 +2030,7 @@
   1.157    if (is_JavaObject()) {
   1.158      return (this == ptn);
   1.159    }
   1.160 -  assert(is_LocalVar(), "sanity");
   1.161 +  assert(is_LocalVar() || is_Field(), "sanity");
   1.162    for (EdgeIterator i(this); i.has_next(); i.next()) {
   1.163      if (i.get() == ptn)
   1.164        return true;
   1.165 @@ -3127,10 +3190,14 @@
   1.166      EscapeState fields_es = fields_escape_state();
   1.167      tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]);
   1.168      if (nt == PointsToNode::JavaObject && !this->scalar_replaceable())
   1.169 -      tty->print("NSR");
   1.170 +      tty->print("NSR ");
   1.171    }
   1.172    if (is_Field()) {
   1.173      FieldNode* f = (FieldNode*)this;
   1.174 +    if (f->is_oop())
   1.175 +      tty->print("oop ");
   1.176 +    if (f->offset() > 0)
   1.177 +      tty->print("+%d ", f->offset());
   1.178      tty->print("(");
   1.179      for (BaseIterator i(f); i.has_next(); i.next()) {
   1.180        PointsToNode* b = i.get();

mercurial