Merge

Fri, 27 Feb 2009 15:13:00 -0800

author
xdono
date
Fri, 27 Feb 2009 15:13:00 -0800
changeset 1012
f9d5cfc2afa2
parent 1011
69c752d99841
parent 1009
dae503d9f04c
child 1013
f5eac45b1641
child 1014
0fbdb4381b99

Merge

     1.1 --- a/.hgtags	Sat Jan 31 17:19:42 2009 -0800
     1.2 +++ b/.hgtags	Fri Feb 27 15:13:00 2009 -0800
     1.3 @@ -18,3 +18,9 @@
     1.4  f9d938ede1960d18cb7cf23c645b026519c1a678 jdk7-b41
     1.5  ad8c8ca4ab0f4c86e74c061958f44a8f4a930f2c jdk7-b42
     1.6  fc6a5ae3fef5ebacfa896dbb3ae37715e388e282 jdk7-b43
     1.7 +809e899c638bd9b21836abf9d09ab2a30ff3900b jdk7-b44
     1.8 +945bf754069766e76873c53102fae48abf04cf5b jdk7-b45
     1.9 +16bb38eeda35b46268eefa4c1f829eb086e0ca46 jdk7-b46
    1.10 +fcb923bad68e2b10380a030ea83a723f4dc3d4d6 jdk7-b47
    1.11 +bcb33806d186561c781992e5f4d8a90bb033f9f0 jdk7-b48
    1.12 +8b22ccb5aba2c6c11bddf6488a7bb7ef5b4bf2be jdk7-b49
     2.1 --- a/agent/src/os/linux/ps_core.c	Sat Jan 31 17:19:42 2009 -0800
     2.2 +++ b/agent/src/os/linux/ps_core.c	Fri Feb 27 15:13:00 2009 -0800
     2.3 @@ -238,8 +238,8 @@
     2.4    // Ignore the rest of the FileMapHeader. We don't need those fields here.
     2.5  };
     2.6  
     2.7 -static bool read_int(struct ps_prochandle* ph, uintptr_t addr, int* pvalue) {
     2.8 -   int i;
     2.9 +static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
    2.10 +   jboolean i;
    2.11     if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
    2.12        *pvalue = i;
    2.13        return true;
    2.14 @@ -295,7 +295,7 @@
    2.15           int fd = -1, m = 0;
    2.16           uintptr_t base = 0, useSharedSpacesAddr = 0;
    2.17           uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
    2.18 -         int useSharedSpaces = 0;
    2.19 +         jboolean useSharedSpaces = 0;
    2.20           map_info* mi = 0;
    2.21  
    2.22           memset(classes_jsa, 0, sizeof(classes_jsa));
    2.23 @@ -306,12 +306,15 @@
    2.24              return false;
    2.25           }
    2.26  
    2.27 -         if (read_int(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
    2.28 +         // Hotspot vm types are not exported to build this library. So
    2.29 +         // using equivalent type jboolean to read the value of
    2.30 +         // UseSharedSpaces which is same as hotspot type "bool".
    2.31 +         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
    2.32              print_debug("can't read the value of 'UseSharedSpaces' flag\n");
    2.33              return false;
    2.34           }
    2.35  
    2.36 -         if (useSharedSpaces == 0) {
    2.37 +         if ((int)useSharedSpaces == 0) {
    2.38              print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
    2.39              return true;
    2.40           }
     3.1 --- a/agent/src/os/solaris/proc/saproc.cpp	Sat Jan 31 17:19:42 2009 -0800
     3.2 +++ b/agent/src/os/solaris/proc/saproc.cpp	Fri Feb 27 15:13:00 2009 -0800
     3.3 @@ -502,8 +502,8 @@
     3.4  };
     3.5  
     3.6  static bool
     3.7 -read_int(struct ps_prochandle* ph, psaddr_t addr, int* pvalue) {
     3.8 -  int i;
     3.9 +read_jboolean(struct ps_prochandle* ph, psaddr_t addr, jboolean* pvalue) {
    3.10 +  jboolean i;
    3.11    if (ps_pread(ph, addr, &i, sizeof(i)) == PS_OK) {
    3.12      *pvalue = i;
    3.13      return true;
    3.14 @@ -575,10 +575,13 @@
    3.15    }
    3.16  
    3.17    // read the value of the flag "UseSharedSpaces"
    3.18 -  int value = 0;
    3.19 -  if (read_int(ph, useSharedSpacesAddr, &value) != true) {
    3.20 +  // Since hotspot types are not available to build this library. So
    3.21 +  // equivalent type "jboolean" is used to read the value of "UseSharedSpaces"
    3.22 +  // which is same as hotspot type "bool".
    3.23 +  jboolean value = 0;
    3.24 +  if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) {
    3.25      THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
    3.26 -  } else if (value == 0) {
    3.27 +  } else if ((int)value == 0) {
    3.28      print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
    3.29      return 1;
    3.30    }
     4.1 --- a/make/hotspot_version	Sat Jan 31 17:19:42 2009 -0800
     4.2 +++ b/make/hotspot_version	Fri Feb 27 15:13:00 2009 -0800
     4.3 @@ -33,9 +33,9 @@
     4.4  # Don't put quotes (fail windows build).
     4.5  HOTSPOT_VM_COPYRIGHT=Copyright 2008
     4.6  
     4.7 -HS_MAJOR_VER=14
     4.8 +HS_MAJOR_VER=15
     4.9  HS_MINOR_VER=0
    4.10 -HS_BUILD_NUMBER=10
    4.11 +HS_BUILD_NUMBER=02
    4.12  
    4.13  JDK_MAJOR_VER=1
    4.14  JDK_MINOR_VER=7
     5.1 --- a/src/cpu/sparc/vm/jni_sparc.h	Sat Jan 31 17:19:42 2009 -0800
     5.2 +++ b/src/cpu/sparc/vm/jni_sparc.h	Fri Feb 27 15:13:00 2009 -0800
     5.3 @@ -28,5 +28,11 @@
     5.4  #define JNICALL
     5.5  
     5.6  typedef int jint;
     5.7 -typedef long long jlong;
     5.8 +
     5.9 +#ifdef _LP64
    5.10 +  typedef long jlong;
    5.11 +#else
    5.12 +  typedef long long jlong;
    5.13 +#endif
    5.14 +
    5.15  typedef signed char jbyte;
     6.1 --- a/src/cpu/sparc/vm/sparc.ad	Sat Jan 31 17:19:42 2009 -0800
     6.2 +++ b/src/cpu/sparc/vm/sparc.ad	Fri Feb 27 15:13:00 2009 -0800
     6.3 @@ -762,7 +762,7 @@
     6.4      case Assembler::stdf_op3: st_op = Op_StoreD; break;
     6.5  
     6.6      case Assembler::ldsb_op3: ld_op = Op_LoadB; break;
     6.7 -    case Assembler::lduh_op3: ld_op = Op_LoadC; break;
     6.8 +    case Assembler::lduh_op3: ld_op = Op_LoadUS; break;
     6.9      case Assembler::ldsh_op3: ld_op = Op_LoadS; break;
    6.10      case Assembler::ldx_op3:  // may become LoadP or stay LoadI
    6.11      case Assembler::ldsw_op3: // may become LoadP or stay LoadI
    6.12 @@ -3869,6 +3869,8 @@
    6.13    constraint(ALLOC_IN_RC(dflt_reg));
    6.14    match(RegD);
    6.15  
    6.16 +  match(regD_low);
    6.17 +
    6.18    format %{ %}
    6.19    interface(REG_INTER);
    6.20  %}
    6.21 @@ -3883,7 +3885,7 @@
    6.22  
    6.23  operand regD_low() %{
    6.24    constraint(ALLOC_IN_RC(dflt_low_reg));
    6.25 -  match(RegD);
    6.26 +  match(regD);
    6.27  
    6.28    format %{ %}
    6.29    interface(REG_INTER);
    6.30 @@ -5314,9 +5316,9 @@
    6.31    ins_pipe(iload_mask_mem);
    6.32  %}
    6.33  
    6.34 -// Load Char (16bit UNsigned) into a Long Register
    6.35 -instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
    6.36 -  match(Set dst (AndL (ConvI2L (LoadC mem)) bytemask));
    6.37 +// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
    6.38 +instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{
    6.39 +  match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask));
    6.40    ins_cost(MEMORY_REF_COST);
    6.41  
    6.42    size(4);
    6.43 @@ -5326,9 +5328,9 @@
    6.44    ins_pipe(iload_mask_mem);
    6.45  %}
    6.46  
    6.47 -// Load Char (16bit unsigned)
    6.48 -instruct loadC(iRegI dst, memory mem) %{
    6.49 -  match(Set dst (LoadC mem));
    6.50 +// Load Unsigned Short/Char (16bit unsigned)
    6.51 +instruct loadUS(iRegI dst, memory mem) %{
    6.52 +  match(Set dst (LoadUS mem));
    6.53    ins_cost(MEMORY_REF_COST);
    6.54  
    6.55    size(4);
     7.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Sat Jan 31 17:19:42 2009 -0800
     7.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Feb 27 15:13:00 2009 -0800
     7.3 @@ -5212,15 +5212,15 @@
     7.4  void MacroAssembler::reset_last_Java_frame(bool clear_fp,
     7.5                                             bool clear_pc) {
     7.6    // we must set sp to zero to clear frame
     7.7 -  movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD);
     7.8 +  movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD);
     7.9    // must clear fp, so that compiled frames are not confused; it is
    7.10    // possible that we need it only for debugging
    7.11    if (clear_fp) {
    7.12 -    movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD);
    7.13 +    movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
    7.14    }
    7.15  
    7.16    if (clear_pc) {
    7.17 -    movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD);
    7.18 +    movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
    7.19    }
    7.20  }
    7.21  
    7.22 @@ -5670,7 +5670,7 @@
    7.23    // get oop result if there is one and reset the value in the thread
    7.24    if (oop_result->is_valid()) {
    7.25      movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset()));
    7.26 -    movptr(Address(java_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
    7.27 +    movptr(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD);
    7.28      verify_oop(oop_result, "broken oop in call_VM_base");
    7.29    }
    7.30  }
    7.31 @@ -6426,13 +6426,13 @@
    7.32      get_thread(java_thread);
    7.33    }
    7.34    // we must set sp to zero to clear frame
    7.35 -  movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD);
    7.36 +  movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), NULL_WORD);
    7.37    if (clear_fp) {
    7.38 -    movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD);
    7.39 +    movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), NULL_WORD);
    7.40    }
    7.41  
    7.42    if (clear_pc)
    7.43 -    movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD);
    7.44 +    movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD);
    7.45  
    7.46  }
    7.47  
    7.48 @@ -6943,29 +6943,32 @@
    7.49  
    7.50    Label slow_case, done;
    7.51  
    7.52 -  // x ?<= pi/4
    7.53 -  fld_d(ExternalAddress((address)&pi_4));
    7.54 -  fld_s(1);                // Stack:  X  PI/4  X
    7.55 -  fabs();                  // Stack: |X| PI/4  X
    7.56 -  fcmp(tmp);
    7.57 -  jcc(Assembler::above, slow_case);
    7.58 -
    7.59 -  // fastest case: -pi/4 <= x <= pi/4
    7.60 -  switch(trig) {
    7.61 -  case 's':
    7.62 -    fsin();
    7.63 -    break;
    7.64 -  case 'c':
    7.65 -    fcos();
    7.66 -    break;
    7.67 -  case 't':
    7.68 -    ftan();
    7.69 -    break;
    7.70 -  default:
    7.71 -    assert(false, "bad intrinsic");
    7.72 -    break;
    7.73 -  }
    7.74 -  jmp(done);
    7.75 +  ExternalAddress pi4_adr = (address)&pi_4;
    7.76 +  if (reachable(pi4_adr)) {
    7.77 +    // x ?<= pi/4
    7.78 +    fld_d(pi4_adr);
    7.79 +    fld_s(1);                // Stack:  X  PI/4  X
    7.80 +    fabs();                  // Stack: |X| PI/4  X
    7.81 +    fcmp(tmp);
    7.82 +    jcc(Assembler::above, slow_case);
    7.83 +
    7.84 +    // fastest case: -pi/4 <= x <= pi/4
    7.85 +    switch(trig) {
    7.86 +    case 's':
    7.87 +      fsin();
    7.88 +      break;
    7.89 +    case 'c':
    7.90 +      fcos();
    7.91 +      break;
    7.92 +    case 't':
    7.93 +      ftan();
    7.94 +      break;
    7.95 +    default:
    7.96 +      assert(false, "bad intrinsic");
    7.97 +      break;
    7.98 +    }
    7.99 +    jmp(done);
   7.100 +  }
   7.101  
   7.102    // slow case: runtime call
   7.103    bind(slow_case);
     8.1 --- a/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Sat Jan 31 17:19:42 2009 -0800
     8.2 +++ b/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Fri Feb 27 15:13:00 2009 -0800
     8.3 @@ -213,7 +213,7 @@
     8.4  
     8.5  inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) {
     8.6    /* it's possible we could catch this special case implicitly */
     8.7 -  if (op1 == 0x80000000 && op2 == -1) return op1;
     8.8 +  if ((juint)op1 == 0x80000000 && op2 == -1) return op1;
     8.9    else return op1 / op2;
    8.10  }
    8.11  
    8.12 @@ -231,7 +231,7 @@
    8.13  
    8.14  inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) {
    8.15    /* it's possible we could catch this special case implicitly */
    8.16 -  if (op1 == 0x80000000 && op2 == -1) return 0;
    8.17 +  if ((juint)op1 == 0x80000000 && op2 == -1) return 0;
    8.18    else return op1 % op2;
    8.19  }
    8.20  
     9.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Sat Jan 31 17:19:42 2009 -0800
     9.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Feb 27 15:13:00 2009 -0800
     9.3 @@ -779,7 +779,7 @@
     9.4      case T_OBJECT:  // fall through
     9.5      case T_ARRAY:
     9.6        if (c->as_jobject() == NULL) {
     9.7 -        __ movptr(as_Address(addr), (int32_t)NULL_WORD);
     9.8 +        __ movptr(as_Address(addr), NULL_WORD);
     9.9        } else {
    9.10          if (is_literal_address(addr)) {
    9.11            ShouldNotReachHere();
    10.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Sat Jan 31 17:19:42 2009 -0800
    10.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Feb 27 15:13:00 2009 -0800
    10.3 @@ -78,10 +78,10 @@
    10.4      movptr(rax, Address(thread, Thread::pending_exception_offset()));
    10.5      // make sure that the vm_results are cleared
    10.6      if (oop_result1->is_valid()) {
    10.7 -      movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
    10.8 +      movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
    10.9      }
   10.10      if (oop_result2->is_valid()) {
   10.11 -      movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
   10.12 +      movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
   10.13      }
   10.14      if (frame_size() == no_frame_size) {
   10.15        leave();
   10.16 @@ -96,12 +96,12 @@
   10.17    // get oop results if there are any and reset the values in the thread
   10.18    if (oop_result1->is_valid()) {
   10.19      movptr(oop_result1, Address(thread, JavaThread::vm_result_offset()));
   10.20 -    movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
   10.21 +    movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
   10.22      verify_oop(oop_result1);
   10.23    }
   10.24    if (oop_result2->is_valid()) {
   10.25      movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset()));
   10.26 -    movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
   10.27 +    movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
   10.28      verify_oop(oop_result2);
   10.29    }
   10.30    return call_offset;
   10.31 @@ -728,8 +728,8 @@
   10.32  
   10.33    // clear exception fields in JavaThread because they are no longer needed
   10.34    // (fields must be cleared because they are processed by GC otherwise)
   10.35 -  __ movptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
   10.36 -  __ movptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
   10.37 +  __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD);
   10.38 +  __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD);
   10.39  
   10.40    // pop the stub frame off
   10.41    __ leave();
   10.42 @@ -878,7 +878,7 @@
   10.43  
   10.44      // load and clear pending exception
   10.45      __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
   10.46 -    __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
   10.47 +    __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
   10.48  
   10.49      // check that there is really a valid exception
   10.50      __ verify_not_null_oop(rax);
   10.51 @@ -971,14 +971,14 @@
   10.52          // load pending exception oop into rax,
   10.53          __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
   10.54          // clear pending exception
   10.55 -        __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
   10.56 +        __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
   10.57  
   10.58          // load issuing PC (the return address for this stub) into rdx
   10.59          __ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
   10.60  
   10.61          // make sure that the vm_results are cleared (may be unnecessary)
   10.62 -        __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
   10.63 -        __ movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD);
   10.64 +        __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
   10.65 +        __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
   10.66  
   10.67          // verify that that there is really a valid exception in rax,
   10.68          __ verify_not_null_oop(exception_oop);
   10.69 @@ -1393,7 +1393,7 @@
   10.70          __ ret(0);
   10.71  
   10.72          __ bind(miss);
   10.73 -        __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 0); // result
   10.74 +        __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
   10.75          __ pop(rax);
   10.76          __ pop(rcx);
   10.77          __ pop(rsi);
    11.1 --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp	Sat Jan 31 17:19:42 2009 -0800
    11.2 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp	Fri Feb 27 15:13:00 2009 -0800
    11.3 @@ -594,7 +594,7 @@
    11.4    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax);
    11.5  
    11.6    // for c++ interpreter can rsi really be munged?
    11.7 -  __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter)));                               // restore state
    11.8 +  __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter)));                               // restore state
    11.9    __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method)));            // restore method
   11.10    __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals)));            // get locals pointer
   11.11  
   11.12 @@ -658,7 +658,7 @@
   11.13      const Address size_of_stack    (rbx, methodOopDesc::max_stack_offset());
   11.14      // Always give one monitor to allow us to start interp if sync method.
   11.15      // Any additional monitors need a check when moving the expression stack
   11.16 -    const one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
   11.17 +    const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
   11.18    __ load_unsigned_word(rax, size_of_stack);                            // get size of expression stack in words
   11.19    __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor));
   11.20    __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
   11.21 @@ -1829,7 +1829,7 @@
   11.22    Label unwind_and_forward;
   11.23  
   11.24    // restore state pointer.
   11.25 -  __ lea(state, Address(rbp,  -sizeof(BytecodeInterpreter)));
   11.26 +  __ lea(state, Address(rbp,  -(int)sizeof(BytecodeInterpreter)));
   11.27  
   11.28    __ movptr(rbx, STATE(_method));                       // get method
   11.29  #ifdef _LP64
   11.30 @@ -1877,14 +1877,14 @@
   11.31  
   11.32    // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
   11.33    if (UseSSE < 2) {
   11.34 -    __ lea(state, Address(rbp,  -sizeof(BytecodeInterpreter)));
   11.35 +    __ lea(state, Address(rbp,  -(int)sizeof(BytecodeInterpreter)));
   11.36      __ movptr(rbx, STATE(_result._to_call._callee));                   // get method just executed
   11.37      __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset()));
   11.38      __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT));    // Result stub address array index
   11.39      __ jcc(Assembler::equal, do_float);
   11.40      __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE));    // Result stub address array index
   11.41      __ jcc(Assembler::equal, do_double);
   11.42 -#ifdef COMPILER2
   11.43 +#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2)
   11.44      __ empty_FPU_stack();
   11.45  #endif // COMPILER2
   11.46      __ jmp(done_conv);
   11.47 @@ -1928,7 +1928,7 @@
   11.48  
   11.49    // Restore rsi/r13 as compiled code may not preserve it
   11.50  
   11.51 -  __ lea(state, Address(rbp,  -sizeof(BytecodeInterpreter)));
   11.52 +  __ lea(state, Address(rbp,  -(int)sizeof(BytecodeInterpreter)));
   11.53  
   11.54    // restore stack to what we had when we left (in case i2c extended it)
   11.55  
   11.56 @@ -1942,7 +1942,7 @@
   11.57  #else
   11.58    __ movptr(rcx, STATE(_thread));                       // get thread
   11.59    __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
   11.60 -#endif / __LP64
   11.61 +#endif // _LP64
   11.62    __ jcc(Assembler::notZero, return_with_exception);
   11.63  
   11.64    // get method just executed
    12.1 --- a/src/cpu/x86/vm/frame_x86.inline.hpp	Sat Jan 31 17:19:42 2009 -0800
    12.2 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Feb 27 15:13:00 2009 -0800
    12.3 @@ -139,7 +139,7 @@
    12.4  #ifdef CC_INTERP
    12.5  
    12.6  inline interpreterState frame::get_interpreterState() const {
    12.7 -  return ((interpreterState)addr_at( -sizeof(BytecodeInterpreter)/wordSize ));
    12.8 +  return ((interpreterState)addr_at( -((int)sizeof(BytecodeInterpreter))/wordSize ));
    12.9  }
   12.10  
   12.11  inline intptr_t*    frame::sender_sp()        const {
    13.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    13.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    13.3 @@ -133,7 +133,7 @@
    13.4                               + in_ByteSize(wordSize));
    13.5    switch (state) {
    13.6      case atos: movptr(rax, oop_addr);
    13.7 -               movptr(oop_addr, (int32_t)NULL_WORD);
    13.8 +               movptr(oop_addr, NULL_WORD);
    13.9                 verify_oop(rax, state);                break;
   13.10      case ltos:
   13.11                 movl(rdx, val_addr1);               // fall through
   13.12 @@ -148,8 +148,8 @@
   13.13    }
   13.14    // Clean up tos value in the thread object
   13.15    movl(tos_addr,  (int32_t) ilgl);
   13.16 -  movptr(val_addr,  (int32_t)NULL_WORD);
   13.17 -  NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD));
   13.18 +  movptr(val_addr,  NULL_WORD);
   13.19 +  NOT_LP64(movptr(val_addr1, NULL_WORD));
   13.20  }
   13.21  
   13.22  
   13.23 @@ -944,7 +944,7 @@
   13.24      movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ()));
   13.25  
   13.26      // Free entry
   13.27 -    movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
   13.28 +    movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD);
   13.29  
   13.30      if (UseBiasedLocking) {
   13.31        biased_locking_exit(obj_reg, header_reg, done);
    14.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.hpp	Sat Jan 31 17:19:42 2009 -0800
    14.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp	Fri Feb 27 15:13:00 2009 -0800
    14.3 @@ -120,7 +120,7 @@
    14.4    void empty_expression_stack()                            {
    14.5         movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
    14.6        // NULL last_sp until next java call
    14.7 -      movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
    14.8 +      movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
    14.9    }
   14.10  
   14.11    // Tagged stack helpers for swap and dup
    15.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Sat Jan 31 17:19:42 2009 -0800
    15.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Fri Feb 27 15:13:00 2009 -0800
    15.3 @@ -30,7 +30,7 @@
    15.4  
    15.5  #ifdef CC_INTERP
    15.6  void InterpreterMacroAssembler::get_method(Register reg) {
    15.7 -  movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize)));
    15.8 +  movptr(reg, Address(rbp, -((int)sizeof(BytecodeInterpreter) + 2 * wordSize)));
    15.9    movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method)));
   15.10  }
   15.11  #endif // CC_INTERP
    16.1 --- a/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    16.2 +++ b/src/cpu/x86/vm/interpreterRT_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    16.3 @@ -54,7 +54,7 @@
    16.4    __ cmpptr(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), (int32_t)NULL_WORD); // do not use temp() to avoid AGI
    16.5    Label L;
    16.6    __ jcc(Assembler::notZero, L);
    16.7 -  __ movptr(temp(), ((int32_t)NULL_WORD));
    16.8 +  __ movptr(temp(), NULL_WORD);
    16.9    __ bind(L);
   16.10    __ movptr(Address(to(), to_offset * wordSize), temp());
   16.11  }
   16.12 @@ -110,7 +110,7 @@
   16.13    virtual void pass_object() {
   16.14      // pass address of from
   16.15      intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0));
   16.16 -    *_to++ = (*(intptr_t*)from_addr == 0) ? NULL : from_addr;
   16.17 +    *_to++ = (*(intptr_t*)from_addr == 0) ? NULL_WORD : from_addr;
   16.18      debug_only(verify_tag(frame::TagReference));
   16.19      _from -= Interpreter::stackElementSize();
   16.20     }
    17.1 --- a/src/cpu/x86/vm/jni_x86.h	Sat Jan 31 17:19:42 2009 -0800
    17.2 +++ b/src/cpu/x86/vm/jni_x86.h	Fri Feb 27 15:13:00 2009 -0800
    17.3 @@ -32,7 +32,13 @@
    17.4    #define JNICALL
    17.5  
    17.6    typedef int jint;
    17.7 +
    17.8 +#ifdef _LP64
    17.9 +  typedef long jlong;
   17.10 +#else
   17.11    typedef long long jlong;
   17.12 +#endif
   17.13 +
   17.14  #else
   17.15    #define JNIEXPORT __declspec(dllexport)
   17.16    #define JNIIMPORT __declspec(dllimport)
    18.1 --- a/src/cpu/x86/vm/runtime_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    18.2 +++ b/src/cpu/x86/vm/runtime_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    18.3 @@ -129,11 +129,11 @@
    18.4    // Get the exception pc in case we are deoptimized
    18.5    __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset()));
    18.6  #ifdef ASSERT
    18.7 -  __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), (int32_t)NULL_WORD);
    18.8 -  __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
    18.9 +  __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), NULL_WORD);
   18.10 +  __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD);
   18.11  #endif
   18.12    // Clear the exception oop so GC no longer processes it as a root.
   18.13 -  __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
   18.14 +  __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD);
   18.15  
   18.16    __ pop(rcx);
   18.17  
    19.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    19.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    19.3 @@ -39,6 +39,8 @@
    19.4  RuntimeStub*       SharedRuntime::_resolve_virtual_call_blob;
    19.5  RuntimeStub*       SharedRuntime::_resolve_static_call_blob;
    19.6  
    19.7 +const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
    19.8 +
    19.9  class RegisterSaver {
   19.10    enum { FPU_regs_live = 8 /*for the FPU stack*/+8/*eight more for XMM registers*/ };
   19.11    // Capture info about frame layout
   19.12 @@ -1299,7 +1301,7 @@
   19.13  
   19.14    // Now compute actual number of stack words we need rounding to make
   19.15    // stack properly aligned.
   19.16 -  stack_slots = round_to(stack_slots, 2 * VMRegImpl::slots_per_word);
   19.17 +  stack_slots = round_to(stack_slots, StackAlignmentInSlots);
   19.18  
   19.19    int stack_size = stack_slots * VMRegImpl::stack_slot_size;
   19.20  
   19.21 @@ -1793,7 +1795,7 @@
   19.22    // reset handle block
   19.23    __ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
   19.24  
   19.25 -  __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
   19.26 +  __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
   19.27  
   19.28    // Any exception pending?
   19.29    __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
   19.30 @@ -1865,7 +1867,7 @@
   19.31      // Save pending exception around call to VM (which contains an EXCEPTION_MARK)
   19.32  
   19.33      __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset())));
   19.34 -    __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
   19.35 +    __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD);
   19.36  
   19.37  
   19.38      // should be a peal
   19.39 @@ -2431,7 +2433,7 @@
   19.40    __ get_thread(rdi);
   19.41    __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset()));
   19.42    __ movptr(Address(rbp, wordSize), rdx);
   19.43 -  __ movptr(Address(rdi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
   19.44 +  __ movptr(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD);
   19.45  
   19.46  #ifdef ASSERT
   19.47    // verify that there is really an exception oop in JavaThread
   19.48 @@ -2489,8 +2491,8 @@
   19.49    __ jcc(Assembler::notEqual, noException);
   19.50    __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
   19.51    __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset()));
   19.52 -  __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
   19.53 -  __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
   19.54 +  __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD);
   19.55 +  __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD);
   19.56  
   19.57    __ verify_oop(rax);
   19.58  
   19.59 @@ -2582,7 +2584,7 @@
   19.60            rbx); // Make it walkable
   19.61  #else /* CC_INTERP */
   19.62    // This value is corrected by layout_activation_impl
   19.63 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD );
   19.64 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   19.65    __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
   19.66  #endif /* CC_INTERP */
   19.67    __ movptr(sp_temp, rsp);              // pass to next frame
   19.68 @@ -2802,7 +2804,7 @@
   19.69            rbx); // Make it walkable
   19.70  #else /* CC_INTERP */
   19.71    // This value is corrected by layout_activation_impl
   19.72 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD );
   19.73 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD );
   19.74    __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
   19.75  #endif /* CC_INTERP */
   19.76    __ movptr(sp_temp, rsp);              // pass to next frame
   19.77 @@ -3020,7 +3022,7 @@
   19.78    // exception pending => remove activation and forward to exception handler
   19.79  
   19.80    __ get_thread(thread);
   19.81 -  __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
   19.82 +  __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
   19.83    __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
   19.84    __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
   19.85  
    20.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Sat Jan 31 17:19:42 2009 -0800
    20.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Fri Feb 27 15:13:00 2009 -0800
    20.3 @@ -39,6 +39,8 @@
    20.4  RuntimeStub*       SharedRuntime::_resolve_virtual_call_blob;
    20.5  RuntimeStub*       SharedRuntime::_resolve_static_call_blob;
    20.6  
    20.7 +const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
    20.8 +
    20.9  #define __ masm->
   20.10  
   20.11  class SimpleRuntimeFrame {
   20.12 @@ -1286,7 +1288,7 @@
   20.13  
   20.14    // Now compute actual number of stack words we need rounding to make
   20.15    // stack properly aligned.
   20.16 -  stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word);
   20.17 +  stack_slots = round_to(stack_slots, StackAlignmentInSlots);
   20.18  
   20.19    int stack_size = stack_slots * VMRegImpl::stack_slot_size;
   20.20  
   20.21 @@ -2954,10 +2956,16 @@
   20.22    __ pushptr(Address(rcx, 0));     // Save return address
   20.23    __ enter();                      // Save old & set new rbp
   20.24    __ subptr(rsp, rbx);             // Prolog
   20.25 +#ifdef CC_INTERP
   20.26 +  __ movptr(Address(rbp,
   20.27 +                  -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))),
   20.28 +            sender_sp); // Make it walkable
   20.29 +#else // CC_INTERP
   20.30    __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize),
   20.31              sender_sp);            // Make it walkable
   20.32    // This value is corrected by layout_activation_impl
   20.33    __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD );
   20.34 +#endif // CC_INTERP
   20.35    __ mov(sender_sp, rsp);          // Pass sender_sp to next frame
   20.36    __ addptr(rsi, wordSize);        // Bump array pointer (sizes)
   20.37    __ addptr(rcx, wordSize);        // Bump array pointer (pcs)
    21.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    21.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    21.3 @@ -407,7 +407,7 @@
    21.4      __ get_thread(rcx);
    21.5      __ pop(rdx);
    21.6      __ movptr(rax, Address(rcx, Thread::pending_exception_offset()));
    21.7 -    __ movptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
    21.8 +    __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD);
    21.9  
   21.10  #ifdef ASSERT
   21.11      // make sure exception is set
    22.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Sat Jan 31 17:19:42 2009 -0800
    22.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Feb 27 15:13:00 2009 -0800
    22.3 @@ -472,7 +472,7 @@
    22.4      // setup rax & rdx, remove return address & clear pending exception
    22.5      __ pop(rdx);
    22.6      __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
    22.7 -    __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD);
    22.8 +    __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
    22.9  
   22.10  #ifdef ASSERT
   22.11      // make sure exception is set
   22.12 @@ -954,9 +954,9 @@
   22.13      __ jcc(Assembler::zero, exit); // if obj is NULL it is OK
   22.14      // Check if the oop is in the right area of memory
   22.15      __ movptr(c_rarg2, rax);
   22.16 -    __ movptr(c_rarg3, (int64_t) Universe::verify_oop_mask());
   22.17 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask());
   22.18      __ andptr(c_rarg2, c_rarg3);
   22.19 -    __ movptr(c_rarg3, (int64_t) Universe::verify_oop_bits());
   22.20 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits());
   22.21      __ cmpptr(c_rarg2, c_rarg3);
   22.22      __ jcc(Assembler::notZero, error);
   22.23  
   22.24 @@ -969,9 +969,9 @@
   22.25      __ jcc(Assembler::zero, error); // if klass is NULL it is broken
   22.26      // Check if the klass is in the right area of memory
   22.27      __ mov(c_rarg2, rax);
   22.28 -    __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask());
   22.29 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask());
   22.30      __ andptr(c_rarg2, c_rarg3);
   22.31 -    __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits());
   22.32 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits());
   22.33      __ cmpptr(c_rarg2, c_rarg3);
   22.34      __ jcc(Assembler::notZero, error);
   22.35  
   22.36 @@ -980,9 +980,9 @@
   22.37      __ testptr(rax, rax);
   22.38      __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
   22.39      // Check if the klass' klass is in the right area of memory
   22.40 -    __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask());
   22.41 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask());
   22.42      __ andptr(rax, c_rarg3);
   22.43 -    __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits());
   22.44 +    __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits());
   22.45      __ cmpptr(rax, c_rarg3);
   22.46      __ jcc(Assembler::notZero, error);
   22.47  
    23.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    23.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    23.3 @@ -110,7 +110,7 @@
    23.4      if (message != NULL) {
    23.5        __ lea(rbx, ExternalAddress((address)message));
    23.6      } else {
    23.7 -      __ movptr(rbx, (int32_t)NULL_WORD);
    23.8 +      __ movptr(rbx, NULL_WORD);
    23.9      }
   23.10      __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), rax, rbx);
   23.11    }
   23.12 @@ -123,7 +123,7 @@
   23.13  address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
   23.14    address entry = __ pc();
   23.15    // NULL last_sp until next java call
   23.16 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   23.17 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   23.18    __ dispatch_next(state);
   23.19    return entry;
   23.20  }
   23.21 @@ -176,7 +176,7 @@
   23.22    // Restore stack bottom in case i2c adjusted stack
   23.23    __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
   23.24    // and NULL it as marker that rsp is now tos until next java call
   23.25 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   23.26 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   23.27  
   23.28    __ restore_bcp();
   23.29    __ restore_locals();
   23.30 @@ -211,7 +211,7 @@
   23.31  
   23.32    // The stack is not extended by deopt but we must NULL last_sp as this
   23.33    // entry is like a "return".
   23.34 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   23.35 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   23.36    __ restore_bcp();
   23.37    __ restore_locals();
   23.38    // handle exceptions
   23.39 @@ -382,7 +382,7 @@
   23.40    // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp).
   23.41    // The call returns the address of the verified entry point for the method or NULL
   23.42    // if the compilation did not complete (either went background or bailed out).
   23.43 -  __ movptr(rax, (int32_t)false);
   23.44 +  __ movptr(rax, (intptr_t)false);
   23.45    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax);
   23.46  
   23.47    __ movptr(rbx, Address(rbp, method_offset));   // restore methodOop
   23.48 @@ -1028,7 +1028,7 @@
   23.49  
   23.50    // reset handle block
   23.51    __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
   23.52 -  __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
   23.53 +  __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
   23.54  
   23.55    // If result was an oop then unbox and save it in the frame
   23.56    { Label L;
   23.57 @@ -1488,7 +1488,7 @@
   23.58  
   23.59    // Restore sp to interpreter_frame_last_sp even though we are going
   23.60    // to empty the expression stack for the exception processing.
   23.61 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   23.62 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   23.63    // rax,: exception
   23.64    // rdx: return address/pc that threw exception
   23.65    __ restore_bcp();                              // rsi points to call/send
   23.66 @@ -1608,7 +1608,7 @@
   23.67    __ reset_last_Java_frame(rcx, true, true);
   23.68    // Restore the last_sp and null it out
   23.69    __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
   23.70 -  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
   23.71 +  __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   23.72  
   23.73    __ restore_bcp();
   23.74    __ restore_locals();
   23.75 @@ -1636,7 +1636,7 @@
   23.76    // restore exception
   23.77    __ get_thread(rcx);
   23.78    __ movptr(rax, Address(rcx, JavaThread::vm_result_offset()));
   23.79 -  __ movptr(Address(rcx, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
   23.80 +  __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD);
   23.81    __ verify_oop(rax);
   23.82  
   23.83    // Inbetween activations - previous activation type unknown yet
    24.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Sat Jan 31 17:19:42 2009 -0800
    24.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Feb 27 15:13:00 2009 -0800
    24.3 @@ -137,7 +137,7 @@
    24.4          // Do the actual store
    24.5          // noreg means NULL
    24.6          if (val == noreg) {
    24.7 -          __ movl(Address(rdx, 0), NULL_WORD);
    24.8 +          __ movptr(Address(rdx, 0), NULL_WORD);
    24.9            // No post barrier for NULL
   24.10          } else {
   24.11            __ movl(Address(rdx, 0), val);
   24.12 @@ -152,7 +152,7 @@
   24.13      case BarrierSet::CardTableExtension:
   24.14        {
   24.15          if (val == noreg) {
   24.16 -          __ movl(obj, NULL_WORD);
   24.17 +          __ movptr(obj, NULL_WORD);
   24.18          } else {
   24.19            __ movl(obj, val);
   24.20            // flatten object address if needed
   24.21 @@ -168,7 +168,7 @@
   24.22      case BarrierSet::ModRef:
   24.23      case BarrierSet::Other:
   24.24        if (val == noreg) {
   24.25 -        __ movl(obj, NULL_WORD);
   24.26 +        __ movptr(obj, NULL_WORD);
   24.27        } else {
   24.28          __ movl(obj, val);
   24.29        }
    25.1 --- a/src/cpu/x86/vm/x86_32.ad	Sat Jan 31 17:19:42 2009 -0800
    25.2 +++ b/src/cpu/x86/vm/x86_32.ad	Fri Feb 27 15:13:00 2009 -0800
    25.3 @@ -3371,7 +3371,7 @@
    25.4           masm.movptr(Address(boxReg, 0), 3) ;            // results in ST-before-CAS penalty
    25.5           masm.get_thread (scrReg) ; 
    25.6           masm.movptr(boxReg, tmpReg);                    // consider: LEA box, [tmp-2] 
    25.7 -         masm.movptr(tmpReg, 0);                         // consider: xor vs mov
    25.8 +         masm.movptr(tmpReg, NULL_WORD);                 // consider: xor vs mov
    25.9           if (os::is_MP()) { masm.lock(); } 
   25.10           masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 
   25.11        } else 
   25.12 @@ -3387,7 +3387,7 @@
   25.13  
   25.14           if ((EmitSync & 64) == 0) {
   25.15             // Optimistic form: consider XORL tmpReg,tmpReg
   25.16 -           masm.movptr(tmpReg, 0 ) ; 
   25.17 +           masm.movptr(tmpReg, NULL_WORD) ; 
   25.18           } else { 
   25.19             // Can suffer RTS->RTO upgrades on shared or cold $ lines
   25.20             // Test-And-CAS instead of CAS
   25.21 @@ -3587,7 +3587,7 @@
   25.22           masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 
   25.23           masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 
   25.24           masm.jccb  (Assembler::notZero, DONE_LABEL) ; 
   25.25 -         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 
   25.26 +         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 
   25.27           masm.jmpb  (DONE_LABEL) ; 
   25.28        } else { 
   25.29           masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;  
   25.30 @@ -3596,7 +3596,7 @@
   25.31           masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 
   25.32           masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 
   25.33           masm.jccb  (Assembler::notZero, CheckSucc) ; 
   25.34 -         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 
   25.35 +         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 
   25.36           masm.jmpb  (DONE_LABEL) ; 
   25.37        }
   25.38  
   25.39 @@ -3644,7 +3644,7 @@
   25.40           // We currently use (3), although it's likely that switching to (2)
   25.41           // is correct for the future.
   25.42              
   25.43 -         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 
   25.44 +         masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 
   25.45           if (os::is_MP()) { 
   25.46              if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 
   25.47                masm.mfence();
   25.48 @@ -6413,9 +6413,9 @@
   25.49    ins_pipe( ialu_reg_mem );
   25.50  %}
   25.51  
   25.52 -// Load Char (16bit unsigned)
   25.53 -instruct loadC(eRegI dst, memory mem) %{
   25.54 -  match(Set dst (LoadC mem));
   25.55 +// Load Unsigned Short/Char (16bit unsigned)
   25.56 +instruct loadUS(eRegI dst, memory mem) %{
   25.57 +  match(Set dst (LoadUS mem));
   25.58  
   25.59    ins_cost(125);
   25.60    format %{ "MOVZX  $dst,$mem" %}
    26.1 --- a/src/cpu/x86/vm/x86_64.ad	Sat Jan 31 17:19:42 2009 -0800
    26.2 +++ b/src/cpu/x86/vm/x86_64.ad	Fri Feb 27 15:13:00 2009 -0800
    26.3 @@ -6096,25 +6096,25 @@
    26.4  //   ins_pipe(ialu_reg_mem);
    26.5  // %}
    26.6  
    26.7 -// Load Char (16 bit UNsigned)
    26.8 -instruct loadC(rRegI dst, memory mem)
    26.9 -%{
   26.10 -  match(Set dst (LoadC mem));
   26.11 +// Load Unsigned Short/Char (16 bit UNsigned)
   26.12 +instruct loadUS(rRegI dst, memory mem)
   26.13 +%{
   26.14 +  match(Set dst (LoadUS mem));
   26.15  
   26.16    ins_cost(125);
   26.17 -  format %{ "movzwl  $dst, $mem\t# char" %}
   26.18 +  format %{ "movzwl  $dst, $mem\t# ushort/char" %}
   26.19    opcode(0x0F, 0xB7);
   26.20    ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
   26.21    ins_pipe(ialu_reg_mem);
   26.22  %}
   26.23  
   26.24 -// Load Char (16 bit UNsigned) into long
   26.25 -// instruct loadC2L(rRegL dst, memory mem)
   26.26 +// Load Unsigned Short/Char (16 bit UNsigned) into long
   26.27 +// instruct loadUS2L(rRegL dst, memory mem)
   26.28  // %{
   26.29 -//   match(Set dst (ConvI2L (LoadC mem)));
   26.30 +//   match(Set dst (ConvI2L (LoadUS mem)));
   26.31  
   26.32  //   ins_cost(125);
   26.33 -//   format %{ "movzwl  $dst, $mem\t# char -> long" %}
   26.34 +//   format %{ "movzwl  $dst, $mem\t# ushort/char -> long" %}
   26.35  //   opcode(0x0F, 0xB7);
   26.36  //   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
   26.37  //   ins_pipe(ialu_reg_mem);
   26.38 @@ -9490,14 +9490,14 @@
   26.39  %{
   26.40    match(Set dst (AndL dst src));
   26.41  
   26.42 -  format %{ "movzbq  $dst, $src\t# long & 0xFF" %}
   26.43 +  format %{ "movzbq  $dst, $dst\t# long & 0xFF" %}
   26.44    opcode(0x0F, 0xB6);
   26.45    ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
   26.46    ins_pipe(ialu_reg);
   26.47  %}
   26.48  
   26.49  // And Register with Immediate 65535
   26.50 -instruct andL_rReg_imm65535(rRegI dst, immL_65535 src)
   26.51 +instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
   26.52  %{
   26.53    match(Set dst (AndL dst src));
   26.54  
    27.1 --- a/src/os/linux/vm/os_linux.cpp	Sat Jan 31 17:19:42 2009 -0800
    27.2 +++ b/src/os/linux/vm/os_linux.cpp	Fri Feb 27 15:13:00 2009 -0800
    27.3 @@ -279,7 +279,11 @@
    27.4   *        ...
    27.5   *        7: The default directories, normally /lib and /usr/lib.
    27.6   */
    27.7 +#if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
    27.8 +#define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
    27.9 +#else
   27.10  #define DEFAULT_LIBPATH "/lib:/usr/lib"
   27.11 +#endif
   27.12  
   27.13  #define EXTENSIONS_DIR  "/lib/ext"
   27.14  #define ENDORSED_DIR    "/lib/endorsed"
   27.15 @@ -1160,7 +1164,10 @@
   27.16  
   27.17          /*                                     1   1   1   1   1   1   1   1   1   1   2   2   2   2   2   2   2   2   2 */
   27.18          /*              3  4  5  6  7  8   9   0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8 */
   27.19 -        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu",
   27.20 +        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld "
   27.21 +                   UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT
   27.22 +                   " %lu "
   27.23 +                   UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT,
   27.24               &state,          /* 3  %c  */
   27.25               &ppid,           /* 4  %d  */
   27.26               &pgrp,           /* 5  %d  */
   27.27 @@ -1180,13 +1187,13 @@
   27.28               &nice,           /* 19 %ld  */
   27.29               &junk,           /* 20 %ld  */
   27.30               &it_real,        /* 21 %ld  */
   27.31 -             &start,          /* 22 %lu  */
   27.32 -             &vsize,          /* 23 %lu  */
   27.33 -             &rss,            /* 24 %ld  */
   27.34 +             &start,          /* 22 UINTX_FORMAT  */
   27.35 +             &vsize,          /* 23 UINTX_FORMAT  */
   27.36 +             &rss,            /* 24 UINTX_FORMAT  */
   27.37               &rsslim,         /* 25 %lu  */
   27.38 -             &scodes,         /* 26 %lu  */
   27.39 -             &ecode,          /* 27 %lu  */
   27.40 -             &stack_start);   /* 28 %lu  */
   27.41 +             &scodes,         /* 26 UINTX_FORMAT  */
   27.42 +             &ecode,          /* 27 UINTX_FORMAT  */
   27.43 +             &stack_start);   /* 28 UINTX_FORMAT  */
   27.44        }
   27.45  
   27.46        if (i != 28 - 2) {
   27.47 @@ -1425,6 +1432,10 @@
   27.48    return buf;
   27.49  }
   27.50  
   27.51 +struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
   27.52 +  return localtime_r(clock, res);
   27.53 +}
   27.54 +
   27.55  ////////////////////////////////////////////////////////////////////////////////
   27.56  // runtime exit support
   27.57  
   27.58 @@ -2024,7 +2035,8 @@
   27.59                  CAST_FROM_FN_PTR(address, os::jvm_path),
   27.60                  dli_fname, sizeof(dli_fname), NULL);
   27.61    assert(ret != 0, "cannot locate libjvm");
   27.62 -  realpath(dli_fname, buf);
   27.63 +  if (realpath(dli_fname, buf) == NULL)
   27.64 +    return;
   27.65  
   27.66    if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
   27.67      // Support for the gamma launcher.  Typical value for buf is
   27.68 @@ -2048,7 +2060,8 @@
   27.69          assert(strstr(p, "/libjvm") == p, "invalid library name");
   27.70          p = strstr(p, "_g") ? "_g" : "";
   27.71  
   27.72 -        realpath(java_home_var, buf);
   27.73 +        if (realpath(java_home_var, buf) == NULL)
   27.74 +          return;
   27.75          sprintf(buf + strlen(buf), "/jre/lib/%s", cpu_arch);
   27.76          if (0 == access(buf, F_OK)) {
   27.77            // Use current module name "libjvm[_g].so" instead of
   27.78 @@ -2059,7 +2072,8 @@
   27.79            sprintf(buf + strlen(buf), "/hotspot/libjvm%s.so", p);
   27.80          } else {
   27.81            // Go back to path of .so
   27.82 -          realpath(dli_fname, buf);
   27.83 +          if (realpath(dli_fname, buf) == NULL)
   27.84 +            return;
   27.85          }
   27.86        }
   27.87      }
   27.88 @@ -4184,11 +4198,11 @@
   27.89    // Skip blank chars
   27.90    do s++; while (isspace(*s));
   27.91  
   27.92 -  count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
   27.93 -                 &idummy, &idummy, &idummy, &idummy, &idummy, &idummy,
   27.94 +  count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
   27.95 +                 &idummy, &idummy, &idummy, &idummy, &idummy,
   27.96                   &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
   27.97                   &user_time, &sys_time);
   27.98 -  if ( count != 13 ) return -1;
   27.99 +  if ( count != 12 ) return -1;
  27.100    if (user_sys_cpu_time) {
  27.101      return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
  27.102    } else {
    28.1 --- a/src/os/solaris/vm/os_solaris.cpp	Sat Jan 31 17:19:42 2009 -0800
    28.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Fri Feb 27 15:13:00 2009 -0800
    28.3 @@ -323,6 +323,10 @@
    28.4    return (size_t)(base - bottom);
    28.5  }
    28.6  
    28.7 +struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
    28.8 +  return localtime_r(clock, res);
    28.9 +}
   28.10 +
   28.11  // interruptible infrastructure
   28.12  
   28.13  // setup_interruptible saves the thread state before going into an
    29.1 --- a/src/os/windows/vm/os_windows.cpp	Sat Jan 31 17:19:42 2009 -0800
    29.2 +++ b/src/os/windows/vm/os_windows.cpp	Fri Feb 27 15:13:00 2009 -0800
    29.3 @@ -327,6 +327,14 @@
    29.4    return sz;
    29.5  }
    29.6  
    29.7 +struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
    29.8 +  const struct tm* time_struct_ptr = localtime(clock);
    29.9 +  if (time_struct_ptr != NULL) {
   29.10 +    *res = *time_struct_ptr;
   29.11 +    return res;
   29.12 +  }
   29.13 +  return NULL;
   29.14 +}
   29.15  
   29.16  LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
   29.17  
    30.1 --- a/src/share/vm/adlc/dict2.cpp	Sat Jan 31 17:19:42 2009 -0800
    30.2 +++ b/src/share/vm/adlc/dict2.cpp	Fri Feb 27 15:13:00 2009 -0800
    30.3 @@ -316,9 +316,12 @@
    30.4    return strcmp((const char *)k1,(const char *)k2);
    30.5  }
    30.6  
    30.7 -// Slimey cheap key comparator.
    30.8 +// Cheap key comparator.
    30.9  int cmpkey(const void *key1, const void *key2) {
   30.10 -  return (int)((intptr_t)key1 - (intptr_t)key2);
   30.11 +  if (key1 == key2) return 0;
   30.12 +  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
   30.13 +  if (delta > 0) return 1;
   30.14 +  return -1;
   30.15  }
   30.16  
   30.17  //=============================================================================
    31.1 --- a/src/share/vm/adlc/forms.cpp	Sat Jan 31 17:19:42 2009 -0800
    31.2 +++ b/src/share/vm/adlc/forms.cpp	Fri Feb 27 15:13:00 2009 -0800
    31.3 @@ -248,7 +248,7 @@
    31.4  // True if 'opType', an ideal name, loads or stores.
    31.5  Form::DataType Form::is_load_from_memory(const char *opType) const {
    31.6    if( strcmp(opType,"LoadB")==0 )  return Form::idealB;
    31.7 -  if( strcmp(opType,"LoadC")==0 )  return Form::idealC;
    31.8 +  if( strcmp(opType,"LoadUS")==0 )  return Form::idealC;
    31.9    if( strcmp(opType,"LoadD")==0 )  return Form::idealD;
   31.10    if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
   31.11    if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
    32.1 --- a/src/share/vm/adlc/formssel.cpp	Sat Jan 31 17:19:42 2009 -0800
    32.2 +++ b/src/share/vm/adlc/formssel.cpp	Fri Feb 27 15:13:00 2009 -0800
    32.3 @@ -3314,7 +3314,7 @@
    32.4      "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
    32.5      "StoreB","StoreC","Store" ,"StoreFP",
    32.6      "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
    32.7 -    "LoadB" ,"LoadC" ,"LoadS" ,"Load"   ,
    32.8 +    "LoadB" ,"LoadUS" ,"LoadS" ,"Load"   ,
    32.9      "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
   32.10      "Store8B","Store4B","Store8C","Store4C","Store2C",
   32.11      "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
    33.1 --- a/src/share/vm/asm/codeBuffer.cpp	Sat Jan 31 17:19:42 2009 -0800
    33.2 +++ b/src/share/vm/asm/codeBuffer.cpp	Fri Feb 27 15:13:00 2009 -0800
    33.3 @@ -123,6 +123,10 @@
    33.4      // addresses constructed before expansions will not be confused.
    33.5      cb->free_blob();
    33.6    }
    33.7 +
    33.8 +  // free any overflow storage
    33.9 +  delete _overflow_arena;
   33.10 +
   33.11  #ifdef ASSERT
   33.12    Copy::fill_to_bytes(this, sizeof(*this), badResourceValue);
   33.13  #endif
    34.1 --- a/src/share/vm/classfile/classFileParser.cpp	Sat Jan 31 17:19:42 2009 -0800
    34.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Fri Feb 27 15:13:00 2009 -0800
    34.3 @@ -232,7 +232,9 @@
    34.4      length >= 1, "Illegal constant pool size %u in class file %s",
    34.5      length, CHECK_(nullHandle));
    34.6    constantPoolOop constant_pool =
    34.7 -                      oopFactory::new_constantPool(length, CHECK_(nullHandle));
    34.8 +                      oopFactory::new_constantPool(length,
    34.9 +                                                   methodOopDesc::IsSafeConc,
   34.10 +                                                   CHECK_(nullHandle));
   34.11    constantPoolHandle cp (THREAD, constant_pool);
   34.12  
   34.13    cp->set_partially_loaded();    // Enables heap verify to work on partial constantPoolOops
   34.14 @@ -1675,7 +1677,8 @@
   34.15    // All sizing information for a methodOop is finally available, now create it
   34.16    methodOop m_oop  = oopFactory::new_method(
   34.17      code_length, access_flags, linenumber_table_length,
   34.18 -    total_lvt_length, checked_exceptions_length, CHECK_(nullHandle));
   34.19 +    total_lvt_length, checked_exceptions_length,
   34.20 +    methodOopDesc::IsSafeConc, CHECK_(nullHandle));
   34.21    methodHandle m (THREAD, m_oop);
   34.22  
   34.23    ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
    35.1 --- a/src/share/vm/classfile/javaClasses.cpp	Sat Jan 31 17:19:42 2009 -0800
    35.2 +++ b/src/share/vm/classfile/javaClasses.cpp	Fri Feb 27 15:13:00 2009 -0800
    35.3 @@ -441,6 +441,7 @@
    35.4  
    35.5  bool java_lang_Class::offsets_computed = false;
    35.6  int  java_lang_Class::classRedefinedCount_offset = -1;
    35.7 +int  java_lang_Class::parallelCapable_offset = -1;
    35.8  
    35.9  void java_lang_Class::compute_offsets() {
   35.10    assert(!offsets_computed, "offsets should be initialized only once");
   35.11 @@ -451,6 +452,23 @@
   35.12    // so don't go fatal.
   35.13    compute_optional_offset(classRedefinedCount_offset,
   35.14      k, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
   35.15 +
   35.16 +  // The field indicating parallelCapable (parallelLockMap) is only present starting in 7,
   35.17 +  klassOop k1 = SystemDictionary::classloader_klass();
   35.18 +  compute_optional_offset(parallelCapable_offset,
   35.19 +    k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
   35.20 +}
   35.21 +
   35.22 +// For class loader classes, parallelCapable defined
   35.23 +// based on non-null field
   35.24 +// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
   35.25 +bool java_lang_Class::parallelCapable(oop class_loader) {
   35.26 +  if (!JDK_Version::is_gte_jdk17x_version()
   35.27 +     || parallelCapable_offset == -1) {
   35.28 +     // Default for backward compatibility is false
   35.29 +     return false;
   35.30 +  }
   35.31 +  return (class_loader->obj_field(parallelCapable_offset) != NULL);
   35.32  }
   35.33  
   35.34  int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
   35.35 @@ -866,7 +884,7 @@
   35.36      }
   35.37      nmethod* nm = method->code();
   35.38      if (WizardMode && nm != NULL) {
   35.39 -      sprintf(buf + (int)strlen(buf), "(nmethod %#x)", nm);
   35.40 +      sprintf(buf + (int)strlen(buf), "(nmethod " PTR_FORMAT ")", (intptr_t)nm);
   35.41      }
   35.42    }
   35.43  
    36.1 --- a/src/share/vm/classfile/javaClasses.hpp	Sat Jan 31 17:19:42 2009 -0800
    36.2 +++ b/src/share/vm/classfile/javaClasses.hpp	Fri Feb 27 15:13:00 2009 -0800
    36.3 @@ -141,6 +141,7 @@
    36.4    static void compute_offsets();
    36.5    static bool offsets_computed;
    36.6    static int classRedefinedCount_offset;
    36.7 +  static int parallelCapable_offset;
    36.8  
    36.9   public:
   36.10    // Instance creation
   36.11 @@ -168,6 +169,8 @@
   36.12    // Support for classRedefinedCount field
   36.13    static int classRedefinedCount(oop the_class_mirror);
   36.14    static void set_classRedefinedCount(oop the_class_mirror, int value);
   36.15 +  // Support for parallelCapable field
   36.16 +  static bool parallelCapable(oop the_class_mirror);
   36.17    // Debugging
   36.18    friend class JavaClasses;
   36.19    friend class instanceKlass;   // verification code accesses offsets
    37.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Sat Jan 31 17:19:42 2009 -0800
    37.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Fri Feb 27 15:13:00 2009 -0800
    37.3 @@ -90,6 +90,14 @@
    37.4  #endif
    37.5  
    37.6  // ----------------------------------------------------------------------------
    37.7 +// Parallel class loading check
    37.8 +
    37.9 +bool SystemDictionary::is_parallelCapable(Handle class_loader) {
   37.10 +  if (UnsyncloadClass || class_loader.is_null()) return true;
   37.11 +  if (AlwaysLockClassLoader) return false;
   37.12 +  return java_lang_Class::parallelCapable(class_loader());
   37.13 +}
   37.14 +// ----------------------------------------------------------------------------
   37.15  // Resolving of classes
   37.16  
   37.17  // Forwards to resolve_or_null
   37.18 @@ -196,7 +204,8 @@
   37.19  // super-class callers:
   37.20  //   ClassFileParser - for defineClass & jvmtiRedefineClasses
   37.21  //   load_shared_class - while loading a class from shared archive
   37.22 -//   resolve_instance_class_or_fail:
   37.23 +//   resolve_instance_class_or_null:
   37.24 +//     via: handle_parallel_super_load
   37.25  //      when resolving a class that has an existing placeholder with
   37.26  //      a saved superclass [i.e. a defineClass is currently in progress]
   37.27  //      if another thread is trying to resolve the class, it must do
   37.28 @@ -283,12 +292,9 @@
   37.29        if (probe && probe->check_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER)) {
   37.30            throw_circularity_error = true;
   37.31        }
   37.32 -
   37.33 -      // add placeholder entry even if error - callers will remove on error
   37.34 +    }
   37.35 +    if (!throw_circularity_error) {
   37.36        PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, child_name, class_loader, PlaceholderTable::LOAD_SUPER, class_name, THREAD);
   37.37 -      if (throw_circularity_error) {
   37.38 -         newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER);
   37.39 -      }
   37.40      }
   37.41    }
   37.42    if (throw_circularity_error) {
   37.43 @@ -325,7 +331,6 @@
   37.44    return superk_h();
   37.45  }
   37.46  
   37.47 -
   37.48  void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
   37.49                                                    Handle class_loader,
   37.50                                                    Handle protection_domain,
   37.51 @@ -421,7 +426,7 @@
   37.52    bool calledholdinglock
   37.53        = ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject);
   37.54    assert(calledholdinglock,"must hold lock for notify");
   37.55 -  assert(!UnsyncloadClass, "unexpected double_lock_wait");
   37.56 +  assert((!(lockObject() == _system_loader_lock_obj) && !is_parallelCapable(lockObject)), "unexpected double_lock_wait");
   37.57    ObjectSynchronizer::notifyall(lockObject, THREAD);
   37.58    intptr_t recursions =  ObjectSynchronizer::complete_exit(lockObject, THREAD);
   37.59    SystemDictionary_lock->wait();
   37.60 @@ -439,7 +444,7 @@
   37.61  // even in non-circularity situations.
   37.62  // Note: only one thread can define the class, but multiple can resolve
   37.63  // Note: must call resolve_super_or_fail even if null super -
   37.64 -// to force placeholder entry creation for this class
   37.65 +// to force placeholder entry creation for this class for circularity detection
   37.66  // Caller must check for pending exception
   37.67  // Returns non-null klassOop if other thread has completed load
   37.68  // and we are done,
   37.69 @@ -477,9 +482,9 @@
   37.70      SystemDictionary_lock->notify_all();
   37.71    }
   37.72  
   37.73 -  // UnsyncloadClass does NOT wait for parallel superclass loads to complete
   37.74 -  // Bootstrap classloader does wait for parallel superclass loads
   37.75 - if (UnsyncloadClass) {
   37.76 +  // parallelCapable class loaders do NOT wait for parallel superclass loads to complete
   37.77 +  // Serial class loaders and bootstrap classloader do wait for superclass loads
   37.78 + if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
   37.79      MutexLocker mu(SystemDictionary_lock, THREAD);
   37.80      // Check if classloading completed while we were loading superclass or waiting
   37.81      klassOop check = find_class(d_index, d_hash, name, class_loader);
   37.82 @@ -566,10 +571,10 @@
   37.83    // This lock must be acquired here so the waiter will find
   37.84    // any successful result in the SystemDictionary and not attempt
   37.85    // the define
   37.86 -  // Classloaders that support parallelism, e.g. bootstrap classloader,
   37.87 +  // ParallelCapable Classloaders and the bootstrap classloader,
   37.88    // or all classloaders with UnsyncloadClass do not acquire lock here
   37.89    bool DoObjectLock = true;
   37.90 -  if (UnsyncloadClass || (class_loader.is_null())) {
   37.91 +  if (is_parallelCapable(class_loader)) {
   37.92      DoObjectLock = false;
   37.93    }
   37.94  
   37.95 @@ -627,6 +632,9 @@
   37.96      // Five cases:
   37.97      // All cases need to prevent modifying bootclasssearchpath
   37.98      // in parallel with a classload of same classname
   37.99 +    // Redefineclasses uses existence of the placeholder for the duration
  37.100 +    // of the class load to prevent concurrent redefinition of not completely
  37.101 +    // defined classes.
  37.102      // case 1. traditional classloaders that rely on the classloader object lock
  37.103      //   - no other need for LOAD_INSTANCE
  37.104      // case 2. traditional classloaders that break the classloader object lock
  37.105 @@ -642,12 +650,13 @@
  37.106      //    This classloader supports parallelism at the classloader level,
  37.107      //    but only allows a single load of a class/classloader pair.
  37.108      //    No performance benefit and no deadlock issues.
  37.109 -    // case 5. Future: parallel user level classloaders - without objectLocker
  37.110 +    // case 5. parallelCapable user level classloaders - without objectLocker
  37.111 +    //    Allow parallel classloading of a class/classloader pair
  37.112      symbolHandle nullsymbolHandle;
  37.113      bool throw_circularity_error = false;
  37.114      {
  37.115        MutexLocker mu(SystemDictionary_lock, THREAD);
  37.116 -      if (!UnsyncloadClass) {
  37.117 +      if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
  37.118          PlaceholderEntry* oldprobe = placeholders()->get_entry(p_index, p_hash, name, class_loader);
  37.119          if (oldprobe) {
  37.120            // only need check_seen_thread once, not on each loop
  37.121 @@ -681,25 +690,25 @@
  37.122          }
  37.123        }
  37.124        // All cases: add LOAD_INSTANCE
  37.125 -      // case 3: UnsyncloadClass: allow competing threads to try
  37.126 +      // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
  37.127        // LOAD_INSTANCE in parallel
  37.128        // add placeholder entry even if error - callers will remove on error
  37.129 -      if (!class_has_been_loaded) {
  37.130 +      if (!throw_circularity_error && !class_has_been_loaded) {
  37.131          PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, class_loader, PlaceholderTable::LOAD_INSTANCE, nullsymbolHandle, THREAD);
  37.132 -        if (throw_circularity_error) {
  37.133 -          newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
  37.134 -        }
  37.135          // For class loaders that do not acquire the classloader object lock,
  37.136          // if they did not catch another thread holding LOAD_INSTANCE,
  37.137          // need a check analogous to the acquire ObjectLocker/find_class
  37.138          // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
  37.139          // one final check if the load has already completed
  37.140 +        // class loaders holding the ObjectLock shouldn't find the class here
  37.141          klassOop check = find_class(d_index, d_hash, name, class_loader);
  37.142          if (check != NULL) {
  37.143          // Klass is already loaded, so just return it
  37.144            k = instanceKlassHandle(THREAD, check);
  37.145            class_has_been_loaded = true;
  37.146            newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
  37.147 +          placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD);
  37.148 +          SystemDictionary_lock->notify_all();
  37.149          }
  37.150        }
  37.151      }
  37.152 @@ -714,18 +723,14 @@
  37.153        // Do actual loading
  37.154        k = load_instance_class(name, class_loader, THREAD);
  37.155  
  37.156 -      // In custom class loaders, the usual findClass calls
  37.157 -      // findLoadedClass, which directly searches  the SystemDictionary, then
  37.158 -      // defineClass. If these are not atomic with respect to other threads,
  37.159 -      // the findLoadedClass can fail, but the defineClass can get a
  37.160 -      // LinkageError:: duplicate class definition.
  37.161 +      // For UnsyncloadClass and AllowParallelDefineClass only:
  37.162        // If they got a linkageError, check if a parallel class load succeeded.
  37.163        // If it did, then for bytecode resolution the specification requires
  37.164        // that we return the same result we did for the other thread, i.e. the
  37.165        // successfully loaded instanceKlass
  37.166 -      // Note: Class can not be unloaded as long as any classloader refs exist
  37.167        // Should not get here for classloaders that support parallelism
  37.168 -      // with the new cleaner mechanism, e.g. bootstrap classloader
  37.169 +      // with the new cleaner mechanism
  37.170 +      // Bootstrap goes through here to allow for an extra guarantee check
  37.171        if (UnsyncloadClass || (class_loader.is_null())) {
  37.172          if (k.is_null() && HAS_PENDING_EXCEPTION
  37.173            && PENDING_EXCEPTION->is_a(SystemDictionary::linkageError_klass())) {
  37.174 @@ -841,6 +846,12 @@
  37.175                                  Handle protection_domain,
  37.176                                  TRAPS) {
  37.177  
  37.178 +  // UseNewReflection
  37.179 +  // The result of this call should be consistent with the result
  37.180 +  // of the call to resolve_instance_class_or_null().
  37.181 +  // See evaluation 6790209 and 4474172 for more details.
  37.182 +  class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
  37.183 +
  37.184    unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
  37.185    int d_index = dictionary()->hash_to_index(d_hash);
  37.186  
  37.187 @@ -955,10 +966,10 @@
  37.188    instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
  37.189                                                               class_loader,
  37.190                                                               protection_domain,
  37.191 -                                                             cp_patches,
  37.192                                                               parsed_name,
  37.193                                                               THREAD);
  37.194  
  37.195 +
  37.196    // We don't redefine the class, so we just need to clean up whether there
  37.197    // was an error or not (don't want to modify any system dictionary
  37.198    // data structures).
  37.199 @@ -1013,11 +1024,17 @@
  37.200                                                 ClassFileStream* st,
  37.201                                                 TRAPS) {
  37.202  
  37.203 -  // Make sure we are synchronized on the class loader before we initiate
  37.204 -  // loading.
  37.205 +  // Classloaders that support parallelism, e.g. bootstrap classloader,
  37.206 +  // or all classloaders with UnsyncloadClass do not acquire lock here
  37.207 +  bool DoObjectLock = true;
  37.208 +  if (is_parallelCapable(class_loader)) {
  37.209 +    DoObjectLock = false;
  37.210 +  }
  37.211 +
  37.212 +  // Make sure we are synchronized on the class loader before we proceed
  37.213    Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
  37.214    check_loader_lock_contention(lockObject, THREAD);
  37.215 -  ObjectLocker ol(lockObject, THREAD);
  37.216 +  ObjectLocker ol(lockObject, THREAD, DoObjectLock);
  37.217  
  37.218    symbolHandle parsed_name;
  37.219  
  37.220 @@ -1069,7 +1086,13 @@
  37.221             "external class name format used internally");
  37.222  
  37.223      // Add class just loaded
  37.224 -    define_instance_class(k, THREAD);
  37.225 +    // If a class loader supports parallel classloading handle parallel define requests
  37.226 +    // find_or_define_instance_class may return a different instanceKlass
  37.227 +    if (is_parallelCapable(class_loader)) {
  37.228 +      k = find_or_define_instance_class(class_name, class_loader, k, THREAD);
  37.229 +    } else {
  37.230 +      define_instance_class(k, THREAD);
  37.231 +    }
  37.232    }
  37.233  
  37.234    // If parsing the class file or define_instance_class failed, we
  37.235 @@ -1299,7 +1322,7 @@
  37.236      }
  37.237  #endif // KERNEL
  37.238  
  37.239 -    // find_or_define_instance_class may return a different k
  37.240 +    // find_or_define_instance_class may return a different instanceKlass
  37.241      if (!k.is_null()) {
  37.242        k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
  37.243      }
  37.244 @@ -1316,14 +1339,24 @@
  37.245  
  37.246      KlassHandle spec_klass (THREAD, SystemDictionary::classloader_klass());
  37.247  
  37.248 -    // UnsyncloadClass option means don't synchronize loadClass() calls.
  37.249 -    // loadClassInternal() is synchronized and public loadClass(String) is not.
  37.250 -    // This flag is for diagnostic purposes only. It is risky to call
  37.251 +    // Call public unsynchronized loadClass(String) directly for all class loaders
  37.252 +    // for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
  37.253 +    // acquire a class-name based lock rather than the class loader object lock.
  37.254 +    // JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
  37.255 +    // so the call to loadClassInternal() was not required.
  37.256 +    //
  37.257 +    // UnsyncloadClass flag means both call loadClass(String) and do
  37.258 +    // not acquire the class loader lock even for class loaders that are
  37.259 +    // not parallelCapable. This was a risky transitional
  37.260 +    // flag for diagnostic purposes only. It is risky to call
  37.261      // custom class loaders without synchronization.
  37.262      // WARNING If a custom class loader does NOT synchronizer findClass, or callers of
  37.263 -    // findClass, this flag risks unexpected timing bugs in the field.
  37.264 +    // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field.
  37.265      // Do NOT assume this will be supported in future releases.
  37.266 -    if (!UnsyncloadClass && has_loadClassInternal()) {
  37.267 +    //
  37.268 +    // Added MustCallLoadClassInternal in case we discover in the field
  37.269 +    // a customer that counts on this call
  37.270 +    if (MustCallLoadClassInternal && has_loadClassInternal()) {
  37.271        JavaCalls::call_special(&result,
  37.272                                class_loader,
  37.273                                spec_klass,
  37.274 @@ -1365,14 +1398,17 @@
  37.275  
  37.276    Handle class_loader_h(THREAD, k->class_loader());
  37.277  
  37.278 -  // for bootstrap classloader don't acquire lock
  37.279 -  if (!class_loader_h.is_null()) {
  37.280 + // for bootstrap and other parallel classloaders don't acquire lock,
  37.281 + // use placeholder token
  37.282 + // If a parallelCapable class loader calls define_instance_class instead of
  37.283 + // find_or_define_instance_class to get here, we have a timing
  37.284 + // hole with systemDictionary updates and check_constraints
  37.285 + if (!class_loader_h.is_null() && !is_parallelCapable(class_loader_h)) {
  37.286      assert(ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD,
  37.287           compute_loader_lock_object(class_loader_h, THREAD)),
  37.288           "define called without lock");
  37.289    }
  37.290  
  37.291 -
  37.292    // Check class-loading constraints. Throw exception if violation is detected.
  37.293    // Grabs and releases SystemDictionary_lock
  37.294    // The check_constraints/find_class call and update_dictionary sequence
  37.295 @@ -1427,59 +1463,63 @@
  37.296  
  37.297  // Support parallel classloading
  37.298  // Initial implementation for bootstrap classloader
  37.299 -// For future:
  37.300  // For custom class loaders that support parallel classloading,
  37.301 -// in case they do not synchronize around
  37.302 -// FindLoadedClass/DefineClass calls, we check for parallel
  37.303 +// With AllowParallelDefine flag==true, in case they do not synchronize around
  37.304 +// FindLoadedClass/DefineClass, calls, we check for parallel
  37.305  // loading for them, wait if a defineClass is in progress
  37.306  // and return the initial requestor's results
  37.307 +// With AllowParallelDefine flag==false, call through to define_instance_class
  37.308 +// which will throw LinkageError: duplicate class definition.
  37.309  // For better performance, the class loaders should synchronize
  37.310 -// findClass(), i.e. FindLoadedClass/DefineClass or they
  37.311 +// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
  37.312  // potentially waste time reading and parsing the bytestream.
  37.313  // Note: VM callers should ensure consistency of k/class_name,class_loader
  37.314  instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle class_name, Handle class_loader, instanceKlassHandle k, TRAPS) {
  37.315  
  37.316    instanceKlassHandle nh = instanceKlassHandle(); // null Handle
  37.317 +  symbolHandle name_h(THREAD, k->name()); // passed in class_name may be null
  37.318  
  37.319 -  unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
  37.320 +  unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader);
  37.321    int d_index = dictionary()->hash_to_index(d_hash);
  37.322  
  37.323  // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
  37.324 -  unsigned int p_hash = placeholders()->compute_hash(class_name, class_loader);
  37.325 +  unsigned int p_hash = placeholders()->compute_hash(name_h, class_loader);
  37.326    int p_index = placeholders()->hash_to_index(p_hash);
  37.327    PlaceholderEntry* probe;
  37.328  
  37.329    {
  37.330      MutexLocker mu(SystemDictionary_lock, THREAD);
  37.331      // First check if class already defined
  37.332 -    klassOop check = find_class(d_index, d_hash, class_name, class_loader);
  37.333 +    klassOop check = find_class(d_index, d_hash, name_h, class_loader);
  37.334      if (check != NULL) {
  37.335        return(instanceKlassHandle(THREAD, check));
  37.336      }
  37.337  
  37.338      // Acquire define token for this class/classloader
  37.339      symbolHandle nullsymbolHandle;
  37.340 -    probe = placeholders()->find_and_add(p_index, p_hash, class_name, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD);
  37.341 -    // Check if another thread defining in parallel
  37.342 -    if (probe->definer() == NULL) {
  37.343 -      // Thread will define the class
  37.344 +    probe = placeholders()->find_and_add(p_index, p_hash, name_h, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD);
  37.345 +    // Wait if another thread defining in parallel
  37.346 +    // All threads wait - even those that will throw duplicate class: otherwise
  37.347 +    // caller is surprised by LinkageError: duplicate, but findLoadedClass fails
  37.348 +    // if other thread has not finished updating dictionary
  37.349 +    while (probe->definer() != NULL) {
  37.350 +      SystemDictionary_lock->wait();
  37.351 +    }
  37.352 +    // Only special cases allow parallel defines and can use other thread's results
  37.353 +    // Other cases fall through, and may run into duplicate defines
  37.354 +    // caught by finding an entry in the SystemDictionary
  37.355 +    if ((UnsyncloadClass || AllowParallelDefineClass) && (probe->instanceKlass() != NULL)) {
  37.356 +        probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
  37.357 +        placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
  37.358 +        SystemDictionary_lock->notify_all();
  37.359 +#ifdef ASSERT
  37.360 +        klassOop check = find_class(d_index, d_hash, name_h, class_loader);
  37.361 +        assert(check != NULL, "definer missed recording success");
  37.362 +#endif
  37.363 +        return(instanceKlassHandle(THREAD, probe->instanceKlass()));
  37.364 +    } else {
  37.365 +      // This thread will define the class (even if earlier thread tried and had an error)
  37.366        probe->set_definer(THREAD);
  37.367 -    } else {
  37.368 -      // Wait for defining thread to finish and return results
  37.369 -      while (probe->definer() != NULL) {
  37.370 -        SystemDictionary_lock->wait();
  37.371 -      }
  37.372 -      if (probe->instanceKlass() != NULL) {
  37.373 -        probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
  37.374 -        return(instanceKlassHandle(THREAD, probe->instanceKlass()));
  37.375 -      } else {
  37.376 -        // If definer had an error, try again as any new thread would
  37.377 -        probe->set_definer(THREAD);
  37.378 -#ifdef ASSERT
  37.379 -        klassOop check = find_class(d_index, d_hash, class_name, class_loader);
  37.380 -        assert(check == NULL, "definer missed recording success");
  37.381 -#endif
  37.382 -      }
  37.383      }
  37.384    }
  37.385  
  37.386 @@ -1490,7 +1530,7 @@
  37.387    // definer must notify any waiting threads
  37.388    {
  37.389      MutexLocker mu(SystemDictionary_lock, THREAD);
  37.390 -    PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, class_name, class_loader);
  37.391 +    PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name_h, class_loader);
  37.392      assert(probe != NULL, "DEFINE_CLASS placeholder lost?");
  37.393      if (probe != NULL) {
  37.394        if (HAS_PENDING_EXCEPTION) {
  37.395 @@ -1501,6 +1541,7 @@
  37.396        }
  37.397        probe->set_definer(NULL);
  37.398        probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
  37.399 +      placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
  37.400        SystemDictionary_lock->notify_all();
  37.401      }
  37.402    }
  37.403 @@ -1512,7 +1553,6 @@
  37.404  
  37.405    return k;
  37.406  }
  37.407 -
  37.408  Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) {
  37.409    // If class_loader is NULL we synchronize on _system_loader_lock_obj
  37.410    if (class_loader.is_null()) {
  37.411 @@ -1902,11 +1942,11 @@
  37.412      warning("Cannot find sun/jkernel/DownloadManager");
  37.413    }
  37.414  #endif // KERNEL
  37.415 +
  37.416    { // Compute whether we should use loadClass or loadClassInternal when loading classes.
  37.417      methodOop method = instanceKlass::cast(classloader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
  37.418      _has_loadClassInternal = (method != NULL);
  37.419    }
  37.420 -
  37.421    { // Compute whether we should use checkPackageAccess or NOT
  37.422      methodOop method = instanceKlass::cast(classloader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature());
  37.423      _has_checkPackageAccess = (method != NULL);
    38.1 --- a/src/share/vm/classfile/systemDictionary.hpp	Sat Jan 31 17:19:42 2009 -0800
    38.2 +++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Feb 27 15:13:00 2009 -0800
    38.3 @@ -526,6 +526,7 @@
    38.4    static instanceKlassHandle load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS);
    38.5    static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
    38.6    static void check_loader_lock_contention(Handle loader_lock, TRAPS);
    38.7 +  static bool is_parallelCapable(Handle class_loader);
    38.8  
    38.9    static klassOop find_shared_class(symbolHandle class_name);
   38.10  
    39.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Sat Jan 31 17:19:42 2009 -0800
    39.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Feb 27 15:13:00 2009 -0800
    39.3 @@ -362,6 +362,7 @@
    39.4    template(class_signature,                           "Ljava/lang/Class;")                                        \
    39.5    template(string_signature,                          "Ljava/lang/String;")                                       \
    39.6    template(reference_signature,                       "Ljava/lang/ref/Reference;")                                \
    39.7 +  template(concurrenthashmap_signature,               "Ljava/util/concurrent/ConcurrentHashMap;")                 \
    39.8    /* signature symbols needed by intrinsics */                                                                    \
    39.9    VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE)            \
   39.10                                                                                                                    \
   39.11 @@ -374,6 +375,9 @@
   39.12    /* used by ClassFormatError when class name is not known yet */                                                 \
   39.13    template(unknown_class_name,                        "<Unknown>")                                                \
   39.14                                                                                                                    \
   39.15 +  /* used to identify class loaders handling parallel class loading */                                            \
   39.16 +  template(parallelCapable_name,                      "parallelLockMap;")                                         \
   39.17 +                                                                                                                  \
   39.18    /* JVM monitoring and management support */                                                                     \
   39.19    template(java_lang_StackTraceElement_array,          "[Ljava/lang/StackTraceElement;")                          \
   39.20    template(java_lang_management_ThreadState,           "java/lang/management/ThreadState")                        \
    40.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Sat Jan 31 17:19:42 2009 -0800
    40.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Feb 27 15:13:00 2009 -0800
    40.3 @@ -706,6 +706,30 @@
    40.4    }
    40.5  }
    40.6  
    40.7 +// Apply the given closure to each live object in the space
    40.8 +//   The usage of CompactibleFreeListSpace
    40.9 +// by the ConcurrentMarkSweepGeneration for concurrent GC's allows
   40.10 +// objects in the space with references to objects that are no longer
   40.11 +// valid.  For example, an object may reference another object
   40.12 +// that has already been sweep up (collected).  This method uses
   40.13 +// obj_is_alive() to determine whether it is safe to apply the closure to
   40.14 +// an object.  See obj_is_alive() for details on how liveness of an
   40.15 +// object is decided.
   40.16 +
   40.17 +void CompactibleFreeListSpace::safe_object_iterate(ObjectClosure* blk) {
   40.18 +  assert_lock_strong(freelistLock());
   40.19 +  NOT_PRODUCT(verify_objects_initialized());
   40.20 +  HeapWord *cur, *limit;
   40.21 +  size_t curSize;
   40.22 +  for (cur = bottom(), limit = end(); cur < limit;
   40.23 +       cur += curSize) {
   40.24 +    curSize = block_size(cur);
   40.25 +    if (block_is_obj(cur) && obj_is_alive(cur)) {
   40.26 +      blk->do_object(oop(cur));
   40.27 +    }
   40.28 +  }
   40.29 +}
   40.30 +
   40.31  void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr,
   40.32                                                    UpwardsObjectClosure* cl) {
   40.33    assert_locked();
   40.34 @@ -861,7 +885,9 @@
   40.35      } else {
   40.36        // must read from what 'p' points to in each loop.
   40.37        klassOop k = ((volatile oopDesc*)p)->klass_or_null();
   40.38 -      if (k != NULL && ((oopDesc*)p)->is_parsable()) {
   40.39 +      if (k != NULL &&
   40.40 +          ((oopDesc*)p)->is_parsable() &&
   40.41 +          ((oopDesc*)p)->is_conc_safe()) {
   40.42          assert(k->is_oop(), "Should really be klass oop.");
   40.43          oop o = (oop)p;
   40.44          assert(o->is_oop(), "Should be an oop");
    41.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Sat Jan 31 17:19:42 2009 -0800
    41.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Fri Feb 27 15:13:00 2009 -0800
    41.3 @@ -481,6 +481,15 @@
    41.4    void oop_iterate(OopClosure* cl);
    41.5  
    41.6    void object_iterate(ObjectClosure* blk);
    41.7 +  // Apply the closure to each object in the space whose references
    41.8 +  // point to objects in the heap.  The usage of CompactibleFreeListSpace
    41.9 +  // by the ConcurrentMarkSweepGeneration for concurrent GC's allows
   41.10 +  // objects in the space with references to objects that are no longer
   41.11 +  // valid.  For example, an object may reference another object
   41.12 +  // that has already been sweep up (collected).  This method uses
   41.13 +  // obj_is_alive() to determine whether it is safe to iterate of
   41.14 +  // an object.
   41.15 +  void safe_object_iterate(ObjectClosure* blk);
   41.16    void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
   41.17  
   41.18    // Requires that "mr" be entirely within the space.
    42.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Sat Jan 31 17:19:42 2009 -0800
    42.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Feb 27 15:13:00 2009 -0800
    42.3 @@ -3018,6 +3018,16 @@
    42.4  }
    42.5  
    42.6  void
    42.7 +ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) {
    42.8 +  if (freelistLock()->owned_by_self()) {
    42.9 +    Generation::safe_object_iterate(cl);
   42.10 +  } else {
   42.11 +    MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag);
   42.12 +    Generation::safe_object_iterate(cl);
   42.13 +  }
   42.14 +}
   42.15 +
   42.16 +void
   42.17  ConcurrentMarkSweepGeneration::pre_adjust_pointers() {
   42.18  }
   42.19  
   42.20 @@ -6623,7 +6633,11 @@
   42.21    if (_bitMap->isMarked(addr)) {
   42.22      // it's marked; is it potentially uninitialized?
   42.23      if (p->klass_or_null() != NULL) {
   42.24 -      if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) {
   42.25 +      // If is_conc_safe is false, the object may be undergoing
   42.26 +      // change by the VM outside a safepoint.  Don't try to
   42.27 +      // scan it, but rather leave it for the remark phase.
   42.28 +      if (CMSPermGenPrecleaningEnabled &&
   42.29 +          (!p->is_conc_safe() || !p->is_parsable())) {
   42.30          // Signal precleaning to redirty the card since
   42.31          // the klass pointer is already installed.
   42.32          assert(size == 0, "Initial value");
   42.33 @@ -7001,7 +7015,6 @@
   42.34        _mut->clear_range(mr);
   42.35      }
   42.36    DEBUG_ONLY(})
   42.37 -
   42.38    // Note: the finger doesn't advance while we drain
   42.39    // the stack below.
   42.40    PushOrMarkClosure pushOrMarkClosure(_collector,
   42.41 @@ -8062,9 +8075,13 @@
   42.42      #ifdef DEBUG
   42.43        if (oop(addr)->klass_or_null() != NULL &&
   42.44            (   !_collector->should_unload_classes()
   42.45 -           || oop(addr)->is_parsable())) {
   42.46 +           || (oop(addr)->is_parsable()) &&
   42.47 +               oop(addr)->is_conc_safe())) {
   42.48          // Ignore mark word because we are running concurrent with mutators
   42.49          assert(oop(addr)->is_oop(true), "live block should be an oop");
   42.50 +        // is_conc_safe is checked before performing this assertion
   42.51 +        // because an object that is not is_conc_safe may yet have
   42.52 +        // the return from size() correct.
   42.53          assert(size ==
   42.54                 CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()),
   42.55                 "P-mark and computed size do not agree");
   42.56 @@ -8077,6 +8094,13 @@
   42.57             (!_collector->should_unload_classes()
   42.58              || oop(addr)->is_parsable()),
   42.59             "Should be an initialized object");
   42.60 +    // Note that there are objects used during class redefinition
   42.61 +    // (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite()
   42.62 +    // which are discarded with their is_conc_safe state still
   42.63 +    // false.  These object may be floating garbage so may be
   42.64 +    // seen here.  If they are floating garbage their size
   42.65 +    // should be attainable from their klass.  Do not that
   42.66 +    // is_conc_safe() is true for oop(addr).
   42.67      // Ignore mark word because we are running concurrent with mutators
   42.68      assert(oop(addr)->is_oop(true), "live block should be an oop");
   42.69      // Verify that the bit map has no bits marked between
   42.70 @@ -8484,7 +8508,7 @@
   42.71    size_t i = num;
   42.72    oop  cur = _overflow_list;
   42.73    const markOop proto = markOopDesc::prototype();
   42.74 -  NOT_PRODUCT(size_t n = 0;)
   42.75 +  NOT_PRODUCT(ssize_t n = 0;)
   42.76    for (oop next; i > 0 && cur != NULL; cur = next, i--) {
   42.77      next = oop(cur->mark());
   42.78      cur->set_mark(proto);   // until proven otherwise
   42.79 @@ -8501,45 +8525,131 @@
   42.80    return !stack->isEmpty();
   42.81  }
   42.82  
   42.83 -// Multi-threaded; use CAS to break off a prefix
   42.84 +#define BUSY  (oop(0x1aff1aff))
   42.85 +// (MT-safe) Get a prefix of at most "num" from the list.
   42.86 +// The overflow list is chained through the mark word of
   42.87 +// each object in the list. We fetch the entire list,
   42.88 +// break off a prefix of the right size and return the
   42.89 +// remainder. If other threads try to take objects from
   42.90 +// the overflow list at that time, they will wait for
   42.91 +// some time to see if data becomes available. If (and
   42.92 +// only if) another thread places one or more object(s)
   42.93 +// on the global list before we have returned the suffix
   42.94 +// to the global list, we will walk down our local list
   42.95 +// to find its end and append the global list to
   42.96 +// our suffix before returning it. This suffix walk can
   42.97 +// prove to be expensive (quadratic in the amount of traffic)
   42.98 +// when there are many objects in the overflow list and
   42.99 +// there is much producer-consumer contention on the list.
  42.100 +// *NOTE*: The overflow list manipulation code here and
  42.101 +// in ParNewGeneration:: are very similar in shape,
  42.102 +// except that in the ParNew case we use the old (from/eden)
  42.103 +// copy of the object to thread the list via its klass word.
  42.104 +// Because of the common code, if you make any changes in
  42.105 +// the code below, please check the ParNew version to see if
  42.106 +// similar changes might be needed.
  42.107 +// CR 6797058 has been filed to consolidate the common code.
  42.108  bool CMSCollector::par_take_from_overflow_list(size_t num,
  42.109                                                 OopTaskQueue* work_q) {
  42.110 -  assert(work_q->size() == 0, "That's the current policy");
  42.111 +  assert(work_q->size() == 0, "First empty local work queue");
  42.112    assert(num < work_q->max_elems(), "Can't bite more than we can chew");
  42.113    if (_overflow_list == NULL) {
  42.114      return false;
  42.115    }
  42.116    // Grab the entire list; we'll put back a suffix
  42.117 -  oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list);
  42.118 -  if (prefix == NULL) {  // someone grabbed it before we did ...
  42.119 -    // ... we could spin for a short while, but for now we don't
  42.120 -    return false;
  42.121 -  }
  42.122 +  oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
  42.123 +  Thread* tid = Thread::current();
  42.124 +  size_t CMSOverflowSpinCount = (size_t)ParallelGCThreads;
  42.125 +  size_t sleep_time_millis = MAX2((size_t)1, num/100);
  42.126 +  // If the list is busy, we spin for a short while,
  42.127 +  // sleeping between attempts to get the list.
  42.128 +  for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
  42.129 +    os::sleep(tid, sleep_time_millis, false);
  42.130 +    if (_overflow_list == NULL) {
  42.131 +      // Nothing left to take
  42.132 +      return false;
  42.133 +    } else if (_overflow_list != BUSY) {
  42.134 +      // Try and grab the prefix
  42.135 +      prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
  42.136 +    }
  42.137 +  }
  42.138 +  // If the list was found to be empty, or we spun long
  42.139 +  // enough, we give up and return empty-handed. If we leave
  42.140 +  // the list in the BUSY state below, it must be the case that
  42.141 +  // some other thread holds the overflow list and will set it
  42.142 +  // to a non-BUSY state in the future.
  42.143 +  if (prefix == NULL || prefix == BUSY) {
  42.144 +     // Nothing to take or waited long enough
  42.145 +     if (prefix == NULL) {
  42.146 +       // Write back the NULL in case we overwrote it with BUSY above
  42.147 +       // and it is still the same value.
  42.148 +       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  42.149 +     }
  42.150 +     return false;
  42.151 +  }
  42.152 +  assert(prefix != NULL && prefix != BUSY, "Error");
  42.153    size_t i = num;
  42.154    oop cur = prefix;
  42.155 +  // Walk down the first "num" objects, unless we reach the end.
  42.156    for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
  42.157 -  if (cur->mark() != NULL) {
  42.158 +  if (cur->mark() == NULL) {
  42.159 +    // We have "num" or fewer elements in the list, so there
  42.160 +    // is nothing to return to the global list.
  42.161 +    // Write back the NULL in lieu of the BUSY we wrote
  42.162 +    // above, if it is still the same value.
  42.163 +    if (_overflow_list == BUSY) {
  42.164 +      (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  42.165 +    }
  42.166 +  } else {
  42.167 +    // Chop off the suffix and rerturn it to the global list.
  42.168 +    assert(cur->mark() != BUSY, "Error");
  42.169      oop suffix_head = cur->mark(); // suffix will be put back on global list
  42.170      cur->set_mark(NULL);           // break off suffix
  42.171 -    // Find tail of suffix so we can prepend suffix to global list
  42.172 -    for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
  42.173 -    oop suffix_tail = cur;
  42.174 -    assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
  42.175 -           "Tautology");
  42.176 +    // It's possible that the list is still in the empty(busy) state
  42.177 +    // we left it in a short while ago; in that case we may be
  42.178 +    // able to place back the suffix without incurring the cost
  42.179 +    // of a walk down the list.
  42.180      oop observed_overflow_list = _overflow_list;
  42.181 -    do {
  42.182 -      cur = observed_overflow_list;
  42.183 -      suffix_tail->set_mark(markOop(cur));
  42.184 +    oop cur_overflow_list = observed_overflow_list;
  42.185 +    bool attached = false;
  42.186 +    while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
  42.187        observed_overflow_list =
  42.188 -        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur);
  42.189 -    } while (cur != observed_overflow_list);
  42.190 +        (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
  42.191 +      if (cur_overflow_list == observed_overflow_list) {
  42.192 +        attached = true;
  42.193 +        break;
  42.194 +      } else cur_overflow_list = observed_overflow_list;
  42.195 +    }
  42.196 +    if (!attached) {
  42.197 +      // Too bad, someone else sneaked in (at least) an element; we'll need
  42.198 +      // to do a splice. Find tail of suffix so we can prepend suffix to global
  42.199 +      // list.
  42.200 +      for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
  42.201 +      oop suffix_tail = cur;
  42.202 +      assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
  42.203 +             "Tautology");
  42.204 +      observed_overflow_list = _overflow_list;
  42.205 +      do {
  42.206 +        cur_overflow_list = observed_overflow_list;
  42.207 +        if (cur_overflow_list != BUSY) {
  42.208 +          // Do the splice ...
  42.209 +          suffix_tail->set_mark(markOop(cur_overflow_list));
  42.210 +        } else { // cur_overflow_list == BUSY
  42.211 +          suffix_tail->set_mark(NULL);
  42.212 +        }
  42.213 +        // ... and try to place spliced list back on overflow_list ...
  42.214 +        observed_overflow_list =
  42.215 +          (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
  42.216 +      } while (cur_overflow_list != observed_overflow_list);
  42.217 +      // ... until we have succeeded in doing so.
  42.218 +    }
  42.219    }
  42.220  
  42.221    // Push the prefix elements on work_q
  42.222    assert(prefix != NULL, "control point invariant");
  42.223    const markOop proto = markOopDesc::prototype();
  42.224    oop next;
  42.225 -  NOT_PRODUCT(size_t n = 0;)
  42.226 +  NOT_PRODUCT(ssize_t n = 0;)
  42.227    for (cur = prefix; cur != NULL; cur = next) {
  42.228      next = oop(cur->mark());
  42.229      cur->set_mark(proto);   // until proven otherwise
  42.230 @@ -8573,11 +8683,16 @@
  42.231    oop cur_overflow_list;
  42.232    do {
  42.233      cur_overflow_list = observed_overflow_list;
  42.234 -    p->set_mark(markOop(cur_overflow_list));
  42.235 +    if (cur_overflow_list != BUSY) {
  42.236 +      p->set_mark(markOop(cur_overflow_list));
  42.237 +    } else {
  42.238 +      p->set_mark(NULL);
  42.239 +    }
  42.240      observed_overflow_list =
  42.241        (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
  42.242    } while (cur_overflow_list != observed_overflow_list);
  42.243  }
  42.244 +#undef BUSY
  42.245  
  42.246  // Single threaded
  42.247  // General Note on GrowableArray: pushes may silently fail
  42.248 @@ -8586,7 +8701,7 @@
  42.249  // a lot of code in the JVM. The prudent thing for GrowableArray
  42.250  // to do (for now) is to exit with an error. However, that may
  42.251  // be too draconian in some cases because the caller may be
  42.252 -// able to recover without much harm. For suych cases, we
  42.253 +// able to recover without much harm. For such cases, we
  42.254  // should probably introduce a "soft_push" method which returns
  42.255  // an indication of success or failure with the assumption that
  42.256  // the caller may be able to recover from a failure; code in
  42.257 @@ -8594,8 +8709,6 @@
  42.258  // failures where possible, thus, incrementally hardening the VM
  42.259  // in such low resource situations.
  42.260  void CMSCollector::preserve_mark_work(oop p, markOop m) {
  42.261 -  int PreserveMarkStackSize = 128;
  42.262 -
  42.263    if (_preserved_oop_stack == NULL) {
  42.264      assert(_preserved_mark_stack == NULL,
  42.265             "bijection with preserved_oop_stack");
    43.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Sat Jan 31 17:19:42 2009 -0800
    43.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Feb 27 15:13:00 2009 -0800
    43.3 @@ -595,7 +595,7 @@
    43.4    size_t        _ser_kac_preclean_ovflw;
    43.5    size_t        _ser_kac_ovflw;
    43.6    size_t        _par_kac_ovflw;
    43.7 -  NOT_PRODUCT(size_t _num_par_pushes;)
    43.8 +  NOT_PRODUCT(ssize_t _num_par_pushes;)
    43.9  
   43.10    // ("Weak") Reference processing support
   43.11    ReferenceProcessor*            _ref_processor;
   43.12 @@ -1212,6 +1212,7 @@
   43.13    // More iteration support
   43.14    virtual void oop_iterate(MemRegion mr, OopClosure* cl);
   43.15    virtual void oop_iterate(OopClosure* cl);
   43.16 +  virtual void safe_object_iterate(ObjectClosure* cl);
   43.17    virtual void object_iterate(ObjectClosure* cl);
   43.18  
   43.19    // Need to declare the full complement of closures, whether we'll
    44.1 --- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Sat Jan 31 17:19:42 2009 -0800
    44.2 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Fri Feb 27 15:13:00 2009 -0800
    44.3 @@ -24,7 +24,7 @@
    44.4  
    44.5  // We need to sort heap regions by collection desirability.
    44.6  
    44.7 -class CSetChooserCache {
    44.8 +class CSetChooserCache VALUE_OBJ_CLASS_SPEC {
    44.9  private:
   44.10    enum {
   44.11      CacheLength = 16
    45.1 --- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Sat Jan 31 17:19:42 2009 -0800
    45.2 +++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Fri Feb 27 15:13:00 2009 -0800
    45.3 @@ -33,7 +33,7 @@
    45.4    PYA_cancel     // It's been completed by somebody else: cancel.
    45.5  };
    45.6  
    45.7 -class ConcurrentG1Refine {
    45.8 +class ConcurrentG1Refine: public CHeapObj {
    45.9    ConcurrentG1RefineThread* _cg1rThread;
   45.10  
   45.11    volatile jint _pya;
    46.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Sat Jan 31 17:19:42 2009 -0800
    46.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Fri Feb 27 15:13:00 2009 -0800
    46.3 @@ -30,7 +30,7 @@
    46.4  // A generic CM bit map.  This is essentially a wrapper around the BitMap
    46.5  // class, with one bit per (1<<_shifter) HeapWords.
    46.6  
    46.7 -class CMBitMapRO {
    46.8 +class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
    46.9   protected:
   46.10    HeapWord* _bmStartWord;      // base address of range covered by map
   46.11    size_t    _bmWordSize;       // map size (in #HeapWords covered)
   46.12 @@ -139,7 +139,7 @@
   46.13  
   46.14  // Represents a marking stack used by the CM collector.
   46.15  // Ideally this should be GrowableArray<> just like MSC's marking stack(s).
   46.16 -class CMMarkStack {
   46.17 +class CMMarkStack VALUE_OBJ_CLASS_SPEC {
   46.18    ConcurrentMark* _cm;
   46.19    oop*   _base;      // bottom of stack
   46.20    jint   _index;     // one more than last occupied index
   46.21 @@ -237,7 +237,7 @@
   46.22    void oops_do(OopClosure* f);
   46.23  };
   46.24  
   46.25 -class CMRegionStack {
   46.26 +class CMRegionStack VALUE_OBJ_CLASS_SPEC {
   46.27    MemRegion* _base;
   46.28    jint _capacity;
   46.29    jint _index;
   46.30 @@ -312,7 +312,7 @@
   46.31  
   46.32  class ConcurrentMarkThread;
   46.33  
   46.34 -class ConcurrentMark {
   46.35 +class ConcurrentMark: public CHeapObj {
   46.36    friend class ConcurrentMarkThread;
   46.37    friend class CMTask;
   46.38    friend class CMBitMapClosure;
    47.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Sat Jan 31 17:19:42 2009 -0800
    47.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Feb 27 15:13:00 2009 -0800
    47.3 @@ -141,7 +141,7 @@
    47.4      _scan_only_head(NULL), _scan_only_tail(NULL), _curr_scan_only(NULL),
    47.5      _length(0), _scan_only_length(0),
    47.6      _last_sampled_rs_lengths(0),
    47.7 -    _survivor_head(NULL), _survivors_tail(NULL), _survivor_length(0)
    47.8 +    _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0)
    47.9  {
   47.10    guarantee( check_list_empty(false), "just making sure..." );
   47.11  }
   47.12 @@ -159,16 +159,15 @@
   47.13  }
   47.14  
   47.15  void YoungList::add_survivor_region(HeapRegion* hr) {
   47.16 -  assert(!hr->is_survivor(), "should not already be for survived");
   47.17 +  assert(hr->is_survivor(), "should be flagged as survivor region");
   47.18    assert(hr->get_next_young_region() == NULL, "cause it should!");
   47.19  
   47.20    hr->set_next_young_region(_survivor_head);
   47.21    if (_survivor_head == NULL) {
   47.22 -    _survivors_tail = hr;
   47.23 +    _survivor_tail = hr;
   47.24    }
   47.25    _survivor_head = hr;
   47.26  
   47.27 -  hr->set_survivor();
   47.28    ++_survivor_length;
   47.29  }
   47.30  
   47.31 @@ -239,7 +238,7 @@
   47.32  
   47.33    empty_list(_survivor_head);
   47.34    _survivor_head = NULL;
   47.35 -  _survivors_tail = NULL;
   47.36 +  _survivor_tail = NULL;
   47.37    _survivor_length = 0;
   47.38  
   47.39    _last_sampled_rs_lengths = 0;
   47.40 @@ -391,6 +390,7 @@
   47.41  
   47.42    // Add survivor regions to SurvRateGroup.
   47.43    _g1h->g1_policy()->note_start_adding_survivor_regions();
   47.44 +  _g1h->g1_policy()->finished_recalculating_age_indexes(true /* is_survivors */);
   47.45    for (HeapRegion* curr = _survivor_head;
   47.46         curr != NULL;
   47.47         curr = curr->get_next_young_region()) {
   47.48 @@ -401,7 +401,7 @@
   47.49    if (_survivor_head != NULL) {
   47.50      _head           = _survivor_head;
   47.51      _length         = _survivor_length + _scan_only_length;
   47.52 -    _survivors_tail->set_next_young_region(_scan_only_head);
   47.53 +    _survivor_tail->set_next_young_region(_scan_only_head);
   47.54    } else {
   47.55      _head           = _scan_only_head;
   47.56      _length         = _scan_only_length;
   47.57 @@ -418,9 +418,9 @@
   47.58    _curr_scan_only   = NULL;
   47.59  
   47.60    _survivor_head    = NULL;
   47.61 -  _survivors_tail   = NULL;
   47.62 +  _survivor_tail   = NULL;
   47.63    _survivor_length  = 0;
   47.64 -  _g1h->g1_policy()->finished_recalculating_age_indexes();
   47.65 +  _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */);
   47.66  
   47.67    assert(check_list_well_formed(), "young list should be well formed");
   47.68  }
   47.69 @@ -553,7 +553,7 @@
   47.70    if (_gc_alloc_region_counts[purpose] < g1_policy()->max_regions(purpose)) {
   47.71      alloc_region = newAllocRegion_work(word_size, true, zero_filled);
   47.72      if (purpose == GCAllocForSurvived && alloc_region != NULL) {
   47.73 -      _young_list->add_survivor_region(alloc_region);
   47.74 +      alloc_region->set_survivor();
   47.75      }
   47.76      ++_gc_alloc_region_counts[purpose];
   47.77    } else {
   47.78 @@ -949,6 +949,10 @@
   47.79      GCOverheadReporter::recordSTWEnd(end);
   47.80      g1_policy()->record_full_collection_end();
   47.81  
   47.82 +#ifdef TRACESPINNING
   47.83 +    ParallelTaskTerminator::print_termination_counts();
   47.84 +#endif
   47.85 +
   47.86      gc_epilogue(true);
   47.87  
   47.88      // Abandon concurrent refinement.  This must happen last: in the
   47.89 @@ -1285,7 +1289,9 @@
   47.90    _unclean_regions_coming(false),
   47.91    _young_list(new YoungList(this)),
   47.92    _gc_time_stamp(0),
   47.93 -  _surviving_young_words(NULL)
   47.94 +  _surviving_young_words(NULL),
   47.95 +  _in_cset_fast_test(NULL),
   47.96 +  _in_cset_fast_test_base(NULL)
   47.97  {
   47.98    _g1h = this; // To catch bugs.
   47.99    if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
  47.100 @@ -2485,6 +2491,19 @@
  47.101      g1_policy()->record_collection_pause_start(start_time_sec,
  47.102                                                 start_used_bytes);
  47.103  
  47.104 +    guarantee(_in_cset_fast_test == NULL, "invariant");
  47.105 +    guarantee(_in_cset_fast_test_base == NULL, "invariant");
  47.106 +    _in_cset_fast_test_length = n_regions();
  47.107 +    _in_cset_fast_test_base =
  47.108 +                             NEW_C_HEAP_ARRAY(bool, _in_cset_fast_test_length);
  47.109 +    memset(_in_cset_fast_test_base, false,
  47.110 +                                     _in_cset_fast_test_length * sizeof(bool));
  47.111 +    // We're biasing _in_cset_fast_test to avoid subtracting the
  47.112 +    // beginning of the heap every time we want to index; basically
  47.113 +    // it's the same with what we do with the card table.
  47.114 +    _in_cset_fast_test = _in_cset_fast_test_base -
  47.115 +              ((size_t) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes);
  47.116 +
  47.117  #if SCAN_ONLY_VERBOSE
  47.118      _young_list->print();
  47.119  #endif // SCAN_ONLY_VERBOSE
  47.120 @@ -2553,6 +2572,12 @@
  47.121        free_collection_set(g1_policy()->collection_set());
  47.122        g1_policy()->clear_collection_set();
  47.123  
  47.124 +      FREE_C_HEAP_ARRAY(bool, _in_cset_fast_test_base);
  47.125 +      // this is more for peace of mind; we're nulling them here and
  47.126 +      // we're expecting them to be null at the beginning of the next GC
  47.127 +      _in_cset_fast_test = NULL;
  47.128 +      _in_cset_fast_test_base = NULL;
  47.129 +
  47.130        if (popular_region != NULL) {
  47.131          // We have to wait until now, because we don't want the region to
  47.132          // be rescheduled for pop-evac during RS update.
  47.133 @@ -2572,6 +2597,9 @@
  47.134          _young_list->print();
  47.135  #endif // SCAN_ONLY_VERBOSE
  47.136  
  47.137 +        g1_policy()->record_survivor_regions(_young_list->survivor_length(),
  47.138 +                                             _young_list->first_survivor_region(),
  47.139 +                                             _young_list->last_survivor_region());
  47.140          _young_list->reset_auxilary_lists();
  47.141        }
  47.142      } else {
  47.143 @@ -2598,7 +2626,9 @@
  47.144  #endif // SCAN_ONLY_VERBOSE
  47.145  
  47.146      double end_time_sec = os::elapsedTime();
  47.147 -    g1_policy()->record_pause_time((end_time_sec - start_time_sec)*1000.0);
  47.148 +    if (!evacuation_failed()) {
  47.149 +      g1_policy()->record_pause_time((end_time_sec - start_time_sec)*1000.0);
  47.150 +    }
  47.151      GCOverheadReporter::recordSTWEnd(end_time_sec);
  47.152      g1_policy()->record_collection_pause_end(popular_region != NULL,
  47.153                                               abandoned);
  47.154 @@ -2621,8 +2651,13 @@
  47.155        }
  47.156      }
  47.157  
  47.158 -    if (mark_in_progress())
  47.159 +    if (mark_in_progress()) {
  47.160        concurrent_mark()->update_g1_committed();
  47.161 +    }
  47.162 +
  47.163 +#ifdef TRACESPINNING
  47.164 +    ParallelTaskTerminator::print_termination_counts();
  47.165 +#endif
  47.166  
  47.167      gc_epilogue(false);
  47.168    }
  47.169 @@ -2733,6 +2768,13 @@
  47.170      _gc_alloc_region_list = r->next_gc_alloc_region();
  47.171      r->set_next_gc_alloc_region(NULL);
  47.172      r->set_is_gc_alloc_region(false);
  47.173 +    if (r->is_survivor()) {
  47.174 +      if (r->is_empty()) {
  47.175 +        r->set_not_young();
  47.176 +      } else {
  47.177 +        _young_list->add_survivor_region(r);
  47.178 +      }
  47.179 +    }
  47.180      if (r->is_empty()) {
  47.181        ++_free_regions;
  47.182      }
  47.183 @@ -3129,6 +3171,20 @@
  47.184    return block;
  47.185  }
  47.186  
  47.187 +void G1CollectedHeap::retire_alloc_region(HeapRegion* alloc_region,
  47.188 +                                            bool par) {
  47.189 +  // Another thread might have obtained alloc_region for the given
  47.190 +  // purpose, and might be attempting to allocate in it, and might
  47.191 +  // succeed.  Therefore, we can't do the "finalization" stuff on the
  47.192 +  // region below until we're sure the last allocation has happened.
  47.193 +  // We ensure this by allocating the remaining space with a garbage
  47.194 +  // object.
  47.195 +  if (par) par_allocate_remaining_space(alloc_region);
  47.196 +  // Now we can do the post-GC stuff on the region.
  47.197 +  alloc_region->note_end_of_copying();
  47.198 +  g1_policy()->record_after_bytes(alloc_region->used());
  47.199 +}
  47.200 +
  47.201  HeapWord*
  47.202  G1CollectedHeap::allocate_during_gc_slow(GCAllocPurpose purpose,
  47.203                                           HeapRegion*    alloc_region,
  47.204 @@ -3146,16 +3202,7 @@
  47.205      // Otherwise, continue; this new region is empty, too.
  47.206    }
  47.207    assert(alloc_region != NULL, "We better have an allocation region");
  47.208 -  // Another thread might have obtained alloc_region for the given
  47.209 -  // purpose, and might be attempting to allocate in it, and might
  47.210 -  // succeed.  Therefore, we can't do the "finalization" stuff on the
  47.211 -  // region below until we're sure the last allocation has happened.
  47.212 -  // We ensure this by allocating the remaining space with a garbage
  47.213 -  // object.
  47.214 -  if (par) par_allocate_remaining_space(alloc_region);
  47.215 -  // Now we can do the post-GC stuff on the region.
  47.216 -  alloc_region->note_end_of_copying();
  47.217 -  g1_policy()->record_after_bytes(alloc_region->used());
  47.218 +  retire_alloc_region(alloc_region, par);
  47.219  
  47.220    if (_gc_alloc_region_counts[purpose] >= g1_policy()->max_regions(purpose)) {
  47.221      // Cannot allocate more regions for the given purpose.
  47.222 @@ -3164,7 +3211,7 @@
  47.223      if (purpose != alt_purpose) {
  47.224        HeapRegion* alt_region = _gc_alloc_regions[alt_purpose];
  47.225        // Has not the alternative region been aliased?
  47.226 -      if (alloc_region != alt_region) {
  47.227 +      if (alloc_region != alt_region && alt_region != NULL) {
  47.228          // Try to allocate in the alternative region.
  47.229          if (par) {
  47.230            block = alt_region->par_allocate(word_size);
  47.231 @@ -3173,9 +3220,10 @@
  47.232          }
  47.233          // Make an alias.
  47.234          _gc_alloc_regions[purpose] = _gc_alloc_regions[alt_purpose];
  47.235 -      }
  47.236 -      if (block != NULL) {
  47.237 -        return block;
  47.238 +        if (block != NULL) {
  47.239 +          return block;
  47.240 +        }
  47.241 +        retire_alloc_region(alt_region, par);
  47.242        }
  47.243        // Both the allocation region and the alternative one are full
  47.244        // and aliased, replace them with a new allocation region.
  47.245 @@ -3476,6 +3524,7 @@
  47.246    OverflowQueue* _overflowed_refs;
  47.247  
  47.248    G1ParGCAllocBuffer _alloc_buffers[GCAllocPurposeCount];
  47.249 +  ageTable           _age_table;
  47.250  
  47.251    size_t           _alloc_buffer_waste;
  47.252    size_t           _undo_waste;
  47.253 @@ -3517,6 +3566,7 @@
  47.254        _refs(g1h->task_queue(queue_num)),
  47.255        _hash_seed(17), _queue_num(queue_num),
  47.256        _term_attempts(0),
  47.257 +      _age_table(false),
  47.258  #if G1_DETAILED_STATS
  47.259        _pushes(0), _pops(0), _steals(0),
  47.260        _steal_attempts(0),  _overflow_pushes(0),
  47.261 @@ -3551,8 +3601,9 @@
  47.262  
  47.263    RefToScanQueue*   refs()            { return _refs;             }
  47.264    OverflowQueue*    overflowed_refs() { return _overflowed_refs;  }
  47.265 -
  47.266 -  inline G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
  47.267 +  ageTable*         age_table()       { return &_age_table;       }
  47.268 +
  47.269 +  G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
  47.270      return &_alloc_buffers[purpose];
  47.271    }
  47.272  
  47.273 @@ -3560,6 +3611,9 @@
  47.274    size_t undo_waste()                            { return _undo_waste; }
  47.275  
  47.276    void push_on_queue(oop* ref) {
  47.277 +    assert(ref != NULL, "invariant");
  47.278 +    assert(has_partial_array_mask(ref) || _g1h->obj_in_cs(*ref), "invariant");
  47.279 +
  47.280      if (!refs()->push(ref)) {
  47.281        overflowed_refs()->push(ref);
  47.282        IF_G1_DETAILED_STATS(note_overflow_push());
  47.283 @@ -3572,6 +3626,10 @@
  47.284      if (!refs()->pop_local(ref)) {
  47.285        ref = NULL;
  47.286      } else {
  47.287 +      assert(ref != NULL, "invariant");
  47.288 +      assert(has_partial_array_mask(ref) || _g1h->obj_in_cs(*ref),
  47.289 +             "invariant");
  47.290 +
  47.291        IF_G1_DETAILED_STATS(note_pop());
  47.292      }
  47.293    }
  47.294 @@ -3601,8 +3659,7 @@
  47.295  
  47.296        obj = alloc_buf->allocate(word_sz);
  47.297        assert(obj != NULL, "buffer was definitely big enough...");
  47.298 -    }
  47.299 -    else {
  47.300 +    } else {
  47.301        obj = _g1h->par_allocate_during_gc(purpose, word_sz);
  47.302      }
  47.303      return obj;
  47.304 @@ -3695,24 +3752,57 @@
  47.305      }
  47.306    }
  47.307  
  47.308 +private:
  47.309 +  void deal_with_reference(oop* ref_to_scan) {
  47.310 +    if (has_partial_array_mask(ref_to_scan)) {
  47.311 +      _partial_scan_cl->do_oop_nv(ref_to_scan);
  47.312 +    } else {
  47.313 +      // Note: we can use "raw" versions of "region_containing" because
  47.314 +      // "obj_to_scan" is definitely in the heap, and is not in a
  47.315 +      // humongous region.
  47.316 +      HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
  47.317 +      _evac_cl->set_region(r);
  47.318 +      _evac_cl->do_oop_nv(ref_to_scan);
  47.319 +    }
  47.320 +  }
  47.321 +
  47.322 +public:
  47.323    void trim_queue() {
  47.324 +    // I've replicated the loop twice, first to drain the overflow
  47.325 +    // queue, second to drain the task queue. This is better than
  47.326 +    // having a single loop, which checks both conditions and, inside
  47.327 +    // it, either pops the overflow queue or the task queue, as each
  47.328 +    // loop is tighter. Also, the decision to drain the overflow queue
  47.329 +    // first is not arbitrary, as the overflow queue is not visible
  47.330 +    // to the other workers, whereas the task queue is. So, we want to
  47.331 +    // drain the "invisible" entries first, while allowing the other
  47.332 +    // workers to potentially steal the "visible" entries.
  47.333 +
  47.334      while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) {
  47.335 -      oop *ref_to_scan = NULL;
  47.336 -      if (overflowed_refs_to_scan() == 0) {
  47.337 +      while (overflowed_refs_to_scan() > 0) {
  47.338 +        oop *ref_to_scan = NULL;
  47.339 +        pop_from_overflow_queue(ref_to_scan);
  47.340 +        assert(ref_to_scan != NULL, "invariant");
  47.341 +        // We shouldn't have pushed it on the queue if it was not
  47.342 +        // pointing into the CSet.
  47.343 +        assert(ref_to_scan != NULL, "sanity");
  47.344 +        assert(has_partial_array_mask(ref_to_scan) ||
  47.345 +                                      _g1h->obj_in_cs(*ref_to_scan), "sanity");
  47.346 +
  47.347 +        deal_with_reference(ref_to_scan);
  47.348 +      }
  47.349 +
  47.350 +      while (refs_to_scan() > 0) {
  47.351 +        oop *ref_to_scan = NULL;
  47.352          pop_from_queue(ref_to_scan);
  47.353 -      } else {
  47.354 -        pop_from_overflow_queue(ref_to_scan);
  47.355 -      }
  47.356 -      if (ref_to_scan != NULL) {
  47.357 -        if ((intptr_t)ref_to_scan & G1_PARTIAL_ARRAY_MASK) {
  47.358 -          _partial_scan_cl->do_oop_nv(ref_to_scan);
  47.359 -        } else {
  47.360 -          // Note: we can use "raw" versions of "region_containing" because
  47.361 -          // "obj_to_scan" is definitely in the heap, and is not in a
  47.362 -          // humongous region.
  47.363 -          HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan);
  47.364 -          _evac_cl->set_region(r);
  47.365 -          _evac_cl->do_oop_nv(ref_to_scan);
  47.366 +
  47.367 +        if (ref_to_scan != NULL) {
  47.368 +          // We shouldn't have pushed it on the queue if it was not
  47.369 +          // pointing into the CSet.
  47.370 +          assert(has_partial_array_mask(ref_to_scan) ||
  47.371 +                                      _g1h->obj_in_cs(*ref_to_scan), "sanity");
  47.372 +
  47.373 +          deal_with_reference(ref_to_scan);
  47.374          }
  47.375        }
  47.376      }
  47.377 @@ -3728,16 +3818,25 @@
  47.378  // Should probably be made inline and moved in g1OopClosures.inline.hpp.
  47.379  void G1ParScanClosure::do_oop_nv(oop* p) {
  47.380    oop obj = *p;
  47.381 +
  47.382    if (obj != NULL) {
  47.383 -    if (_g1->obj_in_cs(obj)) {
  47.384 -      if (obj->is_forwarded()) {
  47.385 -        *p = obj->forwardee();
  47.386 -      } else {
  47.387 -        _par_scan_state->push_on_queue(p);
  47.388 -        return;
  47.389 -      }
  47.390 +    if (_g1->in_cset_fast_test(obj)) {
  47.391 +      // We're not going to even bother checking whether the object is
  47.392 +      // already forwarded or not, as this usually causes an immediate
  47.393 +      // stall. We'll try to prefetch the object (for write, given that
  47.394 +      // we might need to install the forwarding reference) and we'll
  47.395 +      // get back to it when pop it from the queue
  47.396 +      Prefetch::write(obj->mark_addr(), 0);
  47.397 +      Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
  47.398 +
  47.399 +      // slightly paranoid test; I'm trying to catch potential
  47.400 +      // problems before we go into push_on_queue to know where the
  47.401 +      // problem is coming from
  47.402 +      assert(obj == *p, "the value of *p should not have changed");
  47.403 +      _par_scan_state->push_on_queue(p);
  47.404 +    } else {
  47.405 +      _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num());
  47.406      }
  47.407 -    _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num());
  47.408    }
  47.409  }
  47.410  
  47.411 @@ -3765,7 +3864,9 @@
  47.412            (!from_region->is_young() && young_index == 0), "invariant" );
  47.413    G1CollectorPolicy* g1p = _g1->g1_policy();
  47.414    markOop m = old->mark();
  47.415 -  GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, m->age(),
  47.416 +  int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
  47.417 +                                           : m->age();
  47.418 +  GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
  47.419                                                               word_sz);
  47.420    HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz);
  47.421    oop       obj     = oop(obj_ptr);
  47.422 @@ -3777,13 +3878,39 @@
  47.423      return _g1->handle_evacuation_failure_par(cl, old);
  47.424    }
  47.425  
  47.426 +  // We're going to allocate linearly, so might as well prefetch ahead.
  47.427 +  Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes);
  47.428 +
  47.429    oop forward_ptr = old->forward_to_atomic(obj);
  47.430    if (forward_ptr == NULL) {
  47.431      Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
  47.432 -    obj->set_mark(m);
  47.433      if (g1p->track_object_age(alloc_purpose)) {
  47.434 -      obj->incr_age();
  47.435 +      // We could simply do obj->incr_age(). However, this causes a
  47.436 +      // performance issue. obj->incr_age() will first check whether
  47.437 +      // the object has a displaced mark by checking its mark word;
  47.438 +      // getting the mark word from the new location of the object
  47.439 +      // stalls. So, given that we already have the mark word and we
  47.440 +      // are about to install it anyway, it's better to increase the
  47.441 +      // age on the mark word, when the object does not have a
  47.442 +      // displaced mark word. We're not expecting many objects to have
  47.443 +      // a displaced marked word, so that case is not optimized
  47.444 +      // further (it could be...) and we simply call obj->incr_age().
  47.445 +
  47.446 +      if (m->has_displaced_mark_helper()) {
  47.447 +        // in this case, we have to install the mark word first,
  47.448 +        // otherwise obj looks to be forwarded (the old mark word,
  47.449 +        // which contains the forward pointer, was copied)
  47.450 +        obj->set_mark(m);
  47.451 +        obj->incr_age();
  47.452 +      } else {
  47.453 +        m = m->incr_age();
  47.454 +        obj->set_mark(m);
  47.455 +      }
  47.456 +      _par_scan_state->age_table()->add(obj, word_sz);
  47.457 +    } else {
  47.458 +      obj->set_mark(m);
  47.459      }
  47.460 +
  47.461      // preserve "next" mark bit
  47.462      if (_g1->mark_in_progress() && !_g1->is_obj_ill(old)) {
  47.463        if (!use_local_bitmaps ||
  47.464 @@ -3805,9 +3932,11 @@
  47.465  
  47.466      if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
  47.467        arrayOop(old)->set_length(0);
  47.468 -      _par_scan_state->push_on_queue((oop*) ((intptr_t)old | G1_PARTIAL_ARRAY_MASK));
  47.469 +      _par_scan_state->push_on_queue(set_partial_array_mask(old));
  47.470      } else {
  47.471 -      _scanner->set_region(_g1->heap_region_containing(obj));
  47.472 +      // No point in using the slower heap_region_containing() method,
  47.473 +      // given that we know obj is in the heap.
  47.474 +      _scanner->set_region(_g1->heap_region_containing_raw(obj));
  47.475        obj->oop_iterate_backwards(_scanner);
  47.476      }
  47.477    } else {
  47.478 @@ -3817,47 +3946,55 @@
  47.479    return obj;
  47.480  }
  47.481  
  47.482 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee>
  47.483 -void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_forwardee>::do_oop_work(oop* p) {
  47.484 +template<bool do_gen_barrier, G1Barrier barrier,
  47.485 +         bool do_mark_forwardee, bool skip_cset_test>
  47.486 +void G1ParCopyClosure<do_gen_barrier, barrier,
  47.487 +                      do_mark_forwardee, skip_cset_test>::do_oop_work(oop* p) {
  47.488    oop obj = *p;
  47.489    assert(barrier != G1BarrierRS || obj != NULL,
  47.490           "Precondition: G1BarrierRS implies obj is nonNull");
  47.491  
  47.492 -  if (obj != NULL) {
  47.493 -    if (_g1->obj_in_cs(obj)) {
  47.494 +  // The only time we skip the cset test is when we're scanning
  47.495 +  // references popped from the queue. And we only push on the queue
  47.496 +  // references that we know point into the cset, so no point in
  47.497 +  // checking again. But we'll leave an assert here for peace of mind.
  47.498 +  assert(!skip_cset_test || _g1->obj_in_cs(obj), "invariant");
  47.499 +
  47.500 +  // here the null check is implicit in the cset_fast_test() test
  47.501 +  if (skip_cset_test || _g1->in_cset_fast_test(obj)) {
  47.502  #if G1_REM_SET_LOGGING
  47.503 -      gclog_or_tty->print_cr("Loc "PTR_FORMAT" contains pointer "PTR_FORMAT" into CS.",
  47.504 -                             p, (void*) obj);
  47.505 +    gclog_or_tty->print_cr("Loc "PTR_FORMAT" contains pointer "PTR_FORMAT" "
  47.506 +                           "into CS.", p, (void*) obj);
  47.507  #endif
  47.508 -      if (obj->is_forwarded()) {
  47.509 -        *p = obj->forwardee();
  47.510 -      } else {
  47.511 -        *p = copy_to_survivor_space(obj);
  47.512 -      }
  47.513 -      // When scanning the RS, we only care about objs in CS.
  47.514 -      if (barrier == G1BarrierRS) {
  47.515 -        _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num());
  47.516 -      }
  47.517 +    if (obj->is_forwarded()) {
  47.518 +      *p = obj->forwardee();
  47.519 +    } else {
  47.520 +      *p = copy_to_survivor_space(obj);
  47.521      }
  47.522 -    // When scanning moved objs, must look at all oops.
  47.523 -    if (barrier == G1BarrierEvac) {
  47.524 +    // When scanning the RS, we only care about objs in CS.
  47.525 +    if (barrier == G1BarrierRS) {
  47.526        _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num());
  47.527      }
  47.528 -
  47.529 -    if (do_gen_barrier) {
  47.530 -      par_do_barrier(p);
  47.531 -    }
  47.532 -  }
  47.533 -}
  47.534 -
  47.535 -template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p);
  47.536 -
  47.537 -template <class T> void G1ParScanPartialArrayClosure::process_array_chunk(
  47.538 +  }
  47.539 +
  47.540 +  // When scanning moved objs, must look at all oops.
  47.541 +  if (barrier == G1BarrierEvac && obj != NULL) {
  47.542 +    _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num());
  47.543 +  }
  47.544 +
  47.545 +  if (do_gen_barrier && obj != NULL) {
  47.546 +    par_do_barrier(p);
  47.547 +  }
  47.548 +}
  47.549 +
  47.550 +template void G1ParCopyClosure<false, G1BarrierEvac, false, true>::do_oop_work(oop* p);
  47.551 +
  47.552 +template<class T> void G1ParScanPartialArrayClosure::process_array_chunk(
  47.553    oop obj, int start, int end) {
  47.554    // process our set of indices (include header in first chunk)
  47.555    assert(start < end, "invariant");
  47.556    T* const base      = (T*)objArrayOop(obj)->base();
  47.557 -  T* const start_addr = base + start;
  47.558 +  T* const start_addr = (start == 0) ? (T*) obj : base + start;
  47.559    T* const end_addr   = base + end;
  47.560    MemRegion mr((HeapWord*)start_addr, (HeapWord*)end_addr);
  47.561    _scanner.set_region(_g1->heap_region_containing(obj));
  47.562 @@ -3866,7 +4003,8 @@
  47.563  
  47.564  void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) {
  47.565    assert(!UseCompressedOops, "Needs to be fixed to work with compressed oops");
  47.566 -  oop old = oop((intptr_t)p & ~G1_PARTIAL_ARRAY_MASK);
  47.567 +  assert(has_partial_array_mask(p), "invariant");
  47.568 +  oop old = clear_partial_array_mask(p);
  47.569    assert(old->is_objArray(), "must be obj array");
  47.570    assert(old->is_forwarded(), "must be forwarded");
  47.571    assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
  47.572 @@ -3884,7 +4022,7 @@
  47.573      end = start + ParGCArrayScanChunk;
  47.574      arrayOop(old)->set_length(end);
  47.575      // Push remainder.
  47.576 -    _par_scan_state->push_on_queue((oop*) ((intptr_t) old | G1_PARTIAL_ARRAY_MASK));
  47.577 +    _par_scan_state->push_on_queue(set_partial_array_mask(old));
  47.578    } else {
  47.579      // Restore length so that the heap remains parsable in
  47.580      // case of evacuation failure.
  47.581 @@ -3893,11 +4031,6 @@
  47.582  
  47.583    // process our set of indices (include header in first chunk)
  47.584    process_array_chunk<oop>(obj, start, end);
  47.585 -  oop* start_addr = start == 0 ? (oop*)obj : obj->obj_at_addr<oop>(start);
  47.586 -  oop* end_addr   = (oop*)(obj->base()) + end; // obj_at_addr(end) asserts end < length
  47.587 -  MemRegion mr((HeapWord*)start_addr, (HeapWord*)end_addr);
  47.588 -  _scanner.set_region(_g1->heap_region_containing(obj));
  47.589 -  obj->oop_iterate(&_scanner, mr);
  47.590  }
  47.591  
  47.592  int G1ScanAndBalanceClosure::_nq = 0;
  47.593 @@ -3931,6 +4064,13 @@
  47.594                            pss->hash_seed(),
  47.595                            ref_to_scan)) {
  47.596          IF_G1_DETAILED_STATS(pss->note_steal());
  47.597 +
  47.598 +        // slightly paranoid tests; I'm trying to catch potential
  47.599 +        // problems before we go into push_on_queue to know where the
  47.600 +        // problem is coming from
  47.601 +        assert(ref_to_scan != NULL, "invariant");
  47.602 +        assert(has_partial_array_mask(ref_to_scan) ||
  47.603 +                                   _g1h->obj_in_cs(*ref_to_scan), "invariant");
  47.604          pss->push_on_queue(ref_to_scan);
  47.605          continue;
  47.606        }
  47.607 @@ -3976,10 +4116,10 @@
  47.608      ResourceMark rm;
  47.609      HandleMark   hm;
  47.610  
  47.611 -    G1ParScanThreadState pss(_g1h, i);
  47.612 -    G1ParScanHeapEvacClosure     scan_evac_cl(_g1h, &pss);
  47.613 -    G1ParScanHeapEvacClosure     evac_failure_cl(_g1h, &pss);
  47.614 -    G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss);
  47.615 +    G1ParScanThreadState            pss(_g1h, i);
  47.616 +    G1ParScanHeapEvacClosure        scan_evac_cl(_g1h, &pss);
  47.617 +    G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss);
  47.618 +    G1ParScanPartialArrayClosure    partial_scan_cl(_g1h, &pss);
  47.619  
  47.620      pss.set_evac_closure(&scan_evac_cl);
  47.621      pss.set_evac_failure_closure(&evac_failure_cl);
  47.622 @@ -4024,6 +4164,9 @@
  47.623        _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
  47.624        _g1h->g1_policy()->record_termination_time(i, term_ms);
  47.625      }
  47.626 +    if (G1UseSurvivorSpace) {
  47.627 +      _g1h->g1_policy()->record_thread_age_table(pss.age_table());
  47.628 +    }
  47.629      _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
  47.630  
  47.631      // Clean up any par-expanded rem sets.
  47.632 @@ -4263,7 +4406,7 @@
  47.633    // Is this the right thing to do here?  We don't save marks
  47.634    // on individual heap regions when we allocate from
  47.635    // them in parallel, so this seems like the correct place for this.
  47.636 -  all_alloc_regions_note_end_of_copying();
  47.637 +  retire_all_alloc_regions();
  47.638    {
  47.639      G1IsAliveClosure is_alive(this);
  47.640      G1KeepAliveClosure keep_alive(this);
  47.641 @@ -4903,7 +5046,7 @@
  47.642    return no_allocs;
  47.643  }
  47.644  
  47.645 -void G1CollectedHeap::all_alloc_regions_note_end_of_copying() {
  47.646 +void G1CollectedHeap::retire_all_alloc_regions() {
  47.647    for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
  47.648      HeapRegion* r = _gc_alloc_regions[ap];
  47.649      if (r != NULL) {
  47.650 @@ -4916,8 +5059,7 @@
  47.651          }
  47.652        }
  47.653        if (!has_processed_alias) {
  47.654 -        r->note_end_of_copying();
  47.655 -        g1_policy()->record_after_bytes(r->used());
  47.656 +        retire_alloc_region(r, false /* par */);
  47.657        }
  47.658      }
  47.659    }
    48.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Sat Jan 31 17:19:42 2009 -0800
    48.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Feb 27 15:13:00 2009 -0800
    48.3 @@ -90,7 +90,7 @@
    48.4    HeapRegion* _curr_scan_only;
    48.5  
    48.6    HeapRegion* _survivor_head;
    48.7 -  HeapRegion* _survivors_tail;
    48.8 +  HeapRegion* _survivor_tail;
    48.9    size_t      _survivor_length;
   48.10  
   48.11    void          empty_list(HeapRegion* list);
   48.12 @@ -105,6 +105,7 @@
   48.13    bool          is_empty() { return _length == 0; }
   48.14    size_t        length() { return _length; }
   48.15    size_t        scan_only_length() { return _scan_only_length; }
   48.16 +  size_t        survivor_length() { return _survivor_length; }
   48.17  
   48.18    void rs_length_sampling_init();
   48.19    bool rs_length_sampling_more();
   48.20 @@ -120,6 +121,7 @@
   48.21    HeapRegion* first_region() { return _head; }
   48.22    HeapRegion* first_scan_only_region() { return _scan_only_head; }
   48.23    HeapRegion* first_survivor_region() { return _survivor_head; }
   48.24 +  HeapRegion* last_survivor_region() { return _survivor_tail; }
   48.25    HeapRegion* par_get_next_scan_only_region() {
   48.26      MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
   48.27      HeapRegion* ret = _curr_scan_only;
   48.28 @@ -219,7 +221,7 @@
   48.29    // The to-space memory regions into which objects are being copied during
   48.30    // a GC.
   48.31    HeapRegion* _gc_alloc_regions[GCAllocPurposeCount];
   48.32 -  uint _gc_alloc_region_counts[GCAllocPurposeCount];
   48.33 +  size_t _gc_alloc_region_counts[GCAllocPurposeCount];
   48.34  
   48.35    // A list of the regions that have been set to be alloc regions in the
   48.36    // current collection.
   48.37 @@ -247,6 +249,27 @@
   48.38    NumberSeq _pop_obj_rc_at_copy;
   48.39    void print_popularity_summary_info() const;
   48.40  
   48.41 +  // This is used for a quick test on whether a reference points into
   48.42 +  // the collection set or not. Basically, we have an array, with one
   48.43 +  // byte per region, and that byte denotes whether the corresponding
   48.44 +  // region is in the collection set or not. The entry corresponding
   48.45 +  // the bottom of the heap, i.e., region 0, is pointed to by
   48.46 +  // _in_cset_fast_test_base.  The _in_cset_fast_test field has been
   48.47 +  // biased so that it actually points to address 0 of the address
   48.48 +  // space, to make the test as fast as possible (we can simply shift
   48.49 +  // the address to address into it, instead of having to subtract the
   48.50 +  // bottom of the heap from the address before shifting it; basically
   48.51 +  // it works in the same way the card table works).
   48.52 +  bool* _in_cset_fast_test;
   48.53 +
   48.54 +  // The allocated array used for the fast test on whether a reference
   48.55 +  // points into the collection set or not. This field is also used to
   48.56 +  // free the array.
   48.57 +  bool* _in_cset_fast_test_base;
   48.58 +
   48.59 +  // The length of the _in_cset_fast_test_base array.
   48.60 +  size_t _in_cset_fast_test_length;
   48.61 +
   48.62    volatile unsigned _gc_time_stamp;
   48.63  
   48.64    size_t* _surviving_young_words;
   48.65 @@ -260,8 +283,8 @@
   48.66    // Returns "true" iff none of the gc alloc regions have any allocations
   48.67    // since the last call to "save_marks".
   48.68    bool all_alloc_regions_no_allocs_since_save_marks();
   48.69 -  // Calls "note_end_of_copying on all gc alloc_regions.
   48.70 -  void all_alloc_regions_note_end_of_copying();
   48.71 +  // Perform finalization stuff on all allocation regions.
   48.72 +  void retire_all_alloc_regions();
   48.73  
   48.74    // The number of regions allocated to hold humongous objects.
   48.75    int         _num_humongous_regions;
   48.76 @@ -330,6 +353,10 @@
   48.77    // that parallel threads might be attempting allocations.
   48.78    void par_allocate_remaining_space(HeapRegion* r);
   48.79  
   48.80 +  // Retires an allocation region when it is full or at the end of a
   48.81 +  // GC pause.
   48.82 +  void  retire_alloc_region(HeapRegion* alloc_region, bool par);
   48.83 +
   48.84    // Helper function for two callbacks below.
   48.85    // "full", if true, indicates that the GC is for a System.gc() request,
   48.86    // and should collect the entire heap.  If "clear_all_soft_refs" is true,
   48.87 @@ -368,6 +395,38 @@
   48.88    virtual void gc_prologue(bool full);
   48.89    virtual void gc_epilogue(bool full);
   48.90  
   48.91 +  // We register a region with the fast "in collection set" test. We
   48.92 +  // simply set to true the array slot corresponding to this region.
   48.93 +  void register_region_with_in_cset_fast_test(HeapRegion* r) {
   48.94 +    assert(_in_cset_fast_test_base != NULL, "sanity");
   48.95 +    assert(r->in_collection_set(), "invariant");
   48.96 +    int index = r->hrs_index();
   48.97 +    assert(0 <= (size_t) index && (size_t) index < _in_cset_fast_test_length,
   48.98 +           "invariant");
   48.99 +    assert(!_in_cset_fast_test_base[index], "invariant");
  48.100 +    _in_cset_fast_test_base[index] = true;
  48.101 +  }
  48.102 +
  48.103 +  // This is a fast test on whether a reference points into the
  48.104 +  // collection set or not. It does not assume that the reference
  48.105 +  // points into the heap; if it doesn't, it will return false.
  48.106 +  bool in_cset_fast_test(oop obj) {
  48.107 +    assert(_in_cset_fast_test != NULL, "sanity");
  48.108 +    if (_g1_committed.contains((HeapWord*) obj)) {
  48.109 +      // no need to subtract the bottom of the heap from obj,
  48.110 +      // _in_cset_fast_test is biased
  48.111 +      size_t index = ((size_t) obj) >> HeapRegion::LogOfHRGrainBytes;
  48.112 +      bool ret = _in_cset_fast_test[index];
  48.113 +      // let's make sure the result is consistent with what the slower
  48.114 +      // test returns
  48.115 +      assert( ret || !obj_in_cs(obj), "sanity");
  48.116 +      assert(!ret ||  obj_in_cs(obj), "sanity");
  48.117 +      return ret;
  48.118 +    } else {
  48.119 +      return false;
  48.120 +    }
  48.121 +  }
  48.122 +
  48.123  protected:
  48.124  
  48.125    // Shrink the garbage-first heap by at most the given size (in bytes!).
  48.126 @@ -850,6 +909,7 @@
  48.127  
  48.128    // Iterate over all objects, calling "cl.do_object" on each.
  48.129    virtual void object_iterate(ObjectClosure* cl);
  48.130 +  virtual void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
  48.131  
  48.132    // Iterate over all objects allocated since the last collection, calling
  48.133    // "cl.do_object" on each.  The heap must have been initialized properly
    49.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Sat Jan 31 17:19:42 2009 -0800
    49.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Fri Feb 27 15:13:00 2009 -0800
    49.3 @@ -36,8 +36,11 @@
    49.4  
    49.5  inline HeapRegion*
    49.6  G1CollectedHeap::heap_region_containing_raw(const void* addr) const {
    49.7 -  HeapRegion* res = _hrs->addr_to_region(addr);
    49.8 -  assert(res != NULL, "addr outside of heap?");
    49.9 +  assert(_g1_reserved.contains(addr), "invariant");
   49.10 +  size_t index = ((intptr_t) addr - (intptr_t) _g1_reserved.start())
   49.11 +                                              >> HeapRegion::LogOfHRGrainBytes;
   49.12 +  HeapRegion* res = _hrs->at(index);
   49.13 +  assert(res == _hrs->addr_to_region(addr), "sanity");
   49.14    return res;
   49.15  }
   49.16  
    50.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Sat Jan 31 17:19:42 2009 -0800
    50.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Feb 27 15:13:00 2009 -0800
    50.3 @@ -196,8 +196,13 @@
    50.4    _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived",
    50.5                                                   G1YoungSurvRateNumRegionsSummary)),
    50.6    _survivor_surv_rate_group(new SurvRateGroup(this, "Survivor",
    50.7 -                                              G1YoungSurvRateNumRegionsSummary))
    50.8 +                                              G1YoungSurvRateNumRegionsSummary)),
    50.9    // add here any more surv rate groups
   50.10 +  _recorded_survivor_regions(0),
   50.11 +  _recorded_survivor_head(NULL),
   50.12 +  _recorded_survivor_tail(NULL),
   50.13 +  _survivors_age_table(true)
   50.14 +
   50.15  {
   50.16    _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
   50.17    _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
   50.18 @@ -272,6 +277,15 @@
   50.19    _concurrent_mark_cleanup_times_ms->add(0.20);
   50.20    _tenuring_threshold = MaxTenuringThreshold;
   50.21  
   50.22 +  if (G1UseSurvivorSpace) {
   50.23 +    // if G1FixedSurvivorSpaceSize is 0 which means the size is not
   50.24 +    // fixed, then _max_survivor_regions will be calculated at
   50.25 +    // calculate_young_list_target_config during initialization
   50.26 +    _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
   50.27 +  } else {
   50.28 +    _max_survivor_regions = 0;
   50.29 +  }
   50.30 +
   50.31    initialize_all();
   50.32  }
   50.33  
   50.34 @@ -283,6 +297,9 @@
   50.35  void G1CollectorPolicy::initialize_flags() {
   50.36    set_min_alignment(HeapRegion::GrainBytes);
   50.37    set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name()));
   50.38 +  if (SurvivorRatio < 1) {
   50.39 +    vm_exit_during_initialization("Invalid survivor ratio specified");
   50.40 +  }
   50.41    CollectorPolicy::initialize_flags();
   50.42  }
   50.43  
   50.44 @@ -301,6 +318,8 @@
   50.45                                    "-XX:+UseConcMarkSweepGC.");
   50.46    }
   50.47  
   50.48 +  initialize_gc_policy_counters();
   50.49 +
   50.50    if (G1Gen) {
   50.51      _in_young_gc_mode = true;
   50.52  
   50.53 @@ -322,6 +341,12 @@
   50.54    }
   50.55  }
   50.56  
   50.57 +// Create the jstat counters for the policy.
   50.58 +void G1CollectorPolicy::initialize_gc_policy_counters()
   50.59 +{
   50.60 +  _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 2 + G1Gen);
   50.61 +}
   50.62 +
   50.63  void G1CollectorPolicy::calculate_young_list_min_length() {
   50.64    _young_list_min_length = 0;
   50.65  
   50.66 @@ -352,6 +377,7 @@
   50.67      guarantee( so_length < _young_list_target_length, "invariant" );
   50.68      _young_list_so_prefix_length = so_length;
   50.69    }
   50.70 +  calculate_survivors_policy();
   50.71  }
   50.72  
   50.73  // This method calculate the optimal scan-only set for a fixed young
   50.74 @@ -448,6 +474,9 @@
   50.75    if (full_young_gcs() && _free_regions_at_end_of_collection > 0) {
   50.76      // we are in fully-young mode and there are free regions in the heap
   50.77  
   50.78 +    double survivor_regions_evac_time =
   50.79 +        predict_survivor_regions_evac_time();
   50.80 +
   50.81      size_t min_so_length = 0;
   50.82      size_t max_so_length = 0;
   50.83  
   50.84 @@ -497,9 +526,8 @@
   50.85        scanned_cards = predict_non_young_card_num(adj_rs_lengths);
   50.86      // calculate this once, so that we don't have to recalculate it in
   50.87      // the innermost loop
   50.88 -    double base_time_ms = predict_base_elapsed_time_ms(pending_cards,
   50.89 -                                                       scanned_cards);
   50.90 -
   50.91 +    double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards)
   50.92 +                          + survivor_regions_evac_time;
   50.93      // the result
   50.94      size_t final_young_length = 0;
   50.95      size_t final_so_length = 0;
   50.96 @@ -548,14 +576,14 @@
   50.97      bool done = false;
   50.98      // this is the outermost loop
   50.99      while (!done) {
  50.100 -#if 0
  50.101 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.102        // leave this in for debugging, just in case
  50.103        gclog_or_tty->print_cr("searching between " SIZE_FORMAT " and " SIZE_FORMAT
  50.104                               ", incr " SIZE_FORMAT ", pass %s",
  50.105                               from_so_length, to_so_length, so_length_incr,
  50.106                               (pass == pass_type_coarse) ? "coarse" :
  50.107                               (pass == pass_type_fine) ? "fine" : "final");
  50.108 -#endif // 0
  50.109 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.110  
  50.111        size_t so_length = from_so_length;
  50.112        size_t init_free_regions =
  50.113 @@ -651,11 +679,11 @@
  50.114            guarantee( so_length_incr == so_coarse_increments, "invariant" );
  50.115            guarantee( final_so_length >= min_so_length, "invariant" );
  50.116  
  50.117 -#if 0
  50.118 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.119            // leave this in for debugging, just in case
  50.120            gclog_or_tty->print_cr("  coarse pass: SO length " SIZE_FORMAT,
  50.121                                   final_so_length);
  50.122 -#endif // 0
  50.123 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.124  
  50.125            from_so_length =
  50.126              (final_so_length - min_so_length > so_coarse_increments) ?
  50.127 @@ -687,12 +715,12 @@
  50.128              // of the optimal
  50.129              size_t new_so_length = 950 * final_so_length / 1000;
  50.130  
  50.131 -#if 0
  50.132 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.133              // leave this in for debugging, just in case
  50.134              gclog_or_tty->print_cr("  fine pass: SO length " SIZE_FORMAT
  50.135                                     ", setting it to " SIZE_FORMAT,
  50.136                                      final_so_length, new_so_length);
  50.137 -#endif // 0
  50.138 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.139  
  50.140              from_so_length = new_so_length;
  50.141              to_so_length = new_so_length;
  50.142 @@ -719,7 +747,8 @@
  50.143      }
  50.144  
  50.145      // we should have at least one region in the target young length
  50.146 -    _young_list_target_length = MAX2((size_t) 1, final_young_length);
  50.147 +    _young_list_target_length =
  50.148 +        MAX2((size_t) 1, final_young_length + _recorded_survivor_regions);
  50.149      if (final_so_length >= final_young_length)
  50.150        // and we need to ensure that the S-O length is not greater than
  50.151        // the target young length (this is being a bit careful)
  50.152 @@ -734,7 +763,7 @@
  50.153      double end_time_sec = os::elapsedTime();
  50.154      double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0;
  50.155  
  50.156 -#if 0
  50.157 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.158      // leave this in for debugging, just in case
  50.159      gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT
  50.160                             ", SO = " SIZE_FORMAT ", "
  50.161 @@ -747,9 +776,9 @@
  50.162                             calculations,
  50.163                             full_young_gcs() ? "full" : "partial",
  50.164                             should_initiate_conc_mark() ? " i-m" : "",
  50.165 -                           in_marking_window(),
  50.166 -                           in_marking_window_im());
  50.167 -#endif // 0
  50.168 +                           _in_marking_window,
  50.169 +                           _in_marking_window_im);
  50.170 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.171  
  50.172      if (_young_list_target_length < _young_list_min_length) {
  50.173        // bummer; this means that, if we do a pause when the optimal
  50.174 @@ -768,14 +797,14 @@
  50.175          // S-O length
  50.176          so_length = calculate_optimal_so_length(_young_list_min_length);
  50.177  
  50.178 -#if 0
  50.179 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.180        // leave this in for debugging, just in case
  50.181        gclog_or_tty->print_cr("adjusted target length from "
  50.182                               SIZE_FORMAT " to " SIZE_FORMAT
  50.183                               ", SO " SIZE_FORMAT,
  50.184                               _young_list_target_length, _young_list_min_length,
  50.185                               so_length);
  50.186 -#endif // 0
  50.187 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.188  
  50.189        _young_list_target_length =
  50.190          MAX2(_young_list_min_length, (size_t)1);
  50.191 @@ -785,12 +814,12 @@
  50.192      // we are in a partially-young mode or we've run out of regions (due
  50.193      // to evacuation failure)
  50.194  
  50.195 -#if 0
  50.196 +#ifdef TRACE_CALC_YOUNG_CONFIG
  50.197      // leave this in for debugging, just in case
  50.198      gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
  50.199                             ", SO " SIZE_FORMAT,
  50.200                             _young_list_min_length, 0);
  50.201 -#endif // 0
  50.202 +#endif // TRACE_CALC_YOUNG_CONFIG
  50.203  
  50.204      // we'll do the pause as soon as possible and with no S-O prefix
  50.205      // (see above for the reasons behind the latter)
  50.206 @@ -884,6 +913,16 @@
  50.207    return true;
  50.208  }
  50.209  
  50.210 +double G1CollectorPolicy::predict_survivor_regions_evac_time() {
  50.211 +  double survivor_regions_evac_time = 0.0;
  50.212 +  for (HeapRegion * r = _recorded_survivor_head;
  50.213 +       r != NULL && r != _recorded_survivor_tail->get_next_young_region();
  50.214 +       r = r->get_next_young_region()) {
  50.215 +    survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true);
  50.216 +  }
  50.217 +  return survivor_regions_evac_time;
  50.218 +}
  50.219 +
  50.220  void G1CollectorPolicy::check_prediction_validity() {
  50.221    guarantee( adaptive_young_list_length(), "should not call this otherwise" );
  50.222  
  50.223 @@ -995,11 +1034,15 @@
  50.224    _short_lived_surv_rate_group->start_adding_regions();
  50.225    // also call this on any additional surv rate groups
  50.226  
  50.227 +  record_survivor_regions(0, NULL, NULL);
  50.228 +
  50.229    _prev_region_num_young   = _region_num_young;
  50.230    _prev_region_num_tenured = _region_num_tenured;
  50.231  
  50.232    _free_regions_at_end_of_collection = _g1->free_regions();
  50.233    _scan_only_regions_at_end_of_collection = 0;
  50.234 +  // Reset survivors SurvRateGroup.
  50.235 +  _survivor_surv_rate_group->reset();
  50.236    calculate_young_list_min_length();
  50.237    calculate_young_list_target_config();
  50.238   }
  50.239 @@ -1104,6 +1147,10 @@
  50.240    _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
  50.241    tag_scan_only(short_lived_so_length);
  50.242  
  50.243 +  if (G1UseSurvivorSpace) {
  50.244 +    _survivors_age_table.clear();
  50.245 +  }
  50.246 +
  50.247    assert( verify_young_ages(), "region age verification" );
  50.248  }
  50.249  
  50.250 @@ -1965,9 +2012,6 @@
  50.251    // </NEW PREDICTION>
  50.252  
  50.253    _target_pause_time_ms = -1.0;
  50.254 -
  50.255 -  // TODO: calculate tenuring threshold
  50.256 -  _tenuring_threshold = MaxTenuringThreshold;
  50.257  }
  50.258  
  50.259  // <NEW PREDICTION>
  50.260 @@ -2058,7 +2102,7 @@
  50.261      guarantee( hr->is_young() && hr->age_in_surv_rate_group() != -1,
  50.262                 "invariant" );
  50.263      int age = hr->age_in_surv_rate_group();
  50.264 -    double yg_surv_rate = predict_yg_surv_rate(age);
  50.265 +    double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
  50.266      bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
  50.267    }
  50.268  
  50.269 @@ -2091,7 +2135,7 @@
  50.270    }
  50.271  #if PREDICTIONS_VERBOSE
  50.272    if (young) {
  50.273 -    _recorded_young_bytes += hr->asSpace()->used();
  50.274 +    _recorded_young_bytes += hr->used();
  50.275    } else {
  50.276      _recorded_marked_bytes += hr->max_live_bytes();
  50.277    }
  50.278 @@ -2119,11 +2163,6 @@
  50.279        predict_non_young_card_num(_predicted_rs_lengths);
  50.280    _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions;
  50.281  
  50.282 -  _predicted_young_survival_ratio = 0.0;
  50.283 -  for (int i = 0; i < _recorded_young_regions; ++i)
  50.284 -    _predicted_young_survival_ratio += predict_yg_surv_rate(i);
  50.285 -  _predicted_young_survival_ratio /= (double) _recorded_young_regions;
  50.286 -
  50.287    _predicted_scan_only_scan_time_ms =
  50.288      predict_scan_only_time_ms(_recorded_scan_only_regions);
  50.289    _predicted_rs_update_time_ms =
  50.290 @@ -2673,8 +2712,11 @@
  50.291    assert(in_young_gc_mode(), "should be in young GC mode");
  50.292    bool ret;
  50.293    size_t young_list_length = _g1->young_list_length();
  50.294 -
  50.295 -  if (young_list_length < _young_list_target_length) {
  50.296 +  size_t young_list_max_length = _young_list_target_length;
  50.297 +  if (G1FixedEdenSize) {
  50.298 +    young_list_max_length -= _max_survivor_regions;
  50.299 +  }
  50.300 +  if (young_list_length < young_list_max_length) {
  50.301      ret = true;
  50.302      ++_region_num_young;
  50.303    } else {
  50.304 @@ -2710,17 +2752,39 @@
  50.305  }
  50.306  
  50.307  
  50.308 -uint G1CollectorPolicy::max_regions(int purpose) {
  50.309 +size_t G1CollectorPolicy::max_regions(int purpose) {
  50.310    switch (purpose) {
  50.311      case GCAllocForSurvived:
  50.312 -      return G1MaxSurvivorRegions;
  50.313 +      return _max_survivor_regions;
  50.314      case GCAllocForTenured:
  50.315 -      return UINT_MAX;
  50.316 +      return REGIONS_UNLIMITED;
  50.317      default:
  50.318 -      return UINT_MAX;
  50.319 +      ShouldNotReachHere();
  50.320 +      return REGIONS_UNLIMITED;
  50.321    };
  50.322  }
  50.323  
  50.324 +// Calculates survivor space parameters.
  50.325 +void G1CollectorPolicy::calculate_survivors_policy()
  50.326 +{
  50.327 +  if (!G1UseSurvivorSpace) {
  50.328 +    return;
  50.329 +  }
  50.330 +  if (G1FixedSurvivorSpaceSize == 0) {
  50.331 +    _max_survivor_regions = _young_list_target_length / SurvivorRatio;
  50.332 +  } else {
  50.333 +    _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
  50.334 +  }
  50.335 +
  50.336 +  if (G1FixedTenuringThreshold) {
  50.337 +    _tenuring_threshold = MaxTenuringThreshold;
  50.338 +  } else {
  50.339 +    _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
  50.340 +        HeapRegion::GrainWords * _max_survivor_regions);
  50.341 +  }
  50.342 +}
  50.343 +
  50.344 +
  50.345  void
  50.346  G1CollectorPolicy_BestRegionsFirst::
  50.347  set_single_region_collection_set(HeapRegion* hr) {
  50.348 @@ -2743,7 +2807,11 @@
  50.349    double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
  50.350  
  50.351    size_t young_list_length = _g1->young_list_length();
  50.352 -  bool reached_target_length = young_list_length >= _young_list_target_length;
  50.353 +  size_t young_list_max_length = _young_list_target_length;
  50.354 +  if (G1FixedEdenSize) {
  50.355 +    young_list_max_length -= _max_survivor_regions;
  50.356 +  }
  50.357 +  bool reached_target_length = young_list_length >= young_list_max_length;
  50.358  
  50.359    if (in_young_gc_mode()) {
  50.360      if (reached_target_length) {
  50.361 @@ -2985,6 +3053,7 @@
  50.362    _collection_set = hr;
  50.363    _collection_set_size++;
  50.364    _collection_set_bytes_used_before += hr->used();
  50.365 +  _g1->register_region_with_in_cset_fast_test(hr);
  50.366  }
  50.367  
  50.368  void
    51.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Sat Jan 31 17:19:42 2009 -0800
    51.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Feb 27 15:13:00 2009 -0800
    51.3 @@ -49,7 +49,7 @@
    51.4  class MainBodySummary;
    51.5  class PopPreambleSummary;
    51.6  
    51.7 -class PauseSummary {
    51.8 +class PauseSummary: public CHeapObj {
    51.9    define_num_seq(total)
   51.10      define_num_seq(other)
   51.11  
   51.12 @@ -58,7 +58,7 @@
   51.13    virtual PopPreambleSummary* pop_preamble_summary() { return NULL; }
   51.14  };
   51.15  
   51.16 -class MainBodySummary {
   51.17 +class MainBodySummary: public CHeapObj {
   51.18    define_num_seq(satb_drain) // optional
   51.19    define_num_seq(parallel) // parallel only
   51.20      define_num_seq(ext_root_scan)
   51.21 @@ -75,7 +75,7 @@
   51.22    define_num_seq(clear_ct)  // parallel only
   51.23  };
   51.24  
   51.25 -class PopPreambleSummary {
   51.26 +class PopPreambleSummary: public CHeapObj {
   51.27    define_num_seq(pop_preamble)
   51.28      define_num_seq(pop_update_rs)
   51.29      define_num_seq(pop_scan_rs)
   51.30 @@ -557,6 +557,8 @@
   51.31      return get_new_neg_prediction(_young_gc_eff_seq);
   51.32    }
   51.33  
   51.34 +  double predict_survivor_regions_evac_time();
   51.35 +
   51.36    // </NEW PREDICTION>
   51.37  
   51.38  public:
   51.39 @@ -599,8 +601,8 @@
   51.40  
   51.41    // Returns an estimate of the survival rate of the region at yg-age
   51.42    // "yg_age".
   51.43 -  double predict_yg_surv_rate(int age) {
   51.44 -    TruncatedSeq* seq = _short_lived_surv_rate_group->get_seq(age);
   51.45 +  double predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) {
   51.46 +    TruncatedSeq* seq = surv_rate_group->get_seq(age);
   51.47      if (seq->num() == 0)
   51.48        gclog_or_tty->print("BARF! age is %d", age);
   51.49      guarantee( seq->num() > 0, "invariant" );
   51.50 @@ -610,6 +612,10 @@
   51.51      return pred;
   51.52    }
   51.53  
   51.54 +  double predict_yg_surv_rate(int age) {
   51.55 +    return predict_yg_surv_rate(age, _short_lived_surv_rate_group);
   51.56 +  }
   51.57 +
   51.58    double accum_yg_surv_rate_pred(int age) {
   51.59      return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
   51.60    }
   51.61 @@ -822,6 +828,9 @@
   51.62  
   51.63    virtual void init();
   51.64  
   51.65 +  // Create jstat counters for the policy.
   51.66 +  virtual void initialize_gc_policy_counters();
   51.67 +
   51.68    virtual HeapWord* mem_allocate_work(size_t size,
   51.69                                        bool is_tlab,
   51.70                                        bool* gc_overhead_limit_was_exceeded);
   51.71 @@ -1047,8 +1056,12 @@
   51.72    // Print stats on young survival ratio
   51.73    void print_yg_surv_rate_info() const;
   51.74  
   51.75 -  void finished_recalculating_age_indexes() {
   51.76 -    _short_lived_surv_rate_group->finished_recalculating_age_indexes();
   51.77 +  void finished_recalculating_age_indexes(bool is_survivors) {
   51.78 +    if (is_survivors) {
   51.79 +      _survivor_surv_rate_group->finished_recalculating_age_indexes();
   51.80 +    } else {
   51.81 +      _short_lived_surv_rate_group->finished_recalculating_age_indexes();
   51.82 +    }
   51.83      // do that for any other surv rate groups
   51.84    }
   51.85  
   51.86 @@ -1097,6 +1110,17 @@
   51.87    // maximum amount of suvivors regions.
   51.88    int _tenuring_threshold;
   51.89  
   51.90 +  // The limit on the number of regions allocated for survivors.
   51.91 +  size_t _max_survivor_regions;
   51.92 +
   51.93 +  // The amount of survor regions after a collection.
   51.94 +  size_t _recorded_survivor_regions;
   51.95 +  // List of survivor regions.
   51.96 +  HeapRegion* _recorded_survivor_head;
   51.97 +  HeapRegion* _recorded_survivor_tail;
   51.98 +
   51.99 +  ageTable _survivors_age_table;
  51.100 +
  51.101  public:
  51.102  
  51.103    inline GCAllocPurpose
  51.104 @@ -1116,7 +1140,9 @@
  51.105      return GCAllocForTenured;
  51.106    }
  51.107  
  51.108 -  uint max_regions(int purpose);
  51.109 +  static const size_t REGIONS_UNLIMITED = ~(size_t)0;
  51.110 +
  51.111 +  size_t max_regions(int purpose);
  51.112  
  51.113    // The limit on regions for a particular purpose is reached.
  51.114    void note_alloc_region_limit_reached(int purpose) {
  51.115 @@ -1132,6 +1158,23 @@
  51.116    void note_stop_adding_survivor_regions() {
  51.117      _survivor_surv_rate_group->stop_adding_regions();
  51.118    }
  51.119 +
  51.120 +  void record_survivor_regions(size_t      regions,
  51.121 +                               HeapRegion* head,
  51.122 +                               HeapRegion* tail) {
  51.123 +    _recorded_survivor_regions = regions;
  51.124 +    _recorded_survivor_head    = head;
  51.125 +    _recorded_survivor_tail    = tail;
  51.126 +  }
  51.127 +
  51.128 +  void record_thread_age_table(ageTable* age_table)
  51.129 +  {
  51.130 +    _survivors_age_table.merge_par(age_table);
  51.131 +  }
  51.132 +
  51.133 +  // Calculates survivor space parameters.
  51.134 +  void calculate_survivors_policy();
  51.135 +
  51.136  };
  51.137  
  51.138  // This encapsulates a particular strategy for a g1 Collector.
    52.1 --- a/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Sat Jan 31 17:19:42 2009 -0800
    52.2 +++ b/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Fri Feb 27 15:13:00 2009 -0800
    52.3 @@ -28,7 +28,7 @@
    52.4  /***** ALL TIMES ARE IN SECS!!!!!!! *****/
    52.5  
    52.6  // this is the "interface"
    52.7 -class G1MMUTracker {
    52.8 +class G1MMUTracker: public CHeapObj {
    52.9  protected:
   52.10    double          _time_slice;
   52.11    double          _max_gc_time; // this is per time slice
   52.12 @@ -67,7 +67,7 @@
   52.13    }
   52.14  };
   52.15  
   52.16 -class G1MMUTrackerQueueElem {
   52.17 +class G1MMUTrackerQueueElem VALUE_OBJ_CLASS_SPEC {
   52.18  private:
   52.19    double _start_time;
   52.20    double _end_time;
    53.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Sat Jan 31 17:19:42 2009 -0800
    53.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Feb 27 15:13:00 2009 -0800
    53.3 @@ -77,6 +77,18 @@
    53.4  
    53.5  #define G1_PARTIAL_ARRAY_MASK 1
    53.6  
    53.7 +inline bool has_partial_array_mask(oop* ref) {
    53.8 +  return (intptr_t) ref & G1_PARTIAL_ARRAY_MASK;
    53.9 +}
   53.10 +
   53.11 +inline oop* set_partial_array_mask(oop obj) {
   53.12 +  return (oop*) ((intptr_t) obj | G1_PARTIAL_ARRAY_MASK);
   53.13 +}
   53.14 +
   53.15 +inline oop clear_partial_array_mask(oop* ref) {
   53.16 +  return oop((intptr_t) ref & ~G1_PARTIAL_ARRAY_MASK);
   53.17 +}
   53.18 +
   53.19  class G1ParScanPartialArrayClosure : public G1ParClosureSuper {
   53.20    G1ParScanClosure _scanner;
   53.21    template <class T> void process_array_chunk(oop obj, int start, int end);
   53.22 @@ -101,7 +113,8 @@
   53.23      G1ParClosureSuper(g1, par_scan_state), _scanner(scanner) { }
   53.24  };
   53.25  
   53.26 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee>
   53.27 +template<bool do_gen_barrier, G1Barrier barrier,
   53.28 +         bool do_mark_forwardee, bool skip_cset_test>
   53.29  class G1ParCopyClosure : public G1ParCopyHelper {
   53.30    G1ParScanClosure _scanner;
   53.31    void do_oop_work(oop* p);
   53.32 @@ -119,14 +132,22 @@
   53.33    virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   53.34  };
   53.35  
   53.36 -typedef G1ParCopyClosure<false, G1BarrierNone, false> G1ParScanExtRootClosure;
   53.37 -typedef G1ParCopyClosure<true, G1BarrierNone, false> G1ParScanPermClosure;
   53.38 -typedef G1ParCopyClosure<false, G1BarrierNone, true> G1ParScanAndMarkExtRootClosure;
   53.39 -typedef G1ParCopyClosure<true, G1BarrierNone, true> G1ParScanAndMarkPermClosure;
   53.40 -typedef G1ParCopyClosure<false, G1BarrierRS, false> G1ParScanHeapRSClosure;
   53.41 -typedef G1ParCopyClosure<false, G1BarrierRS, true> G1ParScanAndMarkHeapRSClosure;
   53.42 -typedef G1ParCopyClosure<false, G1BarrierEvac, false> G1ParScanHeapEvacClosure;
   53.43 -
   53.44 +typedef G1ParCopyClosure<false, G1BarrierNone, false, false> G1ParScanExtRootClosure;
   53.45 +typedef G1ParCopyClosure<true,  G1BarrierNone, false, false> G1ParScanPermClosure;
   53.46 +typedef G1ParCopyClosure<false, G1BarrierNone, true,  false> G1ParScanAndMarkExtRootClosure;
   53.47 +typedef G1ParCopyClosure<true,  G1BarrierNone, true,  false> G1ParScanAndMarkPermClosure;
   53.48 +typedef G1ParCopyClosure<false, G1BarrierRS,   false, false> G1ParScanHeapRSClosure;
   53.49 +typedef G1ParCopyClosure<false, G1BarrierRS,   true,  false> G1ParScanAndMarkHeapRSClosure;
   53.50 +// This is the only case when we set skip_cset_test. Basically, this
   53.51 +// closure is (should?) only be called directly while we're draining
   53.52 +// the overflow and task queues. In that case we know that the
   53.53 +// reference in question points into the collection set, otherwise we
   53.54 +// would not have pushed it on the queue.
   53.55 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, true> G1ParScanHeapEvacClosure;
   53.56 +// We need a separate closure to handle references during evacuation
   53.57 +// failure processing, as it cannot asume that the reference already
   53.58 + // points to the collection set (like G1ParScanHeapEvacClosure does).
   53.59 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, false> G1ParScanHeapEvacFailureClosure;
   53.60  
   53.61  class FilterIntoCSClosure: public OopClosure {
   53.62    G1CollectedHeap* _g1;
    54.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Sat Jan 31 17:19:42 2009 -0800
    54.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Feb 27 15:13:00 2009 -0800
    54.3 @@ -572,6 +572,9 @@
    54.4    }
    54.5    guarantee( _cards_scanned == NULL, "invariant" );
    54.6    _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers());
    54.7 +  for (uint i = 0; i < n_workers(); ++i) {
    54.8 +    _cards_scanned[i] = 0;
    54.9 +  }
   54.10    _total_cards_scanned = 0;
   54.11  }
   54.12  
    55.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Sat Jan 31 17:19:42 2009 -0800
    55.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Feb 27 15:13:00 2009 -0800
    55.3 @@ -30,7 +30,7 @@
    55.4  class HRInto_G1RemSet;
    55.5  class ConcurrentG1Refine;
    55.6  
    55.7 -class G1RemSet {
    55.8 +class G1RemSet: public CHeapObj {
    55.9  protected:
   55.10    G1CollectedHeap* _g1;
   55.11  
    56.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Sat Jan 31 17:19:42 2009 -0800
    56.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Feb 27 15:13:00 2009 -0800
    56.3 @@ -28,7 +28,7 @@
    56.4  
    56.5  #define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
    56.6                                                                              \
    56.7 -  product(intx, ParallelGCG1AllocBufferSize, 4*K,                           \
    56.8 +  product(intx, ParallelGCG1AllocBufferSize, 8*K,                           \
    56.9            "Size of parallel G1 allocation buffers in to-space.")            \
   56.10                                                                              \
   56.11    product(intx, G1TimeSliceMS, 500,                                         \
   56.12 @@ -281,7 +281,17 @@
   56.13    develop(bool, G1HRRSFlushLogBuffersOnVerify, false,                       \
   56.14            "Forces flushing of log buffers before verification.")            \
   56.15                                                                              \
   56.16 -  product(intx, G1MaxSurvivorRegions, 0,                                    \
   56.17 -          "The maximum number of survivor regions")
   56.18 +  product(bool, G1UseSurvivorSpace, true,                                   \
   56.19 +          "When true, use survivor space.")                                 \
   56.20 +                                                                            \
   56.21 +  product(bool, G1FixedTenuringThreshold, false,                            \
   56.22 +          "When set, G1 will not adjust the tenuring threshold")            \
   56.23 +                                                                            \
   56.24 +  product(bool, G1FixedEdenSize, false,                                     \
   56.25 +          "When set, G1 will not allocate unused survivor space regions")   \
   56.26 +                                                                            \
   56.27 +  product(uintx, G1FixedSurvivorSpaceSize, 0,                               \
   56.28 +          "If non-0 is the size of the G1 survivor space, "                 \
   56.29 +          "otherwise SurvivorRatio is used to determine the size")
   56.30  
   56.31  G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
    57.1 --- a/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Sat Jan 31 17:19:42 2009 -0800
    57.2 +++ b/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Fri Feb 27 15:13:00 2009 -0800
    57.3 @@ -32,11 +32,13 @@
    57.4    G1BarrierNone, G1BarrierRS, G1BarrierEvac
    57.5  };
    57.6  
    57.7 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee>
    57.8 +template<bool do_gen_barrier, G1Barrier barrier,
    57.9 +         bool do_mark_forwardee, bool skip_cset_test>
   57.10  class G1ParCopyClosure;
   57.11  class G1ParScanClosure;
   57.12  
   57.13 -typedef G1ParCopyClosure<false, G1BarrierEvac, false> G1ParScanHeapEvacClosure;
   57.14 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, true>
   57.15 +                                                      G1ParScanHeapEvacClosure;
   57.16  
   57.17  class FilterIntoCSClosure;
   57.18  class FilterOutOfRegionClosure;
    58.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Sat Jan 31 17:19:42 2009 -0800
    58.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Feb 27 15:13:00 2009 -0800
    58.3 @@ -566,7 +566,11 @@
    58.4    void note_end_of_copying() {
    58.5      assert(top() >= _next_top_at_mark_start,
    58.6             "Increase only");
    58.7 -    _next_top_at_mark_start = top();
    58.8 +    // Survivor regions will be scanned on the start of concurrent
    58.9 +    // marking.
   58.10 +    if (!is_survivor()) {
   58.11 +      _next_top_at_mark_start = top();
   58.12 +    }
   58.13    }
   58.14  
   58.15    // Returns "false" iff no object in the region was allocated when the
   58.16 @@ -829,7 +833,7 @@
   58.17  
   58.18  // A linked lists of heap regions.  It leaves the "next" field
   58.19  // unspecified; that's up to subtypes.
   58.20 -class RegionList {
   58.21 +class RegionList VALUE_OBJ_CLASS_SPEC {
   58.22  protected:
   58.23    virtual HeapRegion* get_next(HeapRegion* chr) = 0;
   58.24    virtual void set_next(HeapRegion* chr,
    59.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Sat Jan 31 17:19:42 2009 -0800
    59.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Fri Feb 27 15:13:00 2009 -0800
    59.3 @@ -65,9 +65,11 @@
    59.4    // We need access in order to union things into the base table.
    59.5    BitMap* bm() { return &_bm; }
    59.6  
    59.7 +#if PRT_COUNT_OCCUPIED
    59.8    void recount_occupied() {
    59.9      _occupied = (jint) bm()->count_one_bits();
   59.10    }
   59.11 +#endif
   59.12  
   59.13    PerRegionTable(HeapRegion* hr) :
   59.14      _hr(hr),
   59.15 @@ -1144,7 +1146,9 @@
   59.16    size_t i = _outgoing_region_map.get_next_one_offset(0);
   59.17    while (i < _outgoing_region_map.size()) {
   59.18      HeapRegion* to_region = g1h->region_at(i);
   59.19 -    to_region->rem_set()->clear_incoming_entry(hr());
   59.20 +    if (!to_region->in_collection_set()) {
   59.21 +      to_region->rem_set()->clear_incoming_entry(hr());
   59.22 +    }
   59.23      i = _outgoing_region_map.get_next_one_offset(i+1);
   59.24    }
   59.25  }
    60.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Sat Jan 31 17:19:42 2009 -0800
    60.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Fri Feb 27 15:13:00 2009 -0800
    60.3 @@ -58,7 +58,7 @@
    60.4  //      is represented.  If a deleted PRT is re-used, a thread adding a bit,
    60.5  //      thinking the PRT is for a different region, does no harm.
    60.6  
    60.7 -class OtherRegionsTable: public CHeapObj {
    60.8 +class OtherRegionsTable VALUE_OBJ_CLASS_SPEC {
    60.9    friend class HeapRegionRemSetIterator;
   60.10  
   60.11    G1CollectedHeap* _g1h;
    61.1 --- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Sat Jan 31 17:19:42 2009 -0800
    61.2 +++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Fri Feb 27 15:13:00 2009 -0800
    61.3 @@ -29,7 +29,7 @@
    61.4  
    61.5  class PtrQueueSet;
    61.6  
    61.7 -class PtrQueue: public CHeapObj {
    61.8 +class PtrQueue VALUE_OBJ_CLASS_SPEC {
    61.9  
   61.10  protected:
   61.11    // The ptr queue set to which this queue belongs.
   61.12 @@ -130,7 +130,7 @@
   61.13  // In particular, the individual queues allocate buffers from this shared
   61.14  // set, and return completed buffers to the set.
   61.15  // All these variables are are protected by the TLOQ_CBL_mon. XXX ???
   61.16 -class PtrQueueSet: public CHeapObj {
   61.17 +class PtrQueueSet VALUE_OBJ_CLASS_SPEC {
   61.18  
   61.19  protected:
   61.20  
    62.1 --- a/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Sat Jan 31 17:19:42 2009 -0800
    62.2 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Fri Feb 27 15:13:00 2009 -0800
    62.3 @@ -33,7 +33,7 @@
    62.4  // old versions synchronously.
    62.5  
    62.6  
    62.7 -class SparsePRTEntry {
    62.8 +class SparsePRTEntry: public CHeapObj {
    62.9  public:
   62.10    enum SomePublicConstants {
   62.11      CardsPerEntry = (short)4,
   62.12 @@ -167,7 +167,7 @@
   62.13  };
   62.14  
   62.15    // ValueObj because will be embedded in HRRS iterator.
   62.16 -class RSHashTableIter: public CHeapObj {
   62.17 +class RSHashTableIter VALUE_OBJ_CLASS_SPEC {
   62.18      short _tbl_ind;
   62.19      short _bl_ind;
   62.20      short _card_ind;
   62.21 @@ -213,7 +213,7 @@
   62.22  
   62.23  class SparsePRTIter;
   62.24  
   62.25 -class SparsePRT : public CHeapObj {
   62.26 +class SparsePRT VALUE_OBJ_CLASS_SPEC {
   62.27    //  Iterations are done on the _cur hash table, since they only need to
   62.28    //  see entries visible at the start of a collection pause.
   62.29    //  All other operations are done using the _next hash table.
    63.1 --- a/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Sat Jan 31 17:19:42 2009 -0800
    63.2 +++ b/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Fri Feb 27 15:13:00 2009 -0800
    63.3 @@ -29,23 +29,14 @@
    63.4                               const char* name,
    63.5                               size_t summary_surv_rates_len) :
    63.6      _g1p(g1p), _name(name),
    63.7 -    _all_regions_allocated(0),
    63.8 -    _curr_length(0), _scan_only_prefix(0), _setup_seq_num(0),
    63.9 -    _array_length(0), _surv_rate(NULL), _accum_surv_rate_pred(NULL),
   63.10 -    _accum_surv_rate(0.0), _surv_rate_pred(NULL), _last_pred(0.0),
   63.11      _summary_surv_rates_len(summary_surv_rates_len),
   63.12      _summary_surv_rates_max_len(0),
   63.13 -    _summary_surv_rates(NULL) {
   63.14 -
   63.15 -  // the following will set up the arrays with length 1
   63.16 -  _curr_length = 1;
   63.17 -  stop_adding_regions();
   63.18 -  guarantee( _array_length == 1, "invariant" );
   63.19 -  guarantee( _surv_rate_pred[0] != NULL, "invariant" );
   63.20 -  _surv_rate_pred[0]->add(0.4);
   63.21 -  all_surviving_words_recorded(false);
   63.22 -  _curr_length = 0;
   63.23 -
   63.24 +    _summary_surv_rates(NULL),
   63.25 +    _surv_rate(NULL),
   63.26 +    _accum_surv_rate_pred(NULL),
   63.27 +    _surv_rate_pred(NULL)
   63.28 +{
   63.29 +  reset();
   63.30    if (summary_surv_rates_len > 0) {
   63.31      size_t length = summary_surv_rates_len;
   63.32        _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
   63.33 @@ -60,61 +51,80 @@
   63.34    start_adding_regions();
   63.35  }
   63.36  
   63.37 +
   63.38 +void SurvRateGroup::reset()
   63.39 +{
   63.40 +  _all_regions_allocated = 0;
   63.41 +  _scan_only_prefix      = 0;
   63.42 +  _setup_seq_num         = 0;
   63.43 +  _stats_arrays_length   = 0;
   63.44 +  _accum_surv_rate       = 0.0;
   63.45 +  _last_pred             = 0.0;
   63.46 +  // the following will set up the arrays with length 1
   63.47 +  _region_num            = 1;
   63.48 +  stop_adding_regions();
   63.49 +  guarantee( _stats_arrays_length == 1, "invariant" );
   63.50 +  guarantee( _surv_rate_pred[0] != NULL, "invariant" );
   63.51 +  _surv_rate_pred[0]->add(0.4);
   63.52 +  all_surviving_words_recorded(false);
   63.53 +  _region_num = 0;
   63.54 +}
   63.55 +
   63.56 +
   63.57  void
   63.58  SurvRateGroup::start_adding_regions() {
   63.59 -  _setup_seq_num   = _array_length;
   63.60 -  _curr_length     = _scan_only_prefix;
   63.61 +  _setup_seq_num   = _stats_arrays_length;
   63.62 +  _region_num      = _scan_only_prefix;
   63.63    _accum_surv_rate = 0.0;
   63.64  
   63.65  #if 0
   63.66 -  gclog_or_tty->print_cr("start adding regions, seq num %d, length %d",
   63.67 -                         _setup_seq_num, _curr_length);
   63.68 +  gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
   63.69 +                         _name, _setup_seq_num, _region_num);
   63.70  #endif // 0
   63.71  }
   63.72  
   63.73  void
   63.74  SurvRateGroup::stop_adding_regions() {
   63.75 -  size_t length = _curr_length;
   63.76  
   63.77  #if 0
   63.78 -  gclog_or_tty->print_cr("stop adding regions, length %d", length);
   63.79 +  gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
   63.80  #endif // 0
   63.81  
   63.82 -  if (length > _array_length) {
   63.83 +  if (_region_num > _stats_arrays_length) {
   63.84      double* old_surv_rate = _surv_rate;
   63.85      double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
   63.86      TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
   63.87  
   63.88 -    _surv_rate = NEW_C_HEAP_ARRAY(double, length);
   63.89 +    _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
   63.90      if (_surv_rate == NULL) {
   63.91 -      vm_exit_out_of_memory(sizeof(double) * length,
   63.92 +      vm_exit_out_of_memory(sizeof(double) * _region_num,
   63.93                              "Not enough space for surv rate array.");
   63.94      }
   63.95 -    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, length);
   63.96 +    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
   63.97      if (_accum_surv_rate_pred == NULL) {
   63.98 -      vm_exit_out_of_memory(sizeof(double) * length,
   63.99 +      vm_exit_out_of_memory(sizeof(double) * _region_num,
  63.100                           "Not enough space for accum surv rate pred array.");
  63.101      }
  63.102 -    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, length);
  63.103 +    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
  63.104      if (_surv_rate == NULL) {
  63.105 -      vm_exit_out_of_memory(sizeof(TruncatedSeq*) * length,
  63.106 +      vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
  63.107                              "Not enough space for surv rate pred array.");
  63.108      }
  63.109  
  63.110 -    for (size_t i = 0; i < _array_length; ++i)
  63.111 +    for (size_t i = 0; i < _stats_arrays_length; ++i)
  63.112        _surv_rate_pred[i] = old_surv_rate_pred[i];
  63.113  
  63.114  #if 0
  63.115 -    gclog_or_tty->print_cr("stop adding regions, new seqs %d to %d",
  63.116 -                  _array_length, length - 1);
  63.117 +    gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
  63.118 +                  _name, _array_length, _region_num - 1);
  63.119  #endif // 0
  63.120  
  63.121 -    for (size_t i = _array_length; i < length; ++i) {
  63.122 +    for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
  63.123        _surv_rate_pred[i] = new TruncatedSeq(10);
  63.124        // _surv_rate_pred[i]->add(last_pred);
  63.125      }
  63.126  
  63.127 -    _array_length = length;
  63.128 +    _stats_arrays_length = _region_num;
  63.129  
  63.130      if (old_surv_rate != NULL)
  63.131        FREE_C_HEAP_ARRAY(double, old_surv_rate);
  63.132 @@ -124,7 +134,7 @@
  63.133        FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
  63.134    }
  63.135  
  63.136 -  for (size_t i = 0; i < _array_length; ++i)
  63.137 +  for (size_t i = 0; i < _stats_arrays_length; ++i)
  63.138      _surv_rate[i] = 0.0;
  63.139  }
  63.140  
  63.141 @@ -135,7 +145,7 @@
  63.142  
  63.143    double ret = _accum_surv_rate;
  63.144    if (adjustment > 0) {
  63.145 -    TruncatedSeq* seq = get_seq(_curr_length+1);
  63.146 +    TruncatedSeq* seq = get_seq(_region_num+1);
  63.147      double surv_rate = _g1p->get_new_prediction(seq);
  63.148      ret += surv_rate;
  63.149    }
  63.150 @@ -145,23 +155,23 @@
  63.151  
  63.152  int
  63.153  SurvRateGroup::next_age_index() {
  63.154 -  TruncatedSeq* seq = get_seq(_curr_length);
  63.155 +  TruncatedSeq* seq = get_seq(_region_num);
  63.156    double surv_rate = _g1p->get_new_prediction(seq);
  63.157    _accum_surv_rate += surv_rate;
  63.158  
  63.159 -  ++_curr_length;
  63.160 +  ++_region_num;
  63.161    return (int) ++_all_regions_allocated;
  63.162  }
  63.163  
  63.164  void
  63.165  SurvRateGroup::record_scan_only_prefix(size_t scan_only_prefix) {
  63.166 -  guarantee( scan_only_prefix <= _curr_length, "pre-condition" );
  63.167 +  guarantee( scan_only_prefix <= _region_num, "pre-condition" );
  63.168    _scan_only_prefix = scan_only_prefix;
  63.169  }
  63.170  
  63.171  void
  63.172  SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
  63.173 -  guarantee( 0 <= age_in_group && (size_t) age_in_group < _curr_length,
  63.174 +  guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num,
  63.175               "pre-condition" );
  63.176    guarantee( _surv_rate[age_in_group] <= 0.00001,
  63.177               "should only update each slot once" );
  63.178 @@ -178,15 +188,15 @@
  63.179  
  63.180  void
  63.181  SurvRateGroup::all_surviving_words_recorded(bool propagate) {
  63.182 -  if (propagate && _curr_length > 0) { // conservative
  63.183 -    double surv_rate = _surv_rate_pred[_curr_length-1]->last();
  63.184 +  if (propagate && _region_num > 0) { // conservative
  63.185 +    double surv_rate = _surv_rate_pred[_region_num-1]->last();
  63.186  
  63.187  #if 0
  63.188      gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
  63.189                    surv_rate, _curr_length, _array_length - 1);
  63.190  #endif // 0
  63.191  
  63.192 -    for (size_t i = _curr_length; i < _array_length; ++i) {
  63.193 +    for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
  63.194        guarantee( _surv_rate[i] <= 0.00001,
  63.195                   "the slot should not have been updated" );
  63.196        _surv_rate_pred[i]->add(surv_rate);
  63.197 @@ -195,7 +205,7 @@
  63.198  
  63.199    double accum = 0.0;
  63.200    double pred = 0.0;
  63.201 -  for (size_t i = 0; i < _array_length; ++i) {
  63.202 +  for (size_t i = 0; i < _stats_arrays_length; ++i) {
  63.203      pred = _g1p->get_new_prediction(_surv_rate_pred[i]);
  63.204      if (pred > 1.0) pred = 1.0;
  63.205      accum += pred;
  63.206 @@ -209,8 +219,8 @@
  63.207  void
  63.208  SurvRateGroup::print() {
  63.209    gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries, %d scan-only)",
  63.210 -                _name, _curr_length, _scan_only_prefix);
  63.211 -  for (size_t i = 0; i < _curr_length; ++i) {
  63.212 +                _name, _region_num, _scan_only_prefix);
  63.213 +  for (size_t i = 0; i < _region_num; ++i) {
  63.214      gclog_or_tty->print_cr("    age %4d   surv rate %6.2lf %%   pred %6.2lf %%%s",
  63.215                    i, _surv_rate[i] * 100.0,
  63.216                    _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0,
    64.1 --- a/src/share/vm/gc_implementation/g1/survRateGroup.hpp	Sat Jan 31 17:19:42 2009 -0800
    64.2 +++ b/src/share/vm/gc_implementation/g1/survRateGroup.hpp	Fri Feb 27 15:13:00 2009 -0800
    64.3 @@ -29,7 +29,7 @@
    64.4    G1CollectorPolicy* _g1p;
    64.5    const char* _name;
    64.6  
    64.7 -  size_t  _array_length;
    64.8 +  size_t  _stats_arrays_length;
    64.9    double* _surv_rate;
   64.10    double* _accum_surv_rate_pred;
   64.11    double  _last_pred;
   64.12 @@ -40,7 +40,7 @@
   64.13    size_t         _summary_surv_rates_max_len;
   64.14  
   64.15    int _all_regions_allocated;
   64.16 -  size_t _curr_length;
   64.17 +  size_t _region_num;
   64.18    size_t _scan_only_prefix;
   64.19    size_t _setup_seq_num;
   64.20  
   64.21 @@ -48,6 +48,7 @@
   64.22    SurvRateGroup(G1CollectorPolicy* g1p,
   64.23                  const char* name,
   64.24                  size_t summary_surv_rates_len);
   64.25 +  void reset();
   64.26    void start_adding_regions();
   64.27    void stop_adding_regions();
   64.28    void record_scan_only_prefix(size_t scan_only_prefix);
   64.29 @@ -55,22 +56,21 @@
   64.30    void all_surviving_words_recorded(bool propagate);
   64.31    const char* name() { return _name; }
   64.32  
   64.33 -  size_t region_num() { return _curr_length; }
   64.34 +  size_t region_num() { return _region_num; }
   64.35    size_t scan_only_length() { return _scan_only_prefix; }
   64.36    double accum_surv_rate_pred(int age) {
   64.37      assert(age >= 0, "must be");
   64.38 -    if ((size_t)age < _array_length)
   64.39 +    if ((size_t)age < _stats_arrays_length)
   64.40        return _accum_surv_rate_pred[age];
   64.41      else {
   64.42 -      double diff = (double) (age - _array_length + 1);
   64.43 -      return _accum_surv_rate_pred[_array_length-1] + diff * _last_pred;
   64.44 +      double diff = (double) (age - _stats_arrays_length + 1);
   64.45 +      return _accum_surv_rate_pred[_stats_arrays_length-1] + diff * _last_pred;
   64.46      }
   64.47    }
   64.48  
   64.49    double accum_surv_rate(size_t adjustment);
   64.50  
   64.51    TruncatedSeq* get_seq(size_t age) {
   64.52 -    guarantee( 0 <= age, "pre-condition" );
   64.53      if (age >= _setup_seq_num) {
   64.54        guarantee( _setup_seq_num > 0, "invariant" );
   64.55        age = _setup_seq_num-1;
    65.1 --- a/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep	Sat Jan 31 17:19:42 2009 -0800
    65.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep	Fri Feb 27 15:13:00 2009 -0800
    65.3 @@ -28,6 +28,7 @@
    65.4  binaryTreeDictionary.cpp                binaryTreeDictionary.hpp
    65.5  binaryTreeDictionary.cpp                globals.hpp
    65.6  binaryTreeDictionary.cpp                ostream.hpp
    65.7 +binaryTreeDictionary.cpp                space.inline.hpp
    65.8  binaryTreeDictionary.cpp                spaceDecorator.hpp
    65.9  
   65.10  binaryTreeDictionary.hpp                freeBlockDictionary.hpp
    66.1 --- a/src/share/vm/gc_implementation/includeDB_gc_g1	Sat Jan 31 17:19:42 2009 -0800
    66.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_g1	Fri Feb 27 15:13:00 2009 -0800
    66.3 @@ -31,9 +31,10 @@
    66.4  cardTableRS.cpp				concurrentMark.hpp
    66.5  cardTableRS.cpp				g1SATBCardTableModRefBS.hpp
    66.6  
    66.7 -collectionSetChooser.cpp		g1CollectedHeap.hpp
    66.8 +collectionSetChooser.cpp		g1CollectedHeap.inline.hpp
    66.9  collectionSetChooser.cpp		g1CollectorPolicy.hpp
   66.10  collectionSetChooser.cpp		collectionSetChooser.hpp
   66.11 +collectionSetChooser.cpp		space.inline.hpp
   66.12  
   66.13  collectionSetChooser.hpp		heapRegion.hpp
   66.14  collectionSetChooser.hpp                growableArray.hpp
   66.15 @@ -42,14 +43,16 @@
   66.16  concurrentG1Refine.cpp			concurrentG1Refine.hpp
   66.17  concurrentG1Refine.cpp			concurrentG1RefineThread.hpp
   66.18  concurrentG1Refine.cpp			copy.hpp
   66.19 -concurrentG1Refine.cpp			g1CollectedHeap.hpp
   66.20 +concurrentG1Refine.cpp			g1CollectedHeap.inline.hpp
   66.21  concurrentG1Refine.cpp			g1RemSet.hpp
   66.22 +concurrentG1Refine.cpp			space.inline.hpp
   66.23  
   66.24  concurrentG1Refine.hpp			globalDefinitions.hpp
   66.25 +concurrentG1Refine.hpp			allocation.hpp
   66.26  
   66.27  concurrentG1RefineThread.cpp		concurrentG1Refine.hpp
   66.28  concurrentG1RefineThread.cpp		concurrentG1RefineThread.hpp
   66.29 -concurrentG1RefineThread.cpp		g1CollectedHeap.hpp
   66.30 +concurrentG1RefineThread.cpp		g1CollectedHeap.inline.hpp
   66.31  concurrentG1RefineThread.cpp            g1CollectorPolicy.hpp
   66.32  concurrentG1RefineThread.cpp		handles.inline.hpp
   66.33  concurrentG1RefineThread.cpp		mutexLocker.hpp
   66.34 @@ -166,10 +169,11 @@
   66.35  g1CollectorPolicy.cpp			concurrentMarkThread.inline.hpp
   66.36  g1CollectorPolicy.cpp			debug.hpp
   66.37  g1CollectorPolicy.cpp			java.hpp
   66.38 -g1CollectorPolicy.cpp                   g1CollectedHeap.hpp
   66.39 +g1CollectorPolicy.cpp                   g1CollectedHeap.inline.hpp
   66.40  g1CollectorPolicy.cpp                   g1CollectorPolicy.hpp
   66.41  g1CollectorPolicy.cpp                   heapRegionRemSet.hpp
   66.42  g1CollectorPolicy.cpp			mutexLocker.hpp
   66.43 +g1CollectorPolicy.cpp			gcPolicyCounters.hpp
   66.44  
   66.45  g1CollectorPolicy.hpp                   collectorPolicy.hpp
   66.46  g1CollectorPolicy.hpp                   collectionSetChooser.hpp
   66.47 @@ -187,7 +191,7 @@
   66.48  g1MarkSweep.cpp                         codeCache.hpp
   66.49  g1MarkSweep.cpp                         events.hpp
   66.50  g1MarkSweep.cpp                         fprofiler.hpp
   66.51 -g1MarkSweep.hpp                         g1CollectedHeap.hpp
   66.52 +g1MarkSweep.hpp                         g1CollectedHeap.inline.hpp
   66.53  g1MarkSweep.cpp                         g1MarkSweep.hpp
   66.54  g1MarkSweep.cpp                         gcLocker.hpp
   66.55  g1MarkSweep.cpp                         genCollectedHeap.hpp
   66.56 @@ -226,7 +230,7 @@
   66.57  g1MMUTracker.cpp			mutexLocker.hpp
   66.58  
   66.59  g1MMUTracker.hpp			debug.hpp
   66.60 -
   66.61 +g1MMUTracker.hpp			allocation.hpp
   66.62  g1RemSet.cpp				bufferingOopClosure.hpp
   66.63  g1RemSet.cpp				concurrentG1Refine.hpp
   66.64  g1RemSet.cpp				concurrentG1RefineThread.hpp
   66.65 @@ -264,12 +268,13 @@
   66.66  heapRegion.cpp                          iterator.hpp
   66.67  heapRegion.cpp                          oop.inline.hpp
   66.68  
   66.69 -heapRegion.hpp                          space.hpp
   66.70 +heapRegion.hpp                          space.inline.hpp
   66.71  heapRegion.hpp                          spaceDecorator.hpp
   66.72  heapRegion.hpp                          g1BlockOffsetTable.inline.hpp
   66.73  heapRegion.hpp                          watermark.hpp
   66.74  heapRegion.hpp				g1_specialized_oop_closures.hpp
   66.75  heapRegion.hpp				survRateGroup.hpp
   66.76 +heapRegion.hpp				ageTable.hpp
   66.77  
   66.78  heapRegionRemSet.hpp			sparsePRT.hpp
   66.79  
   66.80 @@ -283,7 +288,7 @@
   66.81  heapRegionRemSet.cpp                    space.inline.hpp
   66.82  
   66.83  heapRegionSeq.cpp                       allocation.hpp
   66.84 -heapRegionSeq.cpp                       g1CollectedHeap.hpp
   66.85 +heapRegionSeq.cpp                       g1CollectedHeap.inline.hpp
   66.86  heapRegionSeq.cpp                       heapRegionSeq.hpp
   66.87  
   66.88  heapRegionSeq.hpp                       growableArray.hpp
   66.89 @@ -334,18 +339,18 @@
   66.90  survRateGroup.hpp			numberSeq.hpp
   66.91  
   66.92  survRateGroup.cpp			allocation.hpp
   66.93 -survRateGroup.cpp			g1CollectedHeap.hpp
   66.94 +survRateGroup.cpp			g1CollectedHeap.inline.hpp
   66.95  survRateGroup.cpp			g1CollectorPolicy.hpp
   66.96  survRateGroup.cpp			heapRegion.hpp
   66.97  survRateGroup.cpp			survRateGroup.hpp
   66.98  
   66.99  thread.cpp				concurrentMarkThread.inline.hpp
  66.100  
  66.101 -universe.cpp                            g1CollectedHeap.hpp
  66.102 +universe.cpp                            g1CollectedHeap.inline.hpp
  66.103  universe.cpp                            g1CollectorPolicy.hpp
  66.104  
  66.105  vm_operations_g1.hpp			vmGCOperations.hpp
  66.106  
  66.107  vm_operations_g1.cpp			vm_operations_g1.hpp
  66.108 -vm_operations_g1.cpp                    g1CollectedHeap.hpp
  66.109 +vm_operations_g1.cpp                    g1CollectedHeap.inline.hpp
  66.110  vm_operations_g1.cpp                    isGCActiveMark.hpp
    67.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parNew	Sat Jan 31 17:19:42 2009 -0800
    67.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parNew	Fri Feb 27 15:13:00 2009 -0800
    67.3 @@ -29,6 +29,8 @@
    67.4  asParNewGeneration.cpp                  cmsAdaptiveSizePolicy.hpp
    67.5  asParNewGeneration.cpp                  cmsGCAdaptivePolicyCounters.hpp
    67.6  asParNewGeneration.cpp                  defNewGeneration.inline.hpp
    67.7 +asParNewGeneration.cpp                  markOop.inline.hpp
    67.8 +asParNewGeneration.cpp                  markSweep.inline.hpp
    67.9  asParNewGeneration.cpp                  oop.pcgc.inline.hpp
   67.10  asParNewGeneration.cpp                  parNewGeneration.hpp
   67.11  asParNewGeneration.cpp                  referencePolicy.hpp
   67.12 @@ -40,7 +42,7 @@
   67.13  parCardTableModRefBS.cpp                java.hpp
   67.14  parCardTableModRefBS.cpp                mutexLocker.hpp
   67.15  parCardTableModRefBS.cpp                sharedHeap.hpp
   67.16 -parCardTableModRefBS.cpp                space.hpp
   67.17 +parCardTableModRefBS.cpp                space.inline.hpp
   67.18  parCardTableModRefBS.cpp                universe.hpp
   67.19  parCardTableModRefBS.cpp                virtualspace.hpp
   67.20  
   67.21 @@ -77,6 +79,7 @@
   67.22  parNewGeneration.cpp                    sharedHeap.hpp
   67.23  parNewGeneration.cpp                    space.hpp
   67.24  parNewGeneration.cpp                    spaceDecorator.hpp
   67.25 +parNewGeneration.cpp                    thread.hpp
   67.26  parNewGeneration.cpp                    workgroup.hpp
   67.27  
   67.28  parNewGeneration.hpp                    defNewGeneration.hpp
    68.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Sat Jan 31 17:19:42 2009 -0800
    68.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge	Fri Feb 27 15:13:00 2009 -0800
    68.3 @@ -302,6 +302,8 @@
    68.4  psOldGen.hpp                            spaceCounters.hpp
    68.5  
    68.6  psPermGen.cpp                           gcUtil.hpp
    68.7 +psPermGen.cpp                           markOop.inline.hpp
    68.8 +psPermGen.cpp                           markSweep.inline.hpp
    68.9  psPermGen.cpp                           parallelScavengeHeap.hpp
   68.10  psPermGen.cpp                           psMarkSweepDecorator.hpp
   68.11  psPermGen.cpp                           psParallelCompact.hpp
    69.1 --- a/src/share/vm/gc_implementation/includeDB_gc_shared	Sat Jan 31 17:19:42 2009 -0800
    69.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_shared	Fri Feb 27 15:13:00 2009 -0800
    69.3 @@ -100,4 +100,4 @@
    69.4  spaceCounters.hpp                       perfData.hpp
    69.5  spaceCounters.hpp                       generationCounters.hpp
    69.6  
    69.7 -vmGCOperations.cpp                      g1CollectedHeap.hpp
    69.8 +vmGCOperations.cpp                      g1CollectedHeap.inline.hpp
    70.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Sat Jan 31 17:19:42 2009 -0800
    70.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Feb 27 15:13:00 2009 -0800
    70.3 @@ -404,6 +404,8 @@
    70.4      if (terminator()->offer_termination()) break;
    70.5      par_scan_state()->end_term_time();
    70.6    }
    70.7 +  assert(par_gen()->_overflow_list == NULL && par_gen()->_num_par_pushes == 0,
    70.8 +         "Broken overflow list?");
    70.9    // Finish the last termination pause.
   70.10    par_scan_state()->end_term_time();
   70.11  }
   70.12 @@ -456,6 +458,8 @@
   70.13    _is_alive_closure(this),
   70.14    _plab_stats(YoungPLABSize, PLABWeight)
   70.15  {
   70.16 +  NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
   70.17 +  NOT_PRODUCT(_num_par_pushes = 0;)
   70.18    _task_queues = new ObjToScanQueueSet(ParallelGCThreads);
   70.19    guarantee(_task_queues != NULL, "task_queues allocation failure.");
   70.20  
   70.21 @@ -993,12 +997,19 @@
   70.22               "push forwarded object");
   70.23      }
   70.24      // Push it on one of the queues of to-be-scanned objects.
   70.25 -    if (!par_scan_state->work_queue()->push(obj_to_push)) {
   70.26 +    bool simulate_overflow = false;
   70.27 +    NOT_PRODUCT(
   70.28 +      if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
   70.29 +        // simulate a stack overflow
   70.30 +        simulate_overflow = true;
   70.31 +      }
   70.32 +    )
   70.33 +    if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
   70.34        // Add stats for overflow pushes.
   70.35        if (Verbose && PrintGCDetails) {
   70.36          gclog_or_tty->print("queue overflow!\n");
   70.37        }
   70.38 -      push_on_overflow_list(old);
   70.39 +      push_on_overflow_list(old, par_scan_state);
   70.40        par_scan_state->note_overflow_push();
   70.41      }
   70.42      par_scan_state->note_push();
   70.43 @@ -1110,9 +1121,16 @@
   70.44               "push forwarded object");
   70.45      }
   70.46      // Push it on one of the queues of to-be-scanned objects.
   70.47 -    if (!par_scan_state->work_queue()->push(obj_to_push)) {
   70.48 +    bool simulate_overflow = false;
   70.49 +    NOT_PRODUCT(
   70.50 +      if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) {
   70.51 +        // simulate a stack overflow
   70.52 +        simulate_overflow = true;
   70.53 +      }
   70.54 +    )
   70.55 +    if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
   70.56        // Add stats for overflow pushes.
   70.57 -      push_on_overflow_list(old);
   70.58 +      push_on_overflow_list(old, par_scan_state);
   70.59        par_scan_state->note_overflow_push();
   70.60      }
   70.61      par_scan_state->note_push();
   70.62 @@ -1135,89 +1153,190 @@
   70.63    return forward_ptr;
   70.64  }
   70.65  
   70.66 -void ParNewGeneration::push_on_overflow_list(oop from_space_obj) {
   70.67 -  oop cur_overflow_list = _overflow_list;
   70.68 +#ifndef PRODUCT
   70.69 +// It's OK to call this multi-threaded;  the worst thing
   70.70 +// that can happen is that we'll get a bunch of closely
   70.71 +// spaced simulated oveflows, but that's OK, in fact
   70.72 +// probably good as it would exercise the overflow code
   70.73 +// under contention.
   70.74 +bool ParNewGeneration::should_simulate_overflow() {
   70.75 +  if (_overflow_counter-- <= 0) { // just being defensive
   70.76 +    _overflow_counter = ParGCWorkQueueOverflowInterval;
   70.77 +    return true;
   70.78 +  } else {
   70.79 +    return false;
   70.80 +  }
   70.81 +}
   70.82 +#endif
   70.83 +
   70.84 +#define BUSY (oop(0x1aff1aff))
   70.85 +void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) {
   70.86    // if the object has been forwarded to itself, then we cannot
   70.87    // use the klass pointer for the linked list.  Instead we have
   70.88    // to allocate an oopDesc in the C-Heap and use that for the linked list.
   70.89 +  // XXX This is horribly inefficient when a promotion failure occurs
   70.90 +  // and should be fixed. XXX FIX ME !!!
   70.91 +#ifndef PRODUCT
   70.92 +  Atomic::inc_ptr(&_num_par_pushes);
   70.93 +  assert(_num_par_pushes > 0, "Tautology");
   70.94 +#endif
   70.95    if (from_space_obj->forwardee() == from_space_obj) {
   70.96      oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
   70.97      listhead->forward_to(from_space_obj);
   70.98      from_space_obj = listhead;
   70.99    }
  70.100 -  while (true) {
  70.101 -    from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
  70.102 -    oop observed_overflow_list =
  70.103 +  oop observed_overflow_list = _overflow_list;
  70.104 +  oop cur_overflow_list;
  70.105 +  do {
  70.106 +    cur_overflow_list = observed_overflow_list;
  70.107 +    if (cur_overflow_list != BUSY) {
  70.108 +      from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
  70.109 +    } else {
  70.110 +      from_space_obj->set_klass_to_list_ptr(NULL);
  70.111 +    }
  70.112 +    observed_overflow_list =
  70.113        (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
  70.114 -    if (observed_overflow_list == cur_overflow_list) break;
  70.115 -    // Otherwise...
  70.116 -    cur_overflow_list = observed_overflow_list;
  70.117 -  }
  70.118 +  } while (cur_overflow_list != observed_overflow_list);
  70.119  }
  70.120  
  70.121 +// *NOTE*: The overflow list manipulation code here and
  70.122 +// in CMSCollector:: are very similar in shape,
  70.123 +// except that in the CMS case we thread the objects
  70.124 +// directly into the list via their mark word, and do
  70.125 +// not need to deal with special cases below related
  70.126 +// to chunking of object arrays and promotion failure
  70.127 +// handling.
  70.128 +// CR 6797058 has been filed to attempt consolidation of
  70.129 +// the common code.
  70.130 +// Because of the common code, if you make any changes in
  70.131 +// the code below, please check the CMS version to see if
  70.132 +// similar changes might be needed.
  70.133 +// See CMSCollector::par_take_from_overflow_list() for
  70.134 +// more extensive documentation comments.
  70.135  bool
  70.136  ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
  70.137    ObjToScanQueue* work_q = par_scan_state->work_queue();
  70.138 +  assert(work_q->size() == 0, "Should first empty local work queue");
  70.139    // How many to take?
  70.140 -  int objsFromOverflow = MIN2(work_q->max_elems()/4,
  70.141 -                              (juint)ParGCDesiredObjsFromOverflowList);
  70.142 +  size_t objsFromOverflow = MIN2((size_t)work_q->max_elems()/4,
  70.143 +                                 (size_t)ParGCDesiredObjsFromOverflowList);
  70.144  
  70.145    if (_overflow_list == NULL) return false;
  70.146  
  70.147    // Otherwise, there was something there; try claiming the list.
  70.148 -  oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list);
  70.149 -
  70.150 -  if (prefix == NULL) {
  70.151 -    return false;
  70.152 +  oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
  70.153 +  // Trim off a prefix of at most objsFromOverflow items
  70.154 +  Thread* tid = Thread::current();
  70.155 +  size_t spin_count = (size_t)ParallelGCThreads;
  70.156 +  size_t sleep_time_millis = MAX2((size_t)1, objsFromOverflow/100);
  70.157 +  for (size_t spin = 0; prefix == BUSY && spin < spin_count; spin++) {
  70.158 +    // someone grabbed it before we did ...
  70.159 +    // ... we spin for a short while...
  70.160 +    os::sleep(tid, sleep_time_millis, false);
  70.161 +    if (_overflow_list == NULL) {
  70.162 +      // nothing left to take
  70.163 +      return false;
  70.164 +    } else if (_overflow_list != BUSY) {
  70.165 +     // try and grab the prefix
  70.166 +     prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list);
  70.167 +    }
  70.168    }
  70.169 -  // Trim off a prefix of at most objsFromOverflow items
  70.170 -  int i = 1;
  70.171 +  if (prefix == NULL || prefix == BUSY) {
  70.172 +     // Nothing to take or waited long enough
  70.173 +     if (prefix == NULL) {
  70.174 +       // Write back the NULL in case we overwrote it with BUSY above
  70.175 +       // and it is still the same value.
  70.176 +       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  70.177 +     }
  70.178 +     return false;
  70.179 +  }
  70.180 +  assert(prefix != NULL && prefix != BUSY, "Error");
  70.181 +  size_t i = 1;
  70.182    oop cur = prefix;
  70.183    while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
  70.184      i++; cur = oop(cur->klass());
  70.185    }
  70.186  
  70.187    // Reattach remaining (suffix) to overflow list
  70.188 -  if (cur->klass_or_null() != NULL) {
  70.189 -    oop suffix = oop(cur->klass());
  70.190 -    cur->set_klass_to_list_ptr(NULL);
  70.191 -
  70.192 -    // Find last item of suffix list
  70.193 -    oop last = suffix;
  70.194 -    while (last->klass_or_null() != NULL) {
  70.195 -      last = oop(last->klass());
  70.196 +  if (cur->klass_or_null() == NULL) {
  70.197 +    // Write back the NULL in lieu of the BUSY we wrote
  70.198 +    // above and it is still the same value.
  70.199 +    if (_overflow_list == BUSY) {
  70.200 +      (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  70.201      }
  70.202 -    // Atomically prepend suffix to current overflow list
  70.203 -    oop cur_overflow_list = _overflow_list;
  70.204 -    while (true) {
  70.205 -      last->set_klass_to_list_ptr(cur_overflow_list);
  70.206 -      oop observed_overflow_list =
  70.207 -        (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
  70.208 -      if (observed_overflow_list == cur_overflow_list) break;
  70.209 -      // Otherwise...
  70.210 -      cur_overflow_list = observed_overflow_list;
  70.211 +  } else {
  70.212 +    assert(cur->klass_or_null() != BUSY, "Error");
  70.213 +    oop suffix = oop(cur->klass());       // suffix will be put back on global list
  70.214 +    cur->set_klass_to_list_ptr(NULL);     // break off suffix
  70.215 +    // It's possible that the list is still in the empty(busy) state
  70.216 +    // we left it in a short while ago; in that case we may be
  70.217 +    // able to place back the suffix.
  70.218 +    oop observed_overflow_list = _overflow_list;
  70.219 +    oop cur_overflow_list = observed_overflow_list;
  70.220 +    bool attached = false;
  70.221 +    while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
  70.222 +      observed_overflow_list =
  70.223 +        (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
  70.224 +      if (cur_overflow_list == observed_overflow_list) {
  70.225 +        attached = true;
  70.226 +        break;
  70.227 +      } else cur_overflow_list = observed_overflow_list;
  70.228 +    }
  70.229 +    if (!attached) {
  70.230 +      // Too bad, someone else got in in between; we'll need to do a splice.
  70.231 +      // Find the last item of suffix list
  70.232 +      oop last = suffix;
  70.233 +      while (last->klass_or_null() != NULL) {
  70.234 +        last = oop(last->klass());
  70.235 +      }
  70.236 +      // Atomically prepend suffix to current overflow list
  70.237 +      observed_overflow_list = _overflow_list;
  70.238 +      do {
  70.239 +        cur_overflow_list = observed_overflow_list;
  70.240 +        if (cur_overflow_list != BUSY) {
  70.241 +          // Do the splice ...
  70.242 +          last->set_klass_to_list_ptr(cur_overflow_list);
  70.243 +        } else { // cur_overflow_list == BUSY
  70.244 +          last->set_klass_to_list_ptr(NULL);
  70.245 +        }
  70.246 +        observed_overflow_list =
  70.247 +          (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
  70.248 +      } while (cur_overflow_list != observed_overflow_list);
  70.249      }
  70.250    }
  70.251  
  70.252    // Push objects on prefix list onto this thread's work queue
  70.253 -  assert(cur != NULL, "program logic");
  70.254 +  assert(prefix != NULL && prefix != BUSY, "program logic");
  70.255    cur = prefix;
  70.256 -  int n = 0;
  70.257 +  ssize_t n = 0;
  70.258    while (cur != NULL) {
  70.259      oop obj_to_push = cur->forwardee();
  70.260      oop next        = oop(cur->klass_or_null());
  70.261      cur->set_klass(obj_to_push->klass());
  70.262 -    if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
  70.263 +    // This may be an array object that is self-forwarded. In that case, the list pointer
  70.264 +    // space, cur, is not in the Java heap, but rather in the C-heap and should be freed.
  70.265 +    if (!is_in_reserved(cur)) {
  70.266 +      // This can become a scaling bottleneck when there is work queue overflow coincident
  70.267 +      // with promotion failure.
  70.268 +      oopDesc* f = cur;
  70.269 +      FREE_C_HEAP_ARRAY(oopDesc, f);
  70.270 +    } else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
  70.271 +      assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
  70.272        obj_to_push = cur;
  70.273 -      assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
  70.274      }
  70.275 -    work_q->push(obj_to_push);
  70.276 +    bool ok = work_q->push(obj_to_push);
  70.277 +    assert(ok, "Should have succeeded");
  70.278      cur = next;
  70.279      n++;
  70.280    }
  70.281    par_scan_state->note_overflow_refill(n);
  70.282 +#ifndef PRODUCT
  70.283 +  assert(_num_par_pushes >= n, "Too many pops?");
  70.284 +  Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
  70.285 +#endif
  70.286    return true;
  70.287  }
  70.288 +#undef BUSY
  70.289  
  70.290  void ParNewGeneration::ref_processor_init()
  70.291  {
    71.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Sat Jan 31 17:19:42 2009 -0800
    71.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Feb 27 15:13:00 2009 -0800
    71.3 @@ -278,6 +278,7 @@
    71.4    friend class ParNewRefProcTask;
    71.5    friend class ParNewRefProcTaskExecutor;
    71.6    friend class ParScanThreadStateSet;
    71.7 +  friend class ParEvacuateFollowersClosure;
    71.8  
    71.9   private:
   71.10    // XXX use a global constant instead of 64!
   71.11 @@ -296,6 +297,7 @@
   71.12    // klass-pointers (klass information already copied to the forwarded
   71.13    // image.)  Manipulated with CAS.
   71.14    oop _overflow_list;
   71.15 +  NOT_PRODUCT(ssize_t _num_par_pushes;)
   71.16  
   71.17    // If true, older generation does not support promotion undo, so avoid.
   71.18    static bool _avoid_promotion_undo;
   71.19 @@ -372,8 +374,12 @@
   71.20    oop copy_to_survivor_space_with_undo(ParScanThreadState* par_scan_state,
   71.21                               oop obj, size_t obj_sz, markOop m);
   71.22  
   71.23 +  // in support of testing overflow code
   71.24 +  NOT_PRODUCT(int _overflow_counter;)
   71.25 +  NOT_PRODUCT(bool should_simulate_overflow();)
   71.26 +
   71.27    // Push the given (from-space) object on the global overflow list.
   71.28 -  void push_on_overflow_list(oop from_space_obj);
   71.29 +  void push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state);
   71.30  
   71.31    // If the global overflow list is non-empty, move some tasks from it
   71.32    // onto "work_q" (which must be empty).  No more than 1/4 of the
    72.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Sat Jan 31 17:19:42 2009 -0800
    72.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Fri Feb 27 15:13:00 2009 -0800
    72.3 @@ -200,6 +200,7 @@
    72.4  
    72.5    void oop_iterate(OopClosure* cl);
    72.6    void object_iterate(ObjectClosure* cl);
    72.7 +  void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
    72.8    void permanent_oop_iterate(OopClosure* cl);
    72.9    void permanent_object_iterate(ObjectClosure* cl);
   72.10  
    73.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Sat Jan 31 17:19:42 2009 -0800
    73.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Feb 27 15:13:00 2009 -0800
    73.3 @@ -362,6 +362,10 @@
    73.4    if (PrintHeapAtGC) {
    73.5      Universe::print_heap_after_gc();
    73.6    }
    73.7 +
    73.8 +#ifdef TRACESPINNING
    73.9 +  ParallelTaskTerminator::print_termination_counts();
   73.10 +#endif
   73.11  }
   73.12  
   73.13  bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
    74.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Sat Jan 31 17:19:42 2009 -0800
    74.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Fri Feb 27 15:13:00 2009 -0800
    74.3 @@ -116,7 +116,7 @@
    74.4    // ObjectSpace stuff
    74.5    //
    74.6  
    74.7 -  _object_space = new MutableSpace();
    74.8 +  _object_space = new MutableSpace(virtual_space()->alignment());
    74.9  
   74.10    if (_object_space == NULL)
   74.11      vm_exit_during_initialization("Could not allocate an old gen space");
   74.12 @@ -385,10 +385,10 @@
   74.13    start_array()->set_covered_region(new_memregion);
   74.14    Universe::heap()->barrier_set()->resize_covered_region(new_memregion);
   74.15  
   74.16 -  HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high();
   74.17 -
   74.18    // ALWAYS do this last!!
   74.19 -  object_space()->set_end(virtual_space_high);
   74.20 +  object_space()->initialize(new_memregion,
   74.21 +                             SpaceDecorator::DontClear,
   74.22 +                             SpaceDecorator::DontMangle);
   74.23  
   74.24    assert(new_word_size == heap_word_size(object_space()->capacity_in_bytes()),
   74.25      "Sanity");
    75.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Sat Jan 31 17:19:42 2009 -0800
    75.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Feb 27 15:13:00 2009 -0800
    75.3 @@ -2203,6 +2203,10 @@
    75.4                             collection_exit.ticks());
    75.5      gc_task_manager()->print_task_time_stamps();
    75.6    }
    75.7 +
    75.8 +#ifdef TRACESPINNING
    75.9 +  ParallelTaskTerminator::print_termination_counts();
   75.10 +#endif
   75.11  }
   75.12  
   75.13  bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
    76.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Sat Jan 31 17:19:42 2009 -0800
    76.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Feb 27 15:13:00 2009 -0800
    76.3 @@ -615,6 +615,10 @@
    76.4      gc_task_manager()->print_task_time_stamps();
    76.5    }
    76.6  
    76.7 +#ifdef TRACESPINNING
    76.8 +  ParallelTaskTerminator::print_termination_counts();
    76.9 +#endif
   76.10 +
   76.11    return !promotion_failure_occurred;
   76.12  }
   76.13  
    77.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Sat Jan 31 17:19:42 2009 -0800
    77.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Fri Feb 27 15:13:00 2009 -0800
    77.3 @@ -78,7 +78,7 @@
    77.4    _special = false;
    77.5  }
    77.6  
    77.7 -bool PSVirtualSpace::expand_by(size_t bytes, bool pre_touch) {
    77.8 +bool PSVirtualSpace::expand_by(size_t bytes) {
    77.9    assert(is_aligned(bytes), "arg not aligned");
   77.10    DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   77.11  
   77.12 @@ -92,15 +92,6 @@
   77.13      _committed_high_addr += bytes;
   77.14    }
   77.15  
   77.16 -  if (pre_touch || AlwaysPreTouch) {
   77.17 -    for (char* curr = base_addr;
   77.18 -         curr < _committed_high_addr;
   77.19 -         curr += os::vm_page_size()) {
   77.20 -      char tmp = *curr;
   77.21 -      *curr = 0;
   77.22 -    }
   77.23 -  }
   77.24 -
   77.25    return result;
   77.26  }
   77.27  
   77.28 @@ -255,7 +246,7 @@
   77.29    DEBUG_ONLY(verify());
   77.30  }
   77.31  
   77.32 -bool PSVirtualSpaceHighToLow::expand_by(size_t bytes, bool pre_touch) {
   77.33 +bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
   77.34    assert(is_aligned(bytes), "arg not aligned");
   77.35    DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
   77.36  
   77.37 @@ -269,15 +260,6 @@
   77.38      _committed_low_addr -= bytes;
   77.39    }
   77.40  
   77.41 -  if (pre_touch || AlwaysPreTouch) {
   77.42 -    for (char* curr = base_addr;
   77.43 -         curr < _committed_high_addr;
   77.44 -         curr += os::vm_page_size()) {
   77.45 -      char tmp = *curr;
   77.46 -      *curr = 0;
   77.47 -    }
   77.48 -  }
   77.49 -
   77.50    return result;
   77.51  }
   77.52  
    78.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp	Sat Jan 31 17:19:42 2009 -0800
    78.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp	Fri Feb 27 15:13:00 2009 -0800
    78.3 @@ -80,7 +80,7 @@
    78.4    inline  void   set_reserved(char* low_addr, char* high_addr, bool special);
    78.5    inline  void   set_reserved(ReservedSpace rs);
    78.6    inline  void   set_committed(char* low_addr, char* high_addr);
    78.7 -  virtual bool   expand_by(size_t bytes, bool pre_touch = false);
    78.8 +  virtual bool   expand_by(size_t bytes);
    78.9    virtual bool   shrink_by(size_t bytes);
   78.10    virtual size_t expand_into(PSVirtualSpace* space, size_t bytes);
   78.11    void           release();
   78.12 @@ -127,7 +127,7 @@
   78.13    PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment);
   78.14    PSVirtualSpaceHighToLow(ReservedSpace rs);
   78.15  
   78.16 -  virtual bool   expand_by(size_t bytes, bool pre_touch = false);
   78.17 +  virtual bool   expand_by(size_t bytes);
   78.18    virtual bool   shrink_by(size_t bytes);
   78.19    virtual size_t expand_into(PSVirtualSpace* space, size_t bytes);
   78.20  
    79.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Sat Jan 31 17:19:42 2009 -0800
    79.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Fri Feb 27 15:13:00 2009 -0800
    79.3 @@ -64,12 +64,12 @@
    79.4    }
    79.5  
    79.6    if (UseNUMA) {
    79.7 -    _eden_space = new MutableNUMASpace();
    79.8 +    _eden_space = new MutableNUMASpace(virtual_space()->alignment());
    79.9    } else {
   79.10 -    _eden_space = new MutableSpace();
   79.11 +    _eden_space = new MutableSpace(virtual_space()->alignment());
   79.12    }
   79.13 -  _from_space = new MutableSpace();
   79.14 -  _to_space   = new MutableSpace();
   79.15 +  _from_space = new MutableSpace(virtual_space()->alignment());
   79.16 +  _to_space   = new MutableSpace(virtual_space()->alignment());
   79.17  
   79.18    if (_eden_space == NULL || _from_space == NULL || _to_space == NULL) {
   79.19      vm_exit_during_initialization("Could not allocate a young gen space");
    80.1 --- a/src/share/vm/gc_implementation/shared/ageTable.cpp	Sat Jan 31 17:19:42 2009 -0800
    80.2 +++ b/src/share/vm/gc_implementation/shared/ageTable.cpp	Fri Feb 27 15:13:00 2009 -0800
    80.3 @@ -67,6 +67,12 @@
    80.4    }
    80.5  }
    80.6  
    80.7 +void ageTable::merge_par(ageTable* subTable) {
    80.8 +  for (int i = 0; i < table_size; i++) {
    80.9 +    Atomic::add_ptr(subTable->sizes[i], &sizes[i]);
   80.10 +  }
   80.11 +}
   80.12 +
   80.13  int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
   80.14    size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
   80.15    size_t total = 0;
    81.1 --- a/src/share/vm/gc_implementation/shared/ageTable.hpp	Sat Jan 31 17:19:42 2009 -0800
    81.2 +++ b/src/share/vm/gc_implementation/shared/ageTable.hpp	Fri Feb 27 15:13:00 2009 -0800
    81.3 @@ -56,6 +56,7 @@
    81.4    // Merge another age table with the current one.  Used
    81.5    // for parallel young generation gc.
    81.6    void merge(ageTable* subTable);
    81.7 +  void merge_par(ageTable* subTable);
    81.8  
    81.9    // calculate new tenuring threshold based on age information
   81.10    int compute_tenuring_threshold(size_t survivor_capacity);
    82.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Sat Jan 31 17:19:42 2009 -0800
    82.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Fri Feb 27 15:13:00 2009 -0800
    82.3 @@ -27,7 +27,7 @@
    82.4  # include "incls/_mutableNUMASpace.cpp.incl"
    82.5  
    82.6  
    82.7 -MutableNUMASpace::MutableNUMASpace() {
    82.8 +MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) {
    82.9    _lgrp_spaces = new (ResourceObj::C_HEAP) GrowableArray<LGRPSpace*>(0, true);
   82.10    _page_size = os::vm_page_size();
   82.11    _adaptation_cycles = 0;
   82.12 @@ -221,7 +221,7 @@
   82.13          }
   82.14        }
   82.15        if (!found) {
   82.16 -        lgrp_spaces()->append(new LGRPSpace(lgrp_ids[i]));
   82.17 +        lgrp_spaces()->append(new LGRPSpace(lgrp_ids[i], alignment()));
   82.18        }
   82.19      }
   82.20  
   82.21 @@ -443,10 +443,10 @@
   82.22    // Is there bottom?
   82.23    if (new_region.start() < intersection.start()) { // Yes
   82.24      // Try to coalesce small pages into a large one.
   82.25 -    if (UseLargePages && page_size() >= os::large_page_size()) {
   82.26 -      HeapWord* p = (HeapWord*)round_to((intptr_t) intersection.start(), os::large_page_size());
   82.27 +    if (UseLargePages && page_size() >= alignment()) {
   82.28 +      HeapWord* p = (HeapWord*)round_to((intptr_t) intersection.start(), alignment());
   82.29        if (new_region.contains(p)
   82.30 -          && pointer_delta(p, new_region.start(), sizeof(char)) >= os::large_page_size()) {
   82.31 +          && pointer_delta(p, new_region.start(), sizeof(char)) >= alignment()) {
   82.32          if (intersection.contains(p)) {
   82.33            intersection = MemRegion(p, intersection.end());
   82.34          } else {
   82.35 @@ -462,10 +462,10 @@
   82.36    // Is there top?
   82.37    if (intersection.end() < new_region.end()) { // Yes
   82.38      // Try to coalesce small pages into a large one.
   82.39 -    if (UseLargePages && page_size() >= os::large_page_size()) {
   82.40 -      HeapWord* p = (HeapWord*)round_down((intptr_t) intersection.end(), os::large_page_size());
   82.41 +    if (UseLargePages && page_size() >= alignment()) {
   82.42 +      HeapWord* p = (HeapWord*)round_down((intptr_t) intersection.end(), alignment());
   82.43        if (new_region.contains(p)
   82.44 -          && pointer_delta(new_region.end(), p, sizeof(char)) >= os::large_page_size()) {
   82.45 +          && pointer_delta(new_region.end(), p, sizeof(char)) >= alignment()) {
   82.46          if (intersection.contains(p)) {
   82.47            intersection = MemRegion(intersection.start(), p);
   82.48          } else {
   82.49 @@ -504,12 +504,12 @@
   82.50              // That's the only case we have to make an additional bias_region() call.
   82.51              HeapWord* start = invalid_region->start();
   82.52              HeapWord* end = invalid_region->end();
   82.53 -            if (UseLargePages && page_size() >= os::large_page_size()) {
   82.54 -              HeapWord *p = (HeapWord*)round_down((intptr_t) start, os::large_page_size());
   82.55 +            if (UseLargePages && page_size() >= alignment()) {
   82.56 +              HeapWord *p = (HeapWord*)round_down((intptr_t) start, alignment());
   82.57                if (new_region.contains(p)) {
   82.58                  start = p;
   82.59                }
   82.60 -              p = (HeapWord*)round_to((intptr_t) end, os::large_page_size());
   82.61 +              p = (HeapWord*)round_to((intptr_t) end, alignment());
   82.62                if (new_region.contains(end)) {
   82.63                  end = p;
   82.64                }
   82.65 @@ -526,7 +526,8 @@
   82.66  
   82.67  void MutableNUMASpace::initialize(MemRegion mr,
   82.68                                    bool clear_space,
   82.69 -                                  bool mangle_space) {
   82.70 +                                  bool mangle_space,
   82.71 +                                  bool setup_pages) {
   82.72    assert(clear_space, "Reallocation will destory data!");
   82.73    assert(lgrp_spaces()->length() > 0, "There should be at least one space");
   82.74  
   82.75 @@ -538,7 +539,7 @@
   82.76  
   82.77    // Compute chunk sizes
   82.78    size_t prev_page_size = page_size();
   82.79 -  set_page_size(UseLargePages ? os::large_page_size() : os::vm_page_size());
   82.80 +  set_page_size(UseLargePages ? alignment() : os::vm_page_size());
   82.81    HeapWord* rounded_bottom = (HeapWord*)round_to((intptr_t) bottom(), page_size());
   82.82    HeapWord* rounded_end = (HeapWord*)round_down((intptr_t) end(), page_size());
   82.83    size_t base_space_size_pages = pointer_delta(rounded_end, rounded_bottom, sizeof(char)) / page_size();
   82.84 @@ -666,7 +667,7 @@
   82.85      }
   82.86  
   82.87      // Clear space (set top = bottom) but never mangle.
   82.88 -    s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle);
   82.89 +    s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle, MutableSpace::DontSetupPages);
   82.90  
   82.91      set_adaptation_cycles(samples_count());
   82.92    }
    83.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Sat Jan 31 17:19:42 2009 -0800
    83.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Fri Feb 27 15:13:00 2009 -0800
    83.3 @@ -82,8 +82,8 @@
    83.4      char* last_page_scanned()            { return _last_page_scanned; }
    83.5      void set_last_page_scanned(char* p)  { _last_page_scanned = p;    }
    83.6     public:
    83.7 -    LGRPSpace(int l) : _lgrp_id(l), _last_page_scanned(NULL), _allocation_failed(false) {
    83.8 -      _space = new MutableSpace();
    83.9 +    LGRPSpace(int l, size_t alignment) : _lgrp_id(l), _last_page_scanned(NULL), _allocation_failed(false) {
   83.10 +      _space = new MutableSpace(alignment);
   83.11        _alloc_rate = new AdaptiveWeightedAverage(NUMAChunkResizeWeight);
   83.12      }
   83.13      ~LGRPSpace() {
   83.14 @@ -183,10 +183,10 @@
   83.15  
   83.16   public:
   83.17    GrowableArray<LGRPSpace*>* lgrp_spaces() const     { return _lgrp_spaces;       }
   83.18 -  MutableNUMASpace();
   83.19 +  MutableNUMASpace(size_t alignment);
   83.20    virtual ~MutableNUMASpace();
   83.21    // Space initialization.
   83.22 -  virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
   83.23 +  virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space, bool setup_pages = SetupPages);
   83.24    // Update space layout if necessary. Do all adaptive resizing job.
   83.25    virtual void update();
   83.26    // Update allocation rate averages.
    84.1 --- a/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Sat Jan 31 17:19:42 2009 -0800
    84.2 +++ b/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Fri Feb 27 15:13:00 2009 -0800
    84.3 @@ -25,7 +25,10 @@
    84.4  # include "incls/_precompiled.incl"
    84.5  # include "incls/_mutableSpace.cpp.incl"
    84.6  
    84.7 -MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) {
    84.8 +MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) {
    84.9 +  assert(MutableSpace::alignment() >= 0 &&
   84.10 +         MutableSpace::alignment() % os::vm_page_size() == 0,
   84.11 +         "Space should be aligned");
   84.12    _mangler = new MutableSpaceMangler(this);
   84.13  }
   84.14  
   84.15 @@ -33,16 +36,88 @@
   84.16    delete _mangler;
   84.17  }
   84.18  
   84.19 +void MutableSpace::numa_setup_pages(MemRegion mr, bool clear_space) {
   84.20 +  if (!mr.is_empty()) {
   84.21 +    size_t page_size = UseLargePages ? alignment() : os::vm_page_size();
   84.22 +    HeapWord *start = (HeapWord*)round_to((intptr_t) mr.start(), page_size);
   84.23 +    HeapWord *end =  (HeapWord*)round_down((intptr_t) mr.end(), page_size);
   84.24 +    if (end > start) {
   84.25 +      size_t size = pointer_delta(end, start, sizeof(char));
   84.26 +      if (clear_space) {
   84.27 +        // Prefer page reallocation to migration.
   84.28 +        os::free_memory((char*)start, size);
   84.29 +      }
   84.30 +      os::numa_make_global((char*)start, size);
   84.31 +    }
   84.32 +  }
   84.33 +}
   84.34 +
   84.35 +void MutableSpace::pretouch_pages(MemRegion mr) {
   84.36 +  for (volatile char *p = (char*)mr.start(); p < (char*)mr.end(); p += os::vm_page_size()) {
   84.37 +    char t = *p; *p = t;
   84.38 +  }
   84.39 +}
   84.40 +
   84.41  void MutableSpace::initialize(MemRegion mr,
   84.42                                bool clear_space,
   84.43 -                              bool mangle_space) {
   84.44 -  HeapWord* bottom = mr.start();
   84.45 -  HeapWord* end    = mr.end();
   84.46 +                              bool mangle_space,
   84.47 +                              bool setup_pages) {
   84.48  
   84.49 -  assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end),
   84.50 +  assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()),
   84.51           "invalid space boundaries");
   84.52 -  set_bottom(bottom);
   84.53 -  set_end(end);
   84.54 +
   84.55 +  if (setup_pages && (UseNUMA || AlwaysPreTouch)) {
   84.56 +    // The space may move left and right or expand/shrink.
   84.57 +    // We'd like to enforce the desired page placement.
   84.58 +    MemRegion head, tail;
   84.59 +    if (last_setup_region().is_empty()) {
   84.60 +      // If it's the first initialization don't limit the amount of work.
   84.61 +      head = mr;
   84.62 +      tail = MemRegion(mr.end(), mr.end());
   84.63 +    } else {
   84.64 +      // Is there an intersection with the address space?
   84.65 +      MemRegion intersection = last_setup_region().intersection(mr);
   84.66 +      if (intersection.is_empty()) {
   84.67 +        intersection = MemRegion(mr.end(), mr.end());
   84.68 +      }
   84.69 +      // All the sizes below are in words.
   84.70 +      size_t head_size = 0, tail_size = 0;
   84.71 +      if (mr.start() <= intersection.start()) {
   84.72 +        head_size = pointer_delta(intersection.start(), mr.start());
   84.73 +      }
   84.74 +      if(intersection.end() <= mr.end()) {
   84.75 +        tail_size = pointer_delta(mr.end(), intersection.end());
   84.76 +      }
   84.77 +      // Limit the amount of page manipulation if necessary.
   84.78 +      if (NUMASpaceResizeRate > 0 && !AlwaysPreTouch) {
   84.79 +        const size_t change_size = head_size + tail_size;
   84.80 +        const float setup_rate_words = NUMASpaceResizeRate >> LogBytesPerWord;
   84.81 +        head_size = MIN2((size_t)(setup_rate_words * head_size / change_size),
   84.82 +                         head_size);
   84.83 +        tail_size = MIN2((size_t)(setup_rate_words * tail_size / change_size),
   84.84 +                         tail_size);
   84.85 +      }
   84.86 +      head = MemRegion(intersection.start() - head_size, intersection.start());
   84.87 +      tail = MemRegion(intersection.end(), intersection.end() + tail_size);
   84.88 +    }
   84.89 +    assert(mr.contains(head) && mr.contains(tail), "Sanity");
   84.90 +
   84.91 +    if (UseNUMA) {
   84.92 +      numa_setup_pages(head, clear_space);
   84.93 +      numa_setup_pages(tail, clear_space);
   84.94 +    }
   84.95 +
   84.96 +    if (AlwaysPreTouch) {
   84.97 +      pretouch_pages(head);
   84.98 +      pretouch_pages(tail);
   84.99 +    }
  84.100 +
  84.101 +    // Remember where we stopped so that we can continue later.
  84.102 +    set_last_setup_region(MemRegion(head.start(), tail.end()));
  84.103 +  }
  84.104 +
  84.105 +  set_bottom(mr.start());
  84.106 +  set_end(mr.end());
  84.107  
  84.108    if (clear_space) {
  84.109      clear(mangle_space);
    85.1 --- a/src/share/vm/gc_implementation/shared/mutableSpace.hpp	Sat Jan 31 17:19:42 2009 -0800
    85.2 +++ b/src/share/vm/gc_implementation/shared/mutableSpace.hpp	Fri Feb 27 15:13:00 2009 -0800
    85.3 @@ -25,7 +25,10 @@
    85.4  // A MutableSpace is a subtype of ImmutableSpace that supports the
    85.5  // concept of allocation. This includes the concepts that a space may
    85.6  // be only partially full, and the querry methods that go with such
    85.7 -// an assumption.
    85.8 +// an assumption. MutableSpace is also responsible for minimizing the
    85.9 +// page allocation time by having the memory pretouched (with
   85.10 +// AlwaysPretouch) and for optimizing page placement on NUMA systems
   85.11 +// by make the underlying region interleaved (with UseNUMA).
   85.12  //
   85.13  // Invariant: (ImmutableSpace +) bottom() <= top() <= end()
   85.14  // top() is inclusive and end() is exclusive.
   85.15 @@ -37,15 +40,23 @@
   85.16  
   85.17    // Helper for mangling unused space in debug builds
   85.18    MutableSpaceMangler* _mangler;
   85.19 -
   85.20 +  // The last region which page had been setup to be interleaved.
   85.21 +  MemRegion _last_setup_region;
   85.22 +  size_t _alignment;
   85.23   protected:
   85.24    HeapWord* _top;
   85.25  
   85.26    MutableSpaceMangler* mangler() { return _mangler; }
   85.27  
   85.28 +  void numa_setup_pages(MemRegion mr, bool clear_space);
   85.29 +  void pretouch_pages(MemRegion mr);
   85.30 +
   85.31 +  void set_last_setup_region(MemRegion mr) { _last_setup_region = mr;   }
   85.32 +  MemRegion last_setup_region() const      { return _last_setup_region; }
   85.33 +
   85.34   public:
   85.35    virtual ~MutableSpace();
   85.36 -  MutableSpace();
   85.37 +  MutableSpace(size_t page_size);
   85.38  
   85.39    // Accessors
   85.40    HeapWord* top() const                    { return _top;    }
   85.41 @@ -57,13 +68,20 @@
   85.42    virtual void set_bottom(HeapWord* value) { _bottom = value; }
   85.43    virtual void set_end(HeapWord* value)    { _end = value; }
   85.44  
   85.45 +  size_t alignment()                       { return _alignment; }
   85.46 +
   85.47    // Returns a subregion containing all objects in this space.
   85.48    MemRegion used_region() { return MemRegion(bottom(), top()); }
   85.49  
   85.50 +  static const bool SetupPages = true;
   85.51 +  static const bool DontSetupPages = false;
   85.52 +
   85.53    // Initialization
   85.54    virtual void initialize(MemRegion mr,
   85.55                            bool clear_space,
   85.56 -                          bool mangle_space);
   85.57 +                          bool mangle_space,
   85.58 +                          bool setup_pages = SetupPages);
   85.59 +
   85.60    virtual void clear(bool mangle_space);
   85.61    // Does the usual initialization but optionally resets top to bottom.
   85.62  #if 0  // MANGLE_SPACE
    86.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp	Sat Jan 31 17:19:42 2009 -0800
    86.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp	Fri Feb 27 15:13:00 2009 -0800
    86.3 @@ -42,6 +42,7 @@
    86.4  class CollectedHeap : public CHeapObj {
    86.5    friend class VMStructs;
    86.6    friend class IsGCActiveMark; // Block structured external access to _is_gc_active
    86.7 +  friend class constantPoolCacheKlass; // allocate() method inserts is_conc_safe
    86.8  
    86.9  #ifdef ASSERT
   86.10    static int       _fire_out_of_memory_count;
   86.11 @@ -82,8 +83,6 @@
   86.12    // Reinitialize tlabs before resuming mutators.
   86.13    virtual void resize_all_tlabs();
   86.14  
   86.15 -  debug_only(static void check_for_valid_allocation_state();)
   86.16 -
   86.17   protected:
   86.18    // Allocate from the current thread's TLAB, with broken-out slow path.
   86.19    inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
   86.20 @@ -142,6 +141,7 @@
   86.21      PRODUCT_RETURN;
   86.22    virtual void check_for_non_bad_heap_word_value(HeapWord* addr, size_t size)
   86.23      PRODUCT_RETURN;
   86.24 +  debug_only(static void check_for_valid_allocation_state();)
   86.25  
   86.26   public:
   86.27    enum Name {
   86.28 @@ -466,6 +466,10 @@
   86.29    // This includes objects in permanent memory.
   86.30    virtual void object_iterate(ObjectClosure* cl) = 0;
   86.31  
   86.32 +  // Similar to object_iterate() except iterates only
   86.33 +  // over live objects.
   86.34 +  virtual void safe_object_iterate(ObjectClosure* cl) = 0;
   86.35 +
   86.36    // Behaves the same as oop_iterate, except only traverses
   86.37    // interior pointers contained in permanent memory. If there
   86.38    // is no permanent memory, does nothing.
    87.1 --- a/src/share/vm/includeDB_compiler2	Sat Jan 31 17:19:42 2009 -0800
    87.2 +++ b/src/share/vm/includeDB_compiler2	Fri Feb 27 15:13:00 2009 -0800
    87.3 @@ -140,6 +140,7 @@
    87.4  c2_globals_<os_family>.hpp              macros.hpp
    87.5  
    87.6  c2_init_<arch>.cpp                      compile.hpp
    87.7 +c2_init_<arch>.cpp                      node.hpp
    87.8  
    87.9  c2compiler.cpp                          ad_<arch_model>.hpp
   87.10  c2compiler.cpp                          c2compiler.hpp
   87.11 @@ -839,6 +840,7 @@
   87.12  phase.cpp                               compile.hpp
   87.13  phase.cpp                               compileBroker.hpp
   87.14  phase.cpp                               nmethod.hpp
   87.15 +phase.cpp                               node.hpp
   87.16  phase.cpp                               phase.hpp
   87.17  
   87.18  phase.hpp                               port.hpp
    88.1 --- a/src/share/vm/includeDB_core	Sat Jan 31 17:19:42 2009 -0800
    88.2 +++ b/src/share/vm/includeDB_core	Fri Feb 27 15:13:00 2009 -0800
    88.3 @@ -1311,6 +1311,7 @@
    88.4  cppInterpreter_<arch>.cpp               debug.hpp
    88.5  cppInterpreter_<arch>.cpp               deoptimization.hpp
    88.6  cppInterpreter_<arch>.cpp               frame.inline.hpp
    88.7 +cppInterpreter_<arch>.cpp               interfaceSupport.hpp
    88.8  cppInterpreter_<arch>.cpp               interpreterRuntime.hpp
    88.9  cppInterpreter_<arch>.cpp               interpreter.hpp
   88.10  cppInterpreter_<arch>.cpp               interpreterGenerator.hpp
   88.11 @@ -2014,7 +2015,7 @@
   88.12  instanceKlass.cpp                       vmSymbols.hpp
   88.13  
   88.14  instanceKlass.hpp                       accessFlags.hpp
   88.15 -instanceKlass.hpp                       bitMap.hpp
   88.16 +instanceKlass.hpp                       bitMap.inline.hpp
   88.17  instanceKlass.hpp                       constMethodOop.hpp
   88.18  instanceKlass.hpp                       constantPoolOop.hpp
   88.19  instanceKlass.hpp                       handles.hpp
   88.20 @@ -3771,6 +3772,7 @@
   88.21  
   88.22  spaceDecorator.cpp                      copy.hpp
   88.23  spaceDecorator.cpp                      spaceDecorator.hpp
   88.24 +spaceDecorator.cpp                      space.inline.hpp
   88.25  
   88.26  specialized_oop_closures.cpp            ostream.hpp
   88.27  specialized_oop_closures.cpp            specialized_oop_closures.hpp
    89.1 --- a/src/share/vm/includeDB_features	Sat Jan 31 17:19:42 2009 -0800
    89.2 +++ b/src/share/vm/includeDB_features	Fri Feb 27 15:13:00 2009 -0800
    89.3 @@ -59,6 +59,8 @@
    89.4  
    89.5  dump_<arch_model>.cpp                   assembler_<arch>.inline.hpp
    89.6  dump_<arch_model>.cpp                   compactingPermGenGen.hpp
    89.7 +dump_<arch_model>.cpp                   generation.inline.hpp
    89.8 +dump_<arch_model>.cpp                   space.inline.hpp
    89.9  
   89.10  forte.cpp                               collectedHeap.inline.hpp
   89.11  forte.cpp                               debugInfoRec.hpp
    90.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Sat Jan 31 17:19:42 2009 -0800
    90.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Feb 27 15:13:00 2009 -0800
    90.3 @@ -163,7 +163,7 @@
    90.4  #ifdef USELABELS
    90.5  // Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an
    90.6  // initialization (which is is the initialization of the table pointer...)
    90.7 -#define DISPATCH(opcode) goto *dispatch_table[opcode]
    90.8 +#define DISPATCH(opcode) goto *(void*)dispatch_table[opcode]
    90.9  #define CONTINUE {                              \
   90.10          opcode = *pc;                           \
   90.11          DO_UPDATE_INSTRUCTION_COUNT(opcode);    \
   90.12 @@ -341,7 +341,7 @@
   90.13   */
   90.14  #undef CHECK_NULL
   90.15  #define CHECK_NULL(obj_)                                                 \
   90.16 -    if ((obj_) == 0) {                                                   \
   90.17 +    if ((obj_) == NULL) {                                                \
   90.18          VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), "");  \
   90.19      }
   90.20  
   90.21 @@ -1362,7 +1362,7 @@
   90.22  
   90.23  #define NULL_COMPARISON_NOT_OP(name)                                         \
   90.24        CASE(_if##name): {                                                     \
   90.25 -          int skip = (!(STACK_OBJECT(-1) == 0))                              \
   90.26 +          int skip = (!(STACK_OBJECT(-1) == NULL))                           \
   90.27                        ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
   90.28            address branch_pc = pc;                                            \
   90.29            UPDATE_PC_AND_TOS(skip, -1);                                       \
   90.30 @@ -1372,7 +1372,7 @@
   90.31  
   90.32  #define NULL_COMPARISON_OP(name)                                             \
   90.33        CASE(_if##name): {                                                     \
   90.34 -          int skip = ((STACK_OBJECT(-1) == 0))                               \
   90.35 +          int skip = ((STACK_OBJECT(-1) == NULL))                            \
   90.36                        ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3;             \
   90.37            address branch_pc = pc;                                            \
   90.38            UPDATE_PC_AND_TOS(skip, -1);                                       \
    91.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.hpp	Sat Jan 31 17:19:42 2009 -0800
    91.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp	Fri Feb 27 15:13:00 2009 -0800
    91.3 @@ -66,7 +66,6 @@
    91.4  friend class InterpreterGenerator;
    91.5  friend class InterpreterMacroAssembler;
    91.6  friend class frame;
    91.7 -friend class SharedRuntime;
    91.8  friend class VMStructs;
    91.9  
   91.10  public:
    92.1 --- a/src/share/vm/interpreter/rewriter.cpp	Sat Jan 31 17:19:42 2009 -0800
    92.2 +++ b/src/share/vm/interpreter/rewriter.cpp	Fri Feb 27 15:13:00 2009 -0800
    92.3 @@ -48,9 +48,14 @@
    92.4  
    92.5  
    92.6  // Creates a constant pool cache given an inverse_index_map
    92.7 +// This creates the constant pool cache initially in a state
    92.8 +// that is unsafe for concurrent GC processing but sets it to
    92.9 +// a safe mode before the constant pool cache is returned.
   92.10  constantPoolCacheHandle Rewriter::new_constant_pool_cache(intArray& inverse_index_map, TRAPS) {
   92.11    const int length = inverse_index_map.length();
   92.12 -  constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, CHECK_(constantPoolCacheHandle()));
   92.13 +  constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length,
   92.14 +                                             methodOopDesc::IsUnsafeConc,
   92.15 +                                             CHECK_(constantPoolCacheHandle()));
   92.16    cache->initialize(inverse_index_map);
   92.17    return constantPoolCacheHandle(THREAD, cache);
   92.18  }
    93.1 --- a/src/share/vm/libadt/dict.cpp	Sat Jan 31 17:19:42 2009 -0800
    93.2 +++ b/src/share/vm/libadt/dict.cpp	Fri Feb 27 15:13:00 2009 -0800
    93.3 @@ -346,9 +346,12 @@
    93.4    return strcmp((const char *)k1,(const char *)k2);
    93.5  }
    93.6  
    93.7 -// Slimey cheap key comparator.
    93.8 +// Cheap key comparator.
    93.9  int32 cmpkey(const void *key1, const void *key2) {
   93.10 -  return (int32)((intptr_t)key1 - (intptr_t)key2);
   93.11 +  if (key1 == key2) return 0;
   93.12 +  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
   93.13 +  if (delta > 0) return 1;
   93.14 +  return -1;
   93.15  }
   93.16  
   93.17  //=============================================================================
    94.1 --- a/src/share/vm/libadt/port.hpp	Sat Jan 31 17:19:42 2009 -0800
    94.2 +++ b/src/share/vm/libadt/port.hpp	Fri Feb 27 15:13:00 2009 -0800
    94.3 @@ -34,17 +34,6 @@
    94.4  #include <stddef.h>
    94.5  #include <stdlib.h>
    94.6  #include <string.h>
    94.7 -#undef bzero
    94.8 -inline void bzero(void *b, int len) { memset(b,0,len); }
    94.9 -#undef bcopy
   94.10 -inline void bcopy(const void *s, void *d, size_t len) { memmove(d,s,len); }
   94.11 -#undef bcmp
   94.12 -inline int bcmp(const void *s,const void *t,int len) { return memcmp(s,t,len);}
   94.13 -extern "C" unsigned long strtoul(const char *s, char **end, int base);
   94.14 -
   94.15 -// Definition for sys_errlist varies from Sun 4.1 & Solaris.
   94.16 -// We use the new Solaris definition.
   94.17 -#include <string.h>
   94.18  
   94.19  // Access to the C++ class virtual function pointer
   94.20  // Put the class in the macro
    95.1 --- a/src/share/vm/memory/genCollectedHeap.cpp	Sat Jan 31 17:19:42 2009 -0800
    95.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Feb 27 15:13:00 2009 -0800
    95.3 @@ -610,6 +610,10 @@
    95.4      Universe::print_heap_after_gc();
    95.5    }
    95.6  
    95.7 +#ifdef TRACESPINNING
    95.8 +  ParallelTaskTerminator::print_termination_counts();
    95.9 +#endif
   95.10 +
   95.11    if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
   95.12      tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
   95.13      vm_exit(-1);
   95.14 @@ -910,6 +914,13 @@
   95.15    perm_gen()->object_iterate(cl);
   95.16  }
   95.17  
   95.18 +void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
   95.19 +  for (int i = 0; i < _n_gens; i++) {
   95.20 +    _gens[i]->safe_object_iterate(cl);
   95.21 +  }
   95.22 +  perm_gen()->safe_object_iterate(cl);
   95.23 +}
   95.24 +
   95.25  void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) {
   95.26    for (int i = 0; i < _n_gens; i++) {
   95.27      _gens[i]->object_iterate_since_last_GC(cl);
    96.1 --- a/src/share/vm/memory/genCollectedHeap.hpp	Sat Jan 31 17:19:42 2009 -0800
    96.2 +++ b/src/share/vm/memory/genCollectedHeap.hpp	Fri Feb 27 15:13:00 2009 -0800
    96.3 @@ -215,6 +215,7 @@
    96.4    void oop_iterate(OopClosure* cl);
    96.5    void oop_iterate(MemRegion mr, OopClosure* cl);
    96.6    void object_iterate(ObjectClosure* cl);
    96.7 +  void safe_object_iterate(ObjectClosure* cl);
    96.8    void object_iterate_since_last_GC(ObjectClosure* cl);
    96.9    Space* space_containing(const void* addr) const;
   96.10  
    97.1 --- a/src/share/vm/memory/generation.cpp	Sat Jan 31 17:19:42 2009 -0800
    97.2 +++ b/src/share/vm/memory/generation.cpp	Fri Feb 27 15:13:00 2009 -0800
    97.3 @@ -319,6 +319,21 @@
    97.4    space_iterate(&blk);
    97.5  }
    97.6  
    97.7 +class GenerationSafeObjIterateClosure : public SpaceClosure {
    97.8 + private:
    97.9 +  ObjectClosure* _cl;
   97.10 + public:
   97.11 +  virtual void do_space(Space* s) {
   97.12 +    s->safe_object_iterate(_cl);
   97.13 +  }
   97.14 +  GenerationSafeObjIterateClosure(ObjectClosure* cl) : _cl(cl) {}
   97.15 +};
   97.16 +
   97.17 +void Generation::safe_object_iterate(ObjectClosure* cl) {
   97.18 +  GenerationSafeObjIterateClosure blk(cl);
   97.19 +  space_iterate(&blk);
   97.20 +}
   97.21 +
   97.22  void Generation::prepare_for_compaction(CompactPoint* cp) {
   97.23    // Generic implementation, can be specialized
   97.24    CompactibleSpace* space = first_compaction_space();
    98.1 --- a/src/share/vm/memory/generation.hpp	Sat Jan 31 17:19:42 2009 -0800
    98.2 +++ b/src/share/vm/memory/generation.hpp	Fri Feb 27 15:13:00 2009 -0800
    98.3 @@ -518,6 +518,11 @@
    98.4    // each.
    98.5    virtual void object_iterate(ObjectClosure* cl);
    98.6  
    98.7 +  // Iterate over all safe objects in the generation, calling "cl.do_object" on
    98.8 +  // each.  An object is safe if its references point to other objects in
    98.9 +  // the heap.  This defaults to object_iterate() unless overridden.
   98.10 +  virtual void safe_object_iterate(ObjectClosure* cl);
   98.11 +
   98.12    // Iterate over all objects allocated in the generation since the last
   98.13    // collection, calling "cl.do_object" on each.  The generation must have
   98.14    // been initialized properly to support this function, or else this call
    99.1 --- a/src/share/vm/memory/heapInspection.cpp	Sat Jan 31 17:19:42 2009 -0800
    99.2 +++ b/src/share/vm/memory/heapInspection.cpp	Fri Feb 27 15:13:00 2009 -0800
    99.3 @@ -263,6 +263,9 @@
    99.4    if (!cit.allocation_failed()) {
    99.5      // Iterate over objects in the heap
    99.6      RecordInstanceClosure ric(&cit);
    99.7 +    // If this operation encounters a bad object when using CMS,
    99.8 +    // consider using safe_object_iterate() which avoids perm gen
    99.9 +    // objects that may contain bad references.
   99.10      Universe::heap()->object_iterate(&ric);
   99.11  
   99.12      // Report if certain classes are not counted because of
   99.13 @@ -317,5 +320,8 @@
   99.14  
   99.15    // Iterate over objects in the heap
   99.16    FindInstanceClosure fic(k, result);
   99.17 +  // If this operation encounters a bad object when using CMS,
   99.18 +  // consider using safe_object_iterate() which avoids perm gen
   99.19 +  // objects that may contain bad references.
   99.20    Universe::heap()->object_iterate(&fic);
   99.21  }
   100.1 --- a/src/share/vm/memory/oopFactory.cpp	Sat Jan 31 17:19:42 2009 -0800
   100.2 +++ b/src/share/vm/memory/oopFactory.cpp	Fri Feb 27 15:13:00 2009 -0800
   100.3 @@ -82,15 +82,19 @@
   100.4  }
   100.5  
   100.6  
   100.7 -constantPoolOop oopFactory::new_constantPool(int length, TRAPS) {
   100.8 +constantPoolOop oopFactory::new_constantPool(int length,
   100.9 +                                             bool is_conc_safe,
  100.10 +                                             TRAPS) {
  100.11    constantPoolKlass* ck = constantPoolKlass::cast(Universe::constantPoolKlassObj());
  100.12 -  return ck->allocate(length, CHECK_NULL);
  100.13 +  return ck->allocate(length, is_conc_safe, CHECK_NULL);
  100.14  }
  100.15  
  100.16  
  100.17 -constantPoolCacheOop oopFactory::new_constantPoolCache(int length, TRAPS) {
  100.18 +constantPoolCacheOop oopFactory::new_constantPoolCache(int length,
  100.19 +                                                       bool is_conc_safe,
  100.20 +                                                       TRAPS) {
  100.21    constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj());
  100.22 -  return ck->allocate(length, CHECK_NULL);
  100.23 +  return ck->allocate(length, is_conc_safe, CHECK_NULL);
  100.24  }
  100.25  
  100.26  
  100.27 @@ -105,11 +109,13 @@
  100.28                                             int compressed_line_number_size,
  100.29                                             int localvariable_table_length,
  100.30                                             int checked_exceptions_length,
  100.31 +                                           bool is_conc_safe,
  100.32                                             TRAPS) {
  100.33    klassOop cmkObj = Universe::constMethodKlassObj();
  100.34    constMethodKlass* cmk = constMethodKlass::cast(cmkObj);
  100.35    return cmk->allocate(byte_code_size, compressed_line_number_size,
  100.36                         localvariable_table_length, checked_exceptions_length,
  100.37 +                       is_conc_safe,
  100.38                         CHECK_NULL);
  100.39  }
  100.40  
  100.41 @@ -117,14 +123,17 @@
  100.42  methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags,
  100.43                                   int compressed_line_number_size,
  100.44                                   int localvariable_table_length,
  100.45 -                                 int checked_exceptions_length, TRAPS) {
  100.46 +                                 int checked_exceptions_length,
  100.47 +                                 bool is_conc_safe,
  100.48 +                                 TRAPS) {
  100.49    methodKlass* mk = methodKlass::cast(Universe::methodKlassObj());
  100.50    assert(!access_flags.is_native() || byte_code_size == 0,
  100.51           "native methods should not contain byte codes");
  100.52    constMethodOop cm = new_constMethod(byte_code_size,
  100.53                                        compressed_line_number_size,
  100.54                                        localvariable_table_length,
  100.55 -                                      checked_exceptions_length, CHECK_NULL);
  100.56 +                                      checked_exceptions_length,
  100.57 +                                      is_conc_safe, CHECK_NULL);
  100.58    constMethodHandle rw(THREAD, cm);
  100.59    return mk->allocate(rw, access_flags, CHECK_NULL);
  100.60  }
   101.1 --- a/src/share/vm/memory/oopFactory.hpp	Sat Jan 31 17:19:42 2009 -0800
   101.2 +++ b/src/share/vm/memory/oopFactory.hpp	Fri Feb 27 15:13:00 2009 -0800
   101.3 @@ -81,8 +81,12 @@
   101.4    static symbolHandle    new_symbol_handle(const char* name, TRAPS) { return new_symbol_handle(name, (int)strlen(name), CHECK_(symbolHandle())); }
   101.5  
   101.6    // Constant pools
   101.7 -  static constantPoolOop      new_constantPool     (int length, TRAPS);
   101.8 -  static constantPoolCacheOop new_constantPoolCache(int length, TRAPS);
   101.9 +  static constantPoolOop      new_constantPool     (int length,
  101.10 +                                                    bool is_conc_safe,
  101.11 +                                                    TRAPS);
  101.12 +  static constantPoolCacheOop new_constantPoolCache(int length,
  101.13 +                                                    bool is_conc_safe,
  101.14 +                                                    TRAPS);
  101.15  
  101.16    // Instance classes
  101.17    static klassOop        new_instanceKlass(int vtable_len, int itable_len, int static_field_size,
  101.18 @@ -93,9 +97,20 @@
  101.19    static constMethodOop  new_constMethod(int byte_code_size,
  101.20                                           int compressed_line_number_size,
  101.21                                           int localvariable_table_length,
  101.22 -                                         int checked_exceptions_length, TRAPS);
  101.23 +                                         int checked_exceptions_length,
  101.24 +                                         bool is_conc_safe,
  101.25 +                                         TRAPS);
  101.26  public:
  101.27 -  static methodOop       new_method(int byte_code_size, AccessFlags access_flags, int compressed_line_number_size, int localvariable_table_length, int checked_exceptions_length, TRAPS);
  101.28 +  // Set is_conc_safe for methods which cannot safely be
  101.29 +  // processed by concurrent GC even after the return of
  101.30 +  // the method.
  101.31 +  static methodOop       new_method(int byte_code_size,
  101.32 +                                    AccessFlags access_flags,
  101.33 +                                    int compressed_line_number_size,
  101.34 +                                    int localvariable_table_length,
  101.35 +                                    int checked_exceptions_length,
  101.36 +                                    bool is_conc_safe,
  101.37 +                                    TRAPS);
  101.38  
  101.39    // Method Data containers
  101.40    static methodDataOop   new_methodData(methodHandle method, TRAPS);
   102.1 --- a/src/share/vm/memory/referenceProcessor.cpp	Sat Jan 31 17:19:42 2009 -0800
   102.2 +++ b/src/share/vm/memory/referenceProcessor.cpp	Fri Feb 27 15:13:00 2009 -0800
   102.3 @@ -721,12 +721,6 @@
   102.4                               iter.obj(), iter.obj()->blueprint()->internal_name());
   102.5      }
   102.6      assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
   102.7 -    // If discovery is concurrent, we may have objects with null referents,
   102.8 -    // being those that were concurrently cleared after they were discovered
   102.9 -    // (and not subsequently precleaned).
  102.10 -    assert(   (discovery_is_atomic() && iter.referent()->is_oop())
  102.11 -           || (!discovery_is_atomic() && iter.referent()->is_oop_or_null(UseConcMarkSweepGC)),
  102.12 -           "Adding a bad referent");
  102.13      iter.next();
  102.14    }
  102.15    // Remember to keep sentinel pointer around
   103.1 --- a/src/share/vm/memory/space.cpp	Sat Jan 31 17:19:42 2009 -0800
   103.2 +++ b/src/share/vm/memory/space.cpp	Fri Feb 27 15:13:00 2009 -0800
   103.3 @@ -569,7 +569,15 @@
   103.4    if (prev > mr.start()) {
   103.5      region_start_addr = prev;
   103.6      blk_start_addr    = prev;
   103.7 -    assert(blk_start_addr == block_start(region_start_addr), "invariant");
   103.8 +    // The previous invocation may have pushed "prev" beyond the
   103.9 +    // last allocated block yet there may be still be blocks
  103.10 +    // in this region due to a particular coalescing policy.
  103.11 +    // Relax the assertion so that the case where the unallocated
  103.12 +    // block is maintained and "prev" is beyond the unallocated
  103.13 +    // block does not cause the assertion to fire.
  103.14 +    assert((BlockOffsetArrayUseUnallocatedBlock &&
  103.15 +            (!is_in(prev))) ||
  103.16 +           (blk_start_addr == block_start(region_start_addr)), "invariant");
  103.17    } else {
  103.18      region_start_addr = mr.start();
  103.19      blk_start_addr    = block_start(region_start_addr);
  103.20 @@ -705,6 +713,12 @@
  103.21    object_iterate_from(bm, blk);
  103.22  }
  103.23  
  103.24 +// For a continguous space object_iterate() and safe_object_iterate()
  103.25 +// are the same.
  103.26 +void ContiguousSpace::safe_object_iterate(ObjectClosure* blk) {
  103.27 +  object_iterate(blk);
  103.28 +}
  103.29 +
  103.30  void ContiguousSpace::object_iterate_from(WaterMark mark, ObjectClosure* blk) {
  103.31    assert(mark.space() == this, "Mark does not match space");
  103.32    HeapWord* p = mark.point();
   104.1 --- a/src/share/vm/memory/space.hpp	Sat Jan 31 17:19:42 2009 -0800
   104.2 +++ b/src/share/vm/memory/space.hpp	Fri Feb 27 15:13:00 2009 -0800
   104.3 @@ -193,6 +193,9 @@
   104.4    // each.  Objects allocated by applications of the closure are not
   104.5    // included in the iteration.
   104.6    virtual void object_iterate(ObjectClosure* blk) = 0;
   104.7 +  // Similar to object_iterate() except only iterates over
   104.8 +  // objects whose internal references point to objects in the space.
   104.9 +  virtual void safe_object_iterate(ObjectClosure* blk) = 0;
  104.10  
  104.11    // Iterate over all objects that intersect with mr, calling "cl->do_object"
  104.12    // on each.  There is an exception to this: if this closure has already
  104.13 @@ -843,6 +846,9 @@
  104.14    void oop_iterate(OopClosure* cl);
  104.15    void oop_iterate(MemRegion mr, OopClosure* cl);
  104.16    void object_iterate(ObjectClosure* blk);
  104.17 +  // For contiguous spaces this method will iterate safely over objects
  104.18 +  // in the space (i.e., between bottom and top) when at a safepoint.
  104.19 +  void safe_object_iterate(ObjectClosure* blk);
  104.20    void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
  104.21    // iterates on objects up to the safe limit
  104.22    HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
   105.1 --- a/src/share/vm/oops/constMethodKlass.cpp	Sat Jan 31 17:19:42 2009 -0800
   105.2 +++ b/src/share/vm/oops/constMethodKlass.cpp	Fri Feb 27 15:13:00 2009 -0800
   105.3 @@ -49,10 +49,16 @@
   105.4    return constMethodOop(obj)->object_is_parsable();
   105.5  }
   105.6  
   105.7 +bool constMethodKlass::oop_is_conc_safe(oop obj) const {
   105.8 +  assert(obj->is_constMethod(), "must be constMethod oop");
   105.9 +  return constMethodOop(obj)->is_conc_safe();
  105.10 +}
  105.11 +
  105.12  constMethodOop constMethodKlass::allocate(int byte_code_size,
  105.13                                            int compressed_line_number_size,
  105.14                                            int localvariable_table_length,
  105.15                                            int checked_exceptions_length,
  105.16 +                                          bool is_conc_safe,
  105.17                                            TRAPS) {
  105.18  
  105.19    int size = constMethodOopDesc::object_size(byte_code_size,
  105.20 @@ -75,6 +81,7 @@
  105.21                                  compressed_line_number_size,
  105.22                                  localvariable_table_length);
  105.23    assert(cm->size() == size, "wrong size for object");
  105.24 +  cm->set_is_conc_safe(is_conc_safe);
  105.25    cm->set_partially_loaded();
  105.26    assert(cm->is_parsable(), "Is safely parsable by gc");
  105.27    return cm;
   106.1 --- a/src/share/vm/oops/constMethodKlass.hpp	Sat Jan 31 17:19:42 2009 -0800
   106.2 +++ b/src/share/vm/oops/constMethodKlass.hpp	Fri Feb 27 15:13:00 2009 -0800
   106.3 @@ -32,12 +32,16 @@
   106.4    // Testing
   106.5    bool oop_is_constMethod() const { return true; }
   106.6    virtual bool oop_is_parsable(oop obj) const;
   106.7 +  virtual bool oop_is_conc_safe(oop obj) const;
   106.8 +
   106.9  
  106.10    // Allocation
  106.11    DEFINE_ALLOCATE_PERMANENT(constMethodKlass);
  106.12    constMethodOop allocate(int byte_code_size, int compressed_line_number_size,
  106.13                            int localvariable_table_length,
  106.14 -                          int checked_exceptions_length, TRAPS);
  106.15 +                          int checked_exceptions_length,
  106.16 +                          bool is_conc_safe,
  106.17 +                          TRAPS);
  106.18    static klassOop create_klass(TRAPS);
  106.19  
  106.20    // Sizing
   107.1 --- a/src/share/vm/oops/constMethodOop.hpp	Sat Jan 31 17:19:42 2009 -0800
   107.2 +++ b/src/share/vm/oops/constMethodOop.hpp	Fri Feb 27 15:13:00 2009 -0800
   107.3 @@ -104,6 +104,7 @@
   107.4    // loads and stores.  This value may updated and read without a lock by
   107.5    // multiple threads, so is volatile.
   107.6    volatile uint64_t _fingerprint;
   107.7 +  volatile bool     _is_conc_safe; // if true, safe for concurrent GC processing
   107.8  
   107.9  public:
  107.10    oop* oop_block_beg() const { return adr_method(); }
  107.11 @@ -273,6 +274,8 @@
  107.12    oop*  adr_method() const             { return (oop*)&_method;          }
  107.13    oop*  adr_stackmap_data() const      { return (oop*)&_stackmap_data;   }
  107.14    oop*  adr_exception_table() const    { return (oop*)&_exception_table; }
  107.15 +  bool is_conc_safe() { return _is_conc_safe; }
  107.16 +  void set_is_conc_safe(bool v) { _is_conc_safe = v; }
  107.17  
  107.18    // Unique id for the method
  107.19    static const u2 MAX_IDNUM;
   108.1 --- a/src/share/vm/oops/constantPoolKlass.cpp	Sat Jan 31 17:19:42 2009 -0800
   108.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp	Fri Feb 27 15:13:00 2009 -0800
   108.3 @@ -25,7 +25,7 @@
   108.4  # include "incls/_precompiled.incl"
   108.5  # include "incls/_constantPoolKlass.cpp.incl"
   108.6  
   108.7 -constantPoolOop constantPoolKlass::allocate(int length, TRAPS) {
   108.8 +constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS) {
   108.9    int size = constantPoolOopDesc::object_size(length);
  108.10    KlassHandle klass (THREAD, as_klassOop());
  108.11    constantPoolOop c =
  108.12 @@ -38,6 +38,9 @@
  108.13    c->set_flags(0);
  108.14    // only set to non-zero if constant pool is merged by RedefineClasses
  108.15    c->set_orig_length(0);
  108.16 +  // if constant pool may change during RedefineClasses, it is created
  108.17 +  // unsafe for GC concurrent processing.
  108.18 +  c->set_is_conc_safe(is_conc_safe);
  108.19    // all fields are initialized; needed for GC
  108.20  
  108.21    // initialize tag array
  108.22 @@ -207,6 +210,11 @@
  108.23    return size;
  108.24  }
  108.25  
  108.26 +bool constantPoolKlass::oop_is_conc_safe(oop obj) const {
  108.27 +  assert(obj->is_constantPool(), "must be constantPool");
  108.28 +  return constantPoolOop(obj)->is_conc_safe();
  108.29 +}
  108.30 +
  108.31  #ifndef SERIALGC
  108.32  int constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  108.33    assert (obj->is_constantPool(), "obj must be constant pool");
   109.1 --- a/src/share/vm/oops/constantPoolKlass.hpp	Sat Jan 31 17:19:42 2009 -0800
   109.2 +++ b/src/share/vm/oops/constantPoolKlass.hpp	Fri Feb 27 15:13:00 2009 -0800
   109.3 @@ -34,7 +34,7 @@
   109.4  
   109.5    // Allocation
   109.6    DEFINE_ALLOCATE_PERMANENT(constantPoolKlass);
   109.7 -  constantPoolOop allocate(int length, TRAPS);
   109.8 +  constantPoolOop allocate(int length, bool is_conc_safe, TRAPS);
   109.9    static klassOop create_klass(TRAPS);
  109.10  
  109.11    // Casting from klassOop
  109.12 @@ -48,6 +48,8 @@
  109.13    int object_size() const        { return align_object_size(header_size()); }
  109.14  
  109.15    // Garbage collection
  109.16 +  // Returns true is the object is safe for GC concurrent processing.
  109.17 +  virtual bool oop_is_conc_safe(oop obj) const;
  109.18    void oop_follow_contents(oop obj);
  109.19    int oop_adjust_pointers(oop obj);
  109.20  
   110.1 --- a/src/share/vm/oops/constantPoolOop.cpp	Sat Jan 31 17:19:42 2009 -0800
   110.2 +++ b/src/share/vm/oops/constantPoolOop.cpp	Fri Feb 27 15:13:00 2009 -0800
   110.3 @@ -962,7 +962,7 @@
   110.4        }
   110.5        case JVM_CONSTANT_Long: {
   110.6          u8 val = Bytes::get_Java_u8(bytes);
   110.7 -        printf("long         %lldl", *(jlong *) &val);
   110.8 +        printf("long         "INT64_FORMAT, *(jlong *) &val);
   110.9          ent_size = 8;
  110.10          idx++; // Long takes two cpool slots
  110.11          break;
   111.1 --- a/src/share/vm/oops/constantPoolOop.hpp	Sat Jan 31 17:19:42 2009 -0800
   111.2 +++ b/src/share/vm/oops/constantPoolOop.hpp	Fri Feb 27 15:13:00 2009 -0800
   111.3 @@ -43,6 +43,8 @@
   111.4    klassOop             _pool_holder;   // the corresponding class
   111.5    int                  _flags;         // a few header bits to describe contents for GC
   111.6    int                  _length; // number of elements in the array
   111.7 +  volatile bool        _is_conc_safe; // if true, safe for concurrent
   111.8 +                                      // GC processing
   111.9    // only set to non-zero if constant pool is merged by RedefineClasses
  111.10    int                  _orig_length;
  111.11  
  111.12 @@ -379,6 +381,9 @@
  111.13    static int object_size(int length)   { return align_object_size(header_size() + length); }
  111.14    int object_size()                    { return object_size(length()); }
  111.15  
  111.16 +  bool is_conc_safe()                  { return _is_conc_safe; }
  111.17 +  void set_is_conc_safe(bool v)        { _is_conc_safe = v; }
  111.18 +
  111.19    friend class constantPoolKlass;
  111.20    friend class ClassFileParser;
  111.21    friend class SystemDictionary;
   112.1 --- a/src/share/vm/oops/cpCacheKlass.cpp	Sat Jan 31 17:19:42 2009 -0800
   112.2 +++ b/src/share/vm/oops/cpCacheKlass.cpp	Fri Feb 27 15:13:00 2009 -0800
   112.3 @@ -32,13 +32,43 @@
   112.4  }
   112.5  
   112.6  
   112.7 -constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) {
   112.8 +constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
   112.9 +                                                      bool is_conc_safe,
  112.10 +                                                      TRAPS) {
  112.11    // allocate memory
  112.12    int size = constantPoolCacheOopDesc::object_size(length);
  112.13 +
  112.14    KlassHandle klass (THREAD, as_klassOop());
  112.15 -  constantPoolCacheOop cache = (constantPoolCacheOop)
  112.16 -    CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
  112.17 +
  112.18 +  // This is the original code.  The code from permanent_obj_allocate()
  112.19 +  // was in-lined to allow the setting of is_conc_safe before the klass
  112.20 +  // is installed.
  112.21 +  // constantPoolCacheOop cache = (constantPoolCacheOop)
  112.22 +  //   CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
  112.23 +
  112.24 +  oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
  112.25 +  constantPoolCacheOop cache = (constantPoolCacheOop) obj;
  112.26 +  cache->set_is_conc_safe(is_conc_safe);
  112.27 +  // The store to is_conc_safe must be visible before the klass
  112.28 +  // is set.  This should be done safely because _is_conc_safe has
  112.29 +  // been declared volatile.  If there are any problems, consider adding
  112.30 +  // OrderAccess::storestore();
  112.31 +  CollectedHeap::post_allocation_install_obj_klass(klass, obj, size);
  112.32 +  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
  112.33 +                                                              size));
  112.34 +
  112.35 +  // The length field affects the size of the object.  The allocation
  112.36 +  // above allocates the correct size (see calculation of "size") but
  112.37 +  // the size() method of the constant pool cache oop will not reflect
  112.38 +  // that size until the correct length is set.
  112.39    cache->set_length(length);
  112.40 +
  112.41 +  // The store of the length must be visible before is_conc_safe is
  112.42 +  // set to a safe state.
  112.43 +  // This should be done safely because _is_conc_safe has
  112.44 +  // been declared volatile.  If there are any problems, consider adding
  112.45 +  // OrderAccess::storestore();
  112.46 +  cache->set_is_conc_safe(methodOopDesc::IsSafeConc);
  112.47    cache->set_constant_pool(NULL);
  112.48    return cache;
  112.49  }
  112.50 @@ -114,7 +144,6 @@
  112.51    return size;
  112.52  }
  112.53  
  112.54 -
  112.55  int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
  112.56    assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
  112.57    constantPoolCacheOop cache = (constantPoolCacheOop)obj;
  112.58 @@ -131,6 +160,11 @@
  112.59    return size;
  112.60  }
  112.61  
  112.62 +bool constantPoolCacheKlass::oop_is_conc_safe(oop obj) const {
  112.63 +  assert(obj->is_constantPoolCache(), "should be constant pool");
  112.64 +  return constantPoolCacheOop(obj)->is_conc_safe();
  112.65 +}
  112.66 +
  112.67  #ifndef SERIALGC
  112.68  void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm,
  112.69                                                 oop obj) {
   113.1 --- a/src/share/vm/oops/cpCacheKlass.hpp	Sat Jan 31 17:19:42 2009 -0800
   113.2 +++ b/src/share/vm/oops/cpCacheKlass.hpp	Fri Feb 27 15:13:00 2009 -0800
   113.3 @@ -32,7 +32,7 @@
   113.4  
   113.5    // Allocation
   113.6    DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass);
   113.7 -  constantPoolCacheOop allocate(int length, TRAPS);
   113.8 +  constantPoolCacheOop allocate(int length, bool is_conc_safe, TRAPS);
   113.9    static klassOop create_klass(TRAPS);
  113.10  
  113.11    // Casting from klassOop
  113.12 @@ -48,6 +48,7 @@
  113.13    // Garbage collection
  113.14    void oop_follow_contents(oop obj);
  113.15    int oop_adjust_pointers(oop obj);
  113.16 +  virtual bool oop_is_conc_safe(oop obj) const;
  113.17  
  113.18    // Parallel Scavenge and Parallel Old
  113.19    PARALLEL_GC_DECLS
   114.1 --- a/src/share/vm/oops/cpCacheOop.hpp	Sat Jan 31 17:19:42 2009 -0800
   114.2 +++ b/src/share/vm/oops/cpCacheOop.hpp	Fri Feb 27 15:13:00 2009 -0800
   114.3 @@ -291,6 +291,9 @@
   114.4   private:
   114.5    int             _length;
   114.6    constantPoolOop _constant_pool;                // the corresponding constant pool
   114.7 +  // If true, safe for concurrent GC processing,
   114.8 +  // Set unconditionally in constantPoolCacheKlass::allocate()
   114.9 +  volatile bool        _is_conc_safe;
  114.10  
  114.11    // Sizing
  114.12    debug_only(friend class ClassVerifier;)
  114.13 @@ -316,6 +319,12 @@
  114.14    constantPoolOop constant_pool() const          { return _constant_pool; }
  114.15    ConstantPoolCacheEntry* entry_at(int i) const  { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; }
  114.16  
  114.17 +  // GC support
  114.18 +  // If the _length field has not been set, the size of the
  114.19 +  // constantPoolCache cannot be correctly calculated.
  114.20 +  bool is_conc_safe()                            { return _is_conc_safe; }
  114.21 +  void set_is_conc_safe(bool v)                  { _is_conc_safe = v; }
  114.22 +
  114.23    // Code generation
  114.24    static ByteSize base_offset()                  { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
  114.25  
   115.1 --- a/src/share/vm/oops/klass.hpp	Sat Jan 31 17:19:42 2009 -0800
   115.2 +++ b/src/share/vm/oops/klass.hpp	Fri Feb 27 15:13:00 2009 -0800
   115.3 @@ -606,8 +606,19 @@
   115.4    #undef assert_same_query
   115.5  
   115.6    // Unless overridden, oop is parsable if it has a klass pointer.
   115.7 +  // Parsability of an object is object specific.
   115.8    virtual bool oop_is_parsable(oop obj) const { return true; }
   115.9  
  115.10 +  // Unless overridden, oop is safe for concurrent GC processing
  115.11 +  // after its allocation is complete.  The exception to
  115.12 +  // this is the case where objects are changed after allocation.
  115.13 +  // Class redefinition is one of the known exceptions. During
  115.14 +  // class redefinition, an allocated class can changed in order
  115.15 +  // order to create a merged class (the combiniation of the
  115.16 +  // old class definition that has to be perserved and the new class
  115.17 +  // definition which is being created.
  115.18 +  virtual bool oop_is_conc_safe(oop obj) const { return true; }
  115.19 +
  115.20    // Access flags
  115.21    AccessFlags access_flags() const         { return _access_flags;  }
  115.22    void set_access_flags(AccessFlags flags) { _access_flags = flags; }
   116.1 --- a/src/share/vm/oops/methodOop.cpp	Sat Jan 31 17:19:42 2009 -0800
   116.2 +++ b/src/share/vm/oops/methodOop.cpp	Fri Feb 27 15:13:00 2009 -0800
   116.3 @@ -792,15 +792,34 @@
   116.4    AccessFlags flags = m->access_flags();
   116.5    int checked_exceptions_len = m->checked_exceptions_length();
   116.6    int localvariable_len = m->localvariable_table_length();
   116.7 -  methodOop newm_oop = oopFactory::new_method(new_code_length, flags, new_compressed_linenumber_size, localvariable_len, checked_exceptions_len, CHECK_(methodHandle()));
   116.8 +  // Allocate newm_oop with the is_conc_safe parameter set
   116.9 +  // to IsUnsafeConc to indicate that newm_oop is not yet
  116.10 +  // safe for concurrent processing by a GC.
  116.11 +  methodOop newm_oop = oopFactory::new_method(new_code_length,
  116.12 +                                              flags,
  116.13 +                                              new_compressed_linenumber_size,
  116.14 +                                              localvariable_len,
  116.15 +                                              checked_exceptions_len,
  116.16 +                                              IsUnsafeConc,
  116.17 +                                              CHECK_(methodHandle()));
  116.18    methodHandle newm (THREAD, newm_oop);
  116.19    int new_method_size = newm->method_size();
  116.20    // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop
  116.21    constMethodOop newcm = newm->constMethod();
  116.22    int new_const_method_size = newm->constMethod()->object_size();
  116.23 +
  116.24    memcpy(newm(), m(), sizeof(methodOopDesc));
  116.25    // Create shallow copy of constMethodOopDesc, but be careful to preserve the methodOop
  116.26 +  // is_conc_safe is set to false because that is the value of
  116.27 +  // is_conc_safe initialzied into newcm and the copy should
  116.28 +  // not overwrite that value.  During the window during which it is
  116.29 +  // tagged as unsafe, some extra work could be needed during precleaning
  116.30 +  // or concurrent marking but those phases will be correct.  Setting and
  116.31 +  // resetting is done in preference to a careful copying into newcm to
  116.32 +  // avoid having to know the precise layout of a constMethodOop.
  116.33 +  m->constMethod()->set_is_conc_safe(false);
  116.34    memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc));
  116.35 +  m->constMethod()->set_is_conc_safe(true);
  116.36    // Reset correct method/const method, method size, and parameter info
  116.37    newcm->set_method(newm());
  116.38    newm->set_constMethod(newcm);
  116.39 @@ -831,6 +850,10 @@
  116.40             m->localvariable_table_start(),
  116.41             localvariable_len * sizeof(LocalVariableTableElement));
  116.42    }
  116.43 +
  116.44 +  // Only set is_conc_safe to true when changes to newcm are
  116.45 +  // complete.
  116.46 +  newcm->set_is_conc_safe(true);
  116.47    return newm;
  116.48  }
  116.49  
   117.1 --- a/src/share/vm/oops/methodOop.hpp	Sat Jan 31 17:19:42 2009 -0800
   117.2 +++ b/src/share/vm/oops/methodOop.hpp	Fri Feb 27 15:13:00 2009 -0800
   117.3 @@ -129,6 +129,10 @@
   117.4    volatile address           _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry
   117.5  
   117.6   public:
   117.7 +
   117.8 +  static const bool IsUnsafeConc         = false;
   117.9 +  static const bool IsSafeConc           = true;
  117.10 +
  117.11    // accessors for instance variables
  117.12    constMethodOop constMethod() const             { return _constMethod; }
  117.13    void set_constMethod(constMethodOop xconst)    { oop_store_without_check((oop*)&_constMethod, (oop)xconst); }
   118.1 --- a/src/share/vm/oops/oop.hpp	Sat Jan 31 17:19:42 2009 -0800
   118.2 +++ b/src/share/vm/oops/oop.hpp	Fri Feb 27 15:13:00 2009 -0800
   118.3 @@ -108,6 +108,13 @@
   118.4    // installation of their klass pointer.
   118.5    bool is_parsable();
   118.6  
   118.7 +  // Some perm gen objects that have been allocated and initialized
   118.8 +  // can be changed by the VM when not at a safe point (class rededfinition
   118.9 +  // is an example).  Such objects should not be examined by the
  118.10 +  // concurrent processing of a garbage collector if is_conc_safe()
  118.11 +  // returns false.
  118.12 +  bool is_conc_safe();
  118.13 +
  118.14    // type test operations (inlined in oop.inline.h)
  118.15    bool is_instance()           const;
  118.16    bool is_instanceRef()        const;
   119.1 --- a/src/share/vm/oops/oop.inline.hpp	Sat Jan 31 17:19:42 2009 -0800
   119.2 +++ b/src/share/vm/oops/oop.inline.hpp	Fri Feb 27 15:13:00 2009 -0800
   119.3 @@ -435,6 +435,10 @@
   119.4    return blueprint()->oop_is_parsable(this);
   119.5  }
   119.6  
   119.7 +inline bool oopDesc::is_conc_safe() {
   119.8 +  return blueprint()->oop_is_conc_safe(this);
   119.9 +}
  119.10 +
  119.11  inline void update_barrier_set(void* p, oop v) {
  119.12    assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!");
  119.13    oopDesc::bs()->write_ref_field(p, v);
   120.1 --- a/src/share/vm/oops/oopsHierarchy.hpp	Sat Jan 31 17:19:42 2009 -0800
   120.2 +++ b/src/share/vm/oops/oopsHierarchy.hpp	Fri Feb 27 15:13:00 2009 -0800
   120.3 @@ -126,8 +126,11 @@
   120.4    operator jobject () const           { return (jobject)obj(); }
   120.5    // from javaClasses.cpp
   120.6    operator JavaThread* () const       { return (JavaThread*)obj(); }
   120.7 +
   120.8 +#ifndef _LP64
   120.9    // from jvm.cpp
  120.10    operator jlong* () const            { return (jlong*)obj(); }
  120.11 +#endif
  120.12  
  120.13    // from parNewGeneration and other things that want to get to the end of
  120.14    // an oop for stuff (like constMethodKlass.cpp, objArrayKlass.cpp)
   121.1 --- a/src/share/vm/opto/block.cpp	Sat Jan 31 17:19:42 2009 -0800
   121.2 +++ b/src/share/vm/opto/block.cpp	Fri Feb 27 15:13:00 2009 -0800
   121.3 @@ -880,6 +880,7 @@
   121.4  }
   121.5  
   121.6  void PhaseCFG::verify( ) const {
   121.7 +#ifdef ASSERT
   121.8    // Verify sane CFG
   121.9    for( uint i = 0; i < _num_blocks; i++ ) {
  121.10      Block *b = _blocks[i];
  121.11 @@ -894,10 +895,20 @@
  121.12                  "CreateEx must be first instruction in block" );
  121.13        }
  121.14        for( uint k = 0; k < n->req(); k++ ) {
  121.15 -        Node *use = n->in(k);
  121.16 -        if( use && use != n ) {
  121.17 -          assert( _bbs[use->_idx] || use->is_Con(),
  121.18 +        Node *def = n->in(k);
  121.19 +        if( def && def != n ) {
  121.20 +          assert( _bbs[def->_idx] || def->is_Con(),
  121.21                    "must have block; constants for debug info ok" );
  121.22 +          // Verify that instructions in the block is in correct order.
  121.23 +          // Uses must follow their definition if they are at the same block.
  121.24 +          // Mostly done to check that MachSpillCopy nodes are placed correctly
  121.25 +          // when CreateEx node is moved in build_ifg_physical().
  121.26 +          if( _bbs[def->_idx] == b &&
  121.27 +              !(b->head()->is_Loop() && n->is_Phi()) &&
  121.28 +              // See (+++) comment in reg_split.cpp
  121.29 +              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
  121.30 +            assert( b->find_node(def) < j, "uses must follow definitions" );
  121.31 +          }
  121.32          }
  121.33        }
  121.34      }
  121.35 @@ -914,6 +925,7 @@
  121.36        assert( b->_num_succs == 2, "Conditional branch must have two targets");
  121.37      }
  121.38    }
  121.39 +#endif
  121.40  }
  121.41  #endif
  121.42  
   122.1 --- a/src/share/vm/opto/c2_globals.hpp	Sat Jan 31 17:19:42 2009 -0800
   122.2 +++ b/src/share/vm/opto/c2_globals.hpp	Fri Feb 27 15:13:00 2009 -0800
   122.3 @@ -191,6 +191,9 @@
   122.4    notproduct(bool, VerifyHashTableKeys, true,                               \
   122.5            "Verify the immutability of keys in the VN hash tables")          \
   122.6                                                                              \
   122.7 +  notproduct(bool, VerifyRegisterAllocator , false,                         \
   122.8 +          "Verify Register Allocator")                                      \
   122.9 +                                                                            \
  122.10    develop_pd(intx, FLOATPRESSURE,                                           \
  122.11            "Number of float LRG's that constitute high register pressure")   \
  122.12                                                                              \
   123.1 --- a/src/share/vm/opto/cfgnode.cpp	Sat Jan 31 17:19:42 2009 -0800
   123.2 +++ b/src/share/vm/opto/cfgnode.cpp	Fri Feb 27 15:13:00 2009 -0800
   123.3 @@ -858,12 +858,18 @@
   123.4    // convert the one to the other.
   123.5    const TypePtr* ttp = _type->make_ptr();
   123.6    const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
   123.7 +  const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL;
   123.8    bool is_intf = false;
   123.9    if (ttip != NULL) {
  123.10      ciKlass* k = ttip->klass();
  123.11      if (k->is_loaded() && k->is_interface())
  123.12        is_intf = true;
  123.13    }
  123.14 +  if (ttkp != NULL) {
  123.15 +    ciKlass* k = ttkp->klass();
  123.16 +    if (k->is_loaded() && k->is_interface())
  123.17 +      is_intf = true;
  123.18 +  }
  123.19  
  123.20    // Default case: merge all inputs
  123.21    const Type *t = Type::TOP;        // Merged type starting value
  123.22 @@ -921,6 +927,8 @@
  123.23      // uplift the type.
  123.24      if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() )
  123.25        { assert(ft == _type, ""); } // Uplift to interface
  123.26 +    else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() )
  123.27 +      { assert(ft == _type, ""); } // Uplift to interface
  123.28      // Otherwise it's something stupid like non-overlapping int ranges
  123.29      // found on dying counted loops.
  123.30      else
  123.31 @@ -936,6 +944,7 @@
  123.32      // because the type system doesn't interact well with interfaces.
  123.33      const TypePtr *jtp = jt->make_ptr();
  123.34      const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
  123.35 +    const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL;
  123.36      if( jtip && ttip ) {
  123.37        if( jtip->is_loaded() &&  jtip->klass()->is_interface() &&
  123.38            ttip->is_loaded() && !ttip->klass()->is_interface() ) {
  123.39 @@ -945,6 +954,14 @@
  123.40          jt = ft;
  123.41        }
  123.42      }
  123.43 +    if( jtkp && ttkp ) {
  123.44 +      if( jtkp->is_loaded() &&  jtkp->klass()->is_interface() &&
  123.45 +          ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
  123.46 +        assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
  123.47 +               ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
  123.48 +        jt = ft;
  123.49 +      }
  123.50 +    }
  123.51      if (jt != ft && jt->base() == ft->base()) {
  123.52        if (jt->isa_int() &&
  123.53            jt->is_int()->_lo == ft->is_int()->_lo &&
   124.1 --- a/src/share/vm/opto/chaitin.cpp	Sat Jan 31 17:19:42 2009 -0800
   124.2 +++ b/src/share/vm/opto/chaitin.cpp	Fri Feb 27 15:13:00 2009 -0800
   124.3 @@ -228,6 +228,11 @@
   124.4    // them for real.
   124.5    de_ssa();
   124.6  
   124.7 +#ifdef ASSERT
   124.8 +  // Veify the graph before RA.
   124.9 +  verify(&live_arena);
  124.10 +#endif
  124.11 +
  124.12    {
  124.13      NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
  124.14      _live = NULL;                 // Mark live as being not available
  124.15 @@ -306,12 +311,6 @@
  124.16      C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
  124.17      if (C->failing())  return;
  124.18  
  124.19 -#ifdef ASSERT
  124.20 -    if( VerifyOpto ) {
  124.21 -      _cfg.verify();
  124.22 -      verify_base_ptrs(&live_arena);
  124.23 -    }
  124.24 -#endif
  124.25      NOT_PRODUCT( C->verify_graph_edges(); )
  124.26  
  124.27      compact();                  // Compact LRGs; return new lower max lrg
  124.28 @@ -340,7 +339,7 @@
  124.29      compress_uf_map_for_nodes();
  124.30  
  124.31  #ifdef ASSERT
  124.32 -    if( VerifyOpto ) _ifg->verify(this);
  124.33 +    verify(&live_arena, true);
  124.34  #endif
  124.35    } else {
  124.36      ifg.SquareUp();
  124.37 @@ -376,12 +375,6 @@
  124.38      // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
  124.39      C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
  124.40      if (C->failing())  return;
  124.41 -#ifdef ASSERT
  124.42 -    if( VerifyOpto ) {
  124.43 -      _cfg.verify();
  124.44 -      verify_base_ptrs(&live_arena);
  124.45 -    }
  124.46 -#endif
  124.47  
  124.48      compact();                  // Compact LRGs; return new lower max lrg
  124.49  
  124.50 @@ -412,7 +405,7 @@
  124.51      }
  124.52      compress_uf_map_for_nodes();
  124.53  #ifdef ASSERT
  124.54 -    if( VerifyOpto ) _ifg->verify(this);
  124.55 +    verify(&live_arena, true);
  124.56  #endif
  124.57      cache_lrg_info();           // Count degree of LRGs
  124.58  
  124.59 @@ -432,6 +425,11 @@
  124.60    // Peephole remove copies
  124.61    post_allocate_copy_removal();
  124.62  
  124.63 +#ifdef ASSERT
  124.64 +  // Veify the graph after RA.
  124.65 +  verify(&live_arena);
  124.66 +#endif
  124.67 +
  124.68    // max_reg is past the largest *register* used.
  124.69    // Convert that to a frame_slot number.
  124.70    if( _max_reg <= _matcher._new_SP )
  124.71 @@ -956,7 +954,7 @@
  124.72        while ((neighbor = elements.next()) != 0) {
  124.73          LRG *n = &lrgs(neighbor);
  124.74  #ifdef ASSERT
  124.75 -        if( VerifyOpto ) {
  124.76 +        if( VerifyOpto || VerifyRegisterAllocator ) {
  124.77            assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
  124.78          }
  124.79  #endif
   125.1 --- a/src/share/vm/opto/chaitin.hpp	Sat Jan 31 17:19:42 2009 -0800
   125.2 +++ b/src/share/vm/opto/chaitin.hpp	Fri Feb 27 15:13:00 2009 -0800
   125.3 @@ -491,6 +491,8 @@
   125.4    // Verify that base pointers and derived pointers are still sane
   125.5    void verify_base_ptrs( ResourceArea *a ) const;
   125.6  
   125.7 +  void verify( ResourceArea *a, bool verify_ifg = false ) const;
   125.8 +
   125.9    void dump_for_spill_split_recycle() const;
  125.10  
  125.11  public:
   126.1 --- a/src/share/vm/opto/classes.hpp	Sat Jan 31 17:19:42 2009 -0800
   126.2 +++ b/src/share/vm/opto/classes.hpp	Fri Feb 27 15:13:00 2009 -0800
   126.3 @@ -129,7 +129,7 @@
   126.4  macro(LShiftI)
   126.5  macro(LShiftL)
   126.6  macro(LoadB)
   126.7 -macro(LoadC)
   126.8 +macro(LoadUS)
   126.9  macro(LoadD)
  126.10  macro(LoadD_unaligned)
  126.11  macro(LoadF)
   127.1 --- a/src/share/vm/opto/compile.cpp	Sat Jan 31 17:19:42 2009 -0800
   127.2 +++ b/src/share/vm/opto/compile.cpp	Fri Feb 27 15:13:00 2009 -0800
   127.3 @@ -2005,7 +2005,7 @@
   127.4    case Op_StoreP:
   127.5    case Op_StoreN:
   127.6    case Op_LoadB:
   127.7 -  case Op_LoadC:
   127.8 +  case Op_LoadUS:
   127.9    case Op_LoadI:
  127.10    case Op_LoadKlass:
  127.11    case Op_LoadNKlass:
   128.1 --- a/src/share/vm/opto/divnode.cpp	Sat Jan 31 17:19:42 2009 -0800
   128.2 +++ b/src/share/vm/opto/divnode.cpp	Fri Feb 27 15:13:00 2009 -0800
   128.3 @@ -1,5 +1,5 @@
   128.4  /*
   128.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
   128.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
   128.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   128.8   *
   128.9   * This code is free software; you can redistribute it and/or modify it
  128.10 @@ -244,42 +244,73 @@
  128.11  
  128.12  //---------------------long_by_long_mulhi--------------------------------------
  128.13  // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication
  128.14 -static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_const) {
  128.15 +static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) {
  128.16    // If the architecture supports a 64x64 mulhi, there is
  128.17    // no need to synthesize it in ideal nodes.
  128.18    if (Matcher::has_match_rule(Op_MulHiL)) {
  128.19 -    Node *v = phase->longcon(magic_const);
  128.20 +    Node* v = phase->longcon(magic_const);
  128.21      return new (phase->C, 3) MulHiLNode(dividend, v);
  128.22    }
  128.23  
  128.24 +  // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
  128.25 +  // (http://www.hackersdelight.org/HDcode/mulhs.c)
  128.26 +  //
  128.27 +  // int mulhs(int u, int v) {
  128.28 +  //    unsigned u0, v0, w0;
  128.29 +  //    int u1, v1, w1, w2, t;
  128.30 +  //
  128.31 +  //    u0 = u & 0xFFFF;  u1 = u >> 16;
  128.32 +  //    v0 = v & 0xFFFF;  v1 = v >> 16;
  128.33 +  //    w0 = u0*v0;
  128.34 +  //    t  = u1*v0 + (w0 >> 16);
  128.35 +  //    w1 = t & 0xFFFF;
  128.36 +  //    w2 = t >> 16;
  128.37 +  //    w1 = u0*v1 + w1;
  128.38 +  //    return u1*v1 + w2 + (w1 >> 16);
  128.39 +  // }
  128.40 +  //
  128.41 +  // Note: The version above is for 32x32 multiplications, while the
  128.42 +  // following inline comments are adapted to 64x64.
  128.43 +
  128.44    const int N = 64;
  128.45  
  128.46 -  Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
  128.47 -  Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
  128.48 +  // u0 = u & 0xFFFFFFFF;  u1 = u >> 32;
  128.49 +  Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
  128.50 +  Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
  128.51  
  128.52 -  Node *v_hi = phase->longcon(magic_const >> N/2);
  128.53 -  Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF);
  128.54 +  // v0 = v & 0xFFFFFFFF;  v1 = v >> 32;
  128.55 +  Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF);
  128.56 +  Node* v1 = phase->longcon(magic_const >> (N / 2));
  128.57  
  128.58 -  Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi));
  128.59 -  Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo));
  128.60 -  Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi));
  128.61 -  Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo));
  128.62 +  // w0 = u0*v0;
  128.63 +  Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0));
  128.64  
  128.65 -  Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2)));
  128.66 -  Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1));
  128.67 +  // t = u1*v0 + (w0 >> 32);
  128.68 +  Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0));
  128.69 +  Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2)));
  128.70 +  Node* t    = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp));
  128.71  
  128.72 -  // Construct both t3 and t4 before transforming so t2 doesn't go dead
  128.73 -  // prematurely.
  128.74 -  Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2));
  128.75 -  Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF));
  128.76 -  t3 = phase->transform(t3);
  128.77 -  t4 = phase->transform(t4);
  128.78 +  // w1 = t & 0xFFFFFFFF;
  128.79 +  Node* w1 = new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF));
  128.80  
  128.81 -  Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product));
  128.82 -  Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2)));
  128.83 -  Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product));
  128.84 +  // w2 = t >> 32;
  128.85 +  Node* w2 = new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2));
  128.86  
  128.87 -  return new (phase->C, 3) AddLNode(t7, t6);
  128.88 +  // 6732154: Construct both w1 and w2 before transforming, so t
  128.89 +  // doesn't go dead prematurely.
  128.90 +  w1 = phase->transform(w1);
  128.91 +  w2 = phase->transform(w2);
  128.92 +
  128.93 +  // w1 = u0*v1 + w1;
  128.94 +  Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1));
  128.95 +  w1         = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1));
  128.96 +
  128.97 +  // return u1*v1 + w2 + (w1 >> 32);
  128.98 +  Node* u1v1  = phase->transform(new (phase->C, 3) MulLNode(u1, v1));
  128.99 +  Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2));
 128.100 +  Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2)));
 128.101 +
 128.102 +  return new (phase->C, 3) AddLNode(temp1, temp2);
 128.103  }
 128.104  
 128.105  
 128.106 @@ -976,7 +1007,7 @@
 128.107  
 128.108    // Expand mod
 128.109    if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) {
 128.110 -    uint k = log2_long(con);       // Extract k
 128.111 +    uint k = exact_log2_long(con+1);  // Extract k
 128.112  
 128.113      // Basic algorithm by David Detlefs.  See fastmod_long.java for gory details.
 128.114      // Used to help a popular random number generator which does a long-mod
   129.1 --- a/src/share/vm/opto/gcm.cpp	Sat Jan 31 17:19:42 2009 -0800
   129.2 +++ b/src/share/vm/opto/gcm.cpp	Fri Feb 27 15:13:00 2009 -0800
   129.3 @@ -29,6 +29,9 @@
   129.4  #include "incls/_precompiled.incl"
   129.5  #include "incls/_gcm.cpp.incl"
   129.6  
   129.7 +// To avoid float value underflow
   129.8 +#define MIN_BLOCK_FREQUENCY 1.e-35f
   129.9 +
  129.10  //----------------------------schedule_node_into_block-------------------------
  129.11  // Insert node n into block b. Look for projections of n and make sure they
  129.12  // are in b also.
  129.13 @@ -1380,6 +1383,13 @@
  129.14      }
  129.15    }
  129.16  
  129.17 +#ifdef ASSERT
  129.18 +  for (uint i = 0; i < _num_blocks; i++ ) {
  129.19 +    Block *b = _blocks[i];
  129.20 +    assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency");
  129.21 +  }
  129.22 +#endif
  129.23 +
  129.24  #ifndef PRODUCT
  129.25    if (PrintCFGBlockFreq) {
  129.26      tty->print_cr("CFG Block Frequencies");
  129.27 @@ -1877,7 +1887,9 @@
  129.28    float loop_freq = _freq * trip_count();
  129.29    for (int i = 0; i < _members.length(); i++) {
  129.30      CFGElement* s = _members.at(i);
  129.31 -    s->_freq *= loop_freq;
  129.32 +    float block_freq = s->_freq * loop_freq;
  129.33 +    if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY;
  129.34 +    s->_freq = block_freq;
  129.35    }
  129.36    CFGLoop* ch = _child;
  129.37    while (ch != NULL) {
   130.1 --- a/src/share/vm/opto/graphKit.cpp	Sat Jan 31 17:19:42 2009 -0800
   130.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Feb 27 15:13:00 2009 -0800
   130.3 @@ -1836,10 +1836,7 @@
   130.4      (CardTableModRefBS*)(Universe::heap()->barrier_set());
   130.5    Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
   130.6    // We store into a byte array, so do not bother to left-shift by zero
   130.7 -  // Get base of card map
   130.8 -  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte),
   130.9 -         "adjust this code");
  130.10 -  Node *c = makecon(TypeRawPtr::make((address)ct->byte_map_base));
  130.11 +  Node *c = byte_map_base_node();
  130.12    // Combine
  130.13    Node *sb_ctl = control();
  130.14    Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b ));
  130.15 @@ -2945,16 +2942,10 @@
  130.16  
  130.17    // Now generate allocation code
  130.18  
  130.19 -  // With escape analysis, the entire memory state is needed to be able to
  130.20 -  // eliminate the allocation.  If the allocations cannot be eliminated, this
  130.21 -  // will be optimized to the raw slice when the allocation is expanded.
  130.22 -  Node *mem;
  130.23 -  if (C->do_escape_analysis()) {
  130.24 -    mem = reset_memory();
  130.25 -    set_all_memory(mem);
  130.26 -  } else {
  130.27 -    mem = memory(Compile::AliasIdxRaw);
  130.28 -  }
  130.29 +  // The entire memory state is needed for slow path of the allocation
  130.30 +  // since GC and deoptimization can happened.
  130.31 +  Node *mem = reset_memory();
  130.32 +  set_all_memory(mem); // Create new memory state
  130.33  
  130.34    AllocateNode* alloc
  130.35      = new (C, AllocateNode::ParmLimit)
  130.36 @@ -3091,16 +3082,10 @@
  130.37  
  130.38    // Now generate allocation code
  130.39  
  130.40 -  // With escape analysis, the entire memory state is needed to be able to
  130.41 -  // eliminate the allocation.  If the allocations cannot be eliminated, this
  130.42 -  // will be optimized to the raw slice when the allocation is expanded.
  130.43 -  Node *mem;
  130.44 -  if (C->do_escape_analysis()) {
  130.45 -    mem = reset_memory();
  130.46 -    set_all_memory(mem);
  130.47 -  } else {
  130.48 -    mem = memory(Compile::AliasIdxRaw);
  130.49 -  }
  130.50 +  // The entire memory state is needed for slow path of the allocation
  130.51 +  // since GC and deoptimization can happened.
  130.52 +  Node *mem = reset_memory();
  130.53 +  set_all_memory(mem); // Create new memory state
  130.54  
  130.55    // Create the AllocateArrayNode and its result projections
  130.56    AllocateArrayNode* alloc
  130.57 @@ -3233,12 +3218,11 @@
  130.58  
  130.59    // Now some of the values
  130.60  
  130.61 -  Node* marking = __ load(no_ctrl, marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
  130.62 -  Node* index   = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
  130.63 -  Node* buffer  = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
  130.64 +  Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
  130.65  
  130.66    // if (!marking)
  130.67    __ if_then(marking, BoolTest::ne, zero); {
  130.68 +    Node* index   = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
  130.69  
  130.70      const Type* t1 = adr->bottom_type();
  130.71      const Type* t2 = val->bottom_type();
  130.72 @@ -3246,6 +3230,7 @@
  130.73      Node* orig = __ load(no_ctrl, adr, val_type, bt, alias_idx);
  130.74      // if (orig != NULL)
  130.75      __ if_then(orig, BoolTest::ne, null()); {
  130.76 +      Node* buffer  = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
  130.77  
  130.78        // load original value
  130.79        // alias_idx correct??
  130.80 @@ -3365,14 +3350,6 @@
  130.81  
  130.82    const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
  130.83  
  130.84 -  // Get the address of the card table
  130.85 -  CardTableModRefBS* ct =
  130.86 -    (CardTableModRefBS*)(Universe::heap()->barrier_set());
  130.87 -  Node *card_table = __ makecon(TypeRawPtr::make((address)ct->byte_map_base));
  130.88 -  // Get base of card map
  130.89 -  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
  130.90 -
  130.91 -
  130.92    // Offsets into the thread
  130.93    const int index_offset  = in_bytes(JavaThread::dirty_card_queue_offset() +
  130.94                                       PtrQueue::byte_offset_of_index());
  130.95 @@ -3402,7 +3379,7 @@
  130.96    Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
  130.97  
  130.98    // Combine card table base and card offset
  130.99 -  Node *card_adr = __ AddP(no_base, card_table, card_offset );
 130.100 +  Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
 130.101  
 130.102    // If we know the value being stored does it cross regions?
 130.103  
   131.1 --- a/src/share/vm/opto/graphKit.hpp	Sat Jan 31 17:19:42 2009 -0800
   131.2 +++ b/src/share/vm/opto/graphKit.hpp	Fri Feb 27 15:13:00 2009 -0800
   131.3 @@ -83,6 +83,18 @@
   131.4    Node* zerocon(BasicType bt)   const { return _gvn.zerocon(bt); }
   131.5    // (See also macro MakeConX in type.hpp, which uses intcon or longcon.)
   131.6  
   131.7 +  // Helper for byte_map_base
   131.8 +  Node* byte_map_base_node() {
   131.9 +    // Get base of card map
  131.10 +    CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set());
  131.11 +    assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code");
  131.12 +    if (ct->byte_map_base != NULL) {
  131.13 +      return makecon(TypeRawPtr::make((address)ct->byte_map_base));
  131.14 +    } else {
  131.15 +      return null();
  131.16 +    }
  131.17 +  }
  131.18 +
  131.19    jint  find_int_con(Node* n, jint value_if_unknown) {
  131.20      return _gvn.find_int_con(n, value_if_unknown);
  131.21    }
   132.1 --- a/src/share/vm/opto/idealGraphPrinter.cpp	Sat Jan 31 17:19:42 2009 -0800
   132.2 +++ b/src/share/vm/opto/idealGraphPrinter.cpp	Fri Feb 27 15:13:00 2009 -0800
   132.3 @@ -557,7 +557,7 @@
   132.4  
   132.5          // max. 2 chars allowed
   132.6          if (value >= -9 && value <= 99) {
   132.7 -          sprintf(buffer, "%d", value);
   132.8 +          sprintf(buffer, INT64_FORMAT, value);
   132.9            print_prop(short_name, buffer);
  132.10          } else {
  132.11            print_prop(short_name, "L");
   133.1 --- a/src/share/vm/opto/ifg.cpp	Sat Jan 31 17:19:42 2009 -0800
   133.2 +++ b/src/share/vm/opto/ifg.cpp	Fri Feb 27 15:13:00 2009 -0800
   133.3 @@ -471,12 +471,28 @@
   133.4      // for the "collect_gc_info" phase later.
   133.5      IndexSet liveout(_live->live(b));
   133.6      uint last_inst = b->end_idx();
   133.7 -    // Compute last phi index
   133.8 -    uint last_phi;
   133.9 -    for( last_phi = 1; last_phi < last_inst; last_phi++ )
  133.10 -      if( !b->_nodes[last_phi]->is_Phi() )
  133.11 +    // Compute first nonphi node index
  133.12 +    uint first_inst;
  133.13 +    for( first_inst = 1; first_inst < last_inst; first_inst++ )
  133.14 +      if( !b->_nodes[first_inst]->is_Phi() )
  133.15          break;
  133.16  
  133.17 +    // Spills could be inserted before CreateEx node which should be
  133.18 +    // first instruction in block after Phis. Move CreateEx up.
  133.19 +    for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
  133.20 +      Node *ex = b->_nodes[insidx];
  133.21 +      if( ex->is_SpillCopy() ) continue;
  133.22 +      if( insidx > first_inst && ex->is_Mach() &&
  133.23 +          ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
  133.24 +        // If the CreateEx isn't above all the MachSpillCopies
  133.25 +        // then move it to the top.
  133.26 +        b->_nodes.remove(insidx);
  133.27 +        b->_nodes.insert(first_inst, ex);
  133.28 +      }
  133.29 +      // Stop once a CreateEx or any other node is found
  133.30 +      break;
  133.31 +    }
  133.32 +
  133.33      // Reset block's register pressure values for each ifg construction
  133.34      uint pressure[2], hrp_index[2];
  133.35      pressure[0] = pressure[1] = 0;
  133.36 @@ -485,7 +501,7 @@
  133.37      // Liveout things are presumed live for the whole block.  We accumulate
  133.38      // 'area' accordingly.  If they get killed in the block, we'll subtract
  133.39      // the unused part of the block from the area.
  133.40 -    int inst_count = last_inst - last_phi;
  133.41 +    int inst_count = last_inst - first_inst;
  133.42      double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
  133.43      assert(!(cost < 0.0), "negative spill cost" );
  133.44      IndexSetIterator elements(&liveout);
   134.1 --- a/src/share/vm/opto/lcm.cpp	Sat Jan 31 17:19:42 2009 -0800
   134.2 +++ b/src/share/vm/opto/lcm.cpp	Fri Feb 27 15:13:00 2009 -0800
   134.3 @@ -107,7 +107,7 @@
   134.4      was_store = false;
   134.5      switch( mach->ideal_Opcode() ) {
   134.6      case Op_LoadB:
   134.7 -    case Op_LoadC:
   134.8 +    case Op_LoadUS:
   134.9      case Op_LoadD:
  134.10      case Op_LoadF:
  134.11      case Op_LoadI:
   135.1 --- a/src/share/vm/opto/live.cpp	Sat Jan 31 17:19:42 2009 -0800
   135.2 +++ b/src/share/vm/opto/live.cpp	Fri Feb 27 15:13:00 2009 -0800
   135.3 @@ -271,9 +271,9 @@
   135.4  
   135.5  //------------------------------verify_base_ptrs-------------------------------
   135.6  // Verify that base pointers and derived pointers are still sane.
   135.7 -// Basically, if a derived pointer is live at a safepoint, then its
   135.8 -// base pointer must be live also.
   135.9  void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
  135.10 +#ifdef ASSERT
  135.11 +  Unique_Node_List worklist(a);
  135.12    for( uint i = 0; i < _cfg._num_blocks; i++ ) {
  135.13      Block *b = _cfg._blocks[i];
  135.14      for( uint j = b->end_idx() + 1; j > 1; j-- ) {
  135.15 @@ -287,28 +287,81 @@
  135.16            // Now scan for a live derived pointer
  135.17            if (jvms->oopoff() < sfpt->req()) {
  135.18              // Check each derived/base pair
  135.19 -            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx += 2) {
  135.20 +            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
  135.21                Node *check = sfpt->in(idx);
  135.22 -              uint j = 0;
  135.23 +              bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
  135.24                // search upwards through spills and spill phis for AddP
  135.25 -              while(true) {
  135.26 -                if( !check ) break;
  135.27 -                int idx = check->is_Copy();
  135.28 -                if( idx ) {
  135.29 -                  check = check->in(idx);
  135.30 -                } else if( check->is_Phi() && check->_idx >= _oldphi ) {
  135.31 -                  check = check->in(1);
  135.32 -                } else
  135.33 -                  break;
  135.34 -                j++;
  135.35 -                assert(j < 100000,"Derived pointer checking in infinite loop");
  135.36 +              worklist.clear();
  135.37 +              worklist.push(check);
  135.38 +              uint k = 0;
  135.39 +              while( k < worklist.size() ) {
  135.40 +                check = worklist.at(k);
  135.41 +                assert(check,"Bad base or derived pointer");
  135.42 +                // See PhaseChaitin::find_base_for_derived() for all cases.
  135.43 +                int isc = check->is_Copy();
  135.44 +                if( isc ) {
  135.45 +                  worklist.push(check->in(isc));
  135.46 +                } else if( check->is_Phi() ) {
  135.47 +                  for (uint m = 1; m < check->req(); m++)
  135.48 +                    worklist.push(check->in(m));
  135.49 +                } else if( check->is_Con() ) {
  135.50 +                  if (is_derived) {
  135.51 +                    // Derived is NULL+offset
  135.52 +                    assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
  135.53 +                  } else {
  135.54 +                    assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer");
  135.55 +                    // Base either ConP(NULL) or loadConP
  135.56 +                    if (check->is_Mach()) {
  135.57 +                      assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer");
  135.58 +                    } else {
  135.59 +                      assert(check->Opcode() == Op_ConP &&
  135.60 +                             check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
  135.61 +                    }
  135.62 +                  }
  135.63 +                } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
  135.64 +                  if(check->is_Proj() || check->is_Mach() &&
  135.65 +                     (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
  135.66 +                      check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
  135.67 +                      check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
  135.68 +                      check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
  135.69 +#ifdef _LP64
  135.70 +                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
  135.71 +                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
  135.72 +#endif
  135.73 +                      check->as_Mach()->ideal_Opcode() == Op_LoadP ||
  135.74 +                      check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
  135.75 +                    // Valid nodes
  135.76 +                  } else {
  135.77 +                    check->dump();
  135.78 +                    assert(false,"Bad base or derived pointer");
  135.79 +                  }
  135.80 +                } else {
  135.81 +                  assert(is_derived,"Bad base pointer");
  135.82 +                  assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
  135.83 +                }
  135.84 +                k++;
  135.85 +                assert(k < 100000,"Derived pointer checking in infinite loop");
  135.86                } // End while
  135.87 -              assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer")
  135.88              }
  135.89            } // End of check for derived pointers
  135.90          } // End of Kcheck for debug info
  135.91        } // End of if found a safepoint
  135.92      } // End of forall instructions in block
  135.93    } // End of forall blocks
  135.94 +#endif
  135.95  }
  135.96 +
  135.97 +//------------------------------verify-------------------------------------
  135.98 +// Verify that graphs and base pointers are still sane.
  135.99 +void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
 135.100 +#ifdef ASSERT
 135.101 +  if( VerifyOpto || VerifyRegisterAllocator ) {
 135.102 +    _cfg.verify();
 135.103 +    verify_base_ptrs(a);
 135.104 +    if(verify_ifg)
 135.105 +      _ifg->verify(this);
 135.106 +  }
 135.107  #endif
 135.108 +}
 135.109 +
 135.110 +#endif
   136.1 --- a/src/share/vm/opto/loopnode.cpp	Sat Jan 31 17:19:42 2009 -0800
   136.2 +++ b/src/share/vm/opto/loopnode.cpp	Fri Feb 27 15:13:00 2009 -0800
   136.3 @@ -2654,7 +2654,7 @@
   136.4      case Op_ModF:
   136.5      case Op_ModD:
   136.6      case Op_LoadB:              // Same with Loads; they can sink
   136.7 -    case Op_LoadC:              // during loop optimizations.
   136.8 +    case Op_LoadUS:             // during loop optimizations.
   136.9      case Op_LoadD:
  136.10      case Op_LoadF:
  136.11      case Op_LoadI:
   137.1 --- a/src/share/vm/opto/macro.cpp	Sat Jan 31 17:19:42 2009 -0800
   137.2 +++ b/src/share/vm/opto/macro.cpp	Fri Feb 27 15:13:00 2009 -0800
   137.3 @@ -952,13 +952,6 @@
   137.4    Node* klass_node        = alloc->in(AllocateNode::KlassNode);
   137.5    Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
   137.6  
   137.7 -  // With escape analysis, the entire memory state was needed to be able to
   137.8 -  // eliminate the allocation.  Since the allocations cannot be eliminated,
   137.9 -  // optimize it to the raw slice.
  137.10 -  if (mem->is_MergeMem()) {
  137.11 -    mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
  137.12 -  }
  137.13 -
  137.14    assert(ctrl != NULL, "must have control");
  137.15    // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
  137.16    // they will not be used if "always_slow" is set
  137.17 @@ -1016,6 +1009,11 @@
  137.18    Node *slow_mem = mem;  // save the current memory state for slow path
  137.19    // generate the fast allocation code unless we know that the initial test will always go slow
  137.20    if (!always_slow) {
  137.21 +    // Fast path modifies only raw memory.
  137.22 +    if (mem->is_MergeMem()) {
  137.23 +      mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
  137.24 +    }
  137.25 +
  137.26      Node* eden_top_adr;
  137.27      Node* eden_end_adr;
  137.28  
  137.29 @@ -1239,8 +1237,6 @@
  137.30      }
  137.31    }
  137.32  
  137.33 -  mem = result_phi_rawmem;
  137.34 -
  137.35    // An allocate node has separate i_o projections for the uses on the control and i_o paths
  137.36    // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
  137.37    if (_ioproj_fallthrough == NULL) {
   138.1 --- a/src/share/vm/opto/matcher.cpp	Sat Jan 31 17:19:42 2009 -0800
   138.2 +++ b/src/share/vm/opto/matcher.cpp	Fri Feb 27 15:13:00 2009 -0800
   138.3 @@ -1824,7 +1824,7 @@
   138.4          mem_op = true;
   138.5          break;
   138.6        case Op_LoadB:
   138.7 -      case Op_LoadC:
   138.8 +      case Op_LoadUS:
   138.9        case Op_LoadD:
  138.10        case Op_LoadF:
  138.11        case Op_LoadI:
   139.1 --- a/src/share/vm/opto/memnode.cpp	Sat Jan 31 17:19:42 2009 -0800
   139.2 +++ b/src/share/vm/opto/memnode.cpp	Fri Feb 27 15:13:00 2009 -0800
   139.3 @@ -779,14 +779,14 @@
   139.4           "use LoadRangeNode instead");
   139.5    switch (bt) {
   139.6    case T_BOOLEAN:
   139.7 -  case T_BYTE:    return new (C, 3) LoadBNode(ctl, mem, adr, adr_type, rt->is_int()    );
   139.8 -  case T_INT:     return new (C, 3) LoadINode(ctl, mem, adr, adr_type, rt->is_int()    );
   139.9 -  case T_CHAR:    return new (C, 3) LoadCNode(ctl, mem, adr, adr_type, rt->is_int()    );
  139.10 -  case T_SHORT:   return new (C, 3) LoadSNode(ctl, mem, adr, adr_type, rt->is_int()    );
  139.11 -  case T_LONG:    return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long()   );
  139.12 -  case T_FLOAT:   return new (C, 3) LoadFNode(ctl, mem, adr, adr_type, rt              );
  139.13 -  case T_DOUBLE:  return new (C, 3) LoadDNode(ctl, mem, adr, adr_type, rt              );
  139.14 -  case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr()    );
  139.15 +  case T_BYTE:    return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
  139.16 +  case T_INT:     return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
  139.17 +  case T_CHAR:    return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
  139.18 +  case T_SHORT:   return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
  139.19 +  case T_LONG:    return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
  139.20 +  case T_FLOAT:   return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt              );
  139.21 +  case T_DOUBLE:  return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt              );
  139.22 +  case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
  139.23    case T_OBJECT:
  139.24  #ifdef _LP64
  139.25      if (adr->bottom_type()->is_ptr_to_narrowoop()) {
  139.26 @@ -1076,13 +1076,14 @@
  139.27        // of the original value.
  139.28        Node* mem_phi = in(Memory);
  139.29        Node* offset = in(Address)->in(AddPNode::Offset);
  139.30 +      Node* region = base->in(0);
  139.31  
  139.32        Node* in1 = clone();
  139.33        Node* in1_addr = in1->in(Address)->clone();
  139.34        in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
  139.35        in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
  139.36        in1_addr->set_req(AddPNode::Offset, offset);
  139.37 -      in1->set_req(0, base->in(allocation_index));
  139.38 +      in1->set_req(0, region->in(allocation_index));
  139.39        in1->set_req(Address, in1_addr);
  139.40        in1->set_req(Memory, mem_phi->in(allocation_index));
  139.41  
  139.42 @@ -1091,7 +1092,7 @@
  139.43        in2_addr->set_req(AddPNode::Base, base->in(load_index));
  139.44        in2_addr->set_req(AddPNode::Address, base->in(load_index));
  139.45        in2_addr->set_req(AddPNode::Offset, offset);
  139.46 -      in2->set_req(0, base->in(load_index));
  139.47 +      in2->set_req(0, region->in(load_index));
  139.48        in2->set_req(Address, in2_addr);
  139.49        in2->set_req(Memory, mem_phi->in(load_index));
  139.50  
  139.51 @@ -1100,7 +1101,7 @@
  139.52        in2_addr = phase->transform(in2_addr);
  139.53        in2 =      phase->transform(in2);
  139.54  
  139.55 -      PhiNode* result = PhiNode::make_blank(base->in(0), this);
  139.56 +      PhiNode* result = PhiNode::make_blank(region, this);
  139.57        result->set_req(allocation_index, in1);
  139.58        result->set_req(load_index, in2);
  139.59        return result;
  139.60 @@ -1303,6 +1304,7 @@
  139.61      Node*    base   = AddPNode::Ideal_base_and_offset(address, phase, ignore);
  139.62      if (base != NULL
  139.63          && phase->type(base)->higher_equal(TypePtr::NOTNULL)
  139.64 +        && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw
  139.65          && all_controls_dominate(base, phase->C->start())) {
  139.66        // A method-invariant, non-null address (constant or 'this' argument).
  139.67        set_req(MemNode::Control, NULL);
  139.68 @@ -1356,7 +1358,7 @@
  139.69    // Steps (a), (b):  Walk past independent stores to find an exact match.
  139.70    if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
  139.71      // (c) See if we can fold up on the spot, but don't fold up here.
  139.72 -    // Fold-up might require truncation (for LoadB/LoadS/LoadC) or
  139.73 +    // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or
  139.74      // just return a prior value, which is done by Identity calls.
  139.75      if (can_see_stored_value(prev_mem, phase)) {
  139.76        // Make ready for step (d):
  139.77 @@ -1605,14 +1607,14 @@
  139.78    return LoadNode::Ideal(phase, can_reshape);
  139.79  }
  139.80  
  139.81 -//--------------------------LoadCNode::Ideal--------------------------------------
  139.82 +//--------------------------LoadUSNode::Ideal-------------------------------------
  139.83  //
  139.84  //  If the previous store is to the same address as this load,
  139.85  //  and the value stored was larger than a char, replace this load
  139.86  //  with the value stored truncated to a char.  If no truncation is
  139.87  //  needed, the replacement is done in LoadNode::Identity().
  139.88  //
  139.89 -Node *LoadCNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  139.90 +Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  139.91    Node* mem = in(MemNode::Memory);
  139.92    Node* value = can_see_stored_value(mem,phase);
  139.93    if( value && !phase->type(value)->higher_equal( _type ) )
   140.1 --- a/src/share/vm/opto/memnode.hpp	Sat Jan 31 17:19:42 2009 -0800
   140.2 +++ b/src/share/vm/opto/memnode.hpp	Fri Feb 27 15:13:00 2009 -0800
   140.3 @@ -207,11 +207,11 @@
   140.4    virtual BasicType memory_type() const { return T_BYTE; }
   140.5  };
   140.6  
   140.7 -//------------------------------LoadCNode--------------------------------------
   140.8 -// Load a char (16bits unsigned) from memory
   140.9 -class LoadCNode : public LoadNode {
  140.10 +//------------------------------LoadUSNode-------------------------------------
  140.11 +// Load an unsigned short/char (16bits unsigned) from memory
  140.12 +class LoadUSNode : public LoadNode {
  140.13  public:
  140.14 -  LoadCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
  140.15 +  LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
  140.16      : LoadNode(c,mem,adr,at,ti) {}
  140.17    virtual int Opcode() const;
  140.18    virtual uint ideal_reg() const { return Op_RegI; }
   141.1 --- a/src/share/vm/opto/mulnode.cpp	Sat Jan 31 17:19:42 2009 -0800
   141.2 +++ b/src/share/vm/opto/mulnode.cpp	Fri Feb 27 15:13:00 2009 -0800
   141.3 @@ -1,5 +1,5 @@
   141.4  /*
   141.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
   141.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
   141.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   141.8   *
   141.9   * This code is free software; you can redistribute it and/or modify it
  141.10 @@ -442,16 +442,17 @@
  141.11          return load;
  141.12      }
  141.13      uint lop = load->Opcode();
  141.14 -    if( lop == Op_LoadC &&
  141.15 +    if( lop == Op_LoadUS &&
  141.16          con == 0x0000FFFF )     // Already zero-extended
  141.17        return load;
  141.18      // Masking off the high bits of a unsigned-shift-right is not
  141.19      // needed either.
  141.20      if( lop == Op_URShiftI ) {
  141.21        const TypeInt *t12 = phase->type( load->in(2) )->isa_int();
  141.22 -      if( t12 && t12->is_con() ) {
  141.23 -        int shift_con = t12->get_con();
  141.24 -        int mask = max_juint >> shift_con;
  141.25 +      if( t12 && t12->is_con() ) {  // Shift is by a constant
  141.26 +        int shift = t12->get_con();
  141.27 +        shift &= BitsPerJavaInteger - 1;  // semantics of Java shifts
  141.28 +        int mask = max_juint >> shift;
  141.29          if( (mask&con) == mask )  // If AND is useless, skip it
  141.30            return load;
  141.31        }
  141.32 @@ -470,19 +471,19 @@
  141.33    uint lop = load->Opcode();
  141.34  
  141.35    // Masking bits off of a Character?  Hi bits are already zero.
  141.36 -  if( lop == Op_LoadC &&
  141.37 +  if( lop == Op_LoadUS &&
  141.38        (mask & 0xFFFF0000) )     // Can we make a smaller mask?
  141.39      return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
  141.40  
  141.41    // Masking bits off of a Short?  Loading a Character does some masking
  141.42    if( lop == Op_LoadS &&
  141.43        (mask & 0xFFFF0000) == 0 ) {
  141.44 -    Node *ldc = new (phase->C, 3) LoadCNode(load->in(MemNode::Control),
  141.45 +    Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
  141.46                                    load->in(MemNode::Memory),
  141.47                                    load->in(MemNode::Address),
  141.48                                    load->adr_type());
  141.49 -    ldc = phase->transform(ldc);
  141.50 -    return new (phase->C, 3) AndINode(ldc,phase->intcon(mask&0xFFFF));
  141.51 +    ldus = phase->transform(ldus);
  141.52 +    return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
  141.53    }
  141.54  
  141.55    // Masking sign bits off of a Byte?  Let the matcher use an unsigned load
  141.56 @@ -579,9 +580,10 @@
  141.57      // needed either.
  141.58      if( lop == Op_URShiftL ) {
  141.59        const TypeInt *t12 = phase->type( usr->in(2) )->isa_int();
  141.60 -      if( t12 && t12->is_con() ) {
  141.61 -        int shift_con = t12->get_con();
  141.62 -        jlong mask = max_julong >> shift_con;
  141.63 +      if( t12 && t12->is_con() ) {  // Shift is by a constant
  141.64 +        int shift = t12->get_con();
  141.65 +        shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
  141.66 +        jlong mask = max_julong >> shift;
  141.67          if( (mask&con) == mask )  // If AND is useless, skip it
  141.68            return usr;
  141.69        }
  141.70 @@ -605,8 +607,8 @@
  141.71      const TypeInt *t12 = phase->type(rsh->in(2))->isa_int();
  141.72      if( t12 && t12->is_con() ) { // Shift is by a constant
  141.73        int shift = t12->get_con();
  141.74 -      shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
  141.75 -      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - shift)) -1);
  141.76 +      shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
  141.77 +      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
  141.78        // If the AND'ing of the 2 masks has no bits, then only original shifted
  141.79        // bits survive.  NO sign-extension bits survive the maskings.
  141.80        if( (sign_bits_mask & mask) == 0 ) {
  141.81 @@ -786,7 +788,7 @@
  141.82  
  141.83    // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
  141.84    // before shifting them away.
  141.85 -  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) - CONST64(1);
  141.86 +  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
  141.87    if( add1_op == Op_AndL &&
  141.88        phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
  141.89      return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) );
  141.90 @@ -820,7 +822,7 @@
  141.91      return TypeLong::LONG;
  141.92  
  141.93    uint shift = r2->get_con();
  141.94 -  shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
  141.95 +  shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
  141.96    // Shift by a multiple of 64 does nothing:
  141.97    if (shift == 0)  return t1;
  141.98  
  141.99 @@ -913,7 +915,7 @@
 141.100        set_req(2, phase->intcon(0));
 141.101        return this;
 141.102      }
 141.103 -    else if( ld->Opcode() == Op_LoadC )
 141.104 +    else if( ld->Opcode() == Op_LoadUS )
 141.105        // Replace zero-extension-load with sign-extension-load
 141.106        return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control),
 141.107                                  ld->in(MemNode::Memory),
 141.108 @@ -1235,7 +1237,7 @@
 141.109    if ( con == 0 ) return NULL;  // let Identity() handle a 0 shift count
 141.110                                // note: mask computation below does not work for 0 shift count
 141.111    // We'll be wanting the right-shift amount as a mask of that many bits
 141.112 -  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) -1);
 141.113 +  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1);
 141.114  
 141.115    // Check for ((x << z) + Y) >>> z.  Replace with x + con>>>z
 141.116    // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
 141.117 @@ -1302,7 +1304,7 @@
 141.118  
 141.119    if (r2->is_con()) {
 141.120      uint shift = r2->get_con();
 141.121 -    shift &= (2*BitsPerJavaInteger)-1;  // semantics of Java shifts
 141.122 +    shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
 141.123      // Shift by a multiple of 64 does nothing:
 141.124      if (shift == 0)  return t1;
 141.125      // Calculate reasonably aggressive bounds for the result.
 141.126 @@ -1325,7 +1327,7 @@
 141.127      const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen));
 141.128      #ifdef ASSERT
 141.129      // Make sure we get the sign-capture idiom correct.
 141.130 -    if (shift == (2*BitsPerJavaInteger)-1) {
 141.131 +    if (shift == BitsPerJavaLong - 1) {
 141.132        if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>>63 of + is 0");
 141.133        if (r1->_hi < 0)  assert(tl == TypeLong::ONE,  ">>>63 of - is +1");
 141.134      }
   142.1 --- a/src/share/vm/opto/superword.cpp	Sat Jan 31 17:19:42 2009 -0800
   142.2 +++ b/src/share/vm/opto/superword.cpp	Fri Feb 27 15:13:00 2009 -0800
   142.3 @@ -1444,7 +1444,7 @@
   142.4  // (Start, end] half-open range defining which operands are vector
   142.5  void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
   142.6    switch (n->Opcode()) {
   142.7 -  case Op_LoadB:   case Op_LoadC:
   142.8 +  case Op_LoadB:   case Op_LoadUS:
   142.9    case Op_LoadI:   case Op_LoadL:
  142.10    case Op_LoadF:   case Op_LoadD:
  142.11    case Op_LoadP:
   143.1 --- a/src/share/vm/opto/type.cpp	Sat Jan 31 17:19:42 2009 -0800
   143.2 +++ b/src/share/vm/opto/type.cpp	Fri Feb 27 15:13:00 2009 -0800
   143.3 @@ -2471,6 +2471,8 @@
   143.4    const Type* ft = join(kills);
   143.5    const TypeInstPtr* ftip = ft->isa_instptr();
   143.6    const TypeInstPtr* ktip = kills->isa_instptr();
   143.7 +  const TypeKlassPtr* ftkp = ft->isa_klassptr();
   143.8 +  const TypeKlassPtr* ktkp = kills->isa_klassptr();
   143.9  
  143.10    if (ft->empty()) {
  143.11      // Check for evil case of 'this' being a class and 'kills' expecting an
  143.12 @@ -2484,6 +2486,8 @@
  143.13      // uplift the type.
  143.14      if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface())
  143.15        return kills;             // Uplift to interface
  143.16 +    if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface())
  143.17 +      return kills;             // Uplift to interface
  143.18  
  143.19      return Type::TOP;           // Canonical empty value
  143.20    }
  143.21 @@ -2499,6 +2503,12 @@
  143.22      // Happens in a CTW of rt.jar, 320-341, no extra flags
  143.23      return ktip->cast_to_ptr_type(ftip->ptr());
  143.24    }
  143.25 +  if (ftkp != NULL && ktkp != NULL &&
  143.26 +      ftkp->is_loaded() &&  ftkp->klass()->is_interface() &&
  143.27 +      ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
  143.28 +    // Happens in a CTW of rt.jar, 320-341, no extra flags
  143.29 +    return ktkp->cast_to_ptr_type(ftkp->ptr());
  143.30 +  }
  143.31  
  143.32    return ft;
  143.33  }
  143.34 @@ -3657,7 +3667,7 @@
  143.35  
  143.36  //------------------------------cast_to_ptr_type-------------------------------
  143.37  const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const {
  143.38 -  assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
  143.39 +  assert(_base == KlassPtr, "subclass must override cast_to_ptr_type");
  143.40    if( ptr == _ptr ) return this;
  143.41    return make(ptr, _klass, _offset);
  143.42  }
   144.1 --- a/src/share/vm/opto/type.hpp	Sat Jan 31 17:19:42 2009 -0800
   144.2 +++ b/src/share/vm/opto/type.hpp	Fri Feb 27 15:13:00 2009 -0800
   144.3 @@ -882,6 +882,8 @@
   144.4  public:
   144.5    ciSymbol* name()  const { return _klass->name(); }
   144.6  
   144.7 +  bool  is_loaded() const { return _klass->is_loaded(); }
   144.8 +
   144.9    // ptr to klass 'k'
  144.10    static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); }
  144.11    // ptr to klass 'k' with offset
   145.1 --- a/src/share/vm/opto/vectornode.cpp	Sat Jan 31 17:19:42 2009 -0800
   145.2 +++ b/src/share/vm/opto/vectornode.cpp	Fri Feb 27 15:13:00 2009 -0800
   145.3 @@ -239,7 +239,7 @@
   145.4      return Op_XorV;
   145.5  
   145.6    case Op_LoadB:
   145.7 -  case Op_LoadC:
   145.8 +  case Op_LoadUS:
   145.9    case Op_LoadS:
  145.10    case Op_LoadI:
  145.11    case Op_LoadL:
  145.12 @@ -269,7 +269,7 @@
  145.13      case 16:       return Op_Load16B;
  145.14      }
  145.15      break;
  145.16 -  case Op_LoadC:
  145.17 +  case Op_LoadUS:
  145.18      switch (vlen) {
  145.19      case  2:       return Op_Load2C;
  145.20      case  4:       return Op_Load4C;
   146.1 --- a/src/share/vm/prims/jni.cpp	Sat Jan 31 17:19:42 2009 -0800
   146.2 +++ b/src/share/vm/prims/jni.cpp	Fri Feb 27 15:13:00 2009 -0800
   146.3 @@ -2691,8 +2691,13 @@
   146.4  
   146.5      directBufferSupportInitializeEnded = 1;
   146.6    } else {
   146.7 -    ThreadInVMfromNative tivn(thread); // set state as yield_all can call os:sleep
   146.8      while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
   146.9 +      // Set state as yield_all can call os:sleep. On Solaris, yield_all calls
  146.10 +      // os::sleep which requires the VM state transition. On other platforms, it
  146.11 +      // is not necessary. The following call to change the VM state is purposely
  146.12 +      // put inside the loop to avoid potential deadlock when multiple threads
  146.13 +      // try to call this method. See 6791815 for more details.
  146.14 +      ThreadInVMfromNative tivn(thread);
  146.15        os::yield_all();
  146.16      }
  146.17    }
   147.1 --- a/src/share/vm/prims/jvm.cpp	Sat Jan 31 17:19:42 2009 -0800
   147.2 +++ b/src/share/vm/prims/jvm.cpp	Fri Feb 27 15:13:00 2009 -0800
   147.3 @@ -2475,7 +2475,8 @@
   147.4    if (Arguments::vfprintf_hook() != NULL) {
   147.5      jio_fprintf(defaultStream::output_stream(), "%s", s);
   147.6    } else {
   147.7 -    ::write(defaultStream::output_fd(), s, (int)strlen(s));
   147.8 +    // Make an unused local variable to avoid warning from gcc 4.x compiler.
   147.9 +    size_t count = ::write(defaultStream::output_fd(), s, (int)strlen(s));
  147.10    }
  147.11  }
  147.12  
   148.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Sat Jan 31 17:19:42 2009 -0800
   148.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Feb 27 15:13:00 2009 -0800
   148.3 @@ -1230,8 +1230,14 @@
   148.4  
   148.5    // Constant pools are not easily reused so we allocate a new one
   148.6    // each time.
   148.7 +  // merge_cp is created unsafe for concurrent GC processing.  It
   148.8 +  // should be marked safe before discarding it because, even if
   148.9 +  // garbage.  If it crosses a card boundary, it may be scanned
  148.10 +  // in order to find the start of the first complete object on the card.
  148.11    constantPoolHandle merge_cp(THREAD,
  148.12 -    oopFactory::new_constantPool(merge_cp_length, THREAD));
  148.13 +    oopFactory::new_constantPool(merge_cp_length,
  148.14 +                                 methodOopDesc::IsUnsafeConc,
  148.15 +                                 THREAD));
  148.16    int orig_length = old_cp->orig_length();
  148.17    if (orig_length == 0) {
  148.18      // This old_cp is an actual original constant pool. We save
  148.19 @@ -1274,6 +1280,7 @@
  148.20        // rewriting so we can't use the old constant pool with the new
  148.21        // class.
  148.22  
  148.23 +      merge_cp()->set_is_conc_safe(true);
  148.24        merge_cp = constantPoolHandle();  // toss the merged constant pool
  148.25      } else if (old_cp->length() < scratch_cp->length()) {
  148.26        // The old constant pool has fewer entries than the new constant
  148.27 @@ -1283,6 +1290,7 @@
  148.28        // rewriting so we can't use the new constant pool with the old
  148.29        // class.
  148.30  
  148.31 +      merge_cp()->set_is_conc_safe(true);
  148.32        merge_cp = constantPoolHandle();  // toss the merged constant pool
  148.33      } else {
  148.34        // The old constant pool has more entries than the new constant
  148.35 @@ -1296,6 +1304,7 @@
  148.36        set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
  148.37          THREAD);
  148.38        // drop local ref to the merged constant pool
  148.39 +      merge_cp()->set_is_conc_safe(true);
  148.40        merge_cp = constantPoolHandle();
  148.41      }
  148.42    } else {
  148.43 @@ -1325,7 +1334,10 @@
  148.44      // GCed.
  148.45      set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true,
  148.46        THREAD);
  148.47 +    merge_cp()->set_is_conc_safe(true);
  148.48    }
  148.49 +  assert(old_cp()->is_conc_safe(), "Just checking");
  148.50 +  assert(scratch_cp()->is_conc_safe(), "Just checking");
  148.51  
  148.52    return JVMTI_ERROR_NONE;
  148.53  } // end merge_cp_and_rewrite()
  148.54 @@ -2314,13 +2326,16 @@
  148.55      // worst case merge situation. We want to associate the minimum
  148.56      // sized constant pool with the klass to save space.
  148.57      constantPoolHandle smaller_cp(THREAD,
  148.58 -      oopFactory::new_constantPool(scratch_cp_length, THREAD));
  148.59 +      oopFactory::new_constantPool(scratch_cp_length,
  148.60 +                                   methodOopDesc::IsUnsafeConc,
  148.61 +                                   THREAD));
  148.62      // preserve orig_length() value in the smaller copy
  148.63      int orig_length = scratch_cp->orig_length();
  148.64      assert(orig_length != 0, "sanity check");
  148.65      smaller_cp->set_orig_length(orig_length);
  148.66      scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
  148.67      scratch_cp = smaller_cp;
  148.68 +    smaller_cp()->set_is_conc_safe(true);
  148.69    }
  148.70  
  148.71    // attach new constant pool to klass
  148.72 @@ -2516,6 +2531,7 @@
  148.73  
  148.74      rewrite_cp_refs_in_stack_map_table(method, THREAD);
  148.75    } // end for each method
  148.76 +  assert(scratch_cp()->is_conc_safe(), "Just checking");
  148.77  } // end set_new_constant_pool()
  148.78  
  148.79  
   149.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp	Sat Jan 31 17:19:42 2009 -0800
   149.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp	Fri Feb 27 15:13:00 2009 -0800
   149.3 @@ -1320,6 +1320,9 @@
   149.4      }
   149.5  
   149.6      // do the iteration
   149.7 +    // If this operation encounters a bad object when using CMS,
   149.8 +    // consider using safe_object_iterate() which avoids perm gen
   149.9 +    // objects that may contain bad references.
  149.10      Universe::heap()->object_iterate(_blk);
  149.11  
  149.12      // when sharing is enabled we must iterate over the shared spaces
   150.1 --- a/src/share/vm/runtime/arguments.cpp	Sat Jan 31 17:19:42 2009 -0800
   150.2 +++ b/src/share/vm/runtime/arguments.cpp	Fri Feb 27 15:13:00 2009 -0800
   150.3 @@ -229,6 +229,7 @@
   150.4  
   150.5    inline void set_base(const char* base);
   150.6    inline void add_prefix(const char* prefix);
   150.7 +  inline void add_suffix_to_prefix(const char* suffix);
   150.8    inline void add_suffix(const char* suffix);
   150.9    inline void reset_path(const char* base);
  150.10  
  150.11 @@ -290,6 +291,10 @@
  150.12    _items[_scp_prefix] = add_to_path(_items[_scp_prefix], prefix, true);
  150.13  }
  150.14  
  150.15 +inline void SysClassPath::add_suffix_to_prefix(const char* suffix) {
  150.16 +  _items[_scp_prefix] = add_to_path(_items[_scp_prefix], suffix, false);
  150.17 +}
  150.18 +
  150.19  inline void SysClassPath::add_suffix(const char* suffix) {
  150.20    _items[_scp_suffix] = add_to_path(_items[_scp_suffix], suffix, false);
  150.21  }
  150.22 @@ -512,7 +517,6 @@
  150.23    return CommandLineFlags::boolAtPut(name, &value, origin);
  150.24  }
  150.25  
  150.26 -
  150.27  static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
  150.28    double v;
  150.29    if (sscanf(value, "%lf", &v) != 1) {
  150.30 @@ -525,7 +529,6 @@
  150.31    return false;
  150.32  }
  150.33  
  150.34 -
  150.35  static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
  150.36    julong v;
  150.37    intx intx_v;
  150.38 @@ -555,7 +558,6 @@
  150.39    return false;
  150.40  }
  150.41  
  150.42 -
  150.43  static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) {
  150.44    if (!CommandLineFlags::ccstrAtPut(name, &value, origin))  return false;
  150.45    // Contract:  CommandLineFlags always returns a pointer that needs freeing.
  150.46 @@ -591,7 +593,6 @@
  150.47    return true;
  150.48  }
  150.49  
  150.50 -
  150.51  bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) {
  150.52  
  150.53    // range of acceptable characters spelled out for portability reasons
  150.54 @@ -652,7 +653,6 @@
  150.55    return false;
  150.56  }
  150.57  
  150.58 -
  150.59  void Arguments::add_string(char*** bldarray, int* count, const char* arg) {
  150.60    assert(bldarray != NULL, "illegal argument");
  150.61  
  150.62 @@ -756,7 +756,6 @@
  150.63    return true;
  150.64  }
  150.65  
  150.66 -
  150.67  bool Arguments::process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized) {
  150.68    FILE* stream = fopen(file_name, "rb");
  150.69    if (stream == NULL) {
  150.70 @@ -932,7 +931,6 @@
  150.71    }
  150.72  }
  150.73  
  150.74 -
  150.75  // Conflict: required to use shared spaces (-Xshare:on), but
  150.76  // incompatible command line options were chosen.
  150.77  
  150.78 @@ -946,7 +944,6 @@
  150.79    }
  150.80  }
  150.81  
  150.82 -
  150.83  // If the user has chosen ParallelGCThreads > 0, we set UseParNewGC
  150.84  // if it's not explictly set or unset. If the user has chosen
  150.85  // UseParNewGC and not explicitly set ParallelGCThreads we
  150.86 @@ -1361,7 +1358,7 @@
  150.87  
  150.88      // Feed the cache size setting into the JDK
  150.89      char buffer[1024];
  150.90 -    sprintf(buffer, "java.lang.Integer.IntegerCache.high=%d", AutoBoxCacheMax);
  150.91 +    sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
  150.92      add_property(buffer);
  150.93    }
  150.94    if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
  150.95 @@ -1714,6 +1711,21 @@
  150.96      return result;
  150.97    }
  150.98  
  150.99 +  if (AggressiveOpts) {
 150.100 +    // Insert alt-rt.jar between user-specified bootclasspath
 150.101 +    // prefix and the default bootclasspath.  os::set_boot_path()
 150.102 +    // uses meta_index_dir as the default bootclasspath directory.
 150.103 +    const char* altclasses_jar = "alt-rt.jar";
 150.104 +    size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 +
 150.105 +                                 strlen(altclasses_jar);
 150.106 +    char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len);
 150.107 +    strcpy(altclasses_path, get_meta_index_dir());
 150.108 +    strcat(altclasses_path, altclasses_jar);
 150.109 +    scp.add_suffix_to_prefix(altclasses_path);
 150.110 +    scp_assembly_required = true;
 150.111 +    FREE_C_HEAP_ARRAY(char, altclasses_path);
 150.112 +  }
 150.113 +
 150.114    // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
 150.115    result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
 150.116    if (result != JNI_OK) {
 150.117 @@ -1729,7 +1741,6 @@
 150.118    return JNI_OK;
 150.119  }
 150.120  
 150.121 -
 150.122  jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
 150.123                                         SysClassPath* scp_p,
 150.124                                         bool* scp_assembly_required_p,
 150.125 @@ -1795,7 +1806,7 @@
 150.126        *scp_assembly_required_p = true;
 150.127      // -Xrun
 150.128      } else if (match_option(option, "-Xrun", &tail)) {
 150.129 -      if(tail != NULL) {
 150.130 +      if (tail != NULL) {
 150.131          const char* pos = strchr(tail, ':');
 150.132          size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
 150.133          char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len);
 150.134 @@ -2478,7 +2489,7 @@
 150.135      vm_args.version = JNI_VERSION_1_2;
 150.136      vm_args.options = options;
 150.137      vm_args.nOptions = i;
 150.138 -    vm_args.ignoreUnrecognized = false;
 150.139 +    vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
 150.140  
 150.141      if (PrintVMOptions) {
 150.142        const char* tail;
 150.143 @@ -2525,13 +2536,12 @@
 150.144  
 150.145    // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
 150.146    bool settings_file_specified = false;
 150.147 +  const char* flags_file;
 150.148    int index;
 150.149    for (index = 0; index < args->nOptions; index++) {
 150.150      const JavaVMOption *option = args->options + index;
 150.151      if (match_option(option, "-XX:Flags=", &tail)) {
 150.152 -      if (!process_settings_file(tail, true, args->ignoreUnrecognized)) {
 150.153 -        return JNI_EINVAL;
 150.154 -      }
 150.155 +      flags_file = tail;
 150.156        settings_file_specified = true;
 150.157      }
 150.158      if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
 150.159 @@ -2540,6 +2550,24 @@
 150.160      if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
 150.161        PrintVMOptions = false;
 150.162      }
 150.163 +    if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) {
 150.164 +      IgnoreUnrecognizedVMOptions = true;
 150.165 +    }
 150.166 +    if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) {
 150.167 +      IgnoreUnrecognizedVMOptions = false;
 150.168 +    }
 150.169 +  }
 150.170 +
 150.171 +  if (IgnoreUnrecognizedVMOptions) {
 150.172 +    // uncast const to modify the flag args->ignoreUnrecognized
 150.173 +    *(jboolean*)(&args->ignoreUnrecognized) = true;
 150.174 +  }
 150.175 +
 150.176 +  // Parse specified settings file
 150.177 +  if (settings_file_specified) {
 150.178 +    if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
 150.179 +      return JNI_EINVAL;
 150.180 +    }
 150.181    }
 150.182  
 150.183    // Parse default .hotspotrc settings file
 150.184 @@ -2558,7 +2586,6 @@
 150.185      }
 150.186    }
 150.187  
 150.188 -
 150.189    // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
 150.190    jint result = parse_vm_init_args(args);
 150.191    if (result != JNI_OK) {
   151.1 --- a/src/share/vm/runtime/globals.hpp	Sat Jan 31 17:19:42 2009 -0800
   151.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Feb 27 15:13:00 2009 -0800
   151.3 @@ -835,8 +835,21 @@
   151.4            "Prints the system dictionary at exit")                           \
   151.5                                                                              \
   151.6    diagnostic(bool, UnsyncloadClass, false,                                  \
   151.7 -          "Unstable: VM calls loadClass unsynchronized. Custom classloader "\
   151.8 -          "must call VM synchronized for findClass & defineClass")          \
   151.9 +          "Unstable: VM calls loadClass unsynchronized. Custom "            \
  151.10 +          "class loader  must call VM synchronized for findClass "          \
  151.11 +          "and defineClass.")                                               \
  151.12 +                                                                            \
  151.13 +  product(bool, AlwaysLockClassLoader, false,                               \
  151.14 +          "Require the VM to acquire the class loader lock before calling " \
  151.15 +          "loadClass() even for class loaders registering "                 \
  151.16 +          "as parallel capable. Default false. ")                           \
  151.17 +                                                                            \
  151.18 +  product(bool, AllowParallelDefineClass, false,                            \
  151.19 +          "Allow parallel defineClass requests for class loaders "          \
  151.20 +          "registering as parallel capable. Default false")                 \
  151.21 +                                                                            \
  151.22 +  product(bool, MustCallLoadClassInternal, false,                           \
  151.23 +          "Call loadClassInternal() rather than loadClass().Default false") \
  151.24                                                                              \
  151.25    product_pd(bool, DontYieldALot,                                           \
  151.26            "Throw away obvious excess yield calls (for SOLARIS only)")       \
  151.27 @@ -1294,7 +1307,14 @@
  151.28    product(intx, ParGCArrayScanChunk, 50,                                    \
  151.29            "Scan a subset and push remainder, if array is bigger than this") \
  151.30                                                                              \
  151.31 -  product(intx, ParGCDesiredObjsFromOverflowList, 20,                       \
  151.32 +  notproduct(bool, ParGCWorkQueueOverflowALot, false,                       \
  151.33 +          "Whether we should simulate work queue overflow in ParNew")       \
  151.34 +                                                                            \
  151.35 +  notproduct(uintx, ParGCWorkQueueOverflowInterval, 1000,                   \
  151.36 +          "An `interval' counter that determines how frequently"            \
  151.37 +          " we simulate overflow; a smaller number increases frequency")    \
  151.38 +                                                                            \
  151.39 +  product(uintx, ParGCDesiredObjsFromOverflowList, 20,                      \
  151.40            "The desired number of objects to claim from the overflow list")  \
  151.41                                                                              \
  151.42    product(uintx, CMSParPromoteBlocksToClaim, 50,                            \
  151.43 @@ -1406,18 +1426,18 @@
  151.44    develop(bool, CMSOverflowEarlyRestoration, false,                         \
  151.45            "Whether preserved marks should be restored early")               \
  151.46                                                                              \
  151.47 -  product(uintx, CMSMarkStackSize, 32*K,                                    \
  151.48 +  product(uintx, CMSMarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),           \
  151.49            "Size of CMS marking stack")                                      \
  151.50                                                                              \
  151.51 -  product(uintx, CMSMarkStackSizeMax, 4*M,                                  \
  151.52 +  product(uintx, CMSMarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),       \
  151.53            "Max size of CMS marking stack")                                  \
  151.54                                                                              \
  151.55    notproduct(bool, CMSMarkStackOverflowALot, false,                         \
  151.56            "Whether we should simulate frequent marking stack / work queue"  \
  151.57            " overflow")                                                      \
  151.58                                                                              \
  151.59 -  notproduct(intx, CMSMarkStackOverflowInterval, 1000,                      \
  151.60 -          "A per-thread `interval' counter that determines how frequently"  \
  151.61 +  notproduct(uintx, CMSMarkStackOverflowInterval, 1000,                     \
  151.62 +          "An `interval' counter that determines how frequently"            \
  151.63            " we simulate overflow; a smaller number increases frequency")    \
  151.64                                                                              \
  151.65    product(uintx, CMSMaxAbortablePrecleanLoops, 0,                           \
  151.66 @@ -1635,7 +1655,14 @@
  151.67    develop(uintx, WorkStealingYieldsBeforeSleep, 1000,                       \
  151.68            "Number of yields before a sleep is done during workstealing")    \
  151.69                                                                              \
  151.70 -  product(uintx, PreserveMarkStackSize, 40,                                 \
  151.71 +  develop(uintx, WorkStealingHardSpins, 4096,                               \
  151.72 +          "Number of iterations in a spin loop between checks on "          \
  151.73 +          "time out of hard spin")                                          \
  151.74 +                                                                            \
  151.75 +  develop(uintx, WorkStealingSpinToYieldRatio, 10,                          \
  151.76 +          "Ratio of hard spins to calls to yield")                          \
  151.77 +                                                                            \
  151.78 +  product(uintx, PreserveMarkStackSize, 1024,                               \
  151.79             "Size for stack used in promotion failure handling")             \
  151.80                                                                              \
  151.81    product_pd(bool, UseTLAB, "Use thread-local object allocation")           \
  151.82 @@ -2167,6 +2194,9 @@
  151.83    product(bool, PrintVMOptions, trueInDebug,                                \
  151.84           "print VM flag settings")                                          \
  151.85                                                                              \
  151.86 +  product(bool, IgnoreUnrecognizedVMOptions, false,                         \
  151.87 +         "Ignore unrecognized VM options")                                  \
  151.88 +                                                                            \
  151.89    diagnostic(bool, SerializeVMOutput, true,                                 \
  151.90           "Use a mutex to serialize output to tty and hotspot.log")          \
  151.91                                                                              \
   152.1 --- a/src/share/vm/runtime/memprofiler.cpp	Sat Jan 31 17:19:42 2009 -0800
   152.2 +++ b/src/share/vm/runtime/memprofiler.cpp	Fri Feb 27 15:13:00 2009 -0800
   152.3 @@ -104,21 +104,22 @@
   152.4    }
   152.5  
   152.6    // Print trace line in log
   152.7 -  fprintf(_log_fp, "%6.1f,%5d,%5d,%6ld,%6ld,%6ld,%6ld,",
   152.8 -      os::elapsedTime(),
   152.9 -      Threads::number_of_threads(),
  152.10 -      SystemDictionary::number_of_classes(),
  152.11 -      Universe::heap()->used() / K,
  152.12 -      Universe::heap()->capacity() / K,
  152.13 -      Universe::heap()->permanent_used() / HWperKB,
  152.14 -      Universe::heap()->permanent_capacity() / HWperKB);
  152.15 +  fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ","
  152.16 +          UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
  152.17 +          os::elapsedTime(),
  152.18 +          Threads::number_of_threads(),
  152.19 +          SystemDictionary::number_of_classes(),
  152.20 +          Universe::heap()->used() / K,
  152.21 +          Universe::heap()->capacity() / K,
  152.22 +          Universe::heap()->permanent_used() / HWperKB,
  152.23 +          Universe::heap()->permanent_capacity() / HWperKB);
  152.24  
  152.25 -  fprintf(_log_fp, "%6ld,", CodeCache::capacity() / K);
  152.26 +  fprintf(_log_fp, UINTX_FORMAT_W(6) ",", CodeCache::capacity() / K);
  152.27  
  152.28 -  fprintf(_log_fp, "%6ld,%6ld,%6ld\n",
  152.29 -      handles_memory_usage / K,
  152.30 -      resource_memory_usage / K,
  152.31 -      OopMapCache::memory_usage() / K);
  152.32 +  fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",%6ld\n",
  152.33 +          handles_memory_usage / K,
  152.34 +          resource_memory_usage / K,
  152.35 +          OopMapCache::memory_usage() / K);
  152.36    fflush(_log_fp);
  152.37  }
  152.38  
   153.1 --- a/src/share/vm/runtime/os.cpp	Sat Jan 31 17:19:42 2009 -0800
   153.2 +++ b/src/share/vm/runtime/os.cpp	Fri Feb 27 15:13:00 2009 -0800
   153.3 @@ -74,13 +74,11 @@
   153.4    const int milliseconds_after_second =
   153.5      milliseconds_since_19700101 % milliseconds_per_microsecond;
   153.6    // Convert the time value to a tm and timezone variable
   153.7 -  const struct tm *time_struct_temp = localtime(&seconds_since_19700101);
   153.8 -  if (time_struct_temp == NULL) {
   153.9 -    assert(false, "Failed localtime");
  153.10 +  struct tm time_struct;
  153.11 +  if (localtime_pd(&seconds_since_19700101, &time_struct) == NULL) {
  153.12 +    assert(false, "Failed localtime_pd");
  153.13      return NULL;
  153.14    }
  153.15 -  // Save the results of localtime
  153.16 -  const struct tm time_struct = *time_struct_temp;
  153.17    const time_t zone = timezone;
  153.18  
  153.19    // If daylight savings time is in effect,
  153.20 @@ -93,10 +91,10 @@
  153.21      UTC_to_local = UTC_to_local - seconds_per_hour;
  153.22    }
  153.23    // Compute the time zone offset.
  153.24 -  //    localtime(3C) sets timezone to the difference (in seconds)
  153.25 +  //    localtime_pd() sets timezone to the difference (in seconds)
  153.26    //    between UTC and and local time.
  153.27    //    ISO 8601 says we need the difference between local time and UTC,
  153.28 -  //    we change the sign of the localtime(3C) result.
  153.29 +  //    we change the sign of the localtime_pd() result.
  153.30    const time_t local_to_UTC = -(UTC_to_local);
  153.31    // Then we have to figure out if if we are ahead (+) or behind (-) UTC.
  153.32    char sign_local_to_UTC = '+';
   154.1 --- a/src/share/vm/runtime/os.hpp	Sat Jan 31 17:19:42 2009 -0800
   154.2 +++ b/src/share/vm/runtime/os.hpp	Fri Feb 27 15:13:00 2009 -0800
   154.3 @@ -120,7 +120,8 @@
   154.4    // Return current local time in a string (YYYY-MM-DD HH:MM:SS).
   154.5    // It is MT safe, but not async-safe, as reading time zone
   154.6    // information may require a lock on some platforms.
   154.7 -  static char* local_time_string(char *buf, size_t buflen);
   154.8 +  static char*      local_time_string(char *buf, size_t buflen);
   154.9 +  static struct tm* localtime_pd     (const time_t* clock, struct tm*  res);
  154.10    // Fill in buffer with current local time as an ISO-8601 string.
  154.11    // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz.
  154.12    // Returns buffer, or NULL if it failed.
   155.1 --- a/src/share/vm/runtime/safepoint.cpp	Sat Jan 31 17:19:42 2009 -0800
   155.2 +++ b/src/share/vm/runtime/safepoint.cpp	Fri Feb 27 15:13:00 2009 -0800
   155.3 @@ -730,7 +730,7 @@
   155.4    if (DieOnSafepointTimeout) {
   155.5      char msg[1024];
   155.6      VM_Operation *op = VMThread::vm_operation();
   155.7 -    sprintf(msg, "Safepoint sync time longer than %d ms detected when executing %s.",
   155.8 +    sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
   155.9              SafepointTimeoutDelay,
  155.10              op != NULL ? op->name() : "no vm operation");
  155.11      fatal(msg);
   156.1 --- a/src/share/vm/runtime/sharedRuntime.cpp	Sat Jan 31 17:19:42 2009 -0800
   156.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri Feb 27 15:13:00 2009 -0800
   156.3 @@ -192,64 +192,46 @@
   156.4  
   156.5  
   156.6  JRT_LEAF(jint, SharedRuntime::f2i(jfloat  x))
   156.7 -  if (g_isnan(x)) {return 0;}
   156.8 -  jlong lltmp = (jlong)x;
   156.9 -  jint ltmp   = (jint)lltmp;
  156.10 -  if (ltmp == lltmp) {
  156.11 -    return ltmp;
  156.12 -  } else {
  156.13 -    if (x < 0) {
  156.14 -      return min_jint;
  156.15 -    } else {
  156.16 -      return max_jint;
  156.17 -    }
  156.18 -  }
  156.19 +  if (g_isnan(x))
  156.20 +    return 0;
  156.21 +  if (x >= (jfloat) max_jint)
  156.22 +    return max_jint;
  156.23 +  if (x <= (jfloat) min_jint)
  156.24 +    return min_jint;
  156.25 +  return (jint) x;
  156.26  JRT_END
  156.27  
  156.28  
  156.29  JRT_LEAF(jlong, SharedRuntime::f2l(jfloat  x))
  156.30 -  if (g_isnan(x)) {return 0;}
  156.31 -  jlong lltmp = (jlong)x;
  156.32 -  if (lltmp != min_jlong) {
  156.33 -    return lltmp;
  156.34 -  } else {
  156.35 -    if (x < 0) {
  156.36 -      return min_jlong;
  156.37 -    } else {
  156.38 -      return max_jlong;
  156.39 -    }
  156.40 -  }
  156.41 +  if (g_isnan(x))
  156.42 +    return 0;
  156.43 +  if (x >= (jfloat) max_jlong)
  156.44 +    return max_jlong;
  156.45 +  if (x <= (jfloat) min_jlong)
  156.46 +    return min_jlong;
  156.47 +  return (jlong) x;
  156.48  JRT_END
  156.49  
  156.50  
  156.51  JRT_LEAF(jint, SharedRuntime::d2i(jdouble x))
  156.52 -  if (g_isnan(x)) {return 0;}
  156.53 -  jlong lltmp = (jlong)x;
  156.54 -  jint ltmp   = (jint)lltmp;
  156.55 -  if (ltmp == lltmp) {
  156.56 -    return ltmp;
  156.57 -  } else {
  156.58 -    if (x < 0) {
  156.59 -      return min_jint;
  156.60 -    } else {
  156.61 -      return max_jint;
  156.62 -    }
  156.63 -  }
  156.64 +  if (g_isnan(x))
  156.65 +    return 0;
  156.66 +  if (x >= (jdouble) max_jint)
  156.67 +    return max_jint;
  156.68 +  if (x <= (jdouble) min_jint)
  156.69 +    return min_jint;
  156.70 +  return (jint) x;
  156.71  JRT_END
  156.72  
  156.73  
  156.74  JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x))
  156.75 -  if (g_isnan(x)) {return 0;}
  156.76 -  jlong lltmp = (jlong)x;
  156.77 -  if (lltmp != min_jlong) {
  156.78 -    return lltmp;
  156.79 -  } else {
  156.80 -    if (x < 0) {
  156.81 -      return min_jlong;
  156.82 -    } else {
  156.83 -      return max_jlong;
  156.84 -    }
  156.85 -  }
  156.86 +  if (g_isnan(x))
  156.87 +    return 0;
  156.88 +  if (x >= (jdouble) max_jlong)
  156.89 +    return max_jlong;
  156.90 +  if (x <= (jdouble) min_jlong)
  156.91 +    return min_jlong;
  156.92 +  return (jlong) x;
  156.93  JRT_END
  156.94  
  156.95  
   157.1 --- a/src/share/vm/runtime/synchronizer.cpp	Sat Jan 31 17:19:42 2009 -0800
   157.2 +++ b/src/share/vm/runtime/synchronizer.cpp	Fri Feb 27 15:13:00 2009 -0800
   157.3 @@ -424,7 +424,7 @@
   157.4  // asserts is that error message -- often something about negative array
   157.5  // indices -- is opaque.
   157.6  
   157.7 -#define CTASSERT(x) { int tag[1-(2*!(x))]; printf ("Tag @%X\n", tag); }
   157.8 +#define CTASSERT(x) { int tag[1-(2*!(x))]; printf ("Tag @" INTPTR_FORMAT "\n", (intptr_t)tag); }
   157.9  
  157.10  void ObjectMonitor::ctAsserts() {
  157.11    CTASSERT(offset_of (ObjectMonitor, _header) == 0);
   158.1 --- a/src/share/vm/services/heapDumper.cpp	Sat Jan 31 17:19:42 2009 -0800
   158.2 +++ b/src/share/vm/services/heapDumper.cpp	Fri Feb 27 15:13:00 2009 -0800
   158.3 @@ -1700,7 +1700,7 @@
   158.4    // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
   158.5    // of the heap dump.
   158.6    HeapObjectDumper obj_dumper(this, writer());
   158.7 -  Universe::heap()->object_iterate(&obj_dumper);
   158.8 +  Universe::heap()->safe_object_iterate(&obj_dumper);
   158.9  
  158.10    // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals
  158.11    do_threads();
   159.1 --- a/src/share/vm/utilities/globalDefinitions.hpp	Sat Jan 31 17:19:42 2009 -0800
   159.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Feb 27 15:13:00 2009 -0800
   159.3 @@ -1,5 +1,5 @@
   159.4  /*
   159.5 - * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
   159.6 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
   159.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   159.8   *
   159.9   * This code is free software; you can redistribute it and/or modify it
  159.10 @@ -74,6 +74,7 @@
  159.11  extern int BitsPerHeapOop;
  159.12  
  159.13  const int BitsPerJavaInteger = 32;
  159.14 +const int BitsPerJavaLong    = 64;
  159.15  const int BitsPerSize_t      = size_tSize * BitsPerByte;
  159.16  
  159.17  // Size of a char[] needed to represent a jint as a string in decimal.
  159.18 @@ -906,6 +907,14 @@
  159.19    return log2_intptr(x);
  159.20  }
  159.21  
  159.22 +//* the argument must be exactly a power of 2
  159.23 +inline int exact_log2_long(jlong x) {
  159.24 +  #ifdef ASSERT
  159.25 +    if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2");
  159.26 +  #endif
  159.27 +  return log2_long(x);
  159.28 +}
  159.29 +
  159.30  
  159.31  // returns integer round-up to the nearest multiple of s (s must be a power of two)
  159.32  inline intptr_t round_to(intptr_t x, uintx s) {
  159.33 @@ -1087,15 +1096,24 @@
  159.34  // Format macros that allow the field width to be specified.  The width must be
  159.35  // a string literal (e.g., "8") or a macro that evaluates to one.
  159.36  #ifdef _LP64
  159.37 +#define UINTX_FORMAT_W(width)   UINT64_FORMAT_W(width)
  159.38  #define SSIZE_FORMAT_W(width)   INT64_FORMAT_W(width)
  159.39  #define SIZE_FORMAT_W(width)    UINT64_FORMAT_W(width)
  159.40  #else
  159.41 +#define UINTX_FORMAT_W(width)   UINT32_FORMAT_W(width)
  159.42  #define SSIZE_FORMAT_W(width)   INT32_FORMAT_W(width)
  159.43  #define SIZE_FORMAT_W(width)    UINT32_FORMAT_W(width)
  159.44  #endif // _LP64
  159.45  
  159.46  // Format pointers and size_t (or size_t-like integer types) which change size
  159.47 -// between 32- and 64-bit.
  159.48 +// between 32- and 64-bit. The pointer format theoretically should be "%p",
  159.49 +// however, it has different output on different platforms. On Windows, the data
  159.50 +// will be padded with zeros automatically. On Solaris, we can use "%016p" &
  159.51 +// "%08p" on 64 bit & 32 bit platforms to make the data padded with extra zeros.
  159.52 +// On Linux, "%016p" or "%08p" is not be allowed, at least on the latest GCC
  159.53 +// 4.3.2. So we have to use "%016x" or "%08x" to simulate the printing format.
  159.54 +// GCC 4.3.2, however requires the data to be converted to "intptr_t" when
  159.55 +// using "%x".
  159.56  #ifdef  _LP64
  159.57  #define PTR_FORMAT    PTR64_FORMAT
  159.58  #define UINTX_FORMAT  UINT64_FORMAT
   160.1 --- a/src/share/vm/utilities/globalDefinitions_gcc.hpp	Sat Jan 31 17:19:42 2009 -0800
   160.2 +++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp	Fri Feb 27 15:13:00 2009 -0800
   160.3 @@ -116,7 +116,9 @@
   160.4    #ifdef _LP64
   160.5      #define NULL_WORD  0L
   160.6    #else
   160.7 -    #define NULL_WORD  0
   160.8 +    // Cast 0 to intptr_t rather than int32_t since they are not the same type
   160.9 +    // on platforms such as Mac OS X.
  160.10 +    #define NULL_WORD  ((intptr_t)0)
  160.11    #endif
  160.12  #else
  160.13    #define NULL_WORD  NULL
   161.1 --- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Sat Jan 31 17:19:42 2009 -0800
   161.2 +++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp	Fri Feb 27 15:13:00 2009 -0800
   161.3 @@ -115,7 +115,9 @@
   161.4    #ifdef _LP64
   161.5      #define NULL_WORD  0L
   161.6    #else
   161.7 -    #define NULL_WORD  0
   161.8 +    // Cast 0 to intptr_t rather than int32_t since they are not the same type
   161.9 +    // on some platforms.
  161.10 +    #define NULL_WORD  ((intptr_t)0)
  161.11    #endif
  161.12  #else
  161.13    #define NULL_WORD  NULL
   162.1 --- a/src/share/vm/utilities/ostream.cpp	Sat Jan 31 17:19:42 2009 -0800
   162.2 +++ b/src/share/vm/utilities/ostream.cpp	Fri Feb 27 15:13:00 2009 -0800
   162.3 @@ -300,7 +300,10 @@
   162.4  }
   162.5  
   162.6  void fileStream::write(const char* s, size_t len) {
   162.7 -  if (_file != NULL)  fwrite(s, 1, len, _file);
   162.8 +  if (_file != NULL)  {
   162.9 +    // Make an unused local variable to avoid warning from gcc 4.x compiler.
  162.10 +    size_t count = fwrite(s, 1, len, _file);
  162.11 +  }
  162.12    update_position(s, len);
  162.13  }
  162.14  
  162.15 @@ -328,7 +331,10 @@
  162.16  }
  162.17  
  162.18  void fdStream::write(const char* s, size_t len) {
  162.19 -  if (_fd != -1) ::write(_fd, s, (int)len);
  162.20 +  if (_fd != -1) {
  162.21 +    // Make an unused local variable to avoid warning from gcc 4.x compiler.
  162.22 +    size_t count = ::write(_fd, s, (int)len);
  162.23 +  }
  162.24    update_position(s, len);
  162.25  }
  162.26  
   163.1 --- a/src/share/vm/utilities/taskqueue.cpp	Sat Jan 31 17:19:42 2009 -0800
   163.2 +++ b/src/share/vm/utilities/taskqueue.cpp	Fri Feb 27 15:13:00 2009 -0800
   163.3 @@ -25,6 +25,12 @@
   163.4  # include "incls/_precompiled.incl"
   163.5  # include "incls/_taskqueue.cpp.incl"
   163.6  
   163.7 +#ifdef TRACESPINNING
   163.8 +uint ParallelTaskTerminator::_total_yields = 0;
   163.9 +uint ParallelTaskTerminator::_total_spins = 0;
  163.10 +uint ParallelTaskTerminator::_total_peeks = 0;
  163.11 +#endif
  163.12 +
  163.13  bool TaskQueueSuper::peek() {
  163.14    return _bottom != _age.top();
  163.15  }
  163.16 @@ -69,15 +75,62 @@
  163.17  ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
  163.18    Atomic::inc(&_offered_termination);
  163.19  
  163.20 -  juint yield_count = 0;
  163.21 +  uint yield_count = 0;
  163.22 +  // Number of hard spin loops done since last yield
  163.23 +  uint hard_spin_count = 0;
  163.24 +  // Number of iterations in the hard spin loop.
  163.25 +  uint hard_spin_limit = WorkStealingHardSpins;
  163.26 +
  163.27 +  // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done.
  163.28 +  // If it is greater than 0, then start with a small number
  163.29 +  // of spins and increase number with each turn at spinning until
  163.30 +  // the count of hard spins exceeds WorkStealingSpinToYieldRatio.
  163.31 +  // Then do a yield() call and start spinning afresh.
  163.32 +  if (WorkStealingSpinToYieldRatio > 0) {
  163.33 +    hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio;
  163.34 +    hard_spin_limit = MAX2(hard_spin_limit, 1U);
  163.35 +  }
  163.36 +  // Remember the initial spin limit.
  163.37 +  uint hard_spin_start = hard_spin_limit;
  163.38 +
  163.39 +  // Loop waiting for all threads to offer termination or
  163.40 +  // more work.
  163.41    while (true) {
  163.42 +    // Are all threads offering termination?
  163.43      if (_offered_termination == _n_threads) {
  163.44 -      //inner_termination_loop();
  163.45        return true;
  163.46      } else {
  163.47 +      // Look for more work.
  163.48 +      // Periodically sleep() instead of yield() to give threads
  163.49 +      // waiting on the cores the chance to grab this code
  163.50        if (yield_count <= WorkStealingYieldsBeforeSleep) {
  163.51 +        // Do a yield or hardspin.  For purposes of deciding whether
  163.52 +        // to sleep, count this as a yield.
  163.53          yield_count++;
  163.54 -        yield();
  163.55 +
  163.56 +        // Periodically call yield() instead spinning
  163.57 +        // After WorkStealingSpinToYieldRatio spins, do a yield() call
  163.58 +        // and reset the counts and starting limit.
  163.59 +        if (hard_spin_count > WorkStealingSpinToYieldRatio) {
  163.60 +          yield();
  163.61 +          hard_spin_count = 0;
  163.62 +          hard_spin_limit = hard_spin_start;
  163.63 +#ifdef TRACESPINNING
  163.64 +          _total_yields++;
  163.65 +#endif
  163.66 +        } else {
  163.67 +          // Hard spin this time
  163.68 +          // Increase the hard spinning period but only up to a limit.
  163.69 +          hard_spin_limit = MIN2(2*hard_spin_limit,
  163.70 +                                 (uint) WorkStealingHardSpins);
  163.71 +          for (uint j = 0; j < hard_spin_limit; j++) {
  163.72 +            SpinPause();
  163.73 +          }
  163.74 +          hard_spin_count++;
  163.75 +#ifdef TRACESPINNING
  163.76 +          _total_spins++;
  163.77 +#endif
  163.78 +        }
  163.79        } else {
  163.80          if (PrintGCDetails && Verbose) {
  163.81           gclog_or_tty->print_cr("ParallelTaskTerminator::offer_termination() "
  163.82 @@ -92,6 +145,9 @@
  163.83          sleep(WorkStealingSleepMillis);
  163.84        }
  163.85  
  163.86 +#ifdef TRACESPINNING
  163.87 +      _total_peeks++;
  163.88 +#endif
  163.89        if (peek_in_queue_set() ||
  163.90            (terminator != NULL && terminator->should_exit_termination())) {
  163.91          Atomic::dec(&_offered_termination);
  163.92 @@ -101,6 +157,16 @@
  163.93    }
  163.94  }
  163.95  
  163.96 +#ifdef TRACESPINNING
  163.97 +void ParallelTaskTerminator::print_termination_counts() {
  163.98 +  gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %lld  "
  163.99 +    "Total spins: %lld  Total peeks: %lld",
 163.100 +    total_yields(),
 163.101 +    total_spins(),
 163.102 +    total_peeks());
 163.103 +}
 163.104 +#endif
 163.105 +
 163.106  void ParallelTaskTerminator::reset_for_reuse() {
 163.107    if (_offered_termination != 0) {
 163.108      assert(_offered_termination == _n_threads,
   164.1 --- a/src/share/vm/utilities/taskqueue.hpp	Sat Jan 31 17:19:42 2009 -0800
   164.2 +++ b/src/share/vm/utilities/taskqueue.hpp	Fri Feb 27 15:13:00 2009 -0800
   164.3 @@ -22,67 +22,76 @@
   164.4   *
   164.5   */
   164.6  
   164.7 +#ifdef LP64
   164.8 +typedef juint TAG_TYPE;
   164.9 +// for a taskqueue size of 4M
  164.10 +#define LOG_TASKQ_SIZE 22
  164.11 +#else
  164.12 +typedef jushort TAG_TYPE;
  164.13 +// for a taskqueue size of 16K
  164.14 +#define LOG_TASKQ_SIZE 14
  164.15 +#endif
  164.16 +
  164.17  class TaskQueueSuper: public CHeapObj {
  164.18  protected:
  164.19    // The first free element after the last one pushed (mod _n).
  164.20 -  // (For now we'll assume only 32-bit CAS).
  164.21 -  volatile juint _bottom;
  164.22 +  volatile uint _bottom;
  164.23  
  164.24    // log2 of the size of the queue.
  164.25    enum SomeProtectedConstants {
  164.26 -    Log_n = 14
  164.27 +    Log_n = LOG_TASKQ_SIZE
  164.28    };
  164.29 +#undef LOG_TASKQ_SIZE
  164.30  
  164.31    // Size of the queue.
  164.32 -  juint n() { return (1 << Log_n); }
  164.33 +  uint n() { return (1 << Log_n); }
  164.34    // For computing "x mod n" efficiently.
  164.35 -  juint n_mod_mask() { return n() - 1; }
  164.36 +  uint n_mod_mask() { return n() - 1; }
  164.37  
  164.38    struct Age {
  164.39 -    jushort _top;
  164.40 -    jushort _tag;
  164.41 +    TAG_TYPE _top;
  164.42 +    TAG_TYPE _tag;
  164.43  
  164.44 -    jushort tag() const { return _tag; }
  164.45 -    jushort top() const { return _top; }
  164.46 +    TAG_TYPE tag() const { return _tag; }
  164.47 +    TAG_TYPE top() const { return _top; }
  164.48  
  164.49      Age() { _tag = 0; _top = 0; }
  164.50  
  164.51      friend bool operator ==(const Age& a1, const Age& a2) {
  164.52        return a1.tag() == a2.tag() && a1.top() == a2.top();
  164.53      }
  164.54 -
  164.55    };
  164.56    Age _age;
  164.57    // These make sure we do single atomic reads and writes.
  164.58    Age get_age() {
  164.59 -    jint res = *(volatile jint*)(&_age);
  164.60 +    uint res = *(volatile uint*)(&_age);
  164.61      return *(Age*)(&res);
  164.62    }
  164.63    void set_age(Age a) {
  164.64 -    *(volatile jint*)(&_age) = *(int*)(&a);
  164.65 +    *(volatile uint*)(&_age) = *(uint*)(&a);
  164.66    }
  164.67  
  164.68 -  jushort get_top() {
  164.69 +  TAG_TYPE get_top() {
  164.70      return get_age().top();
  164.71    }
  164.72  
  164.73    // These both operate mod _n.
  164.74 -  juint increment_index(juint ind) {
  164.75 +  uint increment_index(uint ind) {
  164.76      return (ind + 1) & n_mod_mask();
  164.77    }
  164.78 -  juint decrement_index(juint ind) {
  164.79 +  uint decrement_index(uint ind) {
  164.80      return (ind - 1) & n_mod_mask();
  164.81    }
  164.82  
  164.83    // Returns a number in the range [0.._n).  If the result is "n-1", it
  164.84    // should be interpreted as 0.
  164.85 -  juint dirty_size(juint bot, juint top) {
  164.86 -    return ((jint)bot - (jint)top) & n_mod_mask();
  164.87 +  uint dirty_size(uint bot, uint top) {
  164.88 +    return ((int)bot - (int)top) & n_mod_mask();
  164.89    }
  164.90  
  164.91    // Returns the size corresponding to the given "bot" and "top".
  164.92 -  juint size(juint bot, juint top) {
  164.93 -    juint sz = dirty_size(bot, top);
  164.94 +  uint size(uint bot, uint top) {
  164.95 +    uint sz = dirty_size(bot, top);
  164.96      // Has the queue "wrapped", so that bottom is less than top?
  164.97      // There's a complicated special case here.  A pair of threads could
  164.98      // perform pop_local and pop_global operations concurrently, starting
  164.99 @@ -94,7 +103,7 @@
 164.100      // owner performs pop_local's, and several concurrent threads
 164.101      // attempting to perform the pop_global will all perform the same CAS,
 164.102      // and only one can succeed.  Any stealing thread that reads after
 164.103 -    // either the increment or decrement will seen an empty queue, and will
 164.104 +    // either the increment or decrement will see an empty queue, and will
 164.105      // not join the competitors.  The "sz == -1 || sz == _n-1" state will
 164.106      // not be modified  by concurrent queues, so the owner thread can reset
 164.107      // the state to _bottom == top so subsequent pushes will be performed
 164.108 @@ -112,11 +121,11 @@
 164.109    // Return an estimate of the number of elements in the queue.
 164.110    // The "careful" version admits the possibility of pop_local/pop_global
 164.111    // races.
 164.112 -  juint size() {
 164.113 +  uint size() {
 164.114      return size(_bottom, get_top());
 164.115    }
 164.116  
 164.117 -  juint dirty_size() {
 164.118 +  uint dirty_size() {
 164.119      return dirty_size(_bottom, get_top());
 164.120    }
 164.121  
 164.122 @@ -127,15 +136,15 @@
 164.123  
 164.124    // Maximum number of elements allowed in the queue.  This is two less
 164.125    // than the actual queue size, for somewhat complicated reasons.
 164.126 -  juint max_elems() { return n() - 2; }
 164.127 +  uint max_elems() { return n() - 2; }
 164.128  
 164.129  };
 164.130  
 164.131  template<class E> class GenericTaskQueue: public TaskQueueSuper {
 164.132  private:
 164.133    // Slow paths for push, pop_local.  (pop_global has no fast path.)
 164.134 -  bool push_slow(E t, juint dirty_n_elems);
 164.135 -  bool pop_local_slow(juint localBot, Age oldAge);
 164.136 +  bool push_slow(E t, uint dirty_n_elems);
 164.137 +  bool pop_local_slow(uint localBot, Age oldAge);
 164.138  
 164.139  public:
 164.140    // Initializes the queue to empty.
 164.141 @@ -170,7 +179,7 @@
 164.142  
 164.143  template<class E>
 164.144  GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() {
 164.145 -  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
 164.146 +  assert(sizeof(Age) == sizeof(int), "Depends on this.");
 164.147  }
 164.148  
 164.149  template<class E>
 164.150 @@ -182,9 +191,9 @@
 164.151  template<class E>
 164.152  void GenericTaskQueue<E>::oops_do(OopClosure* f) {
 164.153    // tty->print_cr("START OopTaskQueue::oops_do");
 164.154 -  int iters = size();
 164.155 -  juint index = _bottom;
 164.156 -  for (int i = 0; i < iters; ++i) {
 164.157 +  uint iters = size();
 164.158 +  uint index = _bottom;
 164.159 +  for (uint i = 0; i < iters; ++i) {
 164.160      index = decrement_index(index);
 164.161      // tty->print_cr("  doing entry %d," INTPTR_T " -> " INTPTR_T,
 164.162      //            index, &_elems[index], _elems[index]);
 164.163 @@ -198,10 +207,10 @@
 164.164  
 164.165  
 164.166  template<class E>
 164.167 -bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) {
 164.168 +bool GenericTaskQueue<E>::push_slow(E t, uint dirty_n_elems) {
 164.169    if (dirty_n_elems == n() - 1) {
 164.170      // Actually means 0, so do the push.
 164.171 -    juint localBot = _bottom;
 164.172 +    uint localBot = _bottom;
 164.173      _elems[localBot] = t;
 164.174      _bottom = increment_index(localBot);
 164.175      return true;
 164.176 @@ -211,7 +220,7 @@
 164.177  
 164.178  template<class E>
 164.179  bool GenericTaskQueue<E>::
 164.180 -pop_local_slow(juint localBot, Age oldAge) {
 164.181 +pop_local_slow(uint localBot, Age oldAge) {
 164.182    // This queue was observed to contain exactly one element; either this
 164.183    // thread will claim it, or a competing "pop_global".  In either case,
 164.184    // the queue will be logically empty afterwards.  Create a new Age value
 164.185 @@ -230,9 +239,8 @@
 164.186      Age tempAge;
 164.187      // No competing pop_global has yet incremented "top"; we'll try to
 164.188      // install new_age, thus claiming the element.
 164.189 -    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
 164.190 -           "Assumption about CAS unit.");
 164.191 -    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
 164.192 +    assert(sizeof(Age) == sizeof(int), "Assumption about CAS unit.");
 164.193 +    *(uint*)&tempAge = Atomic::cmpxchg(*(uint*)&newAge, (volatile uint*)&_age, *(uint*)&oldAge);
 164.194      if (tempAge == oldAge) {
 164.195        // We win.
 164.196        assert(dirty_size(localBot, get_top()) != n() - 1,
 164.197 @@ -253,8 +261,8 @@
 164.198  bool GenericTaskQueue<E>::pop_global(E& t) {
 164.199    Age newAge;
 164.200    Age oldAge = get_age();
 164.201 -  juint localBot = _bottom;
 164.202 -  juint n_elems = size(localBot, oldAge.top());
 164.203 +  uint localBot = _bottom;
 164.204 +  uint n_elems = size(localBot, oldAge.top());
 164.205    if (n_elems == 0) {
 164.206      return false;
 164.207    }
 164.208 @@ -263,7 +271,7 @@
 164.209    newAge._top = increment_index(newAge.top());
 164.210    if ( newAge._top == 0 ) newAge._tag++;
 164.211    Age resAge;
 164.212 -  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
 164.213 +  *(uint*)&resAge = Atomic::cmpxchg(*(uint*)&newAge, (volatile uint*)&_age, *(uint*)&oldAge);
 164.214    // Note that using "_bottom" here might fail, since a pop_local might
 164.215    // have decremented it.
 164.216    assert(dirty_size(localBot, newAge._top) != n() - 1,
 164.217 @@ -287,7 +295,7 @@
 164.218  
 164.219  template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper {
 164.220  private:
 164.221 -  int _n;
 164.222 +  uint _n;
 164.223    GenericTaskQueue<E>** _queues;
 164.224  
 164.225  public:
 164.226 @@ -300,51 +308,51 @@
 164.227      }
 164.228    }
 164.229  
 164.230 -  bool steal_1_random(int queue_num, int* seed, E& t);
 164.231 -  bool steal_best_of_2(int queue_num, int* seed, E& t);
 164.232 -  bool steal_best_of_all(int queue_num, int* seed, E& t);
 164.233 +  bool steal_1_random(uint queue_num, int* seed, E& t);
 164.234 +  bool steal_best_of_2(uint queue_num, int* seed, E& t);
 164.235 +  bool steal_best_of_all(uint queue_num, int* seed, E& t);
 164.236  
 164.237 -  void register_queue(int i, GenericTaskQueue<E>* q);
 164.238 +  void register_queue(uint i, GenericTaskQueue<E>* q);
 164.239  
 164.240 -  GenericTaskQueue<E>* queue(int n);
 164.241 +  GenericTaskQueue<E>* queue(uint n);
 164.242  
 164.243    // The thread with queue number "queue_num" (and whose random number seed
 164.244    // is at "seed") is trying to steal a task from some other queue.  (It
 164.245    // may try several queues, according to some configuration parameter.)
 164.246    // If some steal succeeds, returns "true" and sets "t" the stolen task,
 164.247    // otherwise returns false.
 164.248 -  bool steal(int queue_num, int* seed, E& t);
 164.249 +  bool steal(uint queue_num, int* seed, E& t);
 164.250  
 164.251    bool peek();
 164.252  };
 164.253  
 164.254  template<class E>
 164.255 -void GenericTaskQueueSet<E>::register_queue(int i, GenericTaskQueue<E>* q) {
 164.256 -  assert(0 <= i && i < _n, "index out of range.");
 164.257 +void GenericTaskQueueSet<E>::register_queue(uint i, GenericTaskQueue<E>* q) {
 164.258 +  assert(i < _n, "index out of range.");
 164.259    _queues[i] = q;
 164.260  }
 164.261  
 164.262  template<class E>
 164.263 -GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(int i) {
 164.264 +GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(uint i) {
 164.265    return _queues[i];
 164.266  }
 164.267  
 164.268  template<class E>
 164.269 -bool GenericTaskQueueSet<E>::steal(int queue_num, int* seed, E& t) {
 164.270 -  for (int i = 0; i < 2 * _n; i++)
 164.271 +bool GenericTaskQueueSet<E>::steal(uint queue_num, int* seed, E& t) {
 164.272 +  for (uint i = 0; i < 2 * _n; i++)
 164.273      if (steal_best_of_2(queue_num, seed, t))
 164.274        return true;
 164.275    return false;
 164.276  }
 164.277  
 164.278  template<class E>
 164.279 -bool GenericTaskQueueSet<E>::steal_best_of_all(int queue_num, int* seed, E& t) {
 164.280 +bool GenericTaskQueueSet<E>::steal_best_of_all(uint queue_num, int* seed, E& t) {
 164.281    if (_n > 2) {
 164.282      int best_k;
 164.283 -    jint best_sz = 0;
 164.284 -    for (int k = 0; k < _n; k++) {
 164.285 +    uint best_sz = 0;
 164.286 +    for (uint k = 0; k < _n; k++) {
 164.287        if (k == queue_num) continue;
 164.288 -      jint sz = _queues[k]->size();
 164.289 +      uint sz = _queues[k]->size();
 164.290        if (sz > best_sz) {
 164.291          best_sz = sz;
 164.292          best_k = k;
 164.293 @@ -362,9 +370,9 @@
 164.294  }
 164.295  
 164.296  template<class E>
 164.297 -bool GenericTaskQueueSet<E>::steal_1_random(int queue_num, int* seed, E& t) {
 164.298 +bool GenericTaskQueueSet<E>::steal_1_random(uint queue_num, int* seed, E& t) {
 164.299    if (_n > 2) {
 164.300 -    int k = queue_num;
 164.301 +    uint k = queue_num;
 164.302      while (k == queue_num) k = randomParkAndMiller(seed) % _n;
 164.303      return _queues[2]->pop_global(t);
 164.304    } else if (_n == 2) {
 164.305 @@ -378,20 +386,20 @@
 164.306  }
 164.307  
 164.308  template<class E>
 164.309 -bool GenericTaskQueueSet<E>::steal_best_of_2(int queue_num, int* seed, E& t) {
 164.310 +bool GenericTaskQueueSet<E>::steal_best_of_2(uint queue_num, int* seed, E& t) {
 164.311    if (_n > 2) {
 164.312 -    int k1 = queue_num;
 164.313 +    uint k1 = queue_num;
 164.314      while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
 164.315 -    int k2 = queue_num;
 164.316 +    uint k2 = queue_num;
 164.317      while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
 164.318      // Sample both and try the larger.
 164.319 -    juint sz1 = _queues[k1]->size();
 164.320 -    juint sz2 = _queues[k2]->size();
 164.321 +    uint sz1 = _queues[k1]->size();
 164.322 +    uint sz2 = _queues[k2]->size();
 164.323      if (sz2 > sz1) return _queues[k2]->pop_global(t);
 164.324      else return _queues[k1]->pop_global(t);
 164.325    } else if (_n == 2) {
 164.326      // Just try the other one.
 164.327 -    int k = (queue_num + 1) % 2;
 164.328 +    uint k = (queue_num + 1) % 2;
 164.329      return _queues[k]->pop_global(t);
 164.330    } else {
 164.331      assert(_n == 1, "can't be zero.");
 164.332 @@ -402,7 +410,7 @@
 164.333  template<class E>
 164.334  bool GenericTaskQueueSet<E>::peek() {
 164.335    // Try all the queues.
 164.336 -  for (int j = 0; j < _n; j++) {
 164.337 +  for (uint j = 0; j < _n; j++) {
 164.338      if (_queues[j]->peek())
 164.339        return true;
 164.340    }
 164.341 @@ -418,11 +426,19 @@
 164.342  // A class to aid in the termination of a set of parallel tasks using
 164.343  // TaskQueueSet's for work stealing.
 164.344  
 164.345 +#undef TRACESPINNING
 164.346 +
 164.347  class ParallelTaskTerminator: public StackObj {
 164.348  private:
 164.349    int _n_threads;
 164.350    TaskQueueSetSuper* _queue_set;
 164.351 -  jint _offered_termination;
 164.352 +  int _offered_termination;
 164.353 +
 164.354 +#ifdef TRACESPINNING
 164.355 +  static uint _total_yields;
 164.356 +  static uint _total_spins;
 164.357 +  static uint _total_peeks;
 164.358 +#endif
 164.359  
 164.360    bool peek_in_queue_set();
 164.361  protected:
 164.362 @@ -454,13 +470,19 @@
 164.363    // the terminator is finished.
 164.364    void reset_for_reuse();
 164.365  
 164.366 +#ifdef TRACESPINNING
 164.367 +  static uint total_yields() { return _total_yields; }
 164.368 +  static uint total_spins() { return _total_spins; }
 164.369 +  static uint total_peeks() { return _total_peeks; }
 164.370 +  static void print_termination_counts();
 164.371 +#endif
 164.372  };
 164.373  
 164.374  #define SIMPLE_STACK 0
 164.375  
 164.376  template<class E> inline bool GenericTaskQueue<E>::push(E t) {
 164.377  #if SIMPLE_STACK
 164.378 -  juint localBot = _bottom;
 164.379 +  uint localBot = _bottom;
 164.380    if (_bottom < max_elems()) {
 164.381      _elems[localBot] = t;
 164.382      _bottom = localBot + 1;
 164.383 @@ -469,10 +491,10 @@
 164.384      return false;
 164.385    }
 164.386  #else
 164.387 -  juint localBot = _bottom;
 164.388 +  uint localBot = _bottom;
 164.389    assert((localBot >= 0) && (localBot < n()), "_bottom out of range.");
 164.390 -  jushort top = get_top();
 164.391 -  juint dirty_n_elems = dirty_size(localBot, top);
 164.392 +  TAG_TYPE top = get_top();
 164.393 +  uint dirty_n_elems = dirty_size(localBot, top);
 164.394    assert((dirty_n_elems >= 0) && (dirty_n_elems < n()),
 164.395           "n_elems out of range.");
 164.396    if (dirty_n_elems < max_elems()) {
 164.397 @@ -487,19 +509,19 @@
 164.398  
 164.399  template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
 164.400  #if SIMPLE_STACK
 164.401 -  juint localBot = _bottom;
 164.402 +  uint localBot = _bottom;
 164.403    assert(localBot > 0, "precondition.");
 164.404    localBot--;
 164.405    t = _elems[localBot];
 164.406    _bottom = localBot;
 164.407    return true;
 164.408  #else
 164.409 -  juint localBot = _bottom;
 164.410 +  uint localBot = _bottom;
 164.411    // This value cannot be n-1.  That can only occur as a result of
 164.412    // the assignment to bottom in this method.  If it does, this method
 164.413    // resets the size( to 0 before the next call (which is sequential,
 164.414    // since this is pop_local.)
 164.415 -  juint dirty_n_elems = dirty_size(localBot, get_top());
 164.416 +  uint dirty_n_elems = dirty_size(localBot, get_top());
 164.417    assert(dirty_n_elems != n() - 1, "Shouldn't be possible...");
 164.418    if (dirty_n_elems == 0) return false;
 164.419    localBot = decrement_index(localBot);
 164.420 @@ -512,7 +534,7 @@
 164.421    // If there's still at least one element in the queue, based on the
 164.422    // "_bottom" and "age" we've read, then there can be no interference with
 164.423    // a "pop_global" operation, and we're done.
 164.424 -  juint tp = get_top();
 164.425 +  TAG_TYPE tp = get_top();    // XXX
 164.426    if (size(localBot, tp) > 0) {
 164.427      assert(dirty_size(localBot, tp) != n() - 1,
 164.428             "Shouldn't be possible...");
 164.429 @@ -581,7 +603,7 @@
 164.430    bool is_empty();
 164.431    bool stealable_is_empty();
 164.432    bool overflow_is_empty();
 164.433 -  juint stealable_size() { return _region_queue.size(); }
 164.434 +  uint stealable_size() { return _region_queue.size(); }
 164.435    RegionTaskQueue* task_queue() { return &_region_queue; }
 164.436  };
 164.437  
   165.1 --- a/src/share/vm/utilities/vmError.cpp	Sat Jan 31 17:19:42 2009 -0800
   165.2 +++ b/src/share/vm/utilities/vmError.cpp	Fri Feb 27 15:13:00 2009 -0800
   165.3 @@ -674,6 +674,11 @@
   165.4      reset_signal_handlers();
   165.5  
   165.6    } else {
   165.7 +    // If UseOsErrorReporting we call this for each level of the call stack
   165.8 +    // while searching for the exception handler.  Only the first level needs
   165.9 +    // to be reported.
  165.10 +    if (UseOSErrorReporting && log_done) return;
  165.11 +
  165.12      // This is not the first error, see if it happened in a different thread
  165.13      // or in the same thread during error reporting.
  165.14      if (first_error_tid != mytid) {
   166.1 --- a/src/share/vm/utilities/vmError.hpp	Sat Jan 31 17:19:42 2009 -0800
   166.2 +++ b/src/share/vm/utilities/vmError.hpp	Fri Feb 27 15:13:00 2009 -0800
   166.3 @@ -50,7 +50,7 @@
   166.4  
   166.5    // additional info for VM internal errors
   166.6    const char * _filename;
   166.7 -  int          _lineno;
   166.8 +  size_t       _lineno;
   166.9  
  166.10    // used by fatal error handler
  166.11    int          _current_step;
   167.1 --- a/src/share/vm/utilities/workgroup.hpp	Sat Jan 31 17:19:42 2009 -0800
   167.2 +++ b/src/share/vm/utilities/workgroup.hpp	Fri Feb 27 15:13:00 2009 -0800
   167.3 @@ -32,7 +32,7 @@
   167.4  
   167.5  // An abstract task to be worked on by a gang.
   167.6  // You subclass this to supply your own work() method
   167.7 -class AbstractGangTask: public CHeapObj {
   167.8 +class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
   167.9  public:
  167.10    // The abstract work method.
  167.11    // The argument tells you which member of the gang you are.
   168.1 --- a/test/Makefile	Sat Jan 31 17:19:42 2009 -0800
   168.2 +++ b/test/Makefile	Fri Feb 27 15:13:00 2009 -0800
   168.3 @@ -28,9 +28,9 @@
   168.4  
   168.5  # Get OS/ARCH specifics
   168.6  OSNAME = $(shell uname -s)
   168.7 -SLASH_JAVA = /java
   168.8  ifeq ($(OSNAME), SunOS)
   168.9    PLATFORM = solaris
  168.10 +  SLASH_JAVA = /java
  168.11    ARCH = $(shell uname -p)
  168.12    ifeq ($(ARCH), i386)
  168.13      ARCH=i586
  168.14 @@ -38,6 +38,7 @@
  168.15  endif
  168.16  ifeq ($(OSNAME), Linux)
  168.17    PLATFORM = linux
  168.18 +  SLASH_JAVA = /java
  168.19    ARCH = $(shell uname -m)
  168.20    ifeq ($(ARCH), i386)
  168.21      ARCH = i586
  168.22 @@ -62,6 +63,10 @@
  168.23    EXESUFFIX = .exe
  168.24  endif
  168.25  
  168.26 +ifdef ALT_SLASH_JAVA
  168.27 +  SLASH_JAVA = $(ALT_SLASH_JAVA)
  168.28 +endif
  168.29 +
  168.30  # Utilities used
  168.31  CD    = cd
  168.32  CP    = cp
   169.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.2 +++ b/test/compiler/6603011/Test.java	Fri Feb 27 15:13:00 2009 -0800
   169.3 @@ -0,0 +1,220 @@
   169.4 +/*
   169.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   169.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   169.7 + *
   169.8 + * This code is free software; you can redistribute it and/or modify it
   169.9 + * under the terms of the GNU General Public License version 2 only, as
  169.10 + * published by the Free Software Foundation.
  169.11 + *
  169.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  169.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  169.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  169.15 + * version 2 for more details (a copy is included in the LICENSE file that
  169.16 + * accompanied this code).
  169.17 + *
  169.18 + * You should have received a copy of the GNU General Public License version
  169.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  169.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  169.21 + *
  169.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  169.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  169.24 + * have any questions.
  169.25 + */
  169.26 +
  169.27 +/**
  169.28 + * @test
  169.29 + * @bug 6603011
  169.30 + * @summary long/int division by constant
  169.31 + *
  169.32 + * @run main/othervm -Xcomp -Xbatch -XX:-Inline Test
  169.33 + */
  169.34 +
  169.35 +//
  169.36 +// -XX:-Inline is essential to this test so that verification functions
  169.37 +//   divi, modi, divl and modl generate "plain" divides.
  169.38 +// -Xcomp -Xbatch are also useful to ensure the full range of
  169.39 +//   dividend and divisor combinations are tested
  169.40 +//
  169.41 +
  169.42 +import java.net.*;
  169.43 +
  169.44 +class s {
  169.45 +  static int  divi(int  dividend, int  divisor) { return dividend / divisor; }
  169.46 +  static int  modi(int  dividend, int  divisor) { return dividend % divisor; }
  169.47 +  static long divl(long dividend, long divisor) { return dividend / divisor; }
  169.48 +  static long modl(long dividend, long divisor) { return dividend % divisor; }
  169.49 +}
  169.50 +
  169.51 +public class Test implements Runnable {
  169.52 +  // Report verbose messages on failure; turn off to suppress
  169.53 +  // too much output with gross numbers of failures.
  169.54 +  static final boolean VERBOSE = true;
  169.55 +
  169.56 +  // Initailize DIVISOR so that it is final in this class.
  169.57 +  static final int DIVISOR;
  169.58 +  static {
  169.59 +    int value = 0;
  169.60 +    try {
  169.61 +      value = Integer.decode(System.getProperty("divisor"));
  169.62 +    } catch (Throwable e) {
  169.63 +    }
  169.64 +    DIVISOR = value;
  169.65 +  }
  169.66 +
  169.67 +  // The methods of interest. We want the JIT to compile these
  169.68 +  // and convert the divide into a multiply.
  169.69 +  public int divbyI (int dividend)   { return dividend / DIVISOR; }
  169.70 +  public int modbyI (int dividend)   { return dividend % DIVISOR; }
  169.71 +  public long divbyL (long dividend) { return dividend / DIVISOR; }
  169.72 +  public long modbyL (long dividend) { return dividend % DIVISOR; }
  169.73 +
  169.74 +  public int divisor() { return DIVISOR; }
  169.75 +
  169.76 +  public boolean checkI (int dividend) {
  169.77 +    int quo = divbyI(dividend);
  169.78 +    int rem = modbyI(dividend);
  169.79 +    int quo0 = s.divi(dividend, divisor());
  169.80 +    int rem0 = s.modi(dividend, divisor());
  169.81 +
  169.82 +    if (quo != quo0 || rem != rem0) {
  169.83 +      if (VERBOSE) {
  169.84 +        System.out.println("Computed: " + dividend + " / " + divisor() + " = " +
  169.85 +                           quo  + ", " + dividend + " % " + divisor() + " = " + rem );
  169.86 +        System.out.println("expected: " + dividend + " / " + divisor() + " = " +
  169.87 +                           quo0 + ", " + dividend + " % " + divisor() + " = " + rem0);
  169.88 +        // Report sign of rem failure
  169.89 +        if (rem != 0 && (rem ^ dividend) < 0) {
  169.90 +          System.out.println("  rem & dividend have different signs");
  169.91 +        }
  169.92 +        // Report range of rem failure
  169.93 +        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
  169.94 +          System.out.println("  remainder out of range");
  169.95 +        }
  169.96 +        // Report quo/rem identity relationship failure
  169.97 +        if ((quo * divisor()) + rem != dividend) {
  169.98 +          System.out.println("  quotien/remainder invariant broken");
  169.99 +        }
 169.100 +      }
 169.101 +      return false;
 169.102 +    }
 169.103 +    return true;
 169.104 +  }
 169.105 +
 169.106 +  public boolean checkL (long dividend) {
 169.107 +    long quo = divbyL(dividend);
 169.108 +    long rem = modbyL(dividend);
 169.109 +    long quo0 = s.divl(dividend, divisor());
 169.110 +    long rem0 = s.modl(dividend, divisor());
 169.111 +
 169.112 +    if (quo != quo0 || rem != rem0) {
 169.113 +      if (VERBOSE) {
 169.114 +        System.out.println("  " + dividend + " / " + divisor() + " = " +
 169.115 +                           quo + ", " + dividend + " % " + divisor() + " = " + rem);
 169.116 +        // Report sign of rem failure
 169.117 +        if (rem != 0 && (rem ^ dividend) < 0) {
 169.118 +          System.out.println("  rem & dividend have different signs");
 169.119 +        }
 169.120 +        // Report range of rem failure
 169.121 +        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
 169.122 +          System.out.println("  remainder out of range");
 169.123 +        }
 169.124 +        // Report quo/rem identity relationship failure
 169.125 +        if ((quo * divisor()) + rem != dividend) {
 169.126 +          System.out.println(" (" + quo + " * " + divisor() + ") + " + rem + " != "
 169.127 +                             + dividend);
 169.128 +        }
 169.129 +      }
 169.130 +      return false;
 169.131 +    }
 169.132 +    return true;
 169.133 +  }
 169.134 +
 169.135 +  public void run() {
 169.136 +    // Don't try to divide by zero
 169.137 +    if (divisor() == 0) return;
 169.138 +
 169.139 +    // Range of dividends to check. Try dividends from start to end
 169.140 +    // inclusive, as well as variations on those values as shifted
 169.141 +    // left.
 169.142 +    int start = -1024;
 169.143 +    int end = 1024;
 169.144 +
 169.145 +    // Test int division using a variety of dividends.
 169.146 +    int wrong = 0;
 169.147 +    int total = 0;
 169.148 +
 169.149 +    outerloop:
 169.150 +    for (int i = start; i <= end; i++) {
 169.151 +      for (int s = 0; s < 32; s += 4) {
 169.152 +        total++;
 169.153 +        int dividend = i << s;
 169.154 +        if (!checkI(dividend)) {
 169.155 +          wrong++;
 169.156 +          // Stop on the first failure
 169.157 +          // break outerloop;
 169.158 +        }
 169.159 +      }
 169.160 +    }
 169.161 +    if (wrong > 0) {
 169.162 +      System.out.println("divisor " + divisor() + ": " +
 169.163 +                         wrong + "/" + total + " wrong int divisions");
 169.164 +    }
 169.165 +
 169.166 +    // Test long division using a variety of dividends.
 169.167 +    wrong = 0;
 169.168 +    total = 0;
 169.169 +
 169.170 +    outerloop:
 169.171 +    for (int i = start; i <= end; i++) {
 169.172 +      for (int s = 0; s < 64; s += 4) {
 169.173 +        total++;
 169.174 +        long dividend = i << s;
 169.175 +        if (!checkL(dividend)) {
 169.176 +          wrong++;
 169.177 +          // Stop on the first failure
 169.178 +          // break outerloop;
 169.179 +        }
 169.180 +      }
 169.181 +    }
 169.182 +    if (wrong > 0) {
 169.183 +      System.out.println("divisor " + divisor() + ": " +
 169.184 +                         wrong + "/" + total + " wrong long divisions");
 169.185 +    }
 169.186 +
 169.187 +  }
 169.188 +
 169.189 +  // Reload this class with the "divisor" property set to the input parameter.
 169.190 +  // This allows the JIT to see q.DIVISOR as a final constant, and change
 169.191 +  // any divisions or mod operations into multiplies.
 169.192 +  public static void test_divisor(int divisor,
 169.193 +                                  URLClassLoader apploader) throws Exception {
 169.194 +    System.setProperty("divisor", "" + divisor);
 169.195 +    ClassLoader loader = new URLClassLoader(apploader.getURLs(),
 169.196 +                                            apploader.getParent());
 169.197 +    Class c = loader.loadClass("Test");
 169.198 +    Runnable r = (Runnable)c.newInstance();
 169.199 +    r.run();
 169.200 +  }
 169.201 +
 169.202 +  public static void main(String[] args) throws Exception {
 169.203 +    Class cl = Class.forName("Test");
 169.204 +    URLClassLoader apploader = (URLClassLoader)cl.getClassLoader();
 169.205 +
 169.206 +
 169.207 +    // Test every divisor between -100 and 100.
 169.208 +    for (int i = -100; i <= 100; i++) {
 169.209 +      test_divisor(i, apploader);
 169.210 +    }
 169.211 +
 169.212 +    // Try a few divisors outside the typical range.
 169.213 +    // The values below have been observed in rt.jar.
 169.214 +    test_divisor(101, apploader);
 169.215 +    test_divisor(400, apploader);
 169.216 +    test_divisor(1000, apploader);
 169.217 +    test_divisor(3600, apploader);
 169.218 +    test_divisor(9973, apploader);
 169.219 +    test_divisor(86400, apploader);
 169.220 +    test_divisor(1000000, apploader);
 169.221 +  }
 169.222 +
 169.223 +}
   170.1 --- a/test/compiler/6775880/Test.java	Sat Jan 31 17:19:42 2009 -0800
   170.2 +++ b/test/compiler/6775880/Test.java	Fri Feb 27 15:13:00 2009 -0800
   170.3 @@ -27,7 +27,7 @@
   170.4   * @bug 6775880
   170.5   * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
   170.6   * @compile -source 1.4 -target 1.4 Test.java
   170.7 - * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
   170.8 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
   170.9   */
  170.10  
  170.11  public class Test {
   171.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.2 +++ b/test/compiler/6778657/Test.java	Fri Feb 27 15:13:00 2009 -0800
   171.3 @@ -0,0 +1,75 @@
   171.4 +/*
   171.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
   171.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   171.7 + *
   171.8 + * This code is free software; you can redistribute it and/or modify it
   171.9 + * under the terms of the GNU General Public License version 2 only, as
  171.10 + * published by the Free Software Foundation.
  171.11 + *
  171.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  171.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  171.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  171.15 + * version 2 for more details (a copy is included in the LICENSE file that
  171.16 + * accompanied this code).
  171.17 + *
  171.18 + * You should have received a copy of the GNU General Public License version
  171.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  171.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  171.21 + *
  171.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  171.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  171.24 + * have any questions.
  171.25 + *
  171.26 + */
  171.27 +
  171.28 +/*
  171.29 + * @test
  171.30 + * @bug 6778657
  171.31 + * @summary Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
  171.32 + */
  171.33 +
  171.34 +public class Test {
  171.35 +  public static void check_f2i(int expect) {
  171.36 +    float check = expect;
  171.37 +    check *= 2;
  171.38 +    int actual = (int) check;
  171.39 +    if (actual != expect)
  171.40 +      throw new RuntimeException("expecting " + expect + ", got " + actual);
  171.41 +  }
  171.42 +
  171.43 +  public static void check_f2l(long expect) {
  171.44 +    float check = expect;
  171.45 +    check *= 2;
  171.46 +    long actual = (long) check;
  171.47 +    if (actual != expect)
  171.48 +      throw new RuntimeException("expecting " + expect + ", got " + actual);
  171.49 +  }
  171.50 +
  171.51 +  public static void check_d2i(int expect) {
  171.52 +    double check = expect;
  171.53 +    check *= 2;
  171.54 +    int actual = (int) check;
  171.55 +    if (actual != expect)
  171.56 +      throw new RuntimeException("expecting " + expect + ", got " + actual);
  171.57 +  }
  171.58 +
  171.59 +  public static void check_d2l(long expect) {
  171.60 +    double check = expect;
  171.61 +    check *= 2;
  171.62 +    long actual = (long) check;
  171.63 +    if (actual != expect)
  171.64 +      throw new RuntimeException("expecting " + expect + ", got " + actual);
  171.65 +  }
  171.66 +
  171.67 +  public static void main(String[] args) {
  171.68 +    check_f2i(Integer.MAX_VALUE);
  171.69 +    check_f2i(Integer.MIN_VALUE);
  171.70 +    check_f2l(Long.MAX_VALUE);
  171.71 +    check_f2l(Long.MIN_VALUE);
  171.72 +    check_d2i(Integer.MAX_VALUE);
  171.73 +    check_d2i(Integer.MIN_VALUE);
  171.74 +    check_d2l(Long.MAX_VALUE);
  171.75 +    check_d2l(Long.MIN_VALUE);
  171.76 +  }
  171.77 +}
  171.78 +
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/test/compiler/6795161/Test.java	Fri Feb 27 15:13:00 2009 -0800
   172.3 @@ -0,0 +1,60 @@
   172.4 +/*
   172.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   172.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   172.7 + *
   172.8 + * This code is free software; you can redistribute it and/or modify it
   172.9 + * under the terms of the GNU General Public License version 2 only, as
  172.10 + * published by the Free Software Foundation.
  172.11 + *
  172.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  172.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  172.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  172.15 + * version 2 for more details (a copy is included in the LICENSE file that
  172.16 + * accompanied this code).
  172.17 + *
  172.18 + * You should have received a copy of the GNU General Public License version
  172.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  172.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  172.21 + *
  172.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  172.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  172.24 + * have any questions.
  172.25 + *
  172.26 + */
  172.27 +
  172.28 +/*
  172.29 + * @test
  172.30 + * @bug 6795161
  172.31 + * @summary Escape analysis leads to data corruption
  172.32 + * @run main/othervm -server -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
  172.33 + */
  172.34 +
  172.35 +class Test_Class_1 {
  172.36 +    static String var_1;
  172.37 +
  172.38 +    static void badFunc(int size)
  172.39 +    {
  172.40 +        try {
  172.41 +          for (int i = 0; i < 1; (new byte[size-i])[0] = 0, i++) {}
  172.42 +        } catch (Exception e) {
  172.43 +          // don't comment it out, it will lead to correct results ;)
  172.44 +          //System.out.println("Got exception: " + e);
  172.45 +        }
  172.46 +    }
  172.47 +}
  172.48 +
  172.49 +public class Test {
  172.50 +    static String var_1_copy = Test_Class_1.var_1;
  172.51 +
  172.52 +    static byte var_check;
  172.53 +
  172.54 +    public static void main(String[] args)
  172.55 +    {
  172.56 +        var_check = 1;
  172.57 +
  172.58 +        Test_Class_1.badFunc(-1);
  172.59 +
  172.60 +        System.out.println("EATester.var_check = " + Test.var_check + " (expected 1)\n");
  172.61 +    }
  172.62 +}
  172.63 +
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/test/compiler/6795362/Test6795362.java	Fri Feb 27 15:13:00 2009 -0800
   173.3 @@ -0,0 +1,48 @@
   173.4 +/*
   173.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   173.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   173.7 + *
   173.8 + * This code is free software; you can redistribute it and/or modify it
   173.9 + * under the terms of the GNU General Public License version 2 only, as
  173.10 + * published by the Free Software Foundation.
  173.11 + *
  173.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  173.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  173.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  173.15 + * version 2 for more details (a copy is included in the LICENSE file that
  173.16 + * accompanied this code).
  173.17 + *
  173.18 + * You should have received a copy of the GNU General Public License version
  173.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  173.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  173.21 + *
  173.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  173.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  173.24 + * have any questions.
  173.25 + */
  173.26 +
  173.27 +/**
  173.28 + * @test
  173.29 + * @bug 6795362
  173.30 + * @summary 32bit server compiler leads to wrong results on solaris-x86
  173.31 + *
  173.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6795362.sub Test6795362
  173.33 + */
  173.34 +
  173.35 +public class Test6795362 {
  173.36 +    public static void main(String[] args)
  173.37 +    {
  173.38 +        sub();
  173.39 +
  173.40 +        if (var_bad != 0)
  173.41 +            throw new InternalError(var_bad + " != 0");
  173.42 +    }
  173.43 +
  173.44 +    static long var_bad = -1L;
  173.45 +
  173.46 +    static void sub()
  173.47 +    {
  173.48 +        var_bad >>= 65;
  173.49 +        var_bad /= 65;
  173.50 +    }
  173.51 +}
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/test/compiler/6799693/Test.java	Fri Feb 27 15:13:00 2009 -0800
   174.3 @@ -0,0 +1,47 @@
   174.4 +/*
   174.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   174.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   174.7 + *
   174.8 + * This code is free software; you can redistribute it and/or modify it
   174.9 + * under the terms of the GNU General Public License version 2 only, as
  174.10 + * published by the Free Software Foundation.
  174.11 + *
  174.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  174.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  174.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  174.15 + * version 2 for more details (a copy is included in the LICENSE file that
  174.16 + * accompanied this code).
  174.17 + *
  174.18 + * You should have received a copy of the GNU General Public License version
  174.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  174.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  174.21 + *
  174.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  174.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  174.24 + * have any questions.
  174.25 + *
  174.26 + */
  174.27 +
  174.28 +/*
  174.29 + * @test
  174.30 + * @bug 6799693
  174.31 + * @summary Server compiler leads to data corruption when expression throws an Exception
  174.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test Test
  174.33 + */
  174.34 +
  174.35 +public class Test {
  174.36 +   static int var_bad = 1;
  174.37 +
  174.38 +   public static void main(String[] args)
  174.39 +   {
  174.40 +      var_bad++;
  174.41 +
  174.42 +      try {
  174.43 +         for (int i = 0; i < 10; i++) (new byte[((byte)-1 << i)])[0]  = 0;
  174.44 +      }
  174.45 +      catch (Exception e) { System.out.println("Got " + e); }
  174.46 +
  174.47 +      System.out.println("Test.var_bad = " +  var_bad + " (expected 2)\n");
  174.48 +   }
  174.49 +}
  174.50 +
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/test/compiler/6800154/Test6800154.java	Fri Feb 27 15:13:00 2009 -0800
   175.3 @@ -0,0 +1,109 @@
   175.4 +/*
   175.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   175.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   175.7 + *
   175.8 + * This code is free software; you can redistribute it and/or modify it
   175.9 + * under the terms of the GNU General Public License version 2 only, as
  175.10 + * published by the Free Software Foundation.
  175.11 + *
  175.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  175.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  175.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  175.15 + * version 2 for more details (a copy is included in the LICENSE file that
  175.16 + * accompanied this code).
  175.17 + *
  175.18 + * You should have received a copy of the GNU General Public License version
  175.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  175.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  175.21 + *
  175.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  175.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  175.24 + * have any questions.
  175.25 + */
  175.26 +
  175.27 +/**
  175.28 + * @test
  175.29 + * @bug 6800154
  175.30 + * @summary Add comments to long_by_long_mulhi() for better understandability
  175.31 + *
  175.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6800154.divcomp Test6800154
  175.33 + */
  175.34 +
  175.35 +import java.net.URLClassLoader;
  175.36 +
  175.37 +public class Test6800154 implements Runnable {
  175.38 +    static final long[] DIVIDENDS = {
  175.39 +        0,
  175.40 +        1,
  175.41 +        2,
  175.42 +        1423487,
  175.43 +        4444441,
  175.44 +        4918923241323L,
  175.45 +        -1,
  175.46 +        -24351,
  175.47 +        0x3333,
  175.48 +        0x0000000080000000L,
  175.49 +        0x7fffffffffffffffL,
  175.50 +        0x8000000000000000L
  175.51 +    };
  175.52 +
  175.53 +    static final long[] DIVISORS = {
  175.54 +        1,
  175.55 +        2,
  175.56 +        17,
  175.57 +        12342,
  175.58 +        24123,
  175.59 +        143444,
  175.60 +        123444442344L,
  175.61 +        -1,
  175.62 +        -2,
  175.63 +        -4423423234231423L,
  175.64 +        0x0000000080000000L,
  175.65 +        0x7fffffffffffffffL,
  175.66 +        0x8000000000000000L
  175.67 +    };
  175.68 +
  175.69 +    // Initialize DIVISOR so that it is final in this class.
  175.70 +    static final long DIVISOR;
  175.71 +
  175.72 +    static {
  175.73 +        long value = 0;
  175.74 +        try {
  175.75 +            value = Long.decode(System.getProperty("divisor"));
  175.76 +        } catch (Throwable e) {
  175.77 +        }
  175.78 +        DIVISOR = value;
  175.79 +    }
  175.80 +
  175.81 +    public static void main(String[] args) throws Exception
  175.82 +    {
  175.83 +        Class cl = Class.forName("Test6800154");
  175.84 +        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
  175.85 +
  175.86 +        // Iterate over all divisors.
  175.87 +        for (int i = 0; i < DIVISORS.length; i++) {
  175.88 +            System.setProperty("divisor", "" + DIVISORS[i]);
  175.89 +            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
  175.90 +            Class c = loader.loadClass("Test6800154");
  175.91 +            Runnable r = (Runnable) c.newInstance();
  175.92 +            r.run();
  175.93 +        }
  175.94 +    }
  175.95 +
  175.96 +    public void run()
  175.97 +    {
  175.98 +        // Iterate over all dividends.
  175.99 +        for (int i = 0; i < DIVIDENDS.length; i++) {
 175.100 +            long dividend = DIVIDENDS[i];
 175.101 +
 175.102 +            long expected = divint(dividend);
 175.103 +            long result = divcomp(dividend);
 175.104 +
 175.105 +            if (result != expected)
 175.106 +                throw new InternalError(dividend + " / " + DIVISOR + " failed: " + result + " != " + expected);
 175.107 +        }
 175.108 +    }
 175.109 +
 175.110 +    static long divint(long a)  { return a / DIVISOR; }
 175.111 +    static long divcomp(long a) { return a / DIVISOR; }
 175.112 +}
   176.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.2 +++ b/test/compiler/6805724/Test6805724.java	Fri Feb 27 15:13:00 2009 -0800
   176.3 @@ -0,0 +1,80 @@
   176.4 +/*
   176.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   176.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   176.7 + *
   176.8 + * This code is free software; you can redistribute it and/or modify it
   176.9 + * under the terms of the GNU General Public License version 2 only, as
  176.10 + * published by the Free Software Foundation.
  176.11 + *
  176.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  176.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  176.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  176.15 + * version 2 for more details (a copy is included in the LICENSE file that
  176.16 + * accompanied this code).
  176.17 + *
  176.18 + * You should have received a copy of the GNU General Public License version
  176.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  176.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  176.21 + *
  176.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  176.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
  176.24 + * have any questions.
  176.25 + */
  176.26 +
  176.27 +/**
  176.28 + * @test
  176.29 + * @bug 6805724
  176.30 + * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant.
  176.31 + *
  176.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724
  176.33 + */
  176.34 +
  176.35 +import java.net.URLClassLoader;
  176.36 +
  176.37 +public class Test6805724 implements Runnable {
  176.38 +    // Initialize DIVISOR so that it is final in this class.
  176.39 +    static final long DIVISOR;  // 2^k-1 constant
  176.40 +
  176.41 +    static {
  176.42 +        long value = 0;
  176.43 +        try {
  176.44 +            value = Long.decode(System.getProperty("divisor"));
  176.45 +        } catch (Throwable t) {
  176.46 +            // This one is required for the Class.forName() in main.
  176.47 +        }
  176.48 +        DIVISOR = value;
  176.49 +    }
  176.50 +
  176.51 +    static long fint(long x) {
  176.52 +        return x % DIVISOR;
  176.53 +    }
  176.54 +
  176.55 +    static long fcomp(long x) {
  176.56 +        return x % DIVISOR;
  176.57 +    }
  176.58 +
  176.59 +    public void run() {
  176.60 +        long a = 0x617981E1L;
  176.61 +
  176.62 +        long expected = fint(a);
  176.63 +        long result = fcomp(a);
  176.64 +
  176.65 +        if (result != expected)
  176.66 +            throw new InternalError(result + " != " + expected);
  176.67 +    }
  176.68 +
  176.69 +    public static void main(String args[]) throws Exception {
  176.70 +        Class cl = Class.forName("Test6805724");
  176.71 +        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
  176.72 +
  176.73 +        // Iterate over all 2^k-1 divisors.
  176.74 +        for (int k = 1; k < Long.SIZE; k++) {
  176.75 +            long divisor = (1L << k) - 1;
  176.76 +            System.setProperty("divisor", "" + divisor);
  176.77 +            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
  176.78 +            Class c = loader.loadClass("Test6805724");
  176.79 +            Runnable r = (Runnable) c.newInstance();
  176.80 +            r.run();
  176.81 +        }
  176.82 +    }
  176.83 +}

mercurial