2033 if (ini != NULL) { |
2033 if (ini != NULL) { |
2034 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; |
2034 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; |
2035 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); |
2035 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); |
2036 if (store != NULL && store->is_Store()) { |
2036 if (store != NULL && store->is_Store()) { |
2037 value = store->in(MemNode::ValueIn); |
2037 value = store->in(MemNode::ValueIn); |
2038 } else if (ptn->edge_count() > 0) { // Are there oop stores? |
2038 } else { |
2039 // Check for a store which follows allocation without branches. |
2039 // There could be initializing stores which follow allocation. |
2040 // For example, a volatile field store is not collected |
2040 // For example, a volatile field store is not collected |
2041 // by Initialize node. TODO: it would be nice to use idom() here. |
2041 // by Initialize node. |
2042 // |
2042 // |
2043 // Search all references to the same field which use different |
2043 // Need to check for dependent loads to separate such stores from |
2044 // AddP nodes, for example, in the next case: |
2044 // stores which follow loads. For now, add initial value NULL so |
2045 // |
2045 // that compare pointers optimization works correctly. |
2046 // Point p[] = new Point[1]; |
|
2047 // if ( x ) { p[0] = new Point(); p[0].x = x; } |
|
2048 // if ( p[0] != null ) { y = p[0].x; } // has CastPP |
|
2049 // |
|
2050 for (uint next = ei; (next < ae_cnt) && (value == NULL); next++) { |
|
2051 uint fpi = pta->edge_target(next); // Field (AddP) |
|
2052 PointsToNode *ptf = ptnode_adr(fpi); |
|
2053 if (ptf->offset() == offset) { |
|
2054 Node* nf = ptf->_node; |
|
2055 for (DUIterator_Fast imax, i = nf->fast_outs(imax); i < imax; i++) { |
|
2056 store = nf->fast_out(i); |
|
2057 if (store->is_Store() && store->in(0) != NULL) { |
|
2058 Node* ctrl = store->in(0); |
|
2059 while(!(ctrl == ini || ctrl == alloc || ctrl == NULL || |
|
2060 ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() || |
|
2061 ctrl->is_IfTrue() || ctrl->is_IfFalse())) { |
|
2062 ctrl = ctrl->in(0); |
|
2063 } |
|
2064 if (ctrl == ini || ctrl == alloc) { |
|
2065 value = store->in(MemNode::ValueIn); |
|
2066 break; |
|
2067 } |
|
2068 } |
|
2069 } |
|
2070 } |
|
2071 } |
|
2072 } |
2046 } |
2073 } |
2047 } |
2074 if (value == NULL || value != ptnode_adr(value->_idx)->_node) { |
2048 if (value == NULL || value != ptnode_adr(value->_idx)->_node) { |
2075 // A field's initializing value was not recorded. Add NULL. |
2049 // A field's initializing value was not recorded. Add NULL. |
2076 add_edge_from_fields(alloc->_idx, null_idx, offset); |
2050 add_edge_from_fields(alloc->_idx, null_idx, offset); |