changeset 6520:2dac17e9dbcf

8011621, PR3209: live_ranges_in_separate_class.patch Reviewed-by: kvn, roland Contributed-by: niclas.adlertz@oracle.com
author neliasso
date Mon, 24 Apr 2017 19:28:39 +0100
parents 34d9f1ce747b
children 73ff7d567421
files make/bsd/makefiles/vm.make make/linux/makefiles/vm.make make/solaris/makefiles/vm.make make/windows/create_obj_files.sh src/os/bsd/vm/chaitin_bsd.cpp src/os/linux/vm/chaitin_linux.cpp src/os/solaris/vm/chaitin_solaris.cpp src/os/windows/vm/chaitin_windows.cpp src/share/vm/opto/chaitin.cpp src/share/vm/opto/chaitin.hpp src/share/vm/opto/coalesce.cpp src/share/vm/opto/coalesce.hpp src/share/vm/opto/compile.cpp src/share/vm/opto/idealGraphPrinter.cpp src/share/vm/opto/ifg.cpp src/share/vm/opto/live.cpp src/share/vm/opto/live.hpp src/share/vm/opto/postaloc.cpp src/share/vm/opto/reg_split.cpp src/share/vm/opto/regalloc.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 21 files changed, 712 insertions(+), 766 deletions(-) [+]
line wrap: on
line diff
--- a/make/bsd/makefiles/vm.make	Mon Apr 24 16:49:33 2017 +0100
+++ b/make/bsd/makefiles/vm.make	Mon Apr 24 19:28:39 2017 +0100
@@ -187,7 +187,7 @@
 Src_Dirs/SHARK     := $(CORE_PATHS) $(SHARK_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
 COMPILER1_SPECIFIC_FILES := c1_\*
 SHARK_SPECIFIC_FILES     := shark
 ZERO_SPECIFIC_FILES      := zero
--- a/make/linux/makefiles/vm.make	Mon Apr 24 16:49:33 2017 +0100
+++ b/make/linux/makefiles/vm.make	Mon Apr 24 19:28:39 2017 +0100
@@ -208,7 +208,7 @@
 Src_Dirs/SHARK     := $(CORE_PATHS) $(SHARK_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
 COMPILER1_SPECIFIC_FILES := c1_\*
 SHARK_SPECIFIC_FILES     := shark
 ZERO_SPECIFIC_FILES      := zero
--- a/make/solaris/makefiles/vm.make	Mon Apr 24 16:49:33 2017 +0100
+++ b/make/solaris/makefiles/vm.make	Mon Apr 24 19:28:39 2017 +0100
@@ -214,7 +214,7 @@
 Src_Dirs/SHARK     := $(CORE_PATHS)
 Src_Dirs := $(Src_Dirs/$(TYPE))
 
-COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp chaitin\* c2_\* runtime_\*
+COMPILER2_SPECIFIC_FILES := opto libadt bcEscapeAnalyzer.cpp c2_\* runtime_\*
 COMPILER1_SPECIFIC_FILES := c1_\*
 SHARK_SPECIFIC_FILES     := shark
 ZERO_SPECIFIC_FILES      := zero
--- a/make/windows/create_obj_files.sh	Mon Apr 24 16:49:33 2017 +0100
+++ b/make/windows/create_obj_files.sh	Mon Apr 24 19:28:39 2017 +0100
@@ -112,7 +112,7 @@
     "shark")     Src_Dirs="${CORE_PATHS}" ;;
 esac
 
-COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp chaitin* c2_* runtime_*"
+COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*"
 COMPILER1_SPECIFIC_FILES="c1_*"
 SHARK_SPECIFIC_FILES="shark"
 ZERO_SPECIFIC_FILES="zero"
--- a/src/os/bsd/vm/chaitin_bsd.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
-  // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
-  // no action
-}
-#endif
-
-
-// Reconciliation History
-// chaitin_solaris.cpp  1.7 99/07/12 23:54:22
-// End
--- a/src/os/linux/vm/chaitin_linux.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
-  // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
-  // no action
-}
-#endif
-
-
-// Reconciliation History
-// chaitin_solaris.cpp  1.7 99/07/12 23:54:22
-// End
--- a/src/os/solaris/vm/chaitin_solaris.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-void PhaseRegAlloc::pd_preallocate_hook() {
-  // no action
-}
-
-#ifdef ASSERT
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
-  // no action
-}
-#endif
-
-
-//Reconciliation History
-// 1.1 99/02/12 15:35:26 chaitin_win32.cpp
-// 1.2 99/02/18 15:38:56 chaitin_win32.cpp
-// 1.4 99/03/09 10:37:48 chaitin_win32.cpp
-// 1.6 99/03/25 11:07:44 chaitin_win32.cpp
-// 1.8 99/06/22 16:38:58 chaitin_win32.cpp
-//End
--- a/src/os/windows/vm/chaitin_windows.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "opto/chaitin.hpp"
-#include "opto/machnode.hpp"
-
-// Disallow the use of the frame pointer (EBP) for implicit null exceptions
-// on win95/98.  If we do not do this, the OS gets confused and gives a stack
-// error.
-void PhaseRegAlloc::pd_preallocate_hook() {
-#ifndef _WIN64
-  if (ImplicitNullChecks && !os::win32::is_nt()) {
-    for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
-      Block *block = _cfg._blocks[block_num];
-
-      Node *block_end = block->end();
-      if (block_end->is_MachNullCheck() &&
-          block_end->as_Mach()->ideal_Opcode() != Op_Con) {
-        // The last instruction in the block is an implicit null check.
-        // Fix its input so that it does not load into the frame pointer.
-        _matcher.pd_implicit_null_fixup(block_end->in(1)->as_Mach(),
-                                        block_end->as_MachNullCheck()->_vidx);
-      }
-    }
-  }
-#else
-  // WIN64==itanium on XP
-#endif
-}
-
-#ifdef ASSERT
-// Verify that no implicit null check uses the frame pointer (EBP) as
-// its register on win95/98.  Use of the frame pointer in an implicit
-// null check confuses the OS, yielding a stack error.
-void PhaseRegAlloc::pd_postallocate_verify_hook() {
-#ifndef _WIN64
-  if (ImplicitNullChecks && !os::win32::is_nt()) {
-    for (uint block_num=1; block_num<_cfg._num_blocks; block_num++) {
-      Block *block = _cfg._blocks[block_num];
-
-      Node *block_end = block->_nodes[block->_nodes.size()-1];
-      if (block_end->is_MachNullCheck() && block_end->as_Mach()->ideal_Opcode() != Op_Con) {
-        // The last instruction in the block is an implicit
-        // null check.  Verify that this instruction does not
-        // use the frame pointer.
-        int reg = get_reg_first(block_end->in(1)->in(block_end->as_MachNullCheck()->_vidx));
-        assert(reg != EBP_num,
-               "implicit null check using frame pointer on win95/98");
-      }
-    }
-  }
-#else
-  // WIN64==itanium on XP
-#endif
-}
-#endif
--- a/src/share/vm/opto/chaitin.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/chaitin.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -141,6 +141,72 @@
 
 #define NUMBUCKS 3
 
+// Straight out of Tarjan's union-find algorithm
+uint LiveRangeMap::find_compress(uint lrg) {
+  uint cur = lrg;
+  uint next = _uf_map[cur];
+  while (next != cur) { // Scan chain of equivalences
+    assert( next < cur, "always union smaller");
+    cur = next; // until find a fixed-point
+    next = _uf_map[cur];
+  }
+
+  // Core of union-find algorithm: update chain of
+  // equivalences to be equal to the root.
+  while (lrg != next) {
+    uint tmp = _uf_map[lrg];
+    _uf_map.map(lrg, next);
+    lrg = tmp;
+  }
+  return lrg;
+}
+
+// Reset the Union-Find map to identity
+void LiveRangeMap::reset_uf_map(uint max_lrg_id) {
+  _max_lrg_id= max_lrg_id;
+  // Force the Union-Find mapping to be at least this large
+  _uf_map.extend(_max_lrg_id, 0);
+  // Initialize it to be the ID mapping.
+  for (uint i = 0; i < _max_lrg_id; ++i) {
+    _uf_map.map(i, i);
+  }
+}
+
+// Make all Nodes map directly to their final live range; no need for
+// the Union-Find mapping after this call.
+void LiveRangeMap::compress_uf_map_for_nodes() {
+  // For all Nodes, compress mapping
+  uint unique = _names.Size();
+  for (uint i = 0; i < unique; ++i) {
+    uint lrg = _names[i];
+    uint compressed_lrg = find(lrg);
+    if (lrg != compressed_lrg) {
+      _names.map(i, compressed_lrg);
+    }
+  }
+}
+
+// Like Find above, but no path compress, so bad asymptotic behavior
+uint LiveRangeMap::find_const(uint lrg) const {
+  if (!lrg) {
+    return lrg; // Ignore the zero LRG
+  }
+
+  // Off the end?  This happens during debugging dumps when you got
+  // brand new live ranges but have not told the allocator yet.
+  if (lrg >= _max_lrg_id) {
+    return lrg;
+  }
+
+  uint next = _uf_map[lrg];
+  while (next != lrg) { // Scan chain of equivalences
+    assert(next < lrg, "always union smaller");
+    lrg = next; // until find a fixed-point
+    next = _uf_map[lrg];
+  }
+  return next;
+}
+
 PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
   : PhaseRegAlloc(unique, cfg, matcher,
 #ifndef PRODUCT
@@ -148,13 +214,13 @@
 #else
        NULL
 #endif
-       ),
-    _names(unique), _uf_map(unique),
-    _maxlrg(0), _live(0),
-    _spilled_once(Thread::current()->resource_area()),
-    _spilled_twice(Thread::current()->resource_area()),
-    _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0),
-    _oldphi(unique)
+       )
+  , _lrg_map(unique)
+  , _live(0)
+  , _spilled_once(Thread::current()->resource_area())
+  , _spilled_twice(Thread::current()->resource_area())
+  , _lo_degree(0), _lo_stk_degree(0), _hi_degree(0), _simplified(0)
+  , _oldphi(unique)
 #ifndef PRODUCT
   , _trace_spilling(TraceSpilling || C->method_has_option("TraceSpilling"))
 #endif
@@ -163,7 +229,6 @@
 
   _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency());
 
-  uint i,j;
   // Build a list of basic blocks, sorted by frequency
   _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
   // Experiment with sorting strategies to speed compilation
@@ -171,30 +236,30 @@
   Block **buckets[NUMBUCKS];             // Array of buckets
   uint    buckcnt[NUMBUCKS];             // Array of bucket counters
   double  buckval[NUMBUCKS];             // Array of bucket value cutoffs
-  for( i = 0; i < NUMBUCKS; i++ ) {
+  for (uint i = 0; i < NUMBUCKS; i++) {
     buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
     buckcnt[i] = 0;
     // Bump by three orders of magnitude each time
     cutoff *= 0.001;
     buckval[i] = cutoff;
-    for ( j = 0; j < _cfg.number_of_blocks(); j++) {
+    for (uint j = 0; j < _cfg.number_of_blocks(); j++) {
       buckets[i][j] = NULL;
     }
   }
   // Sort blocks into buckets
-  for ( i = 0; i < _cfg.number_of_blocks(); i++) {
-    for( j = 0; j < NUMBUCKS; j++ ) {
+  for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+    for (uint j = 0; j < NUMBUCKS; j++) {
       if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) {
         // Assign block to end of list for appropriate bucket
         buckets[j][buckcnt[j]++] = _cfg.get_block(i);
-        break;                      // kick out of inner loop
+        break; // kick out of inner loop
       }
     }
   }
   // Dump buckets into final block array
   uint blkcnt = 0;
-  for( i = 0; i < NUMBUCKS; i++ ) {
-    for( j = 0; j < buckcnt[i]; j++ ) {
+  for (uint i = 0; i < NUMBUCKS; i++) {
+    for (uint j = 0; j < buckcnt[i]; j++) {
       _blks[blkcnt++] = buckets[i][j];
     }
   }
@@ -202,6 +267,82 @@
   assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled");
 }
 
+//------------------------------Union------------------------------------------
+// union 2 sets together.
+void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
+  uint src = _lrg_map.find(src_n);
+  uint dst = _lrg_map.find(dst_n);
+  assert(src, "");
+  assert(dst, "");
+  assert(src < _lrg_map.max_lrg_id(), "oob");
+  assert(dst < _lrg_map.max_lrg_id(), "oob");
+  assert(src < dst, "always union smaller");
+  _lrg_map.uf_map(dst, src);
+}
+
+//------------------------------new_lrg----------------------------------------
+void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
+  // Make the Node->LRG mapping
+  _lrg_map.extend(x->_idx,lrg);
+  // Make the Union-Find mapping an identity function
+  _lrg_map.uf_extend(lrg, lrg);
+}
+
+
+int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
+  assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
+  DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
+  int found_projs = 0;
+  uint cnt = orig->outcnt();
+  for (uint i = 0; i < cnt; i++) {
+    Node* proj = orig->raw_out(i);
+    if (proj->is_MachProj()) {
+      assert(proj->outcnt() == 0, "only kill projections are expected here");
+      assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections");
+      found_projs++;
+      // Copy kill projections after the cloned node
+      Node* kills = proj->clone();
+      kills->set_req(0, copy);
+      b->_nodes.insert(idx++, kills);
+      _cfg.map_node_to_block(kills, b);
+      new_lrg(kills, max_lrg_id++);
+    }
+  }
+  return found_projs;
+}
+
+//------------------------------compact----------------------------------------
+// Renumber the live ranges to compact them.  Makes the IFG smaller.
+void PhaseChaitin::compact() {
+  // Current the _uf_map contains a series of short chains which are headed
+  // by a self-cycle.  All the chains run from big numbers to little numbers.
+  // The Find() call chases the chains & shortens them for the next Find call.
+  // We are going to change this structure slightly.  Numbers above a moving
+  // wave 'i' are unchanged.  Numbers below 'j' point directly to their
+  // compacted live range with no further chaining.  There are no chains or
+  // cycles below 'i', so the Find call no longer works.
+  uint j=1;
+  uint i;
+  for (i = 1; i < _lrg_map.max_lrg_id(); i++) {
+    uint lr = _lrg_map.uf_live_range_id(i);
+    // Ignore unallocated live ranges
+    if (!lr) {
+      continue;
+    }
+    assert(lr <= i, "");
+    _lrg_map.uf_map(i, ( lr == i ) ? j++ : _lrg_map.uf_live_range_id(lr));
+  }
+  // Now change the Node->LR mapping to reflect the compacted names
+  uint unique = _lrg_map.size();
+  for (i = 0; i < unique; i++) {
+    uint lrg_id = _lrg_map.live_range_id(i);
+    _lrg_map.map(i, _lrg_map.uf_live_range_id(lrg_id));
+  }
+
+  // Reset the Union-Find mapping
+  _lrg_map.reset_uf_map(j);
+}
+
 void PhaseChaitin::Register_Allocate() {
 
   // Above the OLD FP (and in registers) are the incoming arguments.  Stack
@@ -226,14 +367,12 @@
   // all copy-related live ranges low and then using the max copy-related
   // live range as a cut-off for LIVE and the IFG.  In other words, I can
   // build a subset of LIVE and IFG just for copies.
-  PhaseLive live(_cfg,_names,&live_arena);
+  PhaseLive live(_cfg, _lrg_map.names(), &live_arena);
 
   // Need IFG for coalescing and coloring
-  PhaseIFG ifg( &live_arena );
+  PhaseIFG ifg(&live_arena);
   _ifg = &ifg;
 
-  if (C->unique() > _names.Size())  _names.extend(C->unique()-1, 0);
-
   // Come out of SSA world to the Named world.  Assign (virtual) registers to
   // Nodes.  Use the same register for all inputs and the output of PhiNodes
   // - effectively ending SSA form.  This requires either coalescing live
@@ -253,9 +392,9 @@
     _live = NULL;                 // Mark live as being not available
     rm.reset_to_mark();           // Reclaim working storage
     IndexSet::reset_memory(C, &live_arena);
-    ifg.init(_maxlrg);            // Empty IFG
+    ifg.init(_lrg_map.max_lrg_id()); // Empty IFG
     gather_lrg_masks( false );    // Collect LRG masks
-    live.compute( _maxlrg );      // Compute liveness
+    live.compute(_lrg_map.max_lrg_id()); // Compute liveness
     _live = &live;                // Mark LIVE as being available
   }
 
@@ -265,19 +404,19 @@
   // across any GC point where the derived value is live.  So this code looks
   // at all the GC points, and "stretches" the live range of any base pointer
   // to the GC point.
-  if( stretch_base_pointer_live_ranges(&live_arena) ) {
-    NOT_PRODUCT( Compile::TracePhase t3("computeLive (sbplr)", &_t_computeLive, TimeCompiler); )
+  if (stretch_base_pointer_live_ranges(&live_arena)) {
+    NOT_PRODUCT(Compile::TracePhase t3("computeLive (sbplr)", &_t_computeLive, TimeCompiler);)
     // Since some live range stretched, I need to recompute live
     _live = NULL;
     rm.reset_to_mark();         // Reclaim working storage
     IndexSet::reset_memory(C, &live_arena);
-    ifg.init(_maxlrg);
-    gather_lrg_masks( false );
-    live.compute( _maxlrg );
+    ifg.init(_lrg_map.max_lrg_id());
+    gather_lrg_masks(false);
+    live.compute(_lrg_map.max_lrg_id());
     _live = &live;
   }
   // Create the interference graph using virtual copies
-  build_ifg_virtual( );  // Include stack slots this time
+  build_ifg_virtual();  // Include stack slots this time
 
   // Aggressive (but pessimistic) copy coalescing.
   // This pass works on virtual copies.  Any virtual copies which are not
@@ -291,8 +430,8 @@
     // given Node and search them for an instance, i.e., time O(#MaxLRG)).
     _ifg->SquareUp();
 
-    PhaseAggressiveCoalesce coalesce( *this );
-    coalesce.coalesce_driver( );
+    PhaseAggressiveCoalesce coalesce(*this);
+    coalesce.coalesce_driver();
     // Insert un-coalesced copies.  Visit all Phis.  Where inputs to a Phi do
     // not match the Phi itself, insert a copy.
     coalesce.insert_copies(_matcher);
@@ -308,28 +447,36 @@
     _live = NULL;
     rm.reset_to_mark();           // Reclaim working storage
     IndexSet::reset_memory(C, &live_arena);
-    ifg.init(_maxlrg);
+    ifg.init(_lrg_map.max_lrg_id());
     gather_lrg_masks( true );
-    live.compute( _maxlrg );
+    live.compute(_lrg_map.max_lrg_id());
     _live = &live;
   }
 
   // Build physical interference graph
   uint must_spill = 0;
-  must_spill = build_ifg_physical( &live_arena );
+  must_spill = build_ifg_physical(&live_arena);
   // If we have a guaranteed spill, might as well spill now
-  if( must_spill ) {
-    if( !_maxlrg ) return;
+  if (must_spill) {
+    if(!_lrg_map.max_lrg_id()) {
+      return;
+    }
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
     C->check_node_count(10*must_spill, "out of nodes before split");
-    if (C->failing())  return;
-    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
+    if (C->failing()) {
+      return;
+    }
+
+    uint new_max_lrg_id = Split(_lrg_map.max_lrg_id(), &split_arena);  // Split spilling LRG everywhere
+    _lrg_map.set_max_lrg_id(new_max_lrg_id);
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     // or we failed to split
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
-    if (C->failing())  return;
+    if (C->failing()) {
+      return;
+    }
 
-    NOT_PRODUCT( C->verify_graph_edges(); )
+    NOT_PRODUCT(C->verify_graph_edges();)
 
     compact();                  // Compact LRGs; return new lower max lrg
 
@@ -338,23 +485,23 @@
       _live = NULL;
       rm.reset_to_mark();         // Reclaim working storage
       IndexSet::reset_memory(C, &live_arena);
-      ifg.init(_maxlrg);          // Build a new interference graph
+      ifg.init(_lrg_map.max_lrg_id()); // Build a new interference graph
       gather_lrg_masks( true );   // Collect intersect mask
-      live.compute( _maxlrg );    // Compute LIVE
+      live.compute(_lrg_map.max_lrg_id()); // Compute LIVE
       _live = &live;
     }
-    build_ifg_physical( &live_arena );
+    build_ifg_physical(&live_arena);
     _ifg->SquareUp();
     _ifg->Compute_Effective_Degree();
     // Only do conservative coalescing if requested
-    if( OptoCoalesce ) {
+    if (OptoCoalesce) {
       // Conservative (and pessimistic) copy coalescing of those spills
-      PhaseConservativeCoalesce coalesce( *this );
+      PhaseConservativeCoalesce coalesce(*this);
       // If max live ranges greater than cutoff, don't color the stack.
       // This cutoff can be larger than below since it is only done once.
-      coalesce.coalesce_driver( );
+      coalesce.coalesce_driver();
     }
-    compress_uf_map_for_nodes();
+    _lrg_map.compress_uf_map_for_nodes();
 
 #ifdef ASSERT
     verify(&live_arena, true);
@@ -388,13 +535,18 @@
       }
     }
 
-    if( !_maxlrg ) return;
-    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
+    if (!_lrg_map.max_lrg_id()) {
+      return;
+    }
+    uint new_max_lrg_id = Split(_lrg_map.max_lrg_id(), &split_arena);  // Split spilling LRG everywhere
+    _lrg_map.set_max_lrg_id(new_max_lrg_id);
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
-    C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
-    if (C->failing())  return;
+    C->check_node_count(2 * NodeLimitFudgeFactor, "out of nodes after split");
+    if (C->failing()) {
+      return;
+    }
 
-    compact();                  // Compact LRGs; return new lower max lrg
+    compact(); // Compact LRGs; return new lower max lrg
 
     // Nuke the live-ness and interference graph and LiveRanGe info
     {
@@ -402,26 +554,26 @@
       _live = NULL;
       rm.reset_to_mark();         // Reclaim working storage
       IndexSet::reset_memory(C, &live_arena);
-      ifg.init(_maxlrg);
+      ifg.init(_lrg_map.max_lrg_id());
 
       // Create LiveRanGe array.
       // Intersect register masks for all USEs and DEFs
-      gather_lrg_masks( true );
-      live.compute( _maxlrg );
+      gather_lrg_masks(true);
+      live.compute(_lrg_map.max_lrg_id());
       _live = &live;
     }
-    must_spill = build_ifg_physical( &live_arena );
+    must_spill = build_ifg_physical(&live_arena);
     _ifg->SquareUp();
     _ifg->Compute_Effective_Degree();
 
     // Only do conservative coalescing if requested
-    if( OptoCoalesce ) {
+    if (OptoCoalesce) {
       // Conservative (and pessimistic) copy coalescing
-      PhaseConservativeCoalesce coalesce( *this );
+      PhaseConservativeCoalesce coalesce(*this);
       // Check for few live ranges determines how aggressive coalesce is.
-      coalesce.coalesce_driver( );
+      coalesce.coalesce_driver();
     }
-    compress_uf_map_for_nodes();
+    _lrg_map.compress_uf_map_for_nodes();
 #ifdef ASSERT
     verify(&live_arena, true);
 #endif
@@ -433,7 +585,7 @@
 
     // Select colors by re-inserting LRGs back into the IFG in reverse order.
     // Return whether or not something spills.
-    spills = Select( );
+    spills = Select();
   }
 
   // Count number of Simplify-Select trips per coloring success.
@@ -450,9 +602,12 @@
 
   // max_reg is past the largest *register* used.
   // Convert that to a frame_slot number.
-  if( _max_reg <= _matcher._new_SP )
+  if (_max_reg <= _matcher._new_SP) {
     _framesize = C->out_preserve_stack_slots();
-  else _framesize = _max_reg -_matcher._new_SP;
+  }
+  else {
+    _framesize = _max_reg -_matcher._new_SP;
+  }
   assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
 
   // This frame must preserve the required fp alignment
@@ -460,8 +615,9 @@
   assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
 #ifndef PRODUCT
   _total_framesize += _framesize;
-  if( (int)_framesize > _max_framesize )
+  if ((int)_framesize > _max_framesize) {
     _max_framesize = _framesize;
+  }
 #endif
 
   // Convert CISC spills
@@ -473,15 +629,17 @@
     log->elem("regalloc attempts='%d' success='%d'", _trip_cnt, !C->failing());
   }
 
-  if (C->failing())  return;
+  if (C->failing()) {
+    return;
+  }
 
-  NOT_PRODUCT( C->verify_graph_edges(); )
+  NOT_PRODUCT(C->verify_graph_edges();)
 
   // Move important info out of the live_arena to longer lasting storage.
-  alloc_node_regs(_names.Size());
-  for (uint i=0; i < _names.Size(); i++) {
-    if (_names[i]) {           // Live range associated with Node?
-      LRG &lrg = lrgs(_names[i]);
+  alloc_node_regs(_lrg_map.size());
+  for (uint i=0; i < _lrg_map.size(); i++) {
+    if (_lrg_map.live_range_id(i)) { // Live range associated with Node?
+      LRG &lrg = lrgs(_lrg_map.live_range_id(i));
       if (!lrg.alive()) {
         set_bad(i);
       } else if (lrg.num_regs() == 1) {
@@ -534,11 +692,11 @@
       Node *n = block->_nodes[j];
       // Pre-color to the zero live range, or pick virtual register
       const RegMask &rm = n->out_RegMask();
-      _names.map( n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0 );
+      _lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
     }
   }
   // Reset the Union-Find mapping to be identity
-  reset_uf_map(lr_counter);
+  _lrg_map.reset_uf_map(lr_counter);
 }
 
 
@@ -547,7 +705,7 @@
 void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
 
   // Nail down the frame pointer live range
-    uint fp_lrg = n2lidx(_cfg.get_root_node()->in(1)->in(TypeFunc::FramePtr));
+  uint fp_lrg = _lrg_map.live_range_id(_cfg.get_root_node()->in(1)->in(TypeFunc::FramePtr));
   lrgs(fp_lrg)._cost += 1e12;   // Cost is infinite
 
   // For all blocks
@@ -564,14 +722,14 @@
       uint idx = n->is_Copy();
 
       // Get virtual register number, same as LiveRanGe index
-      uint vreg = n2lidx(n);
+      uint vreg = _lrg_map.live_range_id(n);
       LRG& lrg = lrgs(vreg);
       if (vreg) {              // No vreg means un-allocable (e.g. memory)
 
         // Collect has-copy bit
         if (idx) {
           lrg._has_copy = 1;
-          uint clidx = n2lidx(n->in(idx));
+          uint clidx = _lrg_map.live_range_id(n->in(idx));
           LRG& copy_src = lrgs(clidx);
           copy_src._has_copy = 1;
         }
@@ -775,8 +933,10 @@
       }
       // Prepare register mask for each input
       for( uint k = input_edge_start; k < cnt; k++ ) {
-        uint vreg = n2lidx(n->in(k));
-        if( !vreg ) continue;
+        uint vreg = _lrg_map.live_range_id(n->in(k));
+        if (!vreg) {
+          continue;
+        }
 
         // If this instruction is CISC Spillable, add the flags
         // bit to its appropriate input
@@ -859,7 +1019,7 @@
   } // end for all blocks
 
   // Final per-liverange setup
-  for (uint i2=0; i2<_maxlrg; i2++) {
+  for (uint i2 = 0; i2 < _lrg_map.max_lrg_id(); i2++) {
     LRG &lrg = lrgs(i2);
     assert(!lrg._is_vector || !lrg._fat_proj, "sanity");
     if (lrg.num_regs() > 1 && !lrg._fat_proj) {
@@ -880,7 +1040,7 @@
 // The bit is checked in Simplify.
 void PhaseChaitin::set_was_low() {
 #ifdef ASSERT
-  for( uint i = 1; i < _maxlrg; i++ ) {
+  for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
     int size = lrgs(i).num_regs();
     uint old_was_lo = lrgs(i)._was_lo;
     lrgs(i)._was_lo = 0;
@@ -913,7 +1073,7 @@
 // Compute cost/area ratio, in case we spill.  Build the lo-degree list.
 void PhaseChaitin::cache_lrg_info( ) {
 
-  for( uint i = 1; i < _maxlrg; i++ ) {
+  for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
     LRG &lrg = lrgs(i);
 
     // Check for being of low degree: means we can be trivially colored.
@@ -948,10 +1108,10 @@
 
   // Warm up the lo-degree no-copy list
   int lo_no_copy = 0;
-  for( uint i = 1; i < _maxlrg; i++ ) {
-    if( (lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
+  for (uint i = 1; i < _lrg_map.max_lrg_id(); i++) {
+    if ((lrgs(i).lo_degree() && !lrgs(i)._has_copy) ||
         !lrgs(i).alive() ||
-        lrgs(i)._must_spill ) {
+        lrgs(i)._must_spill) {
       lrgs(i)._next = lo_no_copy;
       lo_no_copy = i;
     }
@@ -1159,7 +1319,7 @@
 OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
 
   // Check for "at_risk" LRG's
-  uint risk_lrg = Find(lrg._risk_bias);
+  uint risk_lrg = _lrg_map.find(lrg._risk_bias);
   if( risk_lrg != 0 ) {
     // Walk the colored neighbors of the "at_risk" candidate
     // Choose a color which is both legal and already taken by a neighbor
@@ -1175,7 +1335,7 @@
     }
   }
 
-  uint copy_lrg = Find(lrg._copy_bias);
+  uint copy_lrg = _lrg_map.find(lrg._copy_bias);
   if( copy_lrg != 0 ) {
     // If he has a color,
     if( !(*(_ifg->_yanked))[copy_lrg] ) {
@@ -1415,10 +1575,10 @@
 void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
   if( _spilled_once.test(src->_idx) ) {
     _spilled_once.set(dst->_idx);
-    lrgs(Find(dst))._was_spilled1 = 1;
+    lrgs(_lrg_map.find(dst))._was_spilled1 = 1;
     if( _spilled_twice.test(src->_idx) ) {
       _spilled_twice.set(dst->_idx);
-      lrgs(Find(dst))._was_spilled2 = 1;
+      lrgs(_lrg_map.find(dst))._was_spilled2 = 1;
     }
   }
 }
@@ -1461,7 +1621,7 @@
         MachNode *mach = n->as_Mach();
         inp = mach->operand_index(inp);
         Node *src = n->in(inp);   // Value to load or store
-        LRG &lrg_cisc = lrgs( Find_const(src) );
+        LRG &lrg_cisc = lrgs(_lrg_map.find_const(src));
         OptoReg::Name src_reg = lrg_cisc.reg();
         // Doubles record the HIGH register of an adjacent pair.
         src_reg = OptoReg::add(src_reg,1-lrg_cisc.num_regs());
@@ -1543,9 +1703,9 @@
       Block *startb = _cfg.get_block_for_node(C->top());
       startb->_nodes.insert(startb->find_node(C->top()), base );
       _cfg.map_node_to_block(base, startb);
-      assert (n2lidx(base) == 0, "should not have LRG yet");
+      assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet");
     }
-    if (n2lidx(base) == 0) {
+    if (_lrg_map.live_range_id(base) == 0) {
       new_lrg(base, maxlrg++);
     }
     assert(base->in(0) == _cfg.get_root_node() && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
@@ -1554,7 +1714,7 @@
   }
 
   // Check for AddP-related opcodes
-  if( !derived->is_Phi() ) {
+  if (!derived->is_Phi()) {
     assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg_res("but is: %s", derived->Name()));
     Node *base = derived->in(AddPNode::Base);
     derived_base_map[derived->_idx] = base;
@@ -1615,9 +1775,9 @@
 // base pointer that is live across the Safepoint for oopmap building.  The
 // edge pairs get added in after sfpt->jvmtail()->oopoff(), but are in the
 // required edge set.
-bool PhaseChaitin::stretch_base_pointer_live_ranges( ResourceArea *a ) {
+bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
   int must_recompute_live = false;
-  uint maxlrg = _maxlrg;
+  uint maxlrg = _lrg_map.max_lrg_id();
   Node **derived_base_map = (Node**)a->Amalloc(sizeof(Node*)*C->unique());
   memset( derived_base_map, 0, sizeof(Node*)*C->unique() );
 
@@ -1655,15 +1815,18 @@
       }
 
       // Get value being defined
-      uint lidx = n2lidx(n);
-      if( lidx && lidx < _maxlrg /* Ignore the occasional brand-new live range */) {
+      uint lidx = _lrg_map.live_range_id(n);
+      // Ignore the occasional brand-new live range
+      if (lidx && lidx < _lrg_map.max_lrg_id()) {
         // Remove from live-out set
         liveout.remove(lidx);
 
         // Copies do not define a new value and so do not interfere.
         // Remove the copies source from the liveout set before interfering.
         uint idx = n->is_Copy();
-        if( idx ) liveout.remove( n2lidx(n->in(idx)) );
+        if (idx) {
+          liveout.remove(_lrg_map.live_range_id(n->in(idx)));
+        }
       }
 
       // Found a safepoint?
@@ -1681,20 +1844,20 @@
                   derived->bottom_type()->make_ptr()->is_ptr()->_offset == 0, "sanity");
           // If its an OOP with a non-zero offset, then it is derived.
           if( tj && tj->_offset != 0 && tj->isa_oop_ptr() ) {
-            Node *base = find_base_for_derived( derived_base_map, derived, maxlrg );
-            assert( base->_idx < _names.Size(), "" );
+            Node *base = find_base_for_derived(derived_base_map, derived, maxlrg);
+            assert(base->_idx < _lrg_map.size(), "");
             // Add reaching DEFs of derived pointer and base pointer as a
             // pair of inputs
-            n->add_req( derived );
-            n->add_req( base );
+            n->add_req(derived);
+            n->add_req(base);
 
             // See if the base pointer is already live to this point.
             // Since I'm working on the SSA form, live-ness amounts to
             // reaching def's.  So if I find the base's live range then
             // I know the base's def reaches here.
-            if( (n2lidx(base) >= _maxlrg ||// (Brand new base (hence not live) or
-                 !liveout.member( n2lidx(base) ) ) && // not live) AND
-                 (n2lidx(base) > 0)                && // not a constant
+            if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or
+                 !liveout.member(_lrg_map.live_range_id(base))) && // not live) AND
+                 (_lrg_map.live_range_id(base) > 0) && // not a constant
                  _cfg.get_block_for_node(base) != block) { // base not def'd in blk)
               // Base pointer is not currently live.  Since I stretched
               // the base pointer to here and it crosses basic-block
@@ -1707,11 +1870,12 @@
       } // End of if found a GC point
 
       // Make all inputs live
-      if( !n->is_Phi() ) {      // Phi function uses come from prior block
-        for( uint k = 1; k < n->req(); k++ ) {
-          uint lidx = n2lidx(n->in(k));
-          if( lidx < _maxlrg )
-            liveout.insert( lidx );
+      if (!n->is_Phi()) {      // Phi function uses come from prior block
+        for (uint k = 1; k < n->req(); k++) {
+          uint lidx = _lrg_map.live_range_id(n->in(k));
+          if (lidx < _lrg_map.max_lrg_id()) {
+            liveout.insert(lidx);
+          }
         }
       }
 
@@ -1719,25 +1883,27 @@
     liveout.clear();  // Free the memory used by liveout.
 
   } // End of forall blocks
-  _maxlrg = maxlrg;
+  _lrg_map.set_max_lrg_id(maxlrg);
 
   // If I created a new live range I need to recompute live
-  if( maxlrg != _ifg->_maxlrg )
+  if (maxlrg != _ifg->_maxlrg) {
     must_recompute_live = true;
+  }
 
   return must_recompute_live != 0;
 }
 
 // Extend the node to LRG mapping
-void PhaseChaitin::add_reference( const Node *node, const Node *old_node ) {
-  _names.extend( node->_idx, n2lidx(old_node) );
+
+void PhaseChaitin::add_reference(const Node *node, const Node *old_node) {
+  _lrg_map.extend(node->_idx, _lrg_map.live_range_id(old_node));
 }
 
 #ifndef PRODUCT
-void PhaseChaitin::dump( const Node *n ) const {
-  uint r = (n->_idx < _names.Size() ) ? Find_const(n) : 0;
+void PhaseChaitin::dump(const Node *n) const {
+  uint r = (n->_idx < _lrg_map.size()) ? _lrg_map.find_const(n) : 0;
   tty->print("L%d",r);
-  if( r && n->Opcode() != Op_Phi ) {
+  if (r && n->Opcode() != Op_Phi) {
     if( _node_regs ) {          // Got a post-allocation copy of allocation?
       tty->print("[");
       OptoReg::Name second = get_reg_second(n);
@@ -1758,11 +1924,13 @@
   tty->print("/N%d\t",n->_idx);
   tty->print("%s === ", n->Name());
   uint k;
-  for( k = 0; k < n->req(); k++) {
+  for (k = 0; k < n->req(); k++) {
     Node *m = n->in(k);
-    if( !m ) tty->print("_ ");
+    if (!m) {
+      tty->print("_ ");
+    }
     else {
-      uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
+      uint r = (m->_idx < _lrg_map.size()) ? _lrg_map.find_const(m) : 0;
       tty->print("L%d",r);
       // Data MultiNode's can have projections with no real registers.
       // Don't die while dumping them.
@@ -1793,8 +1961,10 @@
   if( k < n->len() && n->in(k) ) tty->print("| ");
   for( ; k < n->len(); k++ ) {
     Node *m = n->in(k);
-    if( !m ) break;
-    uint r = (m->_idx < _names.Size() ) ? Find_const(m) : 0;
+    if(!m) {
+      break;
+    }
+    uint r = (m->_idx < _lrg_map.size()) ? _lrg_map.find_const(m) : 0;
     tty->print("L%d",r);
     tty->print("/N%d ",m->_idx);
   }
@@ -1822,7 +1992,7 @@
     tty->print("{");
     uint i;
     while ((i = elements.next()) != 0) {
-      tty->print("L%d ", Find_const(i));
+      tty->print("L%d ", _lrg_map.find_const(i));
     }
     tty->print_cr("}");
   }
@@ -1847,10 +2017,14 @@
 
   // Dump LRG array
   tty->print("--- Live RanGe Array ---\n");
-  for(uint i2 = 1; i2 < _maxlrg; i2++ ) {
+  for (uint i2 = 1; i2 < _lrg_map.max_lrg_id(); i2++) {
     tty->print("L%d: ",i2);
-    if( i2 < _ifg->_maxlrg ) lrgs(i2).dump( );
-    else tty->print_cr("new LRG");
+    if (i2 < _ifg->_maxlrg) {
+      lrgs(i2).dump();
+    }
+    else {
+      tty->print_cr("new LRG");
+    }
   }
   tty->print_cr("");
 
@@ -1920,7 +2094,7 @@
     // Post allocation, use direct mappings, no LRG info available
     print_reg( get_reg_first(n), this, buf );
   } else {
-    uint lidx = Find_const(n); // Grab LRG number
+    uint lidx = _lrg_map.find_const(n); // Grab LRG number
     if( !_ifg ) {
       sprintf(buf,"L%d",lidx);  // No register binding yet
     } else if( !lidx ) {        // Special, not allocated value
@@ -1948,7 +2122,7 @@
   if( WizardMode && (PrintCompilation || PrintOpto) ) {
     // Display which live ranges need to be split and the allocator's state
     tty->print_cr("Graph-Coloring Iteration %d will split the following live ranges", _trip_cnt);
-    for( uint bidx = 1; bidx < _maxlrg; bidx++ ) {
+    for (uint bidx = 1; bidx < _lrg_map.max_lrg_id(); bidx++) {
       if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) {
         tty->print("L%d: ", bidx);
         lrgs(bidx).dump();
@@ -2077,14 +2251,17 @@
 void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
   tty->print_cr("---dump of L%d---",lidx);
 
-  if( _ifg ) {
-    if( lidx >= _maxlrg ) {
+  if (_ifg) {
+    if (lidx >= _lrg_map.max_lrg_id()) {
       tty->print("Attempt to print live range index beyond max live range.\n");
       return;
     }
     tty->print("L%d: ",lidx);
-    if( lidx < _ifg->_maxlrg ) lrgs(lidx).dump( );
-    else tty->print_cr("new LRG");
+    if (lidx < _ifg->_maxlrg) {
+      lrgs(lidx).dump();
+    } else {
+      tty->print_cr("new LRG");
+    }
   }
   if( _ifg && lidx < _ifg->_maxlrg) {
     tty->print("Neighbors: %d - ", _ifg->neighbor_cnt(lidx));
@@ -2099,8 +2276,8 @@
     // For all instructions
     for( uint j = 0; j < block->_nodes.size(); j++ ) {
       Node *n = block->_nodes[j];
-      if( Find_const(n) == lidx ) {
-        if( !dump_once++ ) {
+      if (_lrg_map.find_const(n) == lidx) {
+        if (!dump_once++) {
           tty->cr();
           block->dump_head(&_cfg);
         }
@@ -2111,9 +2288,11 @@
         uint cnt = n->req();
         for( uint k = 1; k < cnt; k++ ) {
           Node *m = n->in(k);
-          if (!m)  continue;  // be robust in the dumper
-          if( Find_const(m) == lidx ) {
-            if( !dump_once++ ) {
+          if (!m)  {
+            continue;  // be robust in the dumper
+          }
+          if (_lrg_map.find_const(m) == lidx) {
+            if (!dump_once++) {
               tty->cr();
               block->dump_head(&_cfg);
             }
--- a/src/share/vm/opto/chaitin.hpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/chaitin.hpp	Mon Apr 24 19:28:39 2017 +0100
@@ -290,18 +290,118 @@
   int effective_degree( uint lidx ) const;
 };
 
-// TEMPORARILY REPLACED WITH COMMAND LINE FLAG
+// The LiveRangeMap class is responsible for storing node to live range id mapping.
+// Each node is mapped to a live range id (a virtual register). Nodes that are
+// not considered for register allocation are given live range id 0.
+class LiveRangeMap VALUE_OBJ_CLASS_SPEC {
+
+private:
+
+  uint _max_lrg_id;
+
+  // Union-find map.  Declared as a short for speed.
+  // Indexed by live-range number, it returns the compacted live-range number
+  LRG_List _uf_map;
+
+  // Map from Nodes to live ranges
+  LRG_List _names;
+
+  // Straight out of Tarjan's union-find algorithm
+  uint find_compress(const Node *node) {
+    uint lrg_id = find_compress(_names[node->_idx]);
+    _names.map(node->_idx, lrg_id);
+    return lrg_id;
+  }
+
+  uint find_compress(uint lrg);
+
+public:
+
+  const LRG_List& names() {
+    return _names;
+  }
+
+  uint max_lrg_id() const {
+    return _max_lrg_id;
+  }
+
+  void set_max_lrg_id(uint max_lrg_id) {
+    _max_lrg_id = max_lrg_id;
+  }
+
+  uint size() const {
+    return _names.Size();
+  }
+
+  uint live_range_id(uint idx) const {
+    return _names[idx];
+  }
+
+  uint live_range_id(const Node *node) const {
+    return _names[node->_idx];
+  }
+
+  uint uf_live_range_id(uint lrg_id) const {
+    return _uf_map[lrg_id];
+  }
 
-//// !!!!! Magic Constants need to move into ad file
-#ifdef SPARC
-//#define FLOAT_PRESSURE 30  /*     SFLT_REG_mask.Size() - 1 */
-//#define INT_PRESSURE   23  /* NOTEMP_I_REG_mask.Size() - 1 */
-#define FLOAT_INCREMENT(regs) regs
-#else
-//#define FLOAT_PRESSURE 6
-//#define INT_PRESSURE   6
-#define FLOAT_INCREMENT(regs) 1
-#endif
+  void map(uint idx, uint lrg_id) {
+    _names.map(idx, lrg_id);
+  }
+
+  void uf_map(uint dst_lrg_id, uint src_lrg_id) {
+    _uf_map.map(dst_lrg_id, src_lrg_id);
+  }
+
+  void extend(uint idx, uint lrg_id) {
+    _names.extend(idx, lrg_id);
+  }
+
+  void uf_extend(uint dst_lrg_id, uint src_lrg_id) {
+    _uf_map.extend(dst_lrg_id, src_lrg_id);
+  }
+
+  LiveRangeMap(uint unique)
+  : _names(unique)
+  , _uf_map(unique)
+  , _max_lrg_id(0) {}
+
+  uint find_id( const Node *n ) {
+    uint retval = live_range_id(n);
+    assert(retval == find(n),"Invalid node to lidx mapping");
+    return retval;
+  }
+
+  // Reset the Union-Find map to identity
+  void reset_uf_map(uint max_lrg_id);
+
+  // Make all Nodes map directly to their final live range; no need for
+  // the Union-Find mapping after this call.
+  void compress_uf_map_for_nodes();
+
+  uint find(uint lidx) {
+    uint uf_lidx = _uf_map[lidx];
+    return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx);
+  }
+
+  // Convert a Node into a Live Range Index - a lidx
+  uint find(const Node *node) {
+    uint lidx = live_range_id(node);
+    uint uf_lidx = _uf_map[lidx];
+    return (uf_lidx == lidx) ? uf_lidx : find_compress(node);
+  }
+
+  // Like Find above, but no path compress, so bad asymptotic behavior
+  uint find_const(uint lrg) const;
+
+  // Like Find above, but no path compress, so bad asymptotic behavior
+  uint find_const(const Node *node) const {
+    if(node->_idx >= _names.Size()) {
+      return 0; // not mapped, usual for debug dump
+    }
+    return find_const(_names[node->_idx]);
+  }
+};
 
 //------------------------------Chaitin----------------------------------------
 // Briggs-Chaitin style allocation, mostly.
@@ -311,7 +411,6 @@
   int _trip_cnt;
   int _alternate;
 
-  uint _maxlrg;                 // Max live range number
   LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
   PhaseLive *_live;             // Liveness, used in the interference graph
   PhaseIFG *_ifg;               // Interference graph (for original chunk)
@@ -319,16 +418,6 @@
   VectorSet _spilled_once;      // Nodes that have been spilled
   VectorSet _spilled_twice;     // Nodes that have been spilled twice
 
-  LRG_List _names;              // Map from Nodes to Live RanGes
-
-  // Union-find map.  Declared as a short for speed.
-  // Indexed by live-range number, it returns the compacted live-range number
-  LRG_List _uf_map;
-  // Reset the Union-Find map to identity
-  void reset_uf_map( uint maxlrg );
-  // Remove the need for the Union-Find mapping
-  void compress_uf_map_for_nodes( );
-
   // Combine the Live Range Indices for these 2 Nodes into a single live
   // range.  Future requests for any Node in either live range will
   // return the live range index for the combined live range.
@@ -347,7 +436,23 @@
   // Helper functions for Split()
   uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
   uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
-  int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg );
+
+  //------------------------------clone_projs------------------------------------
+  // After cloning some rematerialized instruction, clone any MachProj's that
+  // follow it.  Example: Intel zero is XOR, kills flags.  Sparc FP constants
+  // use G3 as an address temp.
+  int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id);
+
+  int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) {
+    uint max_lrg_id = lrg_map.max_lrg_id();
+    int found_projs = clone_projs(b, idx, orig, copy, max_lrg_id);
+    if (found_projs > 0) {
+      // max_lrg_id is updated during call above
+      lrg_map.set_max_lrg_id(max_lrg_id);
+    }
+    return found_projs;
+  }
+
   Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
                             int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
   // True if lidx is used before any real register is def'd in the block
@@ -374,20 +479,11 @@
   PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher );
   ~PhaseChaitin() {}
 
-  // Convert a Node into a Live Range Index - a lidx
-  uint Find( const Node *n ) {
-    uint lidx = n2lidx(n);
-    uint uf_lidx = _uf_map[lidx];
-    return (uf_lidx == lidx) ? uf_lidx : Find_compress(n);
-  }
-  uint Find_const( uint lrg ) const;
-  uint Find_const( const Node *n ) const;
+  LiveRangeMap _lrg_map;
 
   // Do all the real work of allocate
   void Register_Allocate();
 
-  uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
-
   float high_frequency_lrg() const { return _high_frequency_lrg; }
 
 #ifndef PRODUCT
@@ -399,18 +495,6 @@
   // all inputs to a PhiNode, effectively coalescing live ranges.  Insert
   // copies as needed.
   void de_ssa();
-  uint Find_compress( const Node *n );
-  uint Find( uint lidx ) {
-    uint uf_lidx = _uf_map[lidx];
-    return (uf_lidx == lidx) ? uf_lidx : Find_compress(lidx);
-  }
-  uint Find_compress( uint lidx );
-
-  uint Find_id( const Node *n ) {
-    uint retval = n2lidx(n);
-    assert(retval == Find(n),"Invalid node to lidx mapping");
-    return retval;
-  }
 
   // Add edge between reg and everything in the vector.
   // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask
--- a/src/share/vm/opto/coalesce.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/coalesce.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -35,163 +35,10 @@
 #include "opto/regmask.hpp"
 
 //=============================================================================
-//------------------------------reset_uf_map-----------------------------------
-void PhaseChaitin::reset_uf_map( uint maxlrg ) {
-  _maxlrg = maxlrg;
-  // Force the Union-Find mapping to be at least this large
-  _uf_map.extend(_maxlrg,0);
-  // Initialize it to be the ID mapping.
-  for( uint i=0; i<_maxlrg; i++ )
-    _uf_map.map(i,i);
-}
-
-//------------------------------compress_uf_map--------------------------------
-// Make all Nodes map directly to their final live range; no need for
-// the Union-Find mapping after this call.
-void PhaseChaitin::compress_uf_map_for_nodes( ) {
-  // For all Nodes, compress mapping
-  uint unique = _names.Size();
-  for( uint i=0; i<unique; i++ ) {
-    uint lrg = _names[i];
-    uint compressed_lrg = Find(lrg);
-    if( lrg != compressed_lrg )
-      _names.map(i,compressed_lrg);
-  }
-}
-
-//------------------------------Find-------------------------------------------
-// Straight out of Tarjan's union-find algorithm
-uint PhaseChaitin::Find_compress( uint lrg ) {
-  uint cur = lrg;
-  uint next = _uf_map[cur];
-  while( next != cur ) {        // Scan chain of equivalences
-    assert( next < cur, "always union smaller" );
-    cur = next;                 // until find a fixed-point
-    next = _uf_map[cur];
-  }
-  // Core of union-find algorithm: update chain of
-  // equivalences to be equal to the root.
-  while( lrg != next ) {
-    uint tmp = _uf_map[lrg];
-    _uf_map.map(lrg, next);
-    lrg = tmp;
-  }
-  return lrg;
-}
-
-//------------------------------Find-------------------------------------------
-// Straight out of Tarjan's union-find algorithm
-uint PhaseChaitin::Find_compress( const Node *n ) {
-  uint lrg = Find_compress(_names[n->_idx]);
-  _names.map(n->_idx,lrg);
-  return lrg;
-}
-
-//------------------------------Find_const-------------------------------------
-// Like Find above, but no path compress, so bad asymptotic behavior
-uint PhaseChaitin::Find_const( uint lrg ) const {
-  if( !lrg ) return lrg;        // Ignore the zero LRG
-  // Off the end?  This happens during debugging dumps when you got
-  // brand new live ranges but have not told the allocator yet.
-  if( lrg >= _maxlrg ) return lrg;
-  uint next = _uf_map[lrg];
-  while( next != lrg ) {        // Scan chain of equivalences
-    assert( next < lrg, "always union smaller" );
-    lrg = next;                 // until find a fixed-point
-    next = _uf_map[lrg];
-  }
-  return next;
-}
-
-//------------------------------Find-------------------------------------------
-// Like Find above, but no path compress, so bad asymptotic behavior
-uint PhaseChaitin::Find_const( const Node *n ) const {
-  if( n->_idx >= _names.Size() ) return 0; // not mapped, usual for debug dump
-  return Find_const( _names[n->_idx] );
-}
-
-//------------------------------Union------------------------------------------
-// union 2 sets together.
-void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
-  uint src = Find(src_n);
-  uint dst = Find(dst_n);
-  assert( src, "" );
-  assert( dst, "" );
-  assert( src < _maxlrg, "oob" );
-  assert( dst < _maxlrg, "oob" );
-  assert( src < dst, "always union smaller" );
-  _uf_map.map(dst,src);
-}
-
-//------------------------------new_lrg----------------------------------------
-void PhaseChaitin::new_lrg( const Node *x, uint lrg ) {
-  // Make the Node->LRG mapping
-  _names.extend(x->_idx,lrg);
-  // Make the Union-Find mapping an identity function
-  _uf_map.extend(lrg,lrg);
-}
-
-//------------------------------clone_projs------------------------------------
-// After cloning some rematerialized instruction, clone any MachProj's that
-// follow it.  Example: Intel zero is XOR, kills flags.  Sparc FP constants
-// use G3 as an address temp.
-int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
-  assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
-  DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
-  int found_projs = 0;
-  uint cnt = orig->outcnt();
-  for (uint i = 0; i < cnt; i++) {
-    Node* proj = orig->raw_out(i);
-    if (proj->is_MachProj()) {
-      assert(proj->outcnt() == 0, "only kill projections are expected here");
-      assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections");
-      found_projs++;
-      // Copy kill projections after the cloned node
-      Node* kills = proj->clone();
-      kills->set_req(0, copy);
-      b->_nodes.insert(idx++, kills);
-      _cfg.map_node_to_block(kills, b);
-      new_lrg(kills, max_lrg_id++);
-    }
-  }
-  return found_projs;
-}
-
-//------------------------------compact----------------------------------------
-// Renumber the live ranges to compact them.  Makes the IFG smaller.
-void PhaseChaitin::compact() {
-  // Current the _uf_map contains a series of short chains which are headed
-  // by a self-cycle.  All the chains run from big numbers to little numbers.
-  // The Find() call chases the chains & shortens them for the next Find call.
-  // We are going to change this structure slightly.  Numbers above a moving
-  // wave 'i' are unchanged.  Numbers below 'j' point directly to their
-  // compacted live range with no further chaining.  There are no chains or
-  // cycles below 'i', so the Find call no longer works.
-  uint j=1;
-  uint i;
-  for( i=1; i < _maxlrg; i++ ) {
-    uint lr = _uf_map[i];
-    // Ignore unallocated live ranges
-    if( !lr ) continue;
-    assert( lr <= i, "" );
-    _uf_map.map(i, ( lr == i ) ? j++ : _uf_map[lr]);
-  }
-  if( false )                  // PrintOptoCompactLiveRanges
-    printf("Compacted %d LRs from %d\n",i-j,i);
-  // Now change the Node->LR mapping to reflect the compacted names
-  uint unique = _names.Size();
-  for( i=0; i<unique; i++ )
-    _names.map(i,_uf_map[_names[i]]);
-
-  // Reset the Union-Find mapping
-  reset_uf_map(j);
-
-}
-
 #ifndef PRODUCT
-void PhaseCoalesce::dump( Node *n ) const {
+void PhaseCoalesce::dump(Node *n) const {
   // Being a const function means I cannot use 'Find'
-  uint r = _phc.Find(n);
+  uint r = _phc._lrg_map.find(n);
   tty->print("L%d/N%d ",r,n->_idx);
 }
 
@@ -237,9 +84,9 @@
 #endif
 
 // Combine the live ranges def'd by these 2 Nodes.  N2 is an input to N1.
-void PhaseCoalesce::combine_these_two( Node *n1, Node *n2 ) {
-  uint lr1 = _phc.Find(n1);
-  uint lr2 = _phc.Find(n2);
+void PhaseCoalesce::combine_these_two(Node *n1, Node *n2) {
+  uint lr1 = _phc._lrg_map.find(n1);
+  uint lr2 = _phc._lrg_map.find(n2);
   if( lr1 != lr2 &&             // Different live ranges already AND
       !_phc._ifg->test_edge_sq( lr1, lr2 ) ) {  // Do not interfere
     LRG *lrg1 = &_phc.lrgs(lr1);
@@ -305,14 +152,18 @@
   // I am about to clobber the dst_name, so the copy must be inserted
   // after the last use.  Last use is really first-use on a backwards scan.
   uint i = b->end_idx()-1;
-  while( 1 ) {
+  while(1) {
     Node *n = b->_nodes[i];
     // Check for end of virtual copies; this is also the end of the
     // parallel renaming effort.
-    if( n->_idx < _unique ) break;
+    if (n->_idx < _unique) {
+      break;
+    }
     uint idx = n->is_Copy();
     assert( idx || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
-    if( idx && _phc.Find(n->in(idx)) == dst_name ) break;
+    if (idx && _phc._lrg_map.find(n->in(idx)) == dst_name) {
+      break;
+    }
     i--;
   }
   uint last_use_idx = i;
@@ -323,24 +174,29 @@
   // There can be only 1 kill that exits any block and that is
   // the last kill.  Thus it is the first kill on a backwards scan.
   i = b->end_idx()-1;
-  while( 1 ) {
+  while (1) {
     Node *n = b->_nodes[i];
     // Check for end of virtual copies; this is also the end of the
     // parallel renaming effort.
-    if( n->_idx < _unique ) break;
+    if (n->_idx < _unique) {
+      break;
+    }
     assert( n->is_Copy() || n->is_Con() || n->is_MachProj(), "Only copies during parallel renaming" );
-    if( _phc.Find(n) == src_name ) {
+    if (_phc._lrg_map.find(n) == src_name) {
       kill_src_idx = i;
       break;
     }
     i--;
   }
   // Need a temp?  Last use of dst comes after the kill of src?
-  if( last_use_idx >= kill_src_idx ) {
+  if (last_use_idx >= kill_src_idx) {
     // Need to break a cycle with a temp
     uint idx = copy->is_Copy();
     Node *tmp = copy->clone();
-    _phc.new_lrg(tmp,_phc._maxlrg++);
+    uint max_lrg_id = _phc._lrg_map.max_lrg_id();
+    _phc.new_lrg(tmp, max_lrg_id);
+    _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1);
+
     // Insert new temp between copy and source
     tmp ->set_req(idx,copy->in(idx));
     copy->set_req(idx,tmp);
@@ -357,14 +213,14 @@
 void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
   // We do LRGs compressing and fix a liveout data only here since the other
   // place in Split() is guarded by the assert which we never hit.
-  _phc.compress_uf_map_for_nodes();
+  _phc._lrg_map.compress_uf_map_for_nodes();
   // Fix block's liveout data for compressed live ranges.
-  for(uint lrg = 1; lrg < _phc._maxlrg; lrg++ ) {
-    uint compressed_lrg = _phc.Find(lrg);
-    if( lrg != compressed_lrg ) {
+  for (uint lrg = 1; lrg < _phc._lrg_map.max_lrg_id(); lrg++) {
+    uint compressed_lrg = _phc._lrg_map.find(lrg);
+    if (lrg != compressed_lrg) {
       for (uint bidx = 0; bidx < _phc._cfg.number_of_blocks(); bidx++) {
         IndexSet *liveout = _phc._live->live(_phc._cfg.get_block(bidx));
-        if( liveout->member(lrg) ) {
+        if (liveout->member(lrg)) {
           liveout->remove(lrg);
           liveout->insert(compressed_lrg);
         }
@@ -392,8 +248,9 @@
         uint cidx = copy->is_Copy();
         if( cidx ) {
           Node *def = copy->in(cidx);
-          if( _phc.Find(copy) == _phc.Find(def) )
-            n->set_req(k,def);
+          if (_phc._lrg_map.find(copy) == _phc._lrg_map.find(def)) {
+            n->set_req(k, def);
+          }
         }
       }
 
@@ -401,7 +258,7 @@
       uint cidx = n->is_Copy();
       if( cidx ) {
         Node *def = n->in(cidx);
-        if( _phc.Find(n) == _phc.Find(def) ) {
+        if (_phc._lrg_map.find(n) == _phc._lrg_map.find(def)) {
           n->replace_by(def);
           n->set_req(cidx,NULL);
           b->_nodes.remove(l);
@@ -410,16 +267,18 @@
         }
       }
 
-      if( n->is_Phi() ) {
+      if (n->is_Phi()) {
         // Get the chosen name for the Phi
-        uint phi_name = _phc.Find( n );
+        uint phi_name = _phc._lrg_map.find(n);
         // Ignore the pre-allocated specials
-        if( !phi_name ) continue;
+        if (!phi_name) {
+          continue;
+        }
         // Check for mismatch inputs to Phi
-        for( uint j = 1; j<cnt; j++ ) {
+        for (uint j = 1; j < cnt; j++) {
           Node *m = n->in(j);
-          uint src_name = _phc.Find(m);
-          if( src_name != phi_name ) {
+          uint src_name = _phc._lrg_map.find(m);
+          if (src_name != phi_name) {
             Block *pred = _phc._cfg.get_block_for_node(b->pred(j));
             Node *copy;
             assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
@@ -430,18 +289,18 @@
               // Insert the copy in the predecessor basic block
               pred->add_inst(copy);
               // Copy any flags as well
-              _phc.clone_projs( pred, pred->end_idx(), m, copy, _phc._maxlrg );
+              _phc.clone_projs(pred, pred->end_idx(), m, copy, _phc._lrg_map);
             } else {
               const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
-              copy = new (C) MachSpillCopyNode(m,*rm,*rm);
+              copy = new (C) MachSpillCopyNode(m, *rm, *rm);
               // Find a good place to insert.  Kinda tricky, use a subroutine
               insert_copy_with_overlap(pred,copy,phi_name,src_name);
             }
             // Insert the copy in the use-def chain
-            n->set_req( j, copy );
+            n->set_req(j, copy);
             _phc._cfg.map_node_to_block(copy, pred);
             // Extend ("register allocate") the names array for the copy.
-            _phc._names.extend( copy->_idx, phi_name );
+            _phc._lrg_map.extend(copy->_idx, phi_name);
           } // End of if Phi names do not match
         } // End of for all inputs to Phi
       } else { // End of if Phi
@@ -450,31 +309,31 @@
         uint idx;
         if( n->is_Mach() && (idx=n->as_Mach()->two_adr()) ) {
           // Get the chosen name for the Node
-          uint name = _phc.Find( n );
-          assert( name, "no 2-address specials" );
+          uint name = _phc._lrg_map.find(n);
+          assert (name, "no 2-address specials");
           // Check for name mis-match on the 2-address input
           Node *m = n->in(idx);
-          if( _phc.Find(m) != name ) {
+          if (_phc._lrg_map.find(m) != name) {
             Node *copy;
             assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
             // At this point it is unsafe to extend live ranges (6550579).
             // Rematerialize only constants as we do for Phi above.
-            if( m->is_Mach() && m->as_Mach()->is_Con() &&
-                m->as_Mach()->rematerialize() ) {
+            if(m->is_Mach() && m->as_Mach()->is_Con() &&
+               m->as_Mach()->rematerialize()) {
               copy = m->clone();
               // Insert the copy in the basic block, just before us
-              b->_nodes.insert( l++, copy );
-              l += _phc.clone_projs(b, l, m, copy, _phc._maxlrg);
+              b->_nodes.insert(l++, copy);
+              l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
             } else {
               const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
-              copy = new (C) MachSpillCopyNode( m, *rm, *rm );
+              copy = new (C) MachSpillCopyNode(m, *rm, *rm);
               // Insert the copy in the basic block, just before us
-              b->_nodes.insert( l++, copy );
+              b->_nodes.insert(l++, copy);
             }
             // Insert the copy in the use-def chain
-            n->set_req(idx, copy );
+            n->set_req(idx, copy);
             // Extend ("register allocate") the names array for the copy.
-            _phc._names.extend( copy->_idx, name );
+            _phc._lrg_map.extend(copy->_idx, name);
             _phc._cfg.map_node_to_block(copy, b);
           }
 
@@ -489,9 +348,11 @@
           for(uint inpidx = debug_start; inpidx < debug_end; inpidx++) {
             // Do not split monitors; they are only needed for debug table
             // entries and need no code.
-            if( jvms->is_monitor_use(inpidx) ) continue;
+            if (jvms->is_monitor_use(inpidx)) {
+              continue;
+            }
             Node *inp = n->in(inpidx);
-            uint nidx = _phc.n2lidx(inp);
+            uint nidx = _phc._lrg_map.live_range_id(inp);
             LRG &lrg = lrgs(nidx);
 
             // If this lrg has a high frequency use/def
@@ -518,7 +379,9 @@
               // Insert the copy in the basic block, just before us
               b->_nodes.insert( l++, copy );
               // Extend ("register allocate") the names array for the copy.
-              _phc.new_lrg( copy, _phc._maxlrg++ );
+              uint max_lrg_id = _phc._lrg_map.max_lrg_id();
+              _phc.new_lrg(copy, max_lrg_id);
+              _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1);
               _phc._cfg.map_node_to_block(copy, b);
               //tty->print_cr("Split a debug use in Aggressive Coalesce");
             }  // End of if high frequency use/def
@@ -584,15 +447,15 @@
     uint idx;
     // 2-address instructions have a virtual Copy matching their input
     // to their output
-    if( n->is_Mach() && (idx = n->as_Mach()->two_adr()) ) {
+    if (n->is_Mach() && (idx = n->as_Mach()->two_adr())) {
       MachNode *mach = n->as_Mach();
-      combine_these_two( mach, mach->in(idx) );
+      combine_these_two(mach, mach->in(idx));
     }
   } // End of for all instructions in block
 }
 
-PhaseConservativeCoalesce::PhaseConservativeCoalesce( PhaseChaitin &chaitin ) : PhaseCoalesce(chaitin) {
-  _ulr.initialize(_phc._maxlrg);
+PhaseConservativeCoalesce::PhaseConservativeCoalesce(PhaseChaitin &chaitin) : PhaseCoalesce(chaitin) {
+  _ulr.initialize(_phc._lrg_map.max_lrg_id());
 }
 
 void PhaseConservativeCoalesce::verify() {
@@ -669,10 +532,14 @@
       // Else work back one in copy chain
       prev_copy = prev_copy->in(prev_copy->is_Copy());
     } else {                    // Else collect interferences
-      uint lidx = _phc.Find(x);
+      uint lidx = _phc._lrg_map.find(x);
       // Found another def of live-range being stretched?
-      if( lidx == lr1 ) return max_juint;
-      if( lidx == lr2 ) return max_juint;
+      if(lidx == lr1) {
+        return max_juint;
+      }
+      if(lidx == lr2) {
+        return max_juint;
+      }
 
       // If we attempt to coalesce across a bound def
       if( lrgs(lidx).is_bound() ) {
@@ -744,33 +611,43 @@
 // See if I can coalesce a series of multiple copies together.  I need the
 // final dest copy and the original src copy.  They can be the same Node.
 // Compute the compatible register masks.
-bool PhaseConservativeCoalesce::copy_copy( Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
+bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block *b, uint bindex) {
 
-  if( !dst_copy->is_SpillCopy() ) return false;
-  if( !src_copy->is_SpillCopy() ) return false;
+  if (!dst_copy->is_SpillCopy()) {
+    return false;
+  }
+  if (!src_copy->is_SpillCopy()) {
+    return false;
+  }
   Node *src_def = src_copy->in(src_copy->is_Copy());
-  uint lr1 = _phc.Find(dst_copy);
-  uint lr2 = _phc.Find(src_def );
+  uint lr1 = _phc._lrg_map.find(dst_copy);
+  uint lr2 = _phc._lrg_map.find(src_def);
 
   // Same live ranges already?
-  if( lr1 == lr2 ) return false;
+  if (lr1 == lr2) {
+    return false;
+  }
 
   // Interfere?
-  if( _phc._ifg->test_edge_sq( lr1, lr2 ) ) return false;
+  if (_phc._ifg->test_edge_sq(lr1, lr2)) {
+    return false;
+  }
 
   // Not an oop->int cast; oop->oop, int->int, AND int->oop are OK.
-  if( !lrgs(lr1)._is_oop && lrgs(lr2)._is_oop ) // not an oop->int cast
+  if (!lrgs(lr1)._is_oop && lrgs(lr2)._is_oop) { // not an oop->int cast
     return false;
+  }
 
   // Coalescing between an aligned live range and a mis-aligned live range?
   // No, no!  Alignment changes how we count degree.
-  if( lrgs(lr1)._fat_proj != lrgs(lr2)._fat_proj )
+  if (lrgs(lr1)._fat_proj != lrgs(lr2)._fat_proj) {
     return false;
+  }
 
   // Sort; use smaller live-range number
   Node *lr1_node = dst_copy;
   Node *lr2_node = src_def;
-  if( lr1 > lr2 ) {
+  if (lr1 > lr2) {
     uint tmp = lr1; lr1 = lr2; lr2 = tmp;
     lr1_node = src_def;  lr2_node = dst_copy;
   }
@@ -909,17 +786,5 @@
       PhaseChaitin::_conserv_coalesce++;  // Collect stats on success
       continue;
     }
-
-    /* do not attempt pairs.  About 1/2 of all pairs can be removed by
-       post-alloc.  The other set are too few to bother.
-    Node *copy2 = copy1->in(idx1);
-    uint idx2 = copy2->is_Copy();
-    if( !idx2 ) continue;
-    if( copy_copy(copy1,copy2,b,i) ) {
-      i--;                      // Retry, same location in block
-      PhaseChaitin::_conserv_coalesce_pair++; // Collect stats on success
-      continue;
-    }
-    */
   }
 }
--- a/src/share/vm/opto/coalesce.hpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/coalesce.hpp	Mon Apr 24 19:28:39 2017 +0100
@@ -41,23 +41,25 @@
 
 public:
   // Coalesce copies
-  PhaseCoalesce( PhaseChaitin &chaitin ) : Phase(Coalesce), _phc(chaitin) { }
+  PhaseCoalesce(PhaseChaitin &phc)
+  : Phase(Coalesce)
+  , _phc(phc) {}
 
   virtual void verify() = 0;
 
   // Coalesce copies
-  void coalesce_driver( );
+  void coalesce_driver();
 
   // Coalesce copies in this block
-  virtual void coalesce( Block *b ) = 0;
+  virtual void coalesce(Block *b) = 0;
 
   // Attempt to coalesce live ranges defined by these 2
-  void combine_these_two( Node *n1, Node *n2 );
+  void combine_these_two(Node *n1, Node *n2);
 
-  LRG &lrgs( uint lidx ) { return _phc.lrgs(lidx); }
+  LRG &lrgs(uint lidx) { return _phc.lrgs(lidx); }
 #ifndef PRODUCT
   // Dump internally name
-  void dump( Node *n ) const;
+  void dump(Node *n) const;
   // Dump whole shebang
   void dump() const;
 #endif
--- a/src/share/vm/opto/compile.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/compile.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -2272,18 +2272,15 @@
   _regalloc = &regalloc;
   {
     TracePhase t2("regalloc", &_t_registerAllocation, true);
-    // Perform any platform dependent preallocation actions.  This is used,
-    // for example, to avoid taking an implicit null pointer exception
-    // using the frame pointer on win95.
-    _regalloc->pd_preallocate_hook();
-
     // Perform register allocation.  After Chaitin, use-def chains are
     // no longer accurate (at spill code) and so must be ignored.
     // Node->LRG->reg mappings are still accurate.
     _regalloc->Register_Allocate();
 
     // Bail out if the allocator builds too many nodes
-    if (failing())  return;
+    if (failing()) {
+      return;
+    }
   }
 
   // Prior to register allocation we kept empty basic blocks in case the
@@ -2301,9 +2298,6 @@
     cfg.fixup_flow();
   }
 
-  // Perform any platform dependent postallocation verifications.
-  debug_only( _regalloc->pd_postallocate_verify_hook(); )
-
   // Apply peephole optimizations
   if( OptoPeephole ) {
     NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); )
--- a/src/share/vm/opto/idealGraphPrinter.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/idealGraphPrinter.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -616,7 +616,7 @@
       buffer[0] = 0;
       _chaitin->dump_register(node, buffer);
       print_prop("reg", buffer);
-      print_prop("lrg", _chaitin->n2lidx(node));
+      print_prop("lrg", _chaitin->_lrg_map.live_range_id(node));
     }
 
     Compile::current()->_in_dump_cnt--;
--- a/src/share/vm/opto/ifg.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/ifg.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -271,15 +271,14 @@
     uint idx;
     uint last = 0;
     while ((idx = elements.next()) != 0) {
-      assert( idx != i, "Must have empty diagonal");
-      assert( pc->Find_const(idx) == idx, "Must not need Find" );
-      assert( _adjs[idx].member(i), "IFG not square" );
-      assert( !(*_yanked)[idx], "No yanked neighbors" );
-      assert( last < idx, "not sorted increasing");
+      assert(idx != i, "Must have empty diagonal");
+      assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
+      assert(_adjs[idx].member(i), "IFG not square");
+      assert(!(*_yanked)[idx], "No yanked neighbors");
+      assert(last < idx, "not sorted increasing");
       last = idx;
     }
-    assert( !lrgs(i)._degree_valid ||
-            effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong" );
+    assert(!lrgs(i)._degree_valid || effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong");
   }
 }
 #endif
@@ -325,10 +324,10 @@
       Node* n = block->_nodes[j - 1];
 
       // Get value being defined
-      uint r = n2lidx(n);
+      uint r = _lrg_map.live_range_id(n);
 
       // Some special values do not allocate
-      if( r ) {
+      if (r) {
 
         // Remove from live-out set
         liveout->remove(r);
@@ -336,16 +335,19 @@
         // Copies do not define a new value and so do not interfere.
         // Remove the copies source from the liveout set before interfering.
         uint idx = n->is_Copy();
-        if( idx ) liveout->remove( n2lidx(n->in(idx)) );
+        if (idx) {
+          liveout->remove(_lrg_map.live_range_id(n->in(idx)));
+        }
 
         // Interfere with everything live
-        interfere_with_live( r, liveout );
+        interfere_with_live(r, liveout);
       }
 
       // Make all inputs live
-      if( !n->is_Phi() ) {      // Phi function uses come from prior block
-        for( uint k = 1; k < n->req(); k++ )
-          liveout->insert( n2lidx(n->in(k)) );
+      if (!n->is_Phi()) {      // Phi function uses come from prior block
+        for(uint k = 1; k < n->req(); k++) {
+          liveout->insert(_lrg_map.live_range_id(n->in(k)));
+        }
       }
 
       // 2-address instructions always have the defined value live
@@ -377,11 +379,12 @@
           n->set_req( 2, tmp );
         }
         // Defined value interferes with all inputs
-        uint lidx = n2lidx(n->in(idx));
-        for( uint k = 1; k < n->req(); k++ ) {
-          uint kidx = n2lidx(n->in(k));
-          if( kidx != lidx )
-            _ifg->add_edge( r, kidx );
+        uint lidx = _lrg_map.live_range_id(n->in(idx));
+        for (uint k = 1; k < n->req(); k++) {
+          uint kidx = _lrg_map.live_range_id(n->in(k));
+          if (kidx != lidx) {
+            _ifg->add_edge(r, kidx);
+          }
         }
       }
     } // End of forall instructions in block
@@ -537,10 +540,10 @@
       Node* n = block->_nodes[j - 1];
 
       // Get value being defined
-      uint r = n2lidx(n);
+      uint r = _lrg_map.live_range_id(n);
 
       // Some special values do not allocate
-      if( r ) {
+      if(r) {
         // A DEF normally costs block frequency; rematerialized values are
         // removed from the DEF sight, so LOWER costs here.
         lrgs(r)._cost += n->rematerialize() ? 0 : block->_freq;
@@ -551,7 +554,7 @@
           Node *def = n->in(0);
           if( !n->is_Proj() ||
               // Could also be a flags-projection of a dead ADD or such.
-              (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {
+              (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
             bool remove = true;
             if (n->is_MachProj()) {
               // Don't remove KILL projections if their "defining" nodes have
@@ -572,7 +575,9 @@
             }
             if (remove) {
               block->_nodes.remove(j - 1);
-              if( lrgs(r)._def == n ) lrgs(r)._def = 0;
+	      if (lrgs(r)._def == n) {
+		lrgs(r)._def = 0;
+	      }
               n->disconnect_inputs(NULL, C);
               _cfg.unmap_node_from_block(n);
               n->replace_by(C->top());
@@ -585,7 +590,7 @@
 
           // Fat-projections kill many registers which cannot be used to
           // hold live ranges.
-          if( lrgs(r)._fat_proj ) {
+          if (lrgs(r)._fat_proj) {
             // Count the int-only registers
             RegMask itmp = lrgs(r).mask();
             itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
@@ -663,9 +668,9 @@
           // Copies do not define a new value and so do not interfere.
           // Remove the copies source from the liveout set before interfering.
           uint idx = n->is_Copy();
-          if( idx ) {
-            uint x = n2lidx(n->in(idx));
-            if( liveout.remove( x ) ) {
+          if (idx) {
+            uint x = _lrg_map.live_range_id(n->in(idx));
+            if (liveout.remove(x)) {
               lrgs(x)._area -= cost;
               // Adjust register pressure.
               lower_pressure(&lrgs(x), j - 1, block, pressure, hrp_index);
@@ -754,18 +759,21 @@
         // the flags and assumes it's dead.  This keeps the (useless)
         // flag-setting behavior alive while also keeping the (useful)
         // memory update effect.
-        for( uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++ ) {
+        for (uint k = ((n->Opcode() == Op_SCMemProj) ? 0:1); k < n->req(); k++) {
           Node *def = n->in(k);
-          uint x = n2lidx(def);
-          if( !x ) continue;
+          uint x = _lrg_map.live_range_id(def);
+          if (!x) {
+            continue;
+          }
           LRG &lrg = lrgs(x);
           // No use-side cost for spilling debug info
-          if( k < debug_start )
+          if (k < debug_start) {
             // A USE costs twice block frequency (once for the Load, once
             // for a Load-delay).  Rematerialized uses only cost once.
             lrg._cost += (def->rematerialize() ? block->_freq : (block->_freq + block->_freq));
+          }
           // It is live now
-          if( liveout.insert( x ) ) {
+          if (liveout.insert(x)) {
             // Newly live things assumed live from here to top of block
             lrg._area += cost;
             // Adjust register pressure
--- a/src/share/vm/opto/live.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/live.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -41,7 +41,7 @@
 // block is put on the worklist.
 //   The locally live-in stuff is computed once and added to predecessor
 // live-out sets.  This separate compilation is done in the outer loop below.
-PhaseLive::PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
+PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) {
 }
 
 void PhaseLive::compute(uint maxlrg) {
--- a/src/share/vm/opto/live.hpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/live.hpp	Mon Apr 24 19:28:39 2017 +0100
@@ -56,7 +56,7 @@
   Block_List *_worklist;        // Worklist for iterative solution
 
   const PhaseCFG &_cfg;         // Basic blocks
-  LRG_List &_names;             // Mapping from Nodes to live ranges
+  const LRG_List &_names;       // Mapping from Nodes to live ranges
   uint _maxlrg;                 // Largest live-range number
   Arena *_arena;
 
@@ -67,7 +67,7 @@
   void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass );
 
 public:
-  PhaseLive( const PhaseCFG &cfg, LRG_List &names, Arena *arena );
+  PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena);
   ~PhaseLive() {}
   // Compute liveness info
   void compute(uint maxlrg);
--- a/src/share/vm/opto/postaloc.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/postaloc.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -56,7 +56,7 @@
   int i;
   for( i=0; i < limit; i++ ) {
     if( def->is_Proj() && def->in(0)->is_Start() &&
-        _matcher.is_save_on_entry(lrgs(n2lidx(def)).reg()) )
+        _matcher.is_save_on_entry(lrgs(_lrg_map.live_range_id(def)).reg()))
       return true;              // Direct use of callee-save proj
     if( def->is_Copy() )        // Copies carry value through
       def = def->in(def->is_Copy());
@@ -85,7 +85,7 @@
     blk_adjust++;
   }
   _cfg.unmap_node_from_block(old);
-  OptoReg::Name old_reg = lrgs(n2lidx(old)).reg();
+  OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg();
   if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
     value->map(old_reg,NULL);  // Yank from value/regnd maps
     regnd->map(old_reg,NULL);  // This register's value is now unknown
@@ -169,7 +169,7 @@
   // Not every pair of physical registers are assignment compatible,
   // e.g. on sparc floating point registers are not assignable to integer
   // registers.
-  const LRG &def_lrg = lrgs(n2lidx(def));
+  const LRG &def_lrg = lrgs(_lrg_map.live_range_id(def));
   OptoReg::Name def_reg = def_lrg.reg();
   const RegMask &use_mask = n->in_RegMask(idx);
   bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0)
@@ -214,11 +214,12 @@
 // Skip through any number of copies (that don't mod oop-i-ness)
 Node *PhaseChaitin::skip_copies( Node *c ) {
   int idx = c->is_Copy();
-  uint is_oop = lrgs(n2lidx(c))._is_oop;
+  uint is_oop = lrgs(_lrg_map.live_range_id(c))._is_oop;
   while (idx != 0) {
     guarantee(c->in(idx) != NULL, "must not resurrect dead copy");
-    if (lrgs(n2lidx(c->in(idx)))._is_oop != is_oop)
+    if (lrgs(_lrg_map.live_range_id(c->in(idx)))._is_oop != is_oop) {
       break;  // casting copy, not the same value
+    }
     c = c->in(idx);
     idx = c->is_Copy();
   }
@@ -230,8 +231,8 @@
 int PhaseChaitin::elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs ) {
   int blk_adjust = 0;
 
-  uint nk_idx = n2lidx(n->in(k));
-  OptoReg::Name nk_reg = lrgs(nk_idx ).reg();
+  uint nk_idx = _lrg_map.live_range_id(n->in(k));
+  OptoReg::Name nk_reg = lrgs(nk_idx).reg();
 
   // Remove obvious same-register copies
   Node *x = n->in(k);
@@ -239,9 +240,13 @@
   while( (idx=x->is_Copy()) != 0 ) {
     Node *copy = x->in(idx);
     guarantee(copy != NULL, "must not resurrect dead copy");
-    if( lrgs(n2lidx(copy)).reg() != nk_reg ) break;
+    if(lrgs(_lrg_map.live_range_id(copy)).reg() != nk_reg) {
+      break;
+    }
     blk_adjust += use_prior_register(n,k,copy,current_block,value,regnd);
-    if( n->in(k) != copy ) break; // Failed for some cutout?
+    if (n->in(k) != copy) {
+      break; // Failed for some cutout?
+    }
     x = copy;                   // Progress, try again
   }
 
@@ -261,7 +266,7 @@
 
   if (val == x && nk_idx != 0 &&
       regnd[nk_reg] != NULL && regnd[nk_reg] != x &&
-      n2lidx(x) == n2lidx(regnd[nk_reg])) {
+      _lrg_map.live_range_id(x) == _lrg_map.live_range_id(regnd[nk_reg])) {
     // When rematerialzing nodes and stretching lifetimes, the
     // allocator will reuse the original def for multidef LRG instead
     // of the current reaching def because it can't know it's safe to
@@ -275,7 +280,7 @@
   if (val == x) return blk_adjust; // No progress?
 
   int n_regs = RegMask::num_registers(val->ideal_reg());
-  uint val_idx = n2lidx(val);
+  uint val_idx = _lrg_map.live_range_id(val);
   OptoReg::Name val_reg = lrgs(val_idx).reg();
 
   // See if it happens to already be in the correct register!
@@ -509,12 +514,12 @@
     for (j = 1; j < phi_dex; j++) {
       uint k;
       Node *phi = block->_nodes[j];
-      uint pidx = n2lidx(phi);
-      OptoReg::Name preg = lrgs(n2lidx(phi)).reg();
+      uint pidx = _lrg_map.live_range_id(phi);
+      OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
 
       // Remove copies remaining on edges.  Check for junk phi.
       Node *u = NULL;
-      for( k=1; k<phi->req(); k++ ) {
+      for (k = 1; k < phi->req(); k++) {
         Node *x = phi->in(k);
         if( phi != x && u != x ) // Found a different input
           u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
@@ -566,10 +571,10 @@
       // alive and well at the use (or else the allocator fubar'd).  Take
       // advantage of this info to set a reaching def for the use-reg.
       uint k;
-      for( k = 1; k < n->req(); k++ ) {
+      for (k = 1; k < n->req(); k++) {
         Node *def = n->in(k);   // n->in(k) is a USE; def is the DEF for this USE
         guarantee(def != NULL, "no disconnected nodes at this point");
-        uint useidx = n2lidx(def); // useidx is the live range index for this USE
+        uint useidx = _lrg_map.live_range_id(def); // useidx is the live range index for this USE
 
         if( useidx ) {
           OptoReg::Name ureg = lrgs(useidx).reg();
@@ -577,7 +582,7 @@
             int idx;            // Skip occasional useless copy
             while( (idx=def->is_Copy()) != 0 &&
                    def->in(idx) != NULL &&  // NULL should not happen
-                   ureg == lrgs(n2lidx(def->in(idx))).reg() )
+                   ureg == lrgs(_lrg_map.live_range_id(def->in(idx))).reg())
               def = def->in(idx);
             Node *valdef = skip_copies(def); // tighten up val through non-useless copies
             value.map(ureg,valdef); // record improved reaching-def info
@@ -606,8 +611,10 @@
       }
 
       // Unallocated Nodes define no registers
-      uint lidx = n2lidx(n);
-      if( !lidx ) continue;
+      uint lidx = _lrg_map.live_range_id(n);
+      if (!lidx) {
+        continue;
+      }
 
       // Update the register defined by this instruction
       OptoReg::Name nreg = lrgs(lidx).reg();
--- a/src/share/vm/opto/reg_split.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/reg_split.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -317,13 +317,13 @@
   if( def->req() > 1 ) {
     for( uint i = 1; i < def->req(); i++ ) {
       Node *in = def->in(i);
-      uint lidx = n2lidx(in);
+      uint lidx = _lrg_map.live_range_id(in);
       // We do not need this for live ranges that are only defined once.
       // However, this is not true for spill copies that are added in this
       // Split() pass, since they might get coalesced later on in this pass.
-      if (lidx < _maxlrg && lrgs(lidx).is_singledef()) {
-         continue;
-       }
+      if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).is_singledef()) {
+        continue;
+      }
 
       Block *b_def = _cfg.get_block_for_node(def);
       int idx_def = b_def->find_node(def);
@@ -347,26 +347,28 @@
   if( spill->req() > 1 ) {
     for( uint i = 1; i < spill->req(); i++ ) {
       Node *in = spill->in(i);
-      uint lidx = Find_id(in);
+      uint lidx = _lrg_map.find_id(in);
 
       // Walk backwards thru spill copy node intermediates
       if (walkThru) {
-        while ( in->is_SpillCopy() && lidx >= _maxlrg ) {
+        while (in->is_SpillCopy() && lidx >= _lrg_map.max_lrg_id()) {
           in = in->in(1);
-          lidx = Find_id(in);
+          lidx = _lrg_map.find_id(in);
         }
 
-        if (lidx < _maxlrg && lrgs(lidx).is_multidef()) {
+        if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).is_multidef()) {
           // walkThru found a multidef LRG, which is unsafe to use, so
           // just keep the original def used in the clone.
           in = spill->in(i);
-          lidx = Find_id(in);
+          lidx = _lrg_map.find_id(in);
         }
       }
 
-      if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) {
+      if (lidx < _lrg_map.max_lrg_id() && lrgs(lidx).reg() >= LRG::SPILL_REG) {
         Node *rdef = Reachblock[lrg2reach[lidx]];
-        if( rdef ) spill->set_req(i,rdef);
+        if (rdef) {
+          spill->set_req(i, rdef);
+        }
       }
     }
   }
@@ -432,17 +434,25 @@
 //------------------------------prompt_use---------------------------------
 // True if lidx is used before any real register is def'd in the block
 bool PhaseChaitin::prompt_use( Block *b, uint lidx ) {
-  if( lrgs(lidx)._was_spilled2 ) return false;
+  if (lrgs(lidx)._was_spilled2) {
+    return false;
+  }
 
   // Scan block for 1st use.
   for( uint i = 1; i <= b->end_idx(); i++ ) {
     Node *n = b->_nodes[i];
     // Ignore PHI use, these can be up or down
-    if( n->is_Phi() ) continue;
-    for( uint j = 1; j < n->req(); j++ )
-      if( Find_id(n->in(j)) == lidx )
+    if (n->is_Phi()) {
+      continue;
+    }
+    for (uint j = 1; j < n->req(); j++) {
+      if (_lrg_map.find_id(n->in(j)) == lidx) {
         return true;          // Found 1st use!
-    if( n->out_RegMask().is_NotEmpty() ) return false;
+      }
+    }
+    if (n->out_RegMask().is_NotEmpty()) {
+      return false;
+    }
   }
   return false;
 }
@@ -472,23 +482,23 @@
   bool                 u1, u2, u3;
   Block               *b, *pred;
   PhiNode             *phi;
-  GrowableArray<uint>  lidxs(split_arena, _maxlrg, 0, 0);
+  GrowableArray<uint>  lidxs(split_arena, maxlrg, 0, 0);
 
   // Array of counters to count splits per live range
-  GrowableArray<uint>  splits(split_arena, _maxlrg, 0, 0);
+  GrowableArray<uint>  splits(split_arena, maxlrg, 0, 0);
 
 #define NEW_SPLIT_ARRAY(type, size)\
   (type*) split_arena->allocate_bytes((size) * sizeof(type))
 
   //----------Setup Code----------
   // Create a convenient mapping from lrg numbers to reaches/leaves indices
-  uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
+  uint *lrg2reach = NEW_SPLIT_ARRAY(uint, maxlrg);
   // Keep track of DEFS & Phis for later passes
   defs = new Node_List();
   phis = new Node_List();
   // Gather info on which LRG's are spilling, and build maps
-  for( bidx = 1; bidx < _maxlrg; bidx++ ) {
-    if( lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG ) {
+  for (bidx = 1; bidx < maxlrg; bidx++) {
+    if (lrgs(bidx).alive() && lrgs(bidx).reg() >= LRG::SPILL_REG) {
       assert(!lrgs(bidx).mask().is_AllStack(),"AllStack should color");
       lrg2reach[bidx] = spill_cnt;
       spill_cnt++;
@@ -637,7 +647,7 @@
           break;
         }
         // must be looking at a phi
-        if( Find_id(n1) == lidxs.at(slidx) ) {
+        if (_lrg_map.find_id(n1) == lidxs.at(slidx)) {
           // found the necessary phi
           needs_phi = false;
           has_phi = true;
@@ -659,11 +669,11 @@
           Reachblock[slidx] = phi;
 
           // add node to block & node_to_block mapping
-          insert_proj( b, insidx++, phi, maxlrg++ );
+          insert_proj(b, insidx++, phi, maxlrg++);
           non_phi++;
           // Reset new phi's mapping to be the spilling live range
-          _names.map(phi->_idx, lidx);
-          assert(Find_id(phi) == lidx,"Bad update on Union-Find mapping");
+          _lrg_map.map(phi->_idx, lidx);
+          assert(_lrg_map.find_id(phi) == lidx, "Bad update on Union-Find mapping");
         }  // end if not found correct phi
         // Here you have either found or created the Phi, so record it
         assert(phi != NULL,"Must have a Phi Node here");
@@ -729,12 +739,12 @@
     for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
       Node *n = b->_nodes[insidx];
       // Find the defining Node's live range index
-      uint defidx = Find_id(n);
+      uint defidx = _lrg_map.find_id(n);
       uint cnt = n->req();
 
-      if( n->is_Phi() ) {
+      if (n->is_Phi()) {
         // Skip phi nodes after removing dead copies.
-        if( defidx < _maxlrg ) {
+        if (defidx < _lrg_map.max_lrg_id()) {
           // Check for useless Phis.  These appear if we spill, then
           // coalesce away copies.  Dont touch Phis in spilling live
           // ranges; they are busy getting modifed in this pass.
@@ -752,8 +762,8 @@
               }
             }
             assert( u, "at least 1 valid input expected" );
-            if( i >= cnt ) {    // Found one unique input
-              assert(Find_id(n) == Find_id(u), "should be the same lrg");
+            if (i >= cnt) {    // Found one unique input
+              assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg");
               n->replace_by(u); // Then replace with unique input
               n->disconnect_inputs(NULL, C);
               b->_nodes.remove(insidx);
@@ -801,16 +811,24 @@
                 while( insert_point > 0 ) {
                   Node *n = b->_nodes[insert_point];
                   // Hit top of block?  Quit going backwards
-                  if( n->is_Phi() ) break;
+                  if (n->is_Phi()) {
+                    break;
+                  }
                   // Found a def?  Better split after it.
-                  if( n2lidx(n) == lidx ) break;
+                  if (_lrg_map.live_range_id(n) == lidx) {
+                    break;
+                  }
                   // Look for a use
                   uint i;
-                  for( i = 1; i < n->req(); i++ )
-                    if( n2lidx(n->in(i)) == lidx )
+                  for( i = 1; i < n->req(); i++ ) {
+                    if (_lrg_map.live_range_id(n->in(i)) == lidx) {
                       break;
+                    }
+                  }
                   // Found a use?  Better split after it.
-                  if( i < n->req() ) break;
+                  if (i < n->req()) {
+                    break;
+                  }
                   insert_point--;
                 }
                 uint orig_eidx = b->end_idx();
@@ -820,8 +838,9 @@
                   return 0;
                 }
                 // Spill of NULL check mem op goes into the following block.
-                if (b->end_idx() > orig_eidx)
+                if (b->end_idx() > orig_eidx) {
                   insidx++;
+                }
               }
               // This is a new DEF, so update UP
               UPblock[slidx] = false;
@@ -840,13 +859,13 @@
       }  // end if crossing HRP Boundry
 
       // If the LRG index is oob, then this is a new spillcopy, skip it.
-      if( defidx >= _maxlrg ) {
+      if (defidx >= _lrg_map.max_lrg_id()) {
         continue;
       }
       LRG &deflrg = lrgs(defidx);
       uint copyidx = n->is_Copy();
       // Remove coalesced copy from CFG
-      if( copyidx && defidx == n2lidx(n->in(copyidx)) ) {
+      if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) {
         n->replace_by( n->in(copyidx) );
         n->set_req( copyidx, NULL );
         b->_nodes.remove(insidx--);
@@ -872,13 +891,13 @@
           // If inpidx > old_last, then one of these new inputs is being
           // handled. Skip the derived part of the pair, but process
           // the base like any other input.
-          if( inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED ) {
+          if (inpidx > old_last && ((inpidx - oopoff) & 1) == DERIVED) {
             continue;  // skip derived_debug added below
           }
           // Get lidx of input
-          uint useidx = Find_id(n->in(inpidx));
+          uint useidx = _lrg_map.find_id(n->in(inpidx));
           // Not a brand-new split, and it is a spill use
-          if( useidx < _maxlrg && lrgs(useidx).reg() >= LRG::SPILL_REG ) {
+          if (useidx < _lrg_map.max_lrg_id() && lrgs(useidx).reg() >= LRG::SPILL_REG) {
             // Check for valid reaching DEF
             slidx = lrg2reach[useidx];
             Node *def = Reachblock[slidx];
@@ -894,7 +913,7 @@
               if (def == NULL || C->check_node_count(NodeLimitFudgeFactor, out_of_nodes)) {
                 return 0;
               }
-              _names.extend(def->_idx,0);
+              _lrg_map.extend(def->_idx, 0);
               _cfg.map_node_to_block(def, b);
               n->set_req(inpidx, def);
               continue;
@@ -1194,10 +1213,10 @@
       // ********** Split Left Over Mem-Mem Moves **********
       // Check for mem-mem copies and split them now.  Do not do this
       // to copies about to be spilled; they will be Split shortly.
-      if( copyidx ) {
+      if (copyidx) {
         Node *use = n->in(copyidx);
-        uint useidx = Find_id(use);
-        if( useidx < _maxlrg &&       // This is not a new split
+        uint useidx = _lrg_map.find_id(use);
+        if (useidx < _lrg_map.max_lrg_id() &&       // This is not a new split
             OptoReg::is_stack(deflrg.reg()) &&
             deflrg.reg() < LRG::SPILL_REG ) { // And DEF is from stack
           LRG &uselrg = lrgs(useidx);
@@ -1236,7 +1255,7 @@
         uint member;
         IndexSetIterator isi(liveout);
         while ((member = isi.next()) != 0) {
-          assert(defidx != Find_const(member), "Live out member has not been compressed");
+          assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
         }
 #endif
         Reachblock[slidx] = NULL;
@@ -1269,7 +1288,7 @@
     assert(phi->is_Phi(),"This list must only contain Phi Nodes");
     Block *b = _cfg.get_block_for_node(phi);
     // Grab the live range number
-    uint lidx = Find_id(phi);
+    uint lidx = _lrg_map.find_id(phi);
     uint slidx = lrg2reach[lidx];
     // Update node to lidx map
     new_lrg(phi, maxlrg++);
@@ -1304,11 +1323,13 @@
         int insert = pred->end_idx();
         while (insert >= 1 &&
                pred->_nodes[insert - 1]->is_SpillCopy() &&
-               Find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
+               _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) {
           insert--;
         }
-        def = split_Rematerialize( def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false );
-        if( !def ) return 0;    // Bail out
+        def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false);
+        if (!def) {
+          return 0;    // Bail out
+        }
       }
       // Update the Phi's input edge array
       phi->set_req(i,def);
@@ -1324,7 +1345,7 @@
     }  // End for all inputs to the Phi
   }  // End for all Phi Nodes
   // Update _maxlrg to save Union asserts
-  _maxlrg = maxlrg;
+  _lrg_map.set_max_lrg_id(maxlrg);
 
 
   //----------PASS 3----------
@@ -1336,29 +1357,33 @@
     for( uint i = 1; i < phi->req(); i++ ) {
       // Grab the input node
       Node *n = phi->in(i);
-      assert( n, "" );
-      uint lidx = Find(n);
-      uint pidx = Find(phi);
-      if( lidx < pidx )
+      assert(n, "node should exist");
+      uint lidx = _lrg_map.find(n);
+      uint pidx = _lrg_map.find(phi);
+      if (lidx < pidx) {
         Union(n, phi);
-      else if( lidx > pidx )
+      }
+      else if(lidx > pidx) {
         Union(phi, n);
+      }
     }  // End for all inputs to the Phi Node
   }  // End for all Phi Nodes
   // Now union all two address instructions
-  for( insidx = 0; insidx < defs->size(); insidx++ ) {
+  for (insidx = 0; insidx < defs->size(); insidx++) {
     // Grab the def
     n1 = defs->at(insidx);
     // Set new lidx for DEF & handle 2-addr instructions
-    if( n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0) ) {
-      assert( Find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index");
+    if (n1->is_Mach() && ((twoidx = n1->as_Mach()->two_adr()) != 0)) {
+      assert(_lrg_map.find(n1->in(twoidx)) < maxlrg,"Assigning bad live range index");
       // Union the input and output live ranges
-      uint lr1 = Find(n1);
-      uint lr2 = Find(n1->in(twoidx));
-      if( lr1 < lr2 )
+      uint lr1 = _lrg_map.find(n1);
+      uint lr2 = _lrg_map.find(n1->in(twoidx));
+      if (lr1 < lr2) {
         Union(n1, n1->in(twoidx));
-      else if( lr1 > lr2 )
+      }
+      else if (lr1 > lr2) {
         Union(n1->in(twoidx), n1);
+      }
     }  // End if two address
   }  // End for all defs
   // DEBUG
@@ -1366,17 +1391,17 @@
   // Validate all live range index assignments
   for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) {
     b  = _cfg.get_block(bidx);
-    for( insidx = 0; insidx <= b->end_idx(); insidx++ ) {
+    for (insidx = 0; insidx <= b->end_idx(); insidx++) {
       Node *n = b->_nodes[insidx];
-      uint defidx = Find(n);
-      assert(defidx < _maxlrg,"Bad live range index in Split");
+      uint defidx = _lrg_map.find(n);
+      assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split");
       assert(defidx < maxlrg,"Bad live range index in Split");
     }
   }
   // Issue a warning if splitting made no progress
   int noprogress = 0;
-  for( slidx = 0; slidx < spill_cnt; slidx++ ) {
-    if( PrintOpto && WizardMode && splits.at(slidx) == 0 ) {
+  for (slidx = 0; slidx < spill_cnt; slidx++) {
+    if (PrintOpto && WizardMode && splits.at(slidx) == 0) {
       tty->print_cr("Failed to split live range %d", lidxs.at(slidx));
       //BREAKPOINT;
     }
--- a/src/share/vm/opto/regalloc.hpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/opto/regalloc.hpp	Mon Apr 24 19:28:39 2017 +0100
@@ -113,7 +113,7 @@
   OptoReg::Name offset2reg( int stk_offset ) const;
 
   // Get the register encoding associated with the Node
-  int get_encode( const Node *n ) const {
+  int get_encode(const Node *n) const {
     assert( n->_idx < _node_regs_max_index, "Exceeded _node_regs array");
     OptoReg::Name first = _node_regs[n->_idx].first();
     OptoReg::Name second = _node_regs[n->_idx].second();
@@ -122,15 +122,6 @@
     return Matcher::_regEncode[first];
   }
 
-  // Platform dependent hook for actions prior to allocation
-  void  pd_preallocate_hook();
-
-#ifdef ASSERT
-  // Platform dependent hook for verification after allocation.  Will
-  // only get called when compiling with asserts.
-  void  pd_postallocate_verify_hook();
-#endif
-
 #ifndef PRODUCT
   static int _total_framesize;
   static int _max_framesize;
--- a/src/share/vm/runtime/vmStructs.cpp	Mon Apr 24 16:49:33 2017 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Mon Apr 24 19:28:39 2017 +0100
@@ -1190,7 +1190,6 @@
   c2_nonstatic_field(PhaseChaitin,       _lo_stk_degree,           uint)                                                             \
   c2_nonstatic_field(PhaseChaitin,       _hi_degree,               uint)                                                             \
   c2_nonstatic_field(PhaseChaitin,       _simplified,              uint)                                                             \
-  c2_nonstatic_field(PhaseChaitin,       _maxlrg,                  uint)                                                             \
                                                                                                                                      \
   c2_nonstatic_field(Block,              _nodes,                   Node_List)                                                        \
   c2_nonstatic_field(Block,              _succs,                   Block_Array)                                                      \