< prev index next >
src/share/vm/opto/node.cpp
Print this page
rev 9821 : 8146612: C2: Precedence edges specification violated
Reviewed-by:
*** 1,7 ****
/*
! * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 795,805 ****
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
_in[idx] = in(--_cnt); // Compact the array
! _in[_cnt] = NULL; // NULL out emptied slot
Compile::current()->record_modified_node(this);
}
//------------------------------del_req_ordered--------------------------------
// Delete the required edge and compact the edge array with preserved order
--- 795,814 ----
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
_in[idx] = in(--_cnt); // Compact the array
! // Avoid spec violation: Gap in prec edges.
! uint i = _cnt;
! Node *last = NULL;
! for (; i < len()-1; ++i) {
! Node *next = _in[i+1];
! if (next == NULL) break;
! last = next;
! }
! _in[_cnt] = last; // Move last slot to empty one.
! _in[i] = NULL; // NULL out last slot.
Compile::current()->record_modified_node(this);
}
//------------------------------del_req_ordered--------------------------------
// Delete the required edge and compact the edge array with preserved order
*** 808,821 ****
assert( !VerifyHashTableKeys || _hash_lock == 0,
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
! if (idx < _cnt - 1) { // Not last edge ?
! Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*)));
}
! _in[--_cnt] = NULL; // NULL out emptied slot
Compile::current()->record_modified_node(this);
}
//------------------------------ins_req----------------------------------------
// Insert a new required input at the end
--- 817,839 ----
assert( !VerifyHashTableKeys || _hash_lock == 0,
"remove node from hash table before modifying it");
// First remove corresponding def-use edge
Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this);
! if (idx < --_cnt) { // Not last edge ?
! Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx)*sizeof(Node*)));
! }
! // Avoid spec violation: Gap in prec edges.
! uint i = _cnt;
! Node *last = NULL;
! for (; i < len()-1; ++i) {
! Node *next = _in[i+1];
! if (next == NULL) break;
! last = next;
}
! _in[_cnt] = last; // Move last slot to empty one.
! _in[i] = NULL; // NULL out last slot.
Compile::current()->record_modified_node(this);
}
//------------------------------ins_req----------------------------------------
// Insert a new required input at the end
*** 843,856 ****
int Node::replace_edge(Node* old, Node* neww) {
if (old == neww) return 0; // nothing to do
uint nrep = 0;
for (uint i = 0; i < len(); i++) {
if (in(i) == old) {
! if (i < req())
set_req(i, neww);
! else
set_prec(i, neww);
nrep++;
}
}
return nrep;
}
--- 861,876 ----
int Node::replace_edge(Node* old, Node* neww) {
if (old == neww) return 0; // nothing to do
uint nrep = 0;
for (uint i = 0; i < len(); i++) {
if (in(i) == old) {
! if (i < req()) {
set_req(i, neww);
! } else {
! assert(find_prec_edge(neww) == -1, "spec violation: multiple prec edge (node %d -> %d)", _idx, neww->_idx);
set_prec(i, neww);
+ }
nrep++;
}
}
return nrep;
}
*** 980,1005 ****
if( _cnt >= _max || in(_max-1) )
grow( _max+1 );
// Find a precedence edge to move
uint i = _cnt;
! while( in(i) != NULL ) i++;
_in[i] = n; // Stuff prec edge over NULL
if ( n != NULL) n->add_out((Node *)this); // Add mirror edge
}
//------------------------------rm_prec----------------------------------------
// Remove a precedence input. Precedence inputs are unordered, with
// duplicates removed and NULLs packed down at the end.
void Node::rm_prec( uint j ) {
// Find end of precedence list to pack NULLs
uint i;
! for( i=j; i<_max; i++ )
if( !_in[i] ) // Find the NULL at end of prec edge list
break;
! if (_in[j] != NULL) _in[j]->del_out((Node *)this);
_in[j] = _in[--i]; // Move last element over removed guy
_in[i] = NULL; // NULL out last element
}
//------------------------------size_of----------------------------------------
--- 1000,1034 ----
if( _cnt >= _max || in(_max-1) )
grow( _max+1 );
// Find a precedence edge to move
uint i = _cnt;
! while( in(i) != NULL ) {
! if (in(i) == n) return; // Avoid spec violation: multiple prec edge.
! i++;
! }
_in[i] = n; // Stuff prec edge over NULL
if ( n != NULL) n->add_out((Node *)this); // Add mirror edge
+
+ #ifdef ASSERT
+ while ((++i)<_max) { assert(_in[i] == NULL, "spec violation: Gap in prec edges (node %d)", _idx); }
+ #endif
}
//------------------------------rm_prec----------------------------------------
// Remove a precedence input. Precedence inputs are unordered, with
// duplicates removed and NULLs packed down at the end.
void Node::rm_prec( uint j ) {
+ if (_in[j] == NULL) return; // Avoid spec violation: Gap in prec edges.
// Find end of precedence list to pack NULLs
uint i;
! for( i=j+1; i<_max; i++ ) {
if( !_in[i] ) // Find the NULL at end of prec edge list
break;
! }
! _in[j]->del_out((Node *)this);
_in[j] = _in[--i]; // Move last element over removed guy
_in[i] = NULL; // NULL out last element
}
//------------------------------size_of----------------------------------------
< prev index next >