1 /* |
1 /* |
2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
348 uint n_idx = n->_idx; |
348 uint n_idx = n->_idx; |
349 PointsToNode* n_ptn = ptnode_adr(n_idx); |
349 PointsToNode* n_ptn = ptnode_adr(n_idx); |
350 if (n_ptn != NULL) |
350 if (n_ptn != NULL) |
351 return; // No need to redefine PointsTo node during first iteration. |
351 return; // No need to redefine PointsTo node during first iteration. |
352 |
352 |
|
353 int opcode = n->Opcode(); |
|
354 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode); |
|
355 if (gc_handled) { |
|
356 return; // Ignore node if already handled by GC. |
|
357 } |
|
358 |
353 if (n->is_Call()) { |
359 if (n->is_Call()) { |
354 // Arguments to allocation and locking don't escape. |
360 // Arguments to allocation and locking don't escape. |
355 if (n->is_AbstractLock()) { |
361 if (n->is_AbstractLock()) { |
356 // Put Lock and Unlock nodes on IGVN worklist to process them during |
362 // Put Lock and Unlock nodes on IGVN worklist to process them during |
357 // first IGVN optimization when escape information is still available. |
363 // first IGVN optimization when escape information is still available. |
380 // Put this check here to process call arguments since some call nodes |
386 // Put this check here to process call arguments since some call nodes |
381 // point to phantom_obj. |
387 // point to phantom_obj. |
382 if (n_ptn == phantom_obj || n_ptn == null_obj) |
388 if (n_ptn == phantom_obj || n_ptn == null_obj) |
383 return; // Skip predefined nodes. |
389 return; // Skip predefined nodes. |
384 |
390 |
385 int opcode = n->Opcode(); |
|
386 bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->escape_add_to_con_graph(this, igvn, delayed_worklist, n, opcode); |
|
387 if (gc_handled) { |
|
388 return; // Ignore node if already handled by GC. |
|
389 } |
|
390 switch (opcode) { |
391 switch (opcode) { |
391 case Op_AddP: { |
392 case Op_AddP: { |
392 Node* base = get_addp_base(n); |
393 Node* base = get_addp_base(n); |
393 PointsToNode* ptn_base = ptnode_adr(base->_idx); |
394 PointsToNode* ptn_base = ptnode_adr(base->_idx); |
394 // Field nodes are created for all field types. They are used in |
395 // Field nodes are created for all field types. They are used in |
987 strcmp(call->as_CallLeaf()->_name, "updateBytesAdler32") == 0 || |
988 strcmp(call->as_CallLeaf()->_name, "updateBytesAdler32") == 0 || |
988 strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 || |
989 strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 || |
989 strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || |
990 strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || |
990 strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || |
991 strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || |
991 strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || |
992 strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0 || |
|
993 strcmp(call->as_CallLeaf()->_name, "electronicCodeBook_encryptAESCrypt") == 0 || |
|
994 strcmp(call->as_CallLeaf()->_name, "electronicCodeBook_decryptAESCrypt") == 0 || |
992 strcmp(call->as_CallLeaf()->_name, "counterMode_AESCrypt") == 0 || |
995 strcmp(call->as_CallLeaf()->_name, "counterMode_AESCrypt") == 0 || |
993 strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 || |
996 strcmp(call->as_CallLeaf()->_name, "ghash_processBlocks") == 0 || |
994 strcmp(call->as_CallLeaf()->_name, "encodeBlock") == 0 || |
997 strcmp(call->as_CallLeaf()->_name, "encodeBlock") == 0 || |
995 strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || |
998 strcmp(call->as_CallLeaf()->_name, "sha1_implCompress") == 0 || |
996 strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || |
999 strcmp(call->as_CallLeaf()->_name, "sha1_implCompressMB") == 0 || |
2108 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) { |
2111 BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) { |
2109 bt = T_OBJECT; |
2112 bt = T_OBJECT; |
2110 } |
2113 } |
2111 } |
2114 } |
2112 } |
2115 } |
2113 return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY); |
2116 // Note: T_NARROWOOP is not classed as a real reference type |
|
2117 return (is_reference_type(bt) || bt == T_NARROWOOP); |
2114 } |
2118 } |
2115 |
2119 |
2116 // Returns unique pointed java object or NULL. |
2120 // Returns unique pointed java object or NULL. |
2117 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) { |
2121 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) { |
2118 assert(!_collecting, "should not call when contructed graph"); |
2122 assert(!_collecting, "should not call when contructed graph"); |
2120 uint idx = n->_idx; |
2124 uint idx = n->_idx; |
2121 if (idx >= nodes_size()) { |
2125 if (idx >= nodes_size()) { |
2122 return NULL; |
2126 return NULL; |
2123 } |
2127 } |
2124 PointsToNode* ptn = ptnode_adr(idx); |
2128 PointsToNode* ptn = ptnode_adr(idx); |
|
2129 if (ptn == NULL) { |
|
2130 return NULL; |
|
2131 } |
2125 if (ptn->is_JavaObject()) { |
2132 if (ptn->is_JavaObject()) { |
2126 return ptn->as_JavaObject(); |
2133 return ptn->as_JavaObject(); |
2127 } |
2134 } |
2128 assert(ptn->is_LocalVar(), "sanity"); |
2135 assert(ptn->is_LocalVar(), "sanity"); |
2129 // Check all java objects it points to. |
2136 // Check all java objects it points to. |
2173 uint idx = n->_idx; |
2180 uint idx = n->_idx; |
2174 if (idx >= nodes_size()) { |
2181 if (idx >= nodes_size()) { |
2175 return false; |
2182 return false; |
2176 } |
2183 } |
2177 PointsToNode* ptn = ptnode_adr(idx); |
2184 PointsToNode* ptn = ptnode_adr(idx); |
|
2185 if (ptn == NULL) { |
|
2186 return false; // not in congraph (e.g. ConI) |
|
2187 } |
2178 PointsToNode::EscapeState es = ptn->escape_state(); |
2188 PointsToNode::EscapeState es = ptn->escape_state(); |
2179 // If we have already computed a value, return it. |
2189 // If we have already computed a value, return it. |
2180 if (es >= PointsToNode::GlobalEscape) |
2190 if (es >= PointsToNode::GlobalEscape) |
2181 return false; |
2191 return false; |
2182 if (ptn->is_JavaObject()) { |
2192 if (ptn->is_JavaObject()) { |
2344 Node* uncast_base = base->uncast(); |
2354 Node* uncast_base = base->uncast(); |
2345 int opcode = uncast_base->Opcode(); |
2355 int opcode = uncast_base->Opcode(); |
2346 assert(opcode == Op_ConP || opcode == Op_ThreadLocal || |
2356 assert(opcode == Op_ConP || opcode == Op_ThreadLocal || |
2347 opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() || |
2357 opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() || |
2348 (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) || |
2358 (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) || |
2349 (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()) || |
2359 (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity"); |
2350 BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(uncast_base), "sanity"); |
|
2351 } |
2360 } |
2352 } |
2361 } |
2353 return base; |
2362 return base; |
2354 } |
2363 } |
2355 |
2364 |
3083 if (!split_AddP(n, base)) continue; // wrong type from dead path |
3092 if (!split_AddP(n, base)) continue; // wrong type from dead path |
3084 } else if (n->is_Phi() || |
3093 } else if (n->is_Phi() || |
3085 n->is_CheckCastPP() || |
3094 n->is_CheckCastPP() || |
3086 n->is_EncodeP() || |
3095 n->is_EncodeP() || |
3087 n->is_DecodeN() || |
3096 n->is_DecodeN() || |
3088 BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(n) || |
|
3089 (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { |
3097 (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { |
3090 if (visited.test_set(n->_idx)) { |
3098 if (visited.test_set(n->_idx)) { |
3091 assert(n->is_Phi(), "loops only through Phi's"); |
3099 assert(n->is_Phi(), "loops only through Phi's"); |
3092 continue; // already processed |
3100 continue; // already processed |
3093 } |
3101 } |
3154 alloc_worklist.append_if_missing(use); |
3162 alloc_worklist.append_if_missing(use); |
3155 } else if (use->is_Phi() || |
3163 } else if (use->is_Phi() || |
3156 use->is_CheckCastPP() || |
3164 use->is_CheckCastPP() || |
3157 use->is_EncodeNarrowPtr() || |
3165 use->is_EncodeNarrowPtr() || |
3158 use->is_DecodeNarrowPtr() || |
3166 use->is_DecodeNarrowPtr() || |
3159 BarrierSet::barrier_set()->barrier_set_c2()->escape_is_barrier_node(use) || |
|
3160 (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { |
3167 (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { |
3161 alloc_worklist.append_if_missing(use); |
3168 alloc_worklist.append_if_missing(use); |
3162 #ifdef ASSERT |
3169 #ifdef ASSERT |
3163 } else if (use->is_Mem()) { |
3170 } else if (use->is_Mem()) { |
3164 assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path"); |
3171 assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path"); |