Merge
authorapangin
Sun, 22 Feb 2009 17:11:56 -0800
changeset 2117 85a5555dcb11
parent 2116 57c4d9c2bc0c (current diff)
parent 2108 a76fa2632196 (diff)
child 2119 57dabaf796ea
Merge
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Sun Feb 22 17:11:56 2009 -0800
@@ -762,7 +762,7 @@
     case Assembler::stdf_op3: st_op = Op_StoreD; break;
 
     case Assembler::ldsb_op3: ld_op = Op_LoadB; break;
-    case Assembler::lduh_op3: ld_op = Op_LoadC; break;
+    case Assembler::lduh_op3: ld_op = Op_LoadUS; break;
     case Assembler::ldsh_op3: ld_op = Op_LoadS; break;
     case Assembler::ldx_op3:  // may become LoadP or stay LoadI
     case Assembler::ldsw_op3: // may become LoadP or stay LoadI
@@ -3869,6 +3869,8 @@
   constraint(ALLOC_IN_RC(dflt_reg));
   match(RegD);
 
+  match(regD_low);
+
   format %{ %}
   interface(REG_INTER);
 %}
@@ -3883,7 +3885,7 @@
 
 operand regD_low() %{
   constraint(ALLOC_IN_RC(dflt_low_reg));
-  match(RegD);
+  match(regD);
 
   format %{ %}
   interface(REG_INTER);
@@ -5314,9 +5316,9 @@
   ins_pipe(iload_mask_mem);
 %}
 
-// Load Char (16bit UNsigned) into a Long Register
-instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
-  match(Set dst (AndL (ConvI2L (LoadC mem)) bytemask));
+// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
+instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{
+  match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
@@ -5326,9 +5328,9 @@
   ins_pipe(iload_mask_mem);
 %}
 
-// Load Char (16bit unsigned)
-instruct loadC(iRegI dst, memory mem) %{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16bit unsigned)
+instruct loadUS(iRegI dst, memory mem) %{
+  match(Set dst (LoadUS mem));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Sun Feb 22 17:11:56 2009 -0800
@@ -6413,9 +6413,9 @@
   ins_pipe( ialu_reg_mem );
 %}
 
-// Load Char (16bit unsigned)
-instruct loadC(eRegI dst, memory mem) %{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16bit unsigned)
+instruct loadUS(eRegI dst, memory mem) %{
+  match(Set dst (LoadUS mem));
 
   ins_cost(125);
   format %{ "MOVZX  $dst,$mem" %}
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Sun Feb 22 17:11:56 2009 -0800
@@ -6096,25 +6096,25 @@
 //   ins_pipe(ialu_reg_mem);
 // %}
 
-// Load Char (16 bit UNsigned)
-instruct loadC(rRegI dst, memory mem)
-%{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16 bit UNsigned)
+instruct loadUS(rRegI dst, memory mem)
+%{
+  match(Set dst (LoadUS mem));
 
   ins_cost(125);
-  format %{ "movzwl  $dst, $mem\t# char" %}
+  format %{ "movzwl  $dst, $mem\t# ushort/char" %}
   opcode(0x0F, 0xB7);
   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
   ins_pipe(ialu_reg_mem);
 %}
 
-// Load Char (16 bit UNsigned) into long
-// instruct loadC2L(rRegL dst, memory mem)
+// Load Unsigned Short/Char (16 bit UNsigned) into long
+// instruct loadUS2L(rRegL dst, memory mem)
 // %{
-//   match(Set dst (ConvI2L (LoadC mem)));
+//   match(Set dst (ConvI2L (LoadUS mem)));
 
 //   ins_cost(125);
-//   format %{ "movzwl  $dst, $mem\t# char -> long" %}
+//   format %{ "movzwl  $dst, $mem\t# ushort/char -> long" %}
 //   opcode(0x0F, 0xB7);
 //   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
 //   ins_pipe(ialu_reg_mem);
@@ -9490,14 +9490,14 @@
 %{
   match(Set dst (AndL dst src));
 
-  format %{ "movzbq  $dst, $src\t# long & 0xFF" %}
+  format %{ "movzbq  $dst, $dst\t# long & 0xFF" %}
   opcode(0x0F, 0xB6);
   ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
   ins_pipe(ialu_reg);
 %}
 
 // And Register with Immediate 65535
-instruct andL_rReg_imm65535(rRegI dst, immL_65535 src)
+instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
 %{
   match(Set dst (AndL dst src));
 
--- a/hotspot/src/share/vm/adlc/dict2.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/adlc/dict2.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -316,9 +316,12 @@
   return strcmp((const char *)k1,(const char *)k2);
 }
 
-// Slimey cheap key comparator.
+// Cheap key comparator.
 int cmpkey(const void *key1, const void *key2) {
-  return (int)((intptr_t)key1 - (intptr_t)key2);
+  if (key1 == key2) return 0;
+  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
+  if (delta > 0) return 1;
+  return -1;
 }
 
 //=============================================================================
--- a/hotspot/src/share/vm/adlc/forms.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/adlc/forms.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -248,7 +248,7 @@
 // True if 'opType', an ideal name, loads or stores.
 Form::DataType Form::is_load_from_memory(const char *opType) const {
   if( strcmp(opType,"LoadB")==0 )  return Form::idealB;
-  if( strcmp(opType,"LoadC")==0 )  return Form::idealC;
+  if( strcmp(opType,"LoadUS")==0 )  return Form::idealC;
   if( strcmp(opType,"LoadD")==0 )  return Form::idealD;
   if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
   if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -3314,7 +3314,7 @@
     "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
     "StoreB","StoreC","Store" ,"StoreFP",
     "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
-    "LoadB" ,"LoadC" ,"LoadS" ,"Load"   ,
+    "LoadB" ,"LoadUS" ,"LoadS" ,"Load"   ,
     "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
     "Store8B","Store4B","Store8C","Store4C","Store2C",
     "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -123,6 +123,10 @@
     // addresses constructed before expansions will not be confused.
     cb->free_blob();
   }
+
+  // free any overflow storage
+  delete _overflow_arena;
+
 #ifdef ASSERT
   Copy::fill_to_bytes(this, sizeof(*this), badResourceValue);
 #endif
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -846,6 +846,12 @@
                                 Handle protection_domain,
                                 TRAPS) {
 
+  // UseNewReflection
+  // The result of this call should be consistent with the result
+  // of the call to resolve_instance_class_or_null().
+  // See evaluation 6790209 and 4474172 for more details.
+  class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
+
   unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
   int d_index = dictionary()->hash_to_index(d_hash);
 
--- a/hotspot/src/share/vm/libadt/dict.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/libadt/dict.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -346,9 +346,12 @@
   return strcmp((const char *)k1,(const char *)k2);
 }
 
-// Slimey cheap key comparator.
+// Cheap key comparator.
 int32 cmpkey(const void *key1, const void *key2) {
-  return (int32)((intptr_t)key1 - (intptr_t)key2);
+  if (key1 == key2) return 0;
+  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
+  if (delta > 0) return 1;
+  return -1;
 }
 
 //=============================================================================
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -217,15 +217,28 @@
       (HeapWord*) align_size_up((uintptr_t)new_end, _page_size);
     assert(new_end_aligned >= (HeapWord*) new_end,
            "align up, but less");
+    // Check the other regions (excludes "ind") to ensure that
+    // the new_end_aligned does not intrude onto the committed
+    // space of another region.
     int ri = 0;
     for (ri = 0; ri < _cur_covered_regions; ri++) {
       if (ri != ind) {
         if (_committed[ri].contains(new_end_aligned)) {
-          assert((new_end_aligned >= _committed[ri].start()) &&
-                 (_committed[ri].start() > _committed[ind].start()),
+          // The prior check included in the assert
+          // (new_end_aligned >= _committed[ri].start())
+          // is redundant with the "contains" test.
+          // Any region containing the new end
+          // should start at or beyond the region found (ind)
+          // for the new end (committed regions are not expected to
+          // be proper subsets of other committed regions).
+          assert(_committed[ri].start() >= _committed[ind].start(),
                  "New end of committed region is inconsistent");
           new_end_aligned = _committed[ri].start();
-          assert(new_end_aligned > _committed[ind].start(),
+          // new_end_aligned can be equal to the start of its
+          // committed region (i.e., of "ind") if a second
+          // region following "ind" also start at the same location
+          // as "ind".
+          assert(new_end_aligned >= _committed[ind].start(),
             "New end of committed region is before start");
           debug_only(collided = true;)
           // Should only collide with 1 region
--- a/hotspot/src/share/vm/opto/block.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/block.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -880,6 +880,7 @@
 }
 
 void PhaseCFG::verify( ) const {
+#ifdef ASSERT
   // Verify sane CFG
   for( uint i = 0; i < _num_blocks; i++ ) {
     Block *b = _blocks[i];
@@ -894,10 +895,20 @@
                 "CreateEx must be first instruction in block" );
       }
       for( uint k = 0; k < n->req(); k++ ) {
-        Node *use = n->in(k);
-        if( use && use != n ) {
-          assert( _bbs[use->_idx] || use->is_Con(),
+        Node *def = n->in(k);
+        if( def && def != n ) {
+          assert( _bbs[def->_idx] || def->is_Con(),
                   "must have block; constants for debug info ok" );
+          // Verify that instructions in the block is in correct order.
+          // Uses must follow their definition if they are at the same block.
+          // Mostly done to check that MachSpillCopy nodes are placed correctly
+          // when CreateEx node is moved in build_ifg_physical().
+          if( _bbs[def->_idx] == b &&
+              !(b->head()->is_Loop() && n->is_Phi()) &&
+              // See (+++) comment in reg_split.cpp
+              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
+            assert( b->find_node(def) < j, "uses must follow definitions" );
+          }
         }
       }
     }
@@ -914,6 +925,7 @@
       assert( b->_num_succs == 2, "Conditional branch must have two targets");
     }
   }
+#endif
 }
 #endif
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -191,6 +191,9 @@
   notproduct(bool, VerifyHashTableKeys, true,                               \
           "Verify the immutability of keys in the VN hash tables")          \
                                                                             \
+  notproduct(bool, VerifyRegisterAllocator , false,                         \
+          "Verify Register Allocator")                                      \
+                                                                            \
   develop_pd(intx, FLOATPRESSURE,                                           \
           "Number of float LRG's that constitute high register pressure")   \
                                                                             \
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -858,12 +858,18 @@
   // convert the one to the other.
   const TypePtr* ttp = _type->make_ptr();
   const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
+  const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL;
   bool is_intf = false;
   if (ttip != NULL) {
     ciKlass* k = ttip->klass();
     if (k->is_loaded() && k->is_interface())
       is_intf = true;
   }
+  if (ttkp != NULL) {
+    ciKlass* k = ttkp->klass();
+    if (k->is_loaded() && k->is_interface())
+      is_intf = true;
+  }
 
   // Default case: merge all inputs
   const Type *t = Type::TOP;        // Merged type starting value
@@ -921,6 +927,8 @@
     // uplift the type.
     if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() )
       { assert(ft == _type, ""); } // Uplift to interface
+    else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() )
+      { assert(ft == _type, ""); } // Uplift to interface
     // Otherwise it's something stupid like non-overlapping int ranges
     // found on dying counted loops.
     else
@@ -936,6 +944,7 @@
     // because the type system doesn't interact well with interfaces.
     const TypePtr *jtp = jt->make_ptr();
     const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
+    const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL;
     if( jtip && ttip ) {
       if( jtip->is_loaded() &&  jtip->klass()->is_interface() &&
           ttip->is_loaded() && !ttip->klass()->is_interface() ) {
@@ -945,6 +954,14 @@
         jt = ft;
       }
     }
+    if( jtkp && ttkp ) {
+      if( jtkp->is_loaded() &&  jtkp->klass()->is_interface() &&
+          ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
+        assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
+               ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
+        jt = ft;
+      }
+    }
     if (jt != ft && jt->base() == ft->base()) {
       if (jt->isa_int() &&
           jt->is_int()->_lo == ft->is_int()->_lo &&
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -228,6 +228,11 @@
   // them for real.
   de_ssa();
 
+#ifdef ASSERT
+  // Veify the graph before RA.
+  verify(&live_arena);
+#endif
+
   {
     NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
     _live = NULL;                 // Mark live as being not available
@@ -306,12 +311,6 @@
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
     if (C->failing())  return;
 
-#ifdef ASSERT
-    if( VerifyOpto ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
     NOT_PRODUCT( C->verify_graph_edges(); )
 
     compact();                  // Compact LRGs; return new lower max lrg
@@ -340,7 +339,7 @@
     compress_uf_map_for_nodes();
 
 #ifdef ASSERT
-    if( VerifyOpto ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
   } else {
     ifg.SquareUp();
@@ -376,12 +375,6 @@
     // 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;
-#ifdef ASSERT
-    if( VerifyOpto ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
 
     compact();                  // Compact LRGs; return new lower max lrg
 
@@ -412,7 +405,7 @@
     }
     compress_uf_map_for_nodes();
 #ifdef ASSERT
-    if( VerifyOpto ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
     cache_lrg_info();           // Count degree of LRGs
 
@@ -432,6 +425,11 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+#ifdef ASSERT
+  // Veify the graph after RA.
+  verify(&live_arena);
+#endif
+
   // max_reg is past the largest *register* used.
   // Convert that to a frame_slot number.
   if( _max_reg <= _matcher._new_SP )
@@ -956,7 +954,7 @@
       while ((neighbor = elements.next()) != 0) {
         LRG *n = &lrgs(neighbor);
 #ifdef ASSERT
-        if( VerifyOpto ) {
+        if( VerifyOpto || VerifyRegisterAllocator ) {
           assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
         }
 #endif
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -491,6 +491,8 @@
   // Verify that base pointers and derived pointers are still sane
   void verify_base_ptrs( ResourceArea *a ) const;
 
+  void verify( ResourceArea *a, bool verify_ifg = false ) const;
+
   void dump_for_spill_split_recycle() const;
 
 public:
--- a/hotspot/src/share/vm/opto/classes.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/classes.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -129,7 +129,7 @@
 macro(LShiftI)
 macro(LShiftL)
 macro(LoadB)
-macro(LoadC)
+macro(LoadUS)
 macro(LoadD)
 macro(LoadD_unaligned)
 macro(LoadF)
--- a/hotspot/src/share/vm/opto/compile.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -2005,7 +2005,7 @@
   case Op_StoreP:
   case Op_StoreN:
   case Op_LoadB:
-  case Op_LoadC:
+  case Op_LoadUS:
   case Op_LoadI:
   case Op_LoadKlass:
   case Op_LoadNKlass:
--- a/hotspot/src/share/vm/opto/divnode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/divnode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -244,42 +244,73 @@
 
 //---------------------long_by_long_mulhi--------------------------------------
 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication
-static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_const) {
+static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) {
   // If the architecture supports a 64x64 mulhi, there is
   // no need to synthesize it in ideal nodes.
   if (Matcher::has_match_rule(Op_MulHiL)) {
-    Node *v = phase->longcon(magic_const);
+    Node* v = phase->longcon(magic_const);
     return new (phase->C, 3) MulHiLNode(dividend, v);
   }
 
+  // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
+  // (http://www.hackersdelight.org/HDcode/mulhs.c)
+  //
+  // int mulhs(int u, int v) {
+  //    unsigned u0, v0, w0;
+  //    int u1, v1, w1, w2, t;
+  //
+  //    u0 = u & 0xFFFF;  u1 = u >> 16;
+  //    v0 = v & 0xFFFF;  v1 = v >> 16;
+  //    w0 = u0*v0;
+  //    t  = u1*v0 + (w0 >> 16);
+  //    w1 = t & 0xFFFF;
+  //    w2 = t >> 16;
+  //    w1 = u0*v1 + w1;
+  //    return u1*v1 + w2 + (w1 >> 16);
+  // }
+  //
+  // Note: The version above is for 32x32 multiplications, while the
+  // following inline comments are adapted to 64x64.
+
   const int N = 64;
 
-  Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
-  Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
+  // u0 = u & 0xFFFFFFFF;  u1 = u >> 32;
+  Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
+  Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
+
+  // v0 = v & 0xFFFFFFFF;  v1 = v >> 32;
+  Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF);
+  Node* v1 = phase->longcon(magic_const >> (N / 2));
 
-  Node *v_hi = phase->longcon(magic_const >> N/2);
-  Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF);
+  // w0 = u0*v0;
+  Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0));
 
-  Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi));
-  Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo));
-  Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi));
-  Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo));
+  // t = u1*v0 + (w0 >> 32);
+  Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0));
+  Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2)));
+  Node* t    = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp));
+
+  // w1 = t & 0xFFFFFFFF;
+  Node* w1 = new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF));
 
-  Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2)));
-  Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1));
+  // w2 = t >> 32;
+  Node* w2 = new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2));
+
+  // 6732154: Construct both w1 and w2 before transforming, so t
+  // doesn't go dead prematurely.
+  w1 = phase->transform(w1);
+  w2 = phase->transform(w2);
 
-  // Construct both t3 and t4 before transforming so t2 doesn't go dead
-  // prematurely.
-  Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2));
-  Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF));
-  t3 = phase->transform(t3);
-  t4 = phase->transform(t4);
+  // w1 = u0*v1 + w1;
+  Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1));
+  w1         = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1));
 
-  Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product));
-  Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2)));
-  Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product));
+  // return u1*v1 + w2 + (w1 >> 32);
+  Node* u1v1  = phase->transform(new (phase->C, 3) MulLNode(u1, v1));
+  Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2));
+  Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2)));
 
-  return new (phase->C, 3) AddLNode(t7, t6);
+  return new (phase->C, 3) AddLNode(temp1, temp2);
 }
 
 
@@ -976,7 +1007,7 @@
 
   // Expand mod
   if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) {
-    uint k = log2_long(con);       // Extract k
+    uint k = exact_log2_long(con+1);  // Extract k
 
     // Basic algorithm by David Detlefs.  See fastmod_long.java for gory details.
     // Used to help a popular random number generator which does a long-mod
--- a/hotspot/src/share/vm/opto/gcm.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -29,6 +29,9 @@
 #include "incls/_precompiled.incl"
 #include "incls/_gcm.cpp.incl"
 
+// To avoid float value underflow
+#define MIN_BLOCK_FREQUENCY 1.e-35f
+
 //----------------------------schedule_node_into_block-------------------------
 // Insert node n into block b. Look for projections of n and make sure they
 // are in b also.
@@ -1380,6 +1383,13 @@
     }
   }
 
+#ifdef ASSERT
+  for (uint i = 0; i < _num_blocks; i++ ) {
+    Block *b = _blocks[i];
+    assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency");
+  }
+#endif
+
 #ifndef PRODUCT
   if (PrintCFGBlockFreq) {
     tty->print_cr("CFG Block Frequencies");
@@ -1877,7 +1887,9 @@
   float loop_freq = _freq * trip_count();
   for (int i = 0; i < _members.length(); i++) {
     CFGElement* s = _members.at(i);
-    s->_freq *= loop_freq;
+    float block_freq = s->_freq * loop_freq;
+    if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY;
+    s->_freq = block_freq;
   }
   CFGLoop* ch = _child;
   while (ch != NULL) {
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1836,10 +1836,7 @@
     (CardTableModRefBS*)(Universe::heap()->barrier_set());
   Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
   // We store into a byte array, so do not bother to left-shift by zero
-  // Get base of card map
-  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte),
-         "adjust this code");
-  Node *c = makecon(TypeRawPtr::make((address)ct->byte_map_base));
+  Node *c = byte_map_base_node();
   // Combine
   Node *sb_ctl = control();
   Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b ));
@@ -2945,16 +2942,10 @@
 
   // Now generate allocation code
 
-  // With escape analysis, the entire memory state is needed to be able to
-  // eliminate the allocation.  If the allocations cannot be eliminated, this
-  // will be optimized to the raw slice when the allocation is expanded.
-  Node *mem;
-  if (C->do_escape_analysis()) {
-    mem = reset_memory();
-    set_all_memory(mem);
-  } else {
-    mem = memory(Compile::AliasIdxRaw);
-  }
+  // The entire memory state is needed for slow path of the allocation
+  // since GC and deoptimization can happened.
+  Node *mem = reset_memory();
+  set_all_memory(mem); // Create new memory state
 
   AllocateNode* alloc
     = new (C, AllocateNode::ParmLimit)
@@ -3091,16 +3082,10 @@
 
   // Now generate allocation code
 
-  // With escape analysis, the entire memory state is needed to be able to
-  // eliminate the allocation.  If the allocations cannot be eliminated, this
-  // will be optimized to the raw slice when the allocation is expanded.
-  Node *mem;
-  if (C->do_escape_analysis()) {
-    mem = reset_memory();
-    set_all_memory(mem);
-  } else {
-    mem = memory(Compile::AliasIdxRaw);
-  }
+  // The entire memory state is needed for slow path of the allocation
+  // since GC and deoptimization can happened.
+  Node *mem = reset_memory();
+  set_all_memory(mem); // Create new memory state
 
   // Create the AllocateArrayNode and its result projections
   AllocateArrayNode* alloc
@@ -3365,14 +3350,6 @@
 
   const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
 
-  // Get the address of the card table
-  CardTableModRefBS* ct =
-    (CardTableModRefBS*)(Universe::heap()->barrier_set());
-  Node *card_table = __ makecon(TypeRawPtr::make((address)ct->byte_map_base));
-  // Get base of card map
-  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
-
   // Offsets into the thread
   const int index_offset  = in_bytes(JavaThread::dirty_card_queue_offset() +
                                      PtrQueue::byte_offset_of_index());
@@ -3402,7 +3379,7 @@
   Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
 
   // Combine card table base and card offset
-  Node *card_adr = __ AddP(no_base, card_table, card_offset );
+  Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
 
   // If we know the value being stored does it cross regions?
 
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -83,6 +83,18 @@
   Node* zerocon(BasicType bt)   const { return _gvn.zerocon(bt); }
   // (See also macro MakeConX in type.hpp, which uses intcon or longcon.)
 
+  // Helper for byte_map_base
+  Node* byte_map_base_node() {
+    // Get base of card map
+    CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set());
+    assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code");
+    if (ct->byte_map_base != NULL) {
+      return makecon(TypeRawPtr::make((address)ct->byte_map_base));
+    } else {
+      return null();
+    }
+  }
+
   jint  find_int_con(Node* n, jint value_if_unknown) {
     return _gvn.find_int_con(n, value_if_unknown);
   }
--- a/hotspot/src/share/vm/opto/ifg.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/ifg.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -471,12 +471,28 @@
     // for the "collect_gc_info" phase later.
     IndexSet liveout(_live->live(b));
     uint last_inst = b->end_idx();
-    // Compute last phi index
-    uint last_phi;
-    for( last_phi = 1; last_phi < last_inst; last_phi++ )
-      if( !b->_nodes[last_phi]->is_Phi() )
+    // Compute first nonphi node index
+    uint first_inst;
+    for( first_inst = 1; first_inst < last_inst; first_inst++ )
+      if( !b->_nodes[first_inst]->is_Phi() )
         break;
 
+    // Spills could be inserted before CreateEx node which should be
+    // first instruction in block after Phis. Move CreateEx up.
+    for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
+      Node *ex = b->_nodes[insidx];
+      if( ex->is_SpillCopy() ) continue;
+      if( insidx > first_inst && ex->is_Mach() &&
+          ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+        // If the CreateEx isn't above all the MachSpillCopies
+        // then move it to the top.
+        b->_nodes.remove(insidx);
+        b->_nodes.insert(first_inst, ex);
+      }
+      // Stop once a CreateEx or any other node is found
+      break;
+    }
+
     // Reset block's register pressure values for each ifg construction
     uint pressure[2], hrp_index[2];
     pressure[0] = pressure[1] = 0;
@@ -485,7 +501,7 @@
     // Liveout things are presumed live for the whole block.  We accumulate
     // 'area' accordingly.  If they get killed in the block, we'll subtract
     // the unused part of the block from the area.
-    int inst_count = last_inst - last_phi;
+    int inst_count = last_inst - first_inst;
     double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
     assert(!(cost < 0.0), "negative spill cost" );
     IndexSetIterator elements(&liveout);
--- a/hotspot/src/share/vm/opto/lcm.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -107,7 +107,7 @@
     was_store = false;
     switch( mach->ideal_Opcode() ) {
     case Op_LoadB:
-    case Op_LoadC:
+    case Op_LoadUS:
     case Op_LoadD:
     case Op_LoadF:
     case Op_LoadI:
--- a/hotspot/src/share/vm/opto/live.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/live.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -271,9 +271,9 @@
 
 //------------------------------verify_base_ptrs-------------------------------
 // Verify that base pointers and derived pointers are still sane.
-// Basically, if a derived pointer is live at a safepoint, then its
-// base pointer must be live also.
 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
+#ifdef ASSERT
+  Unique_Node_List worklist(a);
   for( uint i = 0; i < _cfg._num_blocks; i++ ) {
     Block *b = _cfg._blocks[i];
     for( uint j = b->end_idx() + 1; j > 1; j-- ) {
@@ -287,28 +287,81 @@
           // Now scan for a live derived pointer
           if (jvms->oopoff() < sfpt->req()) {
             // Check each derived/base pair
-            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx += 2) {
+            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
               Node *check = sfpt->in(idx);
-              uint j = 0;
+              bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
               // search upwards through spills and spill phis for AddP
-              while(true) {
-                if( !check ) break;
-                int idx = check->is_Copy();
-                if( idx ) {
-                  check = check->in(idx);
-                } else if( check->is_Phi() && check->_idx >= _oldphi ) {
-                  check = check->in(1);
-                } else
-                  break;
-                j++;
-                assert(j < 100000,"Derived pointer checking in infinite loop");
+              worklist.clear();
+              worklist.push(check);
+              uint k = 0;
+              while( k < worklist.size() ) {
+                check = worklist.at(k);
+                assert(check,"Bad base or derived pointer");
+                // See PhaseChaitin::find_base_for_derived() for all cases.
+                int isc = check->is_Copy();
+                if( isc ) {
+                  worklist.push(check->in(isc));
+                } else if( check->is_Phi() ) {
+                  for (uint m = 1; m < check->req(); m++)
+                    worklist.push(check->in(m));
+                } else if( check->is_Con() ) {
+                  if (is_derived) {
+                    // Derived is NULL+offset
+                    assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
+                  } else {
+                    assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer");
+                    // Base either ConP(NULL) or loadConP
+                    if (check->is_Mach()) {
+                      assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer");
+                    } else {
+                      assert(check->Opcode() == Op_ConP &&
+                             check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
+                    }
+                  }
+                } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
+                  if(check->is_Proj() || check->is_Mach() &&
+                     (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
+                      check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
+                      check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
+                      check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
+#ifdef _LP64
+                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
+                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
+#endif
+                      check->as_Mach()->ideal_Opcode() == Op_LoadP ||
+                      check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
+                    // Valid nodes
+                  } else {
+                    check->dump();
+                    assert(false,"Bad base or derived pointer");
+                  }
+                } else {
+                  assert(is_derived,"Bad base pointer");
+                  assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
+                }
+                k++;
+                assert(k < 100000,"Derived pointer checking in infinite loop");
               } // End while
-              assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer")
             }
           } // End of check for derived pointers
         } // End of Kcheck for debug info
       } // End of if found a safepoint
     } // End of forall instructions in block
   } // End of forall blocks
+#endif
 }
+
+//------------------------------verify-------------------------------------
+// Verify that graphs and base pointers are still sane.
+void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
+#ifdef ASSERT
+  if( VerifyOpto || VerifyRegisterAllocator ) {
+    _cfg.verify();
+    verify_base_ptrs(a);
+    if(verify_ifg)
+      _ifg->verify(this);
+  }
 #endif
+}
+
+#endif
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -2654,7 +2654,7 @@
     case Op_ModF:
     case Op_ModD:
     case Op_LoadB:              // Same with Loads; they can sink
-    case Op_LoadC:              // during loop optimizations.
+    case Op_LoadUS:             // during loop optimizations.
     case Op_LoadD:
     case Op_LoadF:
     case Op_LoadI:
--- a/hotspot/src/share/vm/opto/macro.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -952,13 +952,6 @@
   Node* klass_node        = alloc->in(AllocateNode::KlassNode);
   Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
 
-  // With escape analysis, the entire memory state was needed to be able to
-  // eliminate the allocation.  Since the allocations cannot be eliminated,
-  // optimize it to the raw slice.
-  if (mem->is_MergeMem()) {
-    mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
-  }
-
   assert(ctrl != NULL, "must have control");
   // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
   // they will not be used if "always_slow" is set
@@ -1016,6 +1009,11 @@
   Node *slow_mem = mem;  // save the current memory state for slow path
   // generate the fast allocation code unless we know that the initial test will always go slow
   if (!always_slow) {
+    // Fast path modifies only raw memory.
+    if (mem->is_MergeMem()) {
+      mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
+    }
+
     Node* eden_top_adr;
     Node* eden_end_adr;
 
@@ -1239,8 +1237,6 @@
     }
   }
 
-  mem = result_phi_rawmem;
-
   // An allocate node has separate i_o projections for the uses on the control and i_o paths
   // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
   if (_ioproj_fallthrough == NULL) {
--- a/hotspot/src/share/vm/opto/matcher.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1824,7 +1824,7 @@
         mem_op = true;
         break;
       case Op_LoadB:
-      case Op_LoadC:
+      case Op_LoadUS:
       case Op_LoadD:
       case Op_LoadF:
       case Op_LoadI:
--- a/hotspot/src/share/vm/opto/memnode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -779,14 +779,14 @@
          "use LoadRangeNode instead");
   switch (bt) {
   case T_BOOLEAN:
-  case T_BYTE:    return new (C, 3) LoadBNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_INT:     return new (C, 3) LoadINode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_CHAR:    return new (C, 3) LoadCNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_SHORT:   return new (C, 3) LoadSNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_LONG:    return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long()   );
-  case T_FLOAT:   return new (C, 3) LoadFNode(ctl, mem, adr, adr_type, rt              );
-  case T_DOUBLE:  return new (C, 3) LoadDNode(ctl, mem, adr, adr_type, rt              );
-  case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr()    );
+  case T_BYTE:    return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_INT:     return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_CHAR:    return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_SHORT:   return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_LONG:    return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
+  case T_FLOAT:   return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt              );
+  case T_DOUBLE:  return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt              );
+  case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
   case T_OBJECT:
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
@@ -1076,13 +1076,14 @@
       // of the original value.
       Node* mem_phi = in(Memory);
       Node* offset = in(Address)->in(AddPNode::Offset);
+      Node* region = base->in(0);
 
       Node* in1 = clone();
       Node* in1_addr = in1->in(Address)->clone();
       in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
       in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
       in1_addr->set_req(AddPNode::Offset, offset);
-      in1->set_req(0, base->in(allocation_index));
+      in1->set_req(0, region->in(allocation_index));
       in1->set_req(Address, in1_addr);
       in1->set_req(Memory, mem_phi->in(allocation_index));
 
@@ -1091,7 +1092,7 @@
       in2_addr->set_req(AddPNode::Base, base->in(load_index));
       in2_addr->set_req(AddPNode::Address, base->in(load_index));
       in2_addr->set_req(AddPNode::Offset, offset);
-      in2->set_req(0, base->in(load_index));
+      in2->set_req(0, region->in(load_index));
       in2->set_req(Address, in2_addr);
       in2->set_req(Memory, mem_phi->in(load_index));
 
@@ -1100,7 +1101,7 @@
       in2_addr = phase->transform(in2_addr);
       in2 =      phase->transform(in2);
 
-      PhiNode* result = PhiNode::make_blank(base->in(0), this);
+      PhiNode* result = PhiNode::make_blank(region, this);
       result->set_req(allocation_index, in1);
       result->set_req(load_index, in2);
       return result;
@@ -1357,7 +1358,7 @@
   // Steps (a), (b):  Walk past independent stores to find an exact match.
   if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
     // (c) See if we can fold up on the spot, but don't fold up here.
-    // Fold-up might require truncation (for LoadB/LoadS/LoadC) or
+    // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or
     // just return a prior value, which is done by Identity calls.
     if (can_see_stored_value(prev_mem, phase)) {
       // Make ready for step (d):
@@ -1606,14 +1607,14 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
-//--------------------------LoadCNode::Ideal--------------------------------------
+//--------------------------LoadUSNode::Ideal-------------------------------------
 //
 //  If the previous store is to the same address as this load,
 //  and the value stored was larger than a char, replace this load
 //  with the value stored truncated to a char.  If no truncation is
 //  needed, the replacement is done in LoadNode::Identity().
 //
-Node *LoadCNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem,phase);
   if( value && !phase->type(value)->higher_equal( _type ) )
--- a/hotspot/src/share/vm/opto/memnode.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -207,11 +207,11 @@
   virtual BasicType memory_type() const { return T_BYTE; }
 };
 
-//------------------------------LoadCNode--------------------------------------
-// Load a char (16bits unsigned) from memory
-class LoadCNode : public LoadNode {
+//------------------------------LoadUSNode-------------------------------------
+// Load an unsigned short/char (16bits unsigned) from memory
+class LoadUSNode : public LoadNode {
 public:
-  LoadCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
+  LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
     : LoadNode(c,mem,adr,at,ti) {}
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
--- a/hotspot/src/share/vm/opto/mulnode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/mulnode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -442,16 +442,17 @@
         return load;
     }
     uint lop = load->Opcode();
-    if( lop == Op_LoadC &&
+    if( lop == Op_LoadUS &&
         con == 0x0000FFFF )     // Already zero-extended
       return load;
     // Masking off the high bits of a unsigned-shift-right is not
     // needed either.
     if( lop == Op_URShiftI ) {
       const TypeInt *t12 = phase->type( load->in(2) )->isa_int();
-      if( t12 && t12->is_con() ) {
-        int shift_con = t12->get_con();
-        int mask = max_juint >> shift_con;
+      if( t12 && t12->is_con() ) {  // Shift is by a constant
+        int shift = t12->get_con();
+        shift &= BitsPerJavaInteger - 1;  // semantics of Java shifts
+        int mask = max_juint >> shift;
         if( (mask&con) == mask )  // If AND is useless, skip it
           return load;
       }
@@ -470,19 +471,19 @@
   uint lop = load->Opcode();
 
   // Masking bits off of a Character?  Hi bits are already zero.
-  if( lop == Op_LoadC &&
+  if( lop == Op_LoadUS &&
       (mask & 0xFFFF0000) )     // Can we make a smaller mask?
     return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
 
   // Masking bits off of a Short?  Loading a Character does some masking
   if( lop == Op_LoadS &&
       (mask & 0xFFFF0000) == 0 ) {
-    Node *ldc = new (phase->C, 3) LoadCNode(load->in(MemNode::Control),
+    Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
                                   load->in(MemNode::Memory),
                                   load->in(MemNode::Address),
                                   load->adr_type());
-    ldc = phase->transform(ldc);
-    return new (phase->C, 3) AndINode(ldc,phase->intcon(mask&0xFFFF));
+    ldus = phase->transform(ldus);
+    return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
   }
 
   // Masking sign bits off of a Byte?  Let the matcher use an unsigned load
@@ -579,9 +580,10 @@
     // needed either.
     if( lop == Op_URShiftL ) {
       const TypeInt *t12 = phase->type( usr->in(2) )->isa_int();
-      if( t12 && t12->is_con() ) {
-        int shift_con = t12->get_con();
-        jlong mask = max_julong >> shift_con;
+      if( t12 && t12->is_con() ) {  // Shift is by a constant
+        int shift = t12->get_con();
+        shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
+        jlong mask = max_julong >> shift;
         if( (mask&con) == mask )  // If AND is useless, skip it
           return usr;
       }
@@ -605,8 +607,8 @@
     const TypeInt *t12 = phase->type(rsh->in(2))->isa_int();
     if( t12 && t12->is_con() ) { // Shift is by a constant
       int shift = t12->get_con();
-      shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
-      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - shift)) -1);
+      shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
+      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
       // If the AND'ing of the 2 masks has no bits, then only original shifted
       // bits survive.  NO sign-extension bits survive the maskings.
       if( (sign_bits_mask & mask) == 0 ) {
@@ -786,7 +788,7 @@
 
   // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
   // before shifting them away.
-  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) - CONST64(1);
+  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
   if( add1_op == Op_AndL &&
       phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
     return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) );
@@ -820,7 +822,7 @@
     return TypeLong::LONG;
 
   uint shift = r2->get_con();
-  shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
+  shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
   // Shift by a multiple of 64 does nothing:
   if (shift == 0)  return t1;
 
@@ -913,7 +915,7 @@
       set_req(2, phase->intcon(0));
       return this;
     }
-    else if( ld->Opcode() == Op_LoadC )
+    else if( ld->Opcode() == Op_LoadUS )
       // Replace zero-extension-load with sign-extension-load
       return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control),
                                 ld->in(MemNode::Memory),
@@ -1235,7 +1237,7 @@
   if ( con == 0 ) return NULL;  // let Identity() handle a 0 shift count
                               // note: mask computation below does not work for 0 shift count
   // We'll be wanting the right-shift amount as a mask of that many bits
-  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) -1);
+  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1);
 
   // Check for ((x << z) + Y) >>> z.  Replace with x + con>>>z
   // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
@@ -1302,7 +1304,7 @@
 
   if (r2->is_con()) {
     uint shift = r2->get_con();
-    shift &= (2*BitsPerJavaInteger)-1;  // semantics of Java shifts
+    shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
     // Shift by a multiple of 64 does nothing:
     if (shift == 0)  return t1;
     // Calculate reasonably aggressive bounds for the result.
@@ -1325,7 +1327,7 @@
     const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen));
     #ifdef ASSERT
     // Make sure we get the sign-capture idiom correct.
-    if (shift == (2*BitsPerJavaInteger)-1) {
+    if (shift == BitsPerJavaLong - 1) {
       if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>>63 of + is 0");
       if (r1->_hi < 0)  assert(tl == TypeLong::ONE,  ">>>63 of - is +1");
     }
--- a/hotspot/src/share/vm/opto/superword.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/superword.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1444,7 +1444,7 @@
 // (Start, end] half-open range defining which operands are vector
 void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
   switch (n->Opcode()) {
-  case Op_LoadB:   case Op_LoadC:
+  case Op_LoadB:   case Op_LoadUS:
   case Op_LoadI:   case Op_LoadL:
   case Op_LoadF:   case Op_LoadD:
   case Op_LoadP:
--- a/hotspot/src/share/vm/opto/type.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/type.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -2471,6 +2471,8 @@
   const Type* ft = join(kills);
   const TypeInstPtr* ftip = ft->isa_instptr();
   const TypeInstPtr* ktip = kills->isa_instptr();
+  const TypeKlassPtr* ftkp = ft->isa_klassptr();
+  const TypeKlassPtr* ktkp = kills->isa_klassptr();
 
   if (ft->empty()) {
     // Check for evil case of 'this' being a class and 'kills' expecting an
@@ -2484,6 +2486,8 @@
     // uplift the type.
     if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface())
       return kills;             // Uplift to interface
+    if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface())
+      return kills;             // Uplift to interface
 
     return Type::TOP;           // Canonical empty value
   }
@@ -2499,6 +2503,12 @@
     // Happens in a CTW of rt.jar, 320-341, no extra flags
     return ktip->cast_to_ptr_type(ftip->ptr());
   }
+  if (ftkp != NULL && ktkp != NULL &&
+      ftkp->is_loaded() &&  ftkp->klass()->is_interface() &&
+      ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
+    // Happens in a CTW of rt.jar, 320-341, no extra flags
+    return ktkp->cast_to_ptr_type(ftkp->ptr());
+  }
 
   return ft;
 }
@@ -3657,7 +3667,7 @@
 
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const {
-  assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
+  assert(_base == KlassPtr, "subclass must override cast_to_ptr_type");
   if( ptr == _ptr ) return this;
   return make(ptr, _klass, _offset);
 }
--- a/hotspot/src/share/vm/opto/type.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/type.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -882,6 +882,8 @@
 public:
   ciSymbol* name()  const { return _klass->name(); }
 
+  bool  is_loaded() const { return _klass->is_loaded(); }
+
   // ptr to klass 'k'
   static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); }
   // ptr to klass 'k' with offset
--- a/hotspot/src/share/vm/opto/vectornode.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/opto/vectornode.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -239,7 +239,7 @@
     return Op_XorV;
 
   case Op_LoadB:
-  case Op_LoadC:
+  case Op_LoadUS:
   case Op_LoadS:
   case Op_LoadI:
   case Op_LoadL:
@@ -269,7 +269,7 @@
     case 16:       return Op_Load16B;
     }
     break;
-  case Op_LoadC:
+  case Op_LoadUS:
     switch (vlen) {
     case  2:       return Op_Load2C;
     case  4:       return Op_Load4C;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Sun Feb 22 17:11:56 2009 -0800
@@ -2489,7 +2489,7 @@
     vm_args.version = JNI_VERSION_1_2;
     vm_args.options = options;
     vm_args.nOptions = i;
-    vm_args.ignoreUnrecognized = false;
+    vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
 
     if (PrintVMOptions) {
       const char* tail;
@@ -2536,13 +2536,12 @@
 
   // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
   bool settings_file_specified = false;
+  const char* flags_file;
   int index;
   for (index = 0; index < args->nOptions; index++) {
     const JavaVMOption *option = args->options + index;
     if (match_option(option, "-XX:Flags=", &tail)) {
-      if (!process_settings_file(tail, true, args->ignoreUnrecognized)) {
-        return JNI_EINVAL;
-      }
+      flags_file = tail;
       settings_file_specified = true;
     }
     if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
@@ -2551,6 +2550,24 @@
     if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
       PrintVMOptions = false;
     }
+    if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) {
+      IgnoreUnrecognizedVMOptions = true;
+    }
+    if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) {
+      IgnoreUnrecognizedVMOptions = false;
+    }
+  }
+
+  if (IgnoreUnrecognizedVMOptions) {
+    // uncast const to modify the flag args->ignoreUnrecognized
+    *(jboolean*)(&args->ignoreUnrecognized) = true;
+  }
+
+  // Parse specified settings file
+  if (settings_file_specified) {
+    if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
+      return JNI_EINVAL;
+    }
   }
 
   // Parse default .hotspotrc settings file
--- a/hotspot/src/share/vm/runtime/globals.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -2194,6 +2194,9 @@
   product(bool, PrintVMOptions, trueInDebug,                                \
          "print VM flag settings")                                          \
                                                                             \
+  product(bool, IgnoreUnrecognizedVMOptions, false,                         \
+         "Ignore unrecognized VM options")                                  \
+                                                                            \
   diagnostic(bool, SerializeVMOutput, true,                                 \
          "Use a mutex to serialize output to tty and hotspot.log")          \
                                                                             \
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Sun Feb 22 17:11:56 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  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
@@ -74,6 +74,7 @@
 extern int BitsPerHeapOop;
 
 const int BitsPerJavaInteger = 32;
+const int BitsPerJavaLong    = 64;
 const int BitsPerSize_t      = size_tSize * BitsPerByte;
 
 // Size of a char[] needed to represent a jint as a string in decimal.
@@ -906,6 +907,14 @@
   return log2_intptr(x);
 }
 
+//* the argument must be exactly a power of 2
+inline int exact_log2_long(jlong x) {
+  #ifdef ASSERT
+    if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2");
+  #endif
+  return log2_long(x);
+}
+
 
 // returns integer round-up to the nearest multiple of s (s must be a power of two)
 inline intptr_t round_to(intptr_t x, uintx s) {
--- a/hotspot/test/Makefile	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/test/Makefile	Sun Feb 22 17:11:56 2009 -0800
@@ -28,9 +28,9 @@
 
 # Get OS/ARCH specifics
 OSNAME = $(shell uname -s)
-SLASH_JAVA = /java
 ifeq ($(OSNAME), SunOS)
   PLATFORM = solaris
+  SLASH_JAVA = /java
   ARCH = $(shell uname -p)
   ifeq ($(ARCH), i386)
     ARCH=i586
@@ -38,6 +38,7 @@
 endif
 ifeq ($(OSNAME), Linux)
   PLATFORM = linux
+  SLASH_JAVA = /java
   ARCH = $(shell uname -m)
   ifeq ($(ARCH), i386)
     ARCH = i586
@@ -62,6 +63,10 @@
   EXESUFFIX = .exe
 endif
 
+ifdef ALT_SLASH_JAVA
+  SLASH_JAVA = $(ALT_SLASH_JAVA)
+endif
+
 # Utilities used
 CD    = cd
 CP    = cp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6603011/Test.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6603011
+ * @summary long/int division by constant
+ *
+ * @run main/othervm -Xcomp -Xbatch -XX:-Inline Test
+ */
+
+//
+// -XX:-Inline is essential to this test so that verification functions
+//   divi, modi, divl and modl generate "plain" divides.
+// -Xcomp -Xbatch are also useful to ensure the full range of
+//   dividend and divisor combinations are tested
+//
+
+import java.net.*;
+
+class s {
+  static int  divi(int  dividend, int  divisor) { return dividend / divisor; }
+  static int  modi(int  dividend, int  divisor) { return dividend % divisor; }
+  static long divl(long dividend, long divisor) { return dividend / divisor; }
+  static long modl(long dividend, long divisor) { return dividend % divisor; }
+}
+
+public class Test implements Runnable {
+  // Report verbose messages on failure; turn off to suppress
+  // too much output with gross numbers of failures.
+  static final boolean VERBOSE = true;
+
+  // Initailize DIVISOR so that it is final in this class.
+  static final int DIVISOR;
+  static {
+    int value = 0;
+    try {
+      value = Integer.decode(System.getProperty("divisor"));
+    } catch (Throwable e) {
+    }
+    DIVISOR = value;
+  }
+
+  // The methods of interest. We want the JIT to compile these
+  // and convert the divide into a multiply.
+  public int divbyI (int dividend)   { return dividend / DIVISOR; }
+  public int modbyI (int dividend)   { return dividend % DIVISOR; }
+  public long divbyL (long dividend) { return dividend / DIVISOR; }
+  public long modbyL (long dividend) { return dividend % DIVISOR; }
+
+  public int divisor() { return DIVISOR; }
+
+  public boolean checkI (int dividend) {
+    int quo = divbyI(dividend);
+    int rem = modbyI(dividend);
+    int quo0 = s.divi(dividend, divisor());
+    int rem0 = s.modi(dividend, divisor());
+
+    if (quo != quo0 || rem != rem0) {
+      if (VERBOSE) {
+        System.out.println("Computed: " + dividend + " / " + divisor() + " = " +
+                           quo  + ", " + dividend + " % " + divisor() + " = " + rem );
+        System.out.println("expected: " + dividend + " / " + divisor() + " = " +
+                           quo0 + ", " + dividend + " % " + divisor() + " = " + rem0);
+        // Report sign of rem failure
+        if (rem != 0 && (rem ^ dividend) < 0) {
+          System.out.println("  rem & dividend have different signs");
+        }
+        // Report range of rem failure
+        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
+          System.out.println("  remainder out of range");
+        }
+        // Report quo/rem identity relationship failure
+        if ((quo * divisor()) + rem != dividend) {
+          System.out.println("  quotien/remainder invariant broken");
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+
+  public boolean checkL (long dividend) {
+    long quo = divbyL(dividend);
+    long rem = modbyL(dividend);
+    long quo0 = s.divl(dividend, divisor());
+    long rem0 = s.modl(dividend, divisor());
+
+    if (quo != quo0 || rem != rem0) {
+      if (VERBOSE) {
+        System.out.println("  " + dividend + " / " + divisor() + " = " +
+                           quo + ", " + dividend + " % " + divisor() + " = " + rem);
+        // Report sign of rem failure
+        if (rem != 0 && (rem ^ dividend) < 0) {
+          System.out.println("  rem & dividend have different signs");
+        }
+        // Report range of rem failure
+        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
+          System.out.println("  remainder out of range");
+        }
+        // Report quo/rem identity relationship failure
+        if ((quo * divisor()) + rem != dividend) {
+          System.out.println(" (" + quo + " * " + divisor() + ") + " + rem + " != "
+                             + dividend);
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+
+  public void run() {
+    // Don't try to divide by zero
+    if (divisor() == 0) return;
+
+    // Range of dividends to check. Try dividends from start to end
+    // inclusive, as well as variations on those values as shifted
+    // left.
+    int start = -1024;
+    int end = 1024;
+
+    // Test int division using a variety of dividends.
+    int wrong = 0;
+    int total = 0;
+
+    outerloop:
+    for (int i = start; i <= end; i++) {
+      for (int s = 0; s < 32; s += 4) {
+        total++;
+        int dividend = i << s;
+        if (!checkI(dividend)) {
+          wrong++;
+          // Stop on the first failure
+          // break outerloop;
+        }
+      }
+    }
+    if (wrong > 0) {
+      System.out.println("divisor " + divisor() + ": " +
+                         wrong + "/" + total + " wrong int divisions");
+    }
+
+    // Test long division using a variety of dividends.
+    wrong = 0;
+    total = 0;
+
+    outerloop:
+    for (int i = start; i <= end; i++) {
+      for (int s = 0; s < 64; s += 4) {
+        total++;
+        long dividend = i << s;
+        if (!checkL(dividend)) {
+          wrong++;
+          // Stop on the first failure
+          // break outerloop;
+        }
+      }
+    }
+    if (wrong > 0) {
+      System.out.println("divisor " + divisor() + ": " +
+                         wrong + "/" + total + " wrong long divisions");
+    }
+
+  }
+
+  // Reload this class with the "divisor" property set to the input parameter.
+  // This allows the JIT to see q.DIVISOR as a final constant, and change
+  // any divisions or mod operations into multiplies.
+  public static void test_divisor(int divisor,
+                                  URLClassLoader apploader) throws Exception {
+    System.setProperty("divisor", "" + divisor);
+    ClassLoader loader = new URLClassLoader(apploader.getURLs(),
+                                            apploader.getParent());
+    Class c = loader.loadClass("Test");
+    Runnable r = (Runnable)c.newInstance();
+    r.run();
+  }
+
+  public static void main(String[] args) throws Exception {
+    Class cl = Class.forName("Test");
+    URLClassLoader apploader = (URLClassLoader)cl.getClassLoader();
+
+
+    // Test every divisor between -100 and 100.
+    for (int i = -100; i <= 100; i++) {
+      test_divisor(i, apploader);
+    }
+
+    // Try a few divisors outside the typical range.
+    // The values below have been observed in rt.jar.
+    test_divisor(101, apploader);
+    test_divisor(400, apploader);
+    test_divisor(1000, apploader);
+    test_divisor(3600, apploader);
+    test_divisor(9973, apploader);
+    test_divisor(86400, apploader);
+    test_divisor(1000000, apploader);
+  }
+
+}
--- a/hotspot/test/compiler/6775880/Test.java	Sun Feb 15 20:09:02 2009 -0800
+++ b/hotspot/test/compiler/6775880/Test.java	Sun Feb 22 17:11:56 2009 -0800
@@ -27,7 +27,7 @@
  * @bug 6775880
  * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
  * @compile -source 1.4 -target 1.4 Test.java
- * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
  */
 
 public class Test {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6795161/Test.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6795161
+ * @summary Escape analysis leads to data corruption
+ * @run main/othervm -server -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
+ */
+
+class Test_Class_1 {
+    static String var_1;
+
+    static void badFunc(int size)
+    {
+        try {
+          for (int i = 0; i < 1; (new byte[size-i])[0] = 0, i++) {}
+        } catch (Exception e) {
+          // don't comment it out, it will lead to correct results ;)
+          //System.out.println("Got exception: " + e);
+        }
+    }
+}
+
+public class Test {
+    static String var_1_copy = Test_Class_1.var_1;
+
+    static byte var_check;
+
+    public static void main(String[] args)
+    {
+        var_check = 1;
+
+        Test_Class_1.badFunc(-1);
+
+        System.out.println("EATester.var_check = " + Test.var_check + " (expected 1)\n");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6795362/Test6795362.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6795362
+ * @summary 32bit server compiler leads to wrong results on solaris-x86
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6795362.sub Test6795362
+ */
+
+public class Test6795362 {
+    public static void main(String[] args)
+    {
+        sub();
+
+        if (var_bad != 0)
+            throw new InternalError(var_bad + " != 0");
+    }
+
+    static long var_bad = -1L;
+
+    static void sub()
+    {
+        var_bad >>= 65;
+        var_bad /= 65;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6799693/Test.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6799693
+ * @summary Server compiler leads to data corruption when expression throws an Exception
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test Test
+ */
+
+public class Test {
+   static int var_bad = 1;
+
+   public static void main(String[] args)
+   {
+      var_bad++;
+
+      try {
+         for (int i = 0; i < 10; i++) (new byte[((byte)-1 << i)])[0]  = 0;
+      }
+      catch (Exception e) { System.out.println("Got " + e); }
+
+      System.out.println("Test.var_bad = " +  var_bad + " (expected 2)\n");
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6800154/Test6800154.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6800154
+ * @summary Add comments to long_by_long_mulhi() for better understandability
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6800154.divcomp Test6800154
+ */
+
+import java.net.URLClassLoader;
+
+public class Test6800154 implements Runnable {
+    static final long[] DIVIDENDS = {
+        0,
+        1,
+        2,
+        1423487,
+        4444441,
+        4918923241323L,
+        -1,
+        -24351,
+        0x3333,
+        0x0000000080000000L,
+        0x7fffffffffffffffL,
+        0x8000000000000000L
+    };
+
+    static final long[] DIVISORS = {
+        1,
+        2,
+        17,
+        12342,
+        24123,
+        143444,
+        123444442344L,
+        -1,
+        -2,
+        -4423423234231423L,
+        0x0000000080000000L,
+        0x7fffffffffffffffL,
+        0x8000000000000000L
+    };
+
+    // Initialize DIVISOR so that it is final in this class.
+    static final long DIVISOR;
+
+    static {
+        long value = 0;
+        try {
+            value = Long.decode(System.getProperty("divisor"));
+        } catch (Throwable e) {
+        }
+        DIVISOR = value;
+    }
+
+    public static void main(String[] args) throws Exception
+    {
+        Class cl = Class.forName("Test6800154");
+        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+
+        // Iterate over all divisors.
+        for (int i = 0; i < DIVISORS.length; i++) {
+            System.setProperty("divisor", "" + DIVISORS[i]);
+            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            Class c = loader.loadClass("Test6800154");
+            Runnable r = (Runnable) c.newInstance();
+            r.run();
+        }
+    }
+
+    public void run()
+    {
+        // Iterate over all dividends.
+        for (int i = 0; i < DIVIDENDS.length; i++) {
+            long dividend = DIVIDENDS[i];
+
+            long expected = divint(dividend);
+            long result = divcomp(dividend);
+
+            if (result != expected)
+                throw new InternalError(dividend + " / " + DIVISOR + " failed: " + result + " != " + expected);
+        }
+    }
+
+    static long divint(long a)  { return a / DIVISOR; }
+    static long divcomp(long a) { return a / DIVISOR; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6805724/Test6805724.java	Sun Feb 22 17:11:56 2009 -0800
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6805724
+ * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant.
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724
+ */
+
+import java.net.URLClassLoader;
+
+public class Test6805724 implements Runnable {
+    // Initialize DIVISOR so that it is final in this class.
+    static final long DIVISOR;  // 2^k-1 constant
+
+    static {
+        long value = 0;
+        try {
+            value = Long.decode(System.getProperty("divisor"));
+        } catch (Throwable t) {
+            // This one is required for the Class.forName() in main.
+        }
+        DIVISOR = value;
+    }
+
+    static long fint(long x) {
+        return x % DIVISOR;
+    }
+
+    static long fcomp(long x) {
+        return x % DIVISOR;
+    }
+
+    public void run() {
+        long a = 0x617981E1L;
+
+        long expected = fint(a);
+        long result = fcomp(a);
+
+        if (result != expected)
+            throw new InternalError(result + " != " + expected);
+    }
+
+    public static void main(String args[]) throws Exception {
+        Class cl = Class.forName("Test6805724");
+        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+
+        // Iterate over all 2^k-1 divisors.
+        for (int k = 1; k < Long.SIZE; k++) {
+            long divisor = (1L << k) - 1;
+            System.setProperty("divisor", "" + divisor);
+            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            Class c = loader.loadClass("Test6805724");
+            Runnable r = (Runnable) c.newInstance();
+            r.run();
+        }
+    }
+}