1.1 --- a/src/share/vm/opto/node.cpp Tue May 05 18:39:57 2020 +0100 1.2 +++ b/src/share/vm/opto/node.cpp Tue Mar 10 10:46:35 2020 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -818,8 +818,9 @@ 1.11 // First remove corresponding def-use edge 1.12 Node *n = in(idx); 1.13 if (n != NULL) n->del_out((Node *)this); 1.14 - _in[idx] = in(--_cnt); // Compact the array 1.15 - _in[_cnt] = NULL; // NULL out emptied slot 1.16 + _in[idx] = in(--_cnt); // Compact the array 1.17 + // Avoid spec violation: Gap in prec edges. 1.18 + close_prec_gap_at(_cnt); 1.19 } 1.20 1.21 //------------------------------del_req_ordered-------------------------------- 1.22 @@ -831,10 +832,11 @@ 1.23 // First remove corresponding def-use edge 1.24 Node *n = in(idx); 1.25 if (n != NULL) n->del_out((Node *)this); 1.26 - if (idx < _cnt - 1) { // Not last edge ? 1.27 - Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*))); 1.28 + if (idx < --_cnt) { // Not last edge ? 1.29 + Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx)*sizeof(Node*))); 1.30 } 1.31 - _in[--_cnt] = NULL; // NULL out emptied slot 1.32 + // Avoid spec violation: Gap in prec edges. 1.33 + close_prec_gap_at(_cnt); 1.34 } 1.35 1.36 //------------------------------ins_req---------------------------------------- 1.37 @@ -865,10 +867,12 @@ 1.38 uint nrep = 0; 1.39 for (uint i = 0; i < len(); i++) { 1.40 if (in(i) == old) { 1.41 - if (i < req()) 1.42 + if (i < req()) { 1.43 set_req(i, neww); 1.44 - else 1.45 + } else { 1.46 + assert(find_prec_edge(neww) == -1, err_msg("spec violation: duplicated prec edge (node %d -> %d)", _idx, neww->_idx)); 1.47 set_prec(i, neww); 1.48 + } 1.49 nrep++; 1.50 } 1.51 } 1.52 @@ -974,24 +978,27 @@ 1.53 1.54 // Find a precedence edge to move 1.55 uint i = _cnt; 1.56 - while( in(i) != NULL ) i++; 1.57 + while( in(i) != NULL ) { 1.58 + if (in(i) == n) return; // Avoid spec violation: duplicated prec edge. 1.59 + i++; 1.60 + } 1.61 _in[i] = n; // Stuff prec edge over NULL 1.62 if ( n != NULL) n->add_out((Node *)this); // Add mirror edge 1.63 + 1.64 +#ifdef ASSERT 1.65 + while ((++i)<_max) { assert(_in[i] == NULL, err_msg("spec violation: Gap in prec edges (node %d)", _idx)); } 1.66 +#endif 1.67 } 1.68 1.69 //------------------------------rm_prec---------------------------------------- 1.70 // Remove a precedence input. Precedence inputs are unordered, with 1.71 // duplicates removed and NULLs packed down at the end. 1.72 void Node::rm_prec( uint j ) { 1.73 - 1.74 - // Find end of precedence list to pack NULLs 1.75 - uint i; 1.76 - for( i=j; i<_max; i++ ) 1.77 - if( !_in[i] ) // Find the NULL at end of prec edge list 1.78 - break; 1.79 - if (_in[j] != NULL) _in[j]->del_out((Node *)this); 1.80 - _in[j] = _in[--i]; // Move last element over removed guy 1.81 - _in[i] = NULL; // NULL out last element 1.82 + assert(j < _max, err_msg("oob: i=%d, _max=%d", j, _max)); 1.83 + assert(j >= _cnt, "not a precedence edge"); 1.84 + if (_in[j] == NULL) return; // Avoid spec violation: Gap in prec edges. 1.85 + _in[j]->del_out((Node *)this); 1.86 + close_prec_gap_at(j); 1.87 } 1.88 1.89 //------------------------------size_of----------------------------------------