6805427: adlc compiler may generate incorrect machnode emission code
Reviewed-by: kvn, twisti
--- a/hotspot/src/share/vm/adlc/formssel.cpp Tue Feb 24 09:53:20 2009 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Wed Feb 25 10:53:14 2009 -0800
@@ -1217,13 +1217,17 @@
// Seach through operands to determine parameters unique positions.
void InstructForm::set_unique_opnds() {
uint* uniq_idx = NULL;
- uint nopnds = num_opnds();
+ int nopnds = num_opnds();
uint num_uniq = nopnds;
- uint i;
+ int i;
+ _uniq_idx_length = 0;
if ( nopnds > 0 ) {
- // Allocate index array with reserve.
- uniq_idx = (uint*) malloc(sizeof(uint)*(nopnds + 2));
- for( i = 0; i < nopnds+2; i++ ) {
+ // Allocate index array. Worst case we're mapping from each
+ // component back to an index and any DEF always goes at 0 so the
+ // length of the array has to be the number of components + 1.
+ _uniq_idx_length = _components.count() + 1;
+ uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
+ for( i = 0; i < _uniq_idx_length; i++ ) {
uniq_idx[i] = i;
}
}
@@ -1238,8 +1242,8 @@
_parameters.reset();
while( (name = _parameters.iter()) != NULL ) {
count = 0;
- uint position = 0;
- uint uniq_position = 0;
+ int position = 0;
+ int uniq_position = 0;
_components.reset();
Component *comp = NULL;
if( sets_result() ) {
@@ -1255,6 +1259,7 @@
}
if( strcmp(name, comp->_name)==0 ) {
if( ++count > 1 ) {
+ assert(position < _uniq_idx_length, "out of bounds");
uniq_idx[position] = uniq_position;
has_dupl_use = true;
} else {
--- a/hotspot/src/share/vm/adlc/formssel.hpp Tue Feb 24 09:53:20 2009 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.hpp Wed Feb 25 10:53:14 2009 -0800
@@ -101,6 +101,7 @@
const char *_ins_pipe; // Instruction Scheduline description class
uint *_uniq_idx; // Indexes of unique operands
+ int _uniq_idx_length; // Length of _uniq_idx array
uint _num_uniq; // Number of unique operands
ComponentList _components; // List of Components matches MachNode's
// operand structure
@@ -257,11 +258,13 @@
void set_unique_opnds();
uint num_unique_opnds() { return _num_uniq; }
uint unique_opnds_idx(int idx) {
- if( _uniq_idx != NULL && idx > 0 )
+ if( _uniq_idx != NULL && idx > 0 ) {
+ assert(idx < _uniq_idx_length, "out of bounds");
return _uniq_idx[idx];
- else
+ } else {
return idx;
- }
+ }
+ }
// Operands which are only KILLs aren't part of the input array and
// require special handling in some cases. Their position in this