2018 // Ignore array length load 2019 } 2020 #ifdef ASSERT 2021 } else { 2022 // Raw pointers are used for initializing stores so skip it 2023 // since it should be recorded already 2024 Node* base = get_addp_base(ptn->_node); 2025 assert(adr_type->isa_rawptr() && base->is_Proj() && 2026 (base->in(0) == alloc),"unexpected pointer type"); 2027 #endif 2028 } 2029 if (basic_field_type == T_OBJECT || 2030 basic_field_type == T_NARROWOOP || 2031 basic_field_type == T_ARRAY) { 2032 Node* value = NULL; 2033 if (ini != NULL) { 2034 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; 2035 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); 2036 if (store != NULL && store->is_Store()) { 2037 value = store->in(MemNode::ValueIn); 2038 } else if (ptn->edge_count() > 0) { // Are there oop stores? 2039 // Check for a store which follows allocation without branches. 2040 // For example, a volatile field store is not collected 2041 // by Initialize node. TODO: it would be nice to use idom() here. 2042 // 2043 // Search all references to the same field which use different 2044 // AddP nodes, for example, in the next case: 2045 // 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 } 2073 } 2074 if (value == NULL || value != ptnode_adr(value->_idx)->_node) { 2075 // A field's initializing value was not recorded. Add NULL. 2076 add_edge_from_fields(alloc->_idx, null_idx, offset); 2077 } 2078 } 2079 } 2080 } 2081 } 2082 2083 // Adjust escape state after Connection Graph is built. 2084 void ConnectionGraph::adjust_escape_state(Node* n) { 2085 PointsToNode* ptn = ptnode_adr(n->_idx); 2086 assert(n->is_AddP(), "Should be called for AddP nodes only"); 2087 // Search for objects which are not scalar replaceable 2088 // and mark them to propagate the state to referenced objects. 2089 // 2090 2091 int offset = ptn->offset(); 2092 Node* base = get_addp_base(n); 2093 VectorSet* ptset = PointsTo(base); | 2018 // Ignore array length load 2019 } 2020 #ifdef ASSERT 2021 } else { 2022 // Raw pointers are used for initializing stores so skip it 2023 // since it should be recorded already 2024 Node* base = get_addp_base(ptn->_node); 2025 assert(adr_type->isa_rawptr() && base->is_Proj() && 2026 (base->in(0) == alloc),"unexpected pointer type"); 2027 #endif 2028 } 2029 if (basic_field_type == T_OBJECT || 2030 basic_field_type == T_NARROWOOP || 2031 basic_field_type == T_ARRAY) { 2032 Node* value = NULL; 2033 if (ini != NULL) { 2034 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT; 2035 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); 2036 if (store != NULL && store->is_Store()) { 2037 value = store->in(MemNode::ValueIn); 2038 } else { 2039 // There could be initializing stores which follow allocation. 2040 // For example, a volatile field store is not collected 2041 // by Initialize node. 2042 // 2043 // Need to check for dependent loads to separate such stores from 2044 // stores which follow loads. For now, add initial value NULL so 2045 // that compare pointers optimization works correctly. 2046 } 2047 } 2048 if (value == NULL || value != ptnode_adr(value->_idx)->_node) { 2049 // A field's initializing value was not recorded. Add NULL. 2050 add_edge_from_fields(alloc->_idx, null_idx, offset); 2051 } 2052 } 2053 } 2054 } 2055 } 2056 2057 // Adjust escape state after Connection Graph is built. 2058 void ConnectionGraph::adjust_escape_state(Node* n) { 2059 PointsToNode* ptn = ptnode_adr(n->_idx); 2060 assert(n->is_AddP(), "Should be called for AddP nodes only"); 2061 // Search for objects which are not scalar replaceable 2062 // and mark them to propagate the state to referenced objects. 2063 // 2064 2065 int offset = ptn->offset(); 2066 Node* base = get_addp_base(n); 2067 VectorSet* ptset = PointsTo(base); |