Fri, 30 Jan 2009 15:28:00 -0800
Merge
1.1 --- a/agent/src/os/linux/ps_core.c Thu Jan 29 13:20:56 2009 -0800 1.2 +++ b/agent/src/os/linux/ps_core.c Fri Jan 30 15:28:00 2009 -0800 1.3 @@ -238,8 +238,8 @@ 1.4 // Ignore the rest of the FileMapHeader. We don't need those fields here. 1.5 }; 1.6 1.7 -static bool read_int(struct ps_prochandle* ph, uintptr_t addr, int* pvalue) { 1.8 - int i; 1.9 +static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) { 1.10 + jboolean i; 1.11 if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) { 1.12 *pvalue = i; 1.13 return true; 1.14 @@ -295,7 +295,7 @@ 1.15 int fd = -1, m = 0; 1.16 uintptr_t base = 0, useSharedSpacesAddr = 0; 1.17 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0; 1.18 - int useSharedSpaces = 0; 1.19 + jboolean useSharedSpaces = 0; 1.20 map_info* mi = 0; 1.21 1.22 memset(classes_jsa, 0, sizeof(classes_jsa)); 1.23 @@ -306,12 +306,15 @@ 1.24 return false; 1.25 } 1.26 1.27 - if (read_int(ph, useSharedSpacesAddr, &useSharedSpaces) != true) { 1.28 + // Hotspot vm types are not exported to build this library. So 1.29 + // using equivalent type jboolean to read the value of 1.30 + // UseSharedSpaces which is same as hotspot type "bool". 1.31 + if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) { 1.32 print_debug("can't read the value of 'UseSharedSpaces' flag\n"); 1.33 return false; 1.34 } 1.35 1.36 - if (useSharedSpaces == 0) { 1.37 + if ((int)useSharedSpaces == 0) { 1.38 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n"); 1.39 return true; 1.40 }
2.1 --- a/agent/src/os/solaris/proc/saproc.cpp Thu Jan 29 13:20:56 2009 -0800 2.2 +++ b/agent/src/os/solaris/proc/saproc.cpp Fri Jan 30 15:28:00 2009 -0800 2.3 @@ -502,8 +502,8 @@ 2.4 }; 2.5 2.6 static bool 2.7 -read_int(struct ps_prochandle* ph, psaddr_t addr, int* pvalue) { 2.8 - int i; 2.9 +read_jboolean(struct ps_prochandle* ph, psaddr_t addr, jboolean* pvalue) { 2.10 + jboolean i; 2.11 if (ps_pread(ph, addr, &i, sizeof(i)) == PS_OK) { 2.12 *pvalue = i; 2.13 return true; 2.14 @@ -575,10 +575,13 @@ 2.15 } 2.16 2.17 // read the value of the flag "UseSharedSpaces" 2.18 - int value = 0; 2.19 - if (read_int(ph, useSharedSpacesAddr, &value) != true) { 2.20 + // Since hotspot types are not available to build this library. So 2.21 + // equivalent type "jboolean" is used to read the value of "UseSharedSpaces" 2.22 + // which is same as hotspot type "bool". 2.23 + jboolean value = 0; 2.24 + if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) { 2.25 THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1); 2.26 - } else if (value == 0) { 2.27 + } else if ((int)value == 0) { 2.28 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n"); 2.29 return 1; 2.30 }
3.1 --- a/make/hotspot_version Thu Jan 29 13:20:56 2009 -0800 3.2 +++ b/make/hotspot_version Fri Jan 30 15:28:00 2009 -0800 3.3 @@ -33,9 +33,9 @@ 3.4 # Don't put quotes (fail windows build). 3.5 HOTSPOT_VM_COPYRIGHT=Copyright 2008 3.6 3.7 -HS_MAJOR_VER=14 3.8 +HS_MAJOR_VER=15 3.9 HS_MINOR_VER=0 3.10 -HS_BUILD_NUMBER=10 3.11 +HS_BUILD_NUMBER=01 3.12 3.13 JDK_MAJOR_VER=1 3.14 JDK_MINOR_VER=7
4.1 --- a/src/cpu/sparc/vm/jni_sparc.h Thu Jan 29 13:20:56 2009 -0800 4.2 +++ b/src/cpu/sparc/vm/jni_sparc.h Fri Jan 30 15:28:00 2009 -0800 4.3 @@ -28,5 +28,11 @@ 4.4 #define JNICALL 4.5 4.6 typedef int jint; 4.7 -typedef long long jlong; 4.8 + 4.9 +#ifdef _LP64 4.10 + typedef long jlong; 4.11 +#else 4.12 + typedef long long jlong; 4.13 +#endif 4.14 + 4.15 typedef signed char jbyte;
5.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Jan 29 13:20:56 2009 -0800 5.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Jan 30 15:28:00 2009 -0800 5.3 @@ -5212,15 +5212,15 @@ 5.4 void MacroAssembler::reset_last_Java_frame(bool clear_fp, 5.5 bool clear_pc) { 5.6 // we must set sp to zero to clear frame 5.7 - movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); 5.8 + movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD); 5.9 // must clear fp, so that compiled frames are not confused; it is 5.10 // possible that we need it only for debugging 5.11 if (clear_fp) { 5.12 - movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); 5.13 + movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); 5.14 } 5.15 5.16 if (clear_pc) { 5.17 - movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); 5.18 + movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); 5.19 } 5.20 } 5.21 5.22 @@ -5670,7 +5670,7 @@ 5.23 // get oop result if there is one and reset the value in the thread 5.24 if (oop_result->is_valid()) { 5.25 movptr(oop_result, Address(java_thread, JavaThread::vm_result_offset())); 5.26 - movptr(Address(java_thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 5.27 + movptr(Address(java_thread, JavaThread::vm_result_offset()), NULL_WORD); 5.28 verify_oop(oop_result, "broken oop in call_VM_base"); 5.29 } 5.30 } 5.31 @@ -6426,13 +6426,13 @@ 5.32 get_thread(java_thread); 5.33 } 5.34 // we must set sp to zero to clear frame 5.35 - movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), (int32_t)NULL_WORD); 5.36 + movptr(Address(java_thread, JavaThread::last_Java_sp_offset()), NULL_WORD); 5.37 if (clear_fp) { 5.38 - movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), (int32_t)NULL_WORD); 5.39 + movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); 5.40 } 5.41 5.42 if (clear_pc) 5.43 - movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), (int32_t)NULL_WORD); 5.44 + movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); 5.45 5.46 } 5.47 5.48 @@ -6943,29 +6943,32 @@ 5.49 5.50 Label slow_case, done; 5.51 5.52 - // x ?<= pi/4 5.53 - fld_d(ExternalAddress((address)&pi_4)); 5.54 - fld_s(1); // Stack: X PI/4 X 5.55 - fabs(); // Stack: |X| PI/4 X 5.56 - fcmp(tmp); 5.57 - jcc(Assembler::above, slow_case); 5.58 - 5.59 - // fastest case: -pi/4 <= x <= pi/4 5.60 - switch(trig) { 5.61 - case 's': 5.62 - fsin(); 5.63 - break; 5.64 - case 'c': 5.65 - fcos(); 5.66 - break; 5.67 - case 't': 5.68 - ftan(); 5.69 - break; 5.70 - default: 5.71 - assert(false, "bad intrinsic"); 5.72 - break; 5.73 - } 5.74 - jmp(done); 5.75 + ExternalAddress pi4_adr = (address)&pi_4; 5.76 + if (reachable(pi4_adr)) { 5.77 + // x ?<= pi/4 5.78 + fld_d(pi4_adr); 5.79 + fld_s(1); // Stack: X PI/4 X 5.80 + fabs(); // Stack: |X| PI/4 X 5.81 + fcmp(tmp); 5.82 + jcc(Assembler::above, slow_case); 5.83 + 5.84 + // fastest case: -pi/4 <= x <= pi/4 5.85 + switch(trig) { 5.86 + case 's': 5.87 + fsin(); 5.88 + break; 5.89 + case 'c': 5.90 + fcos(); 5.91 + break; 5.92 + case 't': 5.93 + ftan(); 5.94 + break; 5.95 + default: 5.96 + assert(false, "bad intrinsic"); 5.97 + break; 5.98 + } 5.99 + jmp(done); 5.100 + } 5.101 5.102 // slow case: runtime call 5.103 bind(slow_case);
6.1 --- a/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp Thu Jan 29 13:20:56 2009 -0800 6.2 +++ b/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp Fri Jan 30 15:28:00 2009 -0800 6.3 @@ -213,7 +213,7 @@ 6.4 6.5 inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) { 6.6 /* it's possible we could catch this special case implicitly */ 6.7 - if (op1 == 0x80000000 && op2 == -1) return op1; 6.8 + if ((juint)op1 == 0x80000000 && op2 == -1) return op1; 6.9 else return op1 / op2; 6.10 } 6.11 6.12 @@ -231,7 +231,7 @@ 6.13 6.14 inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) { 6.15 /* it's possible we could catch this special case implicitly */ 6.16 - if (op1 == 0x80000000 && op2 == -1) return 0; 6.17 + if ((juint)op1 == 0x80000000 && op2 == -1) return 0; 6.18 else return op1 % op2; 6.19 } 6.20
7.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Jan 29 13:20:56 2009 -0800 7.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Jan 30 15:28:00 2009 -0800 7.3 @@ -779,7 +779,7 @@ 7.4 case T_OBJECT: // fall through 7.5 case T_ARRAY: 7.6 if (c->as_jobject() == NULL) { 7.7 - __ movptr(as_Address(addr), (int32_t)NULL_WORD); 7.8 + __ movptr(as_Address(addr), NULL_WORD); 7.9 } else { 7.10 if (is_literal_address(addr)) { 7.11 ShouldNotReachHere();
8.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Jan 29 13:20:56 2009 -0800 8.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Jan 30 15:28:00 2009 -0800 8.3 @@ -78,10 +78,10 @@ 8.4 movptr(rax, Address(thread, Thread::pending_exception_offset())); 8.5 // make sure that the vm_results are cleared 8.6 if (oop_result1->is_valid()) { 8.7 - movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 8.8 + movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 8.9 } 8.10 if (oop_result2->is_valid()) { 8.11 - movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); 8.12 + movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); 8.13 } 8.14 if (frame_size() == no_frame_size) { 8.15 leave(); 8.16 @@ -96,12 +96,12 @@ 8.17 // get oop results if there are any and reset the values in the thread 8.18 if (oop_result1->is_valid()) { 8.19 movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); 8.20 - movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 8.21 + movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 8.22 verify_oop(oop_result1); 8.23 } 8.24 if (oop_result2->is_valid()) { 8.25 movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); 8.26 - movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); 8.27 + movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); 8.28 verify_oop(oop_result2); 8.29 } 8.30 return call_offset; 8.31 @@ -728,8 +728,8 @@ 8.32 8.33 // clear exception fields in JavaThread because they are no longer needed 8.34 // (fields must be cleared because they are processed by GC otherwise) 8.35 - __ movptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); 8.36 - __ movptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); 8.37 + __ movptr(Address(thread, JavaThread::exception_oop_offset()), NULL_WORD); 8.38 + __ movptr(Address(thread, JavaThread::exception_pc_offset()), NULL_WORD); 8.39 8.40 // pop the stub frame off 8.41 __ leave(); 8.42 @@ -878,7 +878,7 @@ 8.43 8.44 // load and clear pending exception 8.45 __ movptr(rax, Address(thread, Thread::pending_exception_offset())); 8.46 - __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 8.47 + __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 8.48 8.49 // check that there is really a valid exception 8.50 __ verify_not_null_oop(rax); 8.51 @@ -971,14 +971,14 @@ 8.52 // load pending exception oop into rax, 8.53 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 8.54 // clear pending exception 8.55 - __ movptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 8.56 + __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 8.57 8.58 // load issuing PC (the return address for this stub) into rdx 8.59 __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); 8.60 8.61 // make sure that the vm_results are cleared (may be unnecessary) 8.62 - __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 8.63 - __ movptr(Address(thread, JavaThread::vm_result_2_offset()), (int32_t)NULL_WORD); 8.64 + __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 8.65 + __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); 8.66 8.67 // verify that that there is really a valid exception in rax, 8.68 __ verify_not_null_oop(exception_oop); 8.69 @@ -1393,7 +1393,7 @@ 8.70 __ ret(0); 8.71 8.72 __ bind(miss); 8.73 - __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), 0); // result 8.74 + __ movptr(Address(rsp, (super_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result 8.75 __ pop(rax); 8.76 __ pop(rcx); 8.77 __ pop(rsi);
9.1 --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Jan 29 13:20:56 2009 -0800 9.2 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Fri Jan 30 15:28:00 2009 -0800 9.3 @@ -594,7 +594,7 @@ 9.4 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); 9.5 9.6 // for c++ interpreter can rsi really be munged? 9.7 - __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); // restore state 9.8 + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); // restore state 9.9 __ movptr(rbx, Address(state, byte_offset_of(BytecodeInterpreter, _method))); // restore method 9.10 __ movptr(rdi, Address(state, byte_offset_of(BytecodeInterpreter, _locals))); // get locals pointer 9.11 9.12 @@ -658,7 +658,7 @@ 9.13 const Address size_of_stack (rbx, methodOopDesc::max_stack_offset()); 9.14 // Always give one monitor to allow us to start interp if sync method. 9.15 // Any additional monitors need a check when moving the expression stack 9.16 - const one_monitor = frame::interpreter_frame_monitor_size() * wordSize; 9.17 + const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize; 9.18 __ load_unsigned_word(rax, size_of_stack); // get size of expression stack in words 9.19 __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor)); 9.20 __ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size)); 9.21 @@ -1829,7 +1829,7 @@ 9.22 Label unwind_and_forward; 9.23 9.24 // restore state pointer. 9.25 - __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); 9.26 + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); 9.27 9.28 __ movptr(rbx, STATE(_method)); // get method 9.29 #ifdef _LP64 9.30 @@ -1877,14 +1877,14 @@ 9.31 9.32 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases 9.33 if (UseSSE < 2) { 9.34 - __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); 9.35 + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); 9.36 __ movptr(rbx, STATE(_result._to_call._callee)); // get method just executed 9.37 __ movl(rcx, Address(rbx, methodOopDesc::result_index_offset())); 9.38 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_FLOAT)); // Result stub address array index 9.39 __ jcc(Assembler::equal, do_float); 9.40 __ cmpl(rcx, AbstractInterpreter::BasicType_as_index(T_DOUBLE)); // Result stub address array index 9.41 __ jcc(Assembler::equal, do_double); 9.42 -#ifdef COMPILER2 9.43 +#if !defined(_LP64) || defined(COMPILER1) || !defined(COMPILER2) 9.44 __ empty_FPU_stack(); 9.45 #endif // COMPILER2 9.46 __ jmp(done_conv); 9.47 @@ -1928,7 +1928,7 @@ 9.48 9.49 // Restore rsi/r13 as compiled code may not preserve it 9.50 9.51 - __ lea(state, Address(rbp, -sizeof(BytecodeInterpreter))); 9.52 + __ lea(state, Address(rbp, -(int)sizeof(BytecodeInterpreter))); 9.53 9.54 // restore stack to what we had when we left (in case i2c extended it) 9.55 9.56 @@ -1942,7 +1942,7 @@ 9.57 #else 9.58 __ movptr(rcx, STATE(_thread)); // get thread 9.59 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 9.60 -#endif / __LP64 9.61 +#endif // _LP64 9.62 __ jcc(Assembler::notZero, return_with_exception); 9.63 9.64 // get method just executed
10.1 --- a/src/cpu/x86/vm/frame_x86.inline.hpp Thu Jan 29 13:20:56 2009 -0800 10.2 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp Fri Jan 30 15:28:00 2009 -0800 10.3 @@ -139,7 +139,7 @@ 10.4 #ifdef CC_INTERP 10.5 10.6 inline interpreterState frame::get_interpreterState() const { 10.7 - return ((interpreterState)addr_at( -sizeof(BytecodeInterpreter)/wordSize )); 10.8 + return ((interpreterState)addr_at( -((int)sizeof(BytecodeInterpreter))/wordSize )); 10.9 } 10.10 10.11 inline intptr_t* frame::sender_sp() const {
11.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 11.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 11.3 @@ -133,7 +133,7 @@ 11.4 + in_ByteSize(wordSize)); 11.5 switch (state) { 11.6 case atos: movptr(rax, oop_addr); 11.7 - movptr(oop_addr, (int32_t)NULL_WORD); 11.8 + movptr(oop_addr, NULL_WORD); 11.9 verify_oop(rax, state); break; 11.10 case ltos: 11.11 movl(rdx, val_addr1); // fall through 11.12 @@ -148,8 +148,8 @@ 11.13 } 11.14 // Clean up tos value in the thread object 11.15 movl(tos_addr, (int32_t) ilgl); 11.16 - movptr(val_addr, (int32_t)NULL_WORD); 11.17 - NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD)); 11.18 + movptr(val_addr, NULL_WORD); 11.19 + NOT_LP64(movptr(val_addr1, NULL_WORD)); 11.20 } 11.21 11.22 11.23 @@ -944,7 +944,7 @@ 11.24 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); 11.25 11.26 // Free entry 11.27 - movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); 11.28 + movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); 11.29 11.30 if (UseBiasedLocking) { 11.31 biased_locking_exit(obj_reg, header_reg, done);
12.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Jan 29 13:20:56 2009 -0800 12.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Fri Jan 30 15:28:00 2009 -0800 12.3 @@ -120,7 +120,7 @@ 12.4 void empty_expression_stack() { 12.5 movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize)); 12.6 // NULL last_sp until next java call 12.7 - movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 12.8 + movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 12.9 } 12.10 12.11 // Tagged stack helpers for swap and dup
13.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Jan 29 13:20:56 2009 -0800 13.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Jan 30 15:28:00 2009 -0800 13.3 @@ -30,7 +30,7 @@ 13.4 13.5 #ifdef CC_INTERP 13.6 void InterpreterMacroAssembler::get_method(Register reg) { 13.7 - movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); 13.8 + movptr(reg, Address(rbp, -((int)sizeof(BytecodeInterpreter) + 2 * wordSize))); 13.9 movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); 13.10 } 13.11 #endif // CC_INTERP
14.1 --- a/src/cpu/x86/vm/interpreterRT_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 14.2 +++ b/src/cpu/x86/vm/interpreterRT_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 14.3 @@ -54,7 +54,7 @@ 14.4 __ cmpptr(Address(from(), Interpreter::local_offset_in_bytes(from_offset)), (int32_t)NULL_WORD); // do not use temp() to avoid AGI 14.5 Label L; 14.6 __ jcc(Assembler::notZero, L); 14.7 - __ movptr(temp(), ((int32_t)NULL_WORD)); 14.8 + __ movptr(temp(), NULL_WORD); 14.9 __ bind(L); 14.10 __ movptr(Address(to(), to_offset * wordSize), temp()); 14.11 } 14.12 @@ -110,7 +110,7 @@ 14.13 virtual void pass_object() { 14.14 // pass address of from 14.15 intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0)); 14.16 - *_to++ = (*(intptr_t*)from_addr == 0) ? NULL : from_addr; 14.17 + *_to++ = (*(intptr_t*)from_addr == 0) ? NULL_WORD : from_addr; 14.18 debug_only(verify_tag(frame::TagReference)); 14.19 _from -= Interpreter::stackElementSize(); 14.20 }
15.1 --- a/src/cpu/x86/vm/jni_x86.h Thu Jan 29 13:20:56 2009 -0800 15.2 +++ b/src/cpu/x86/vm/jni_x86.h Fri Jan 30 15:28:00 2009 -0800 15.3 @@ -32,7 +32,13 @@ 15.4 #define JNICALL 15.5 15.6 typedef int jint; 15.7 + 15.8 +#ifdef _LP64 15.9 + typedef long jlong; 15.10 +#else 15.11 typedef long long jlong; 15.12 +#endif 15.13 + 15.14 #else 15.15 #define JNIEXPORT __declspec(dllexport) 15.16 #define JNIIMPORT __declspec(dllimport)
16.1 --- a/src/cpu/x86/vm/runtime_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 16.2 +++ b/src/cpu/x86/vm/runtime_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 16.3 @@ -129,11 +129,11 @@ 16.4 // Get the exception pc in case we are deoptimized 16.5 __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); 16.6 #ifdef ASSERT 16.7 - __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), (int32_t)NULL_WORD); 16.8 - __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); 16.9 + __ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), NULL_WORD); 16.10 + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD); 16.11 #endif 16.12 // Clear the exception oop so GC no longer processes it as a root. 16.13 - __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); 16.14 + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD); 16.15 16.16 __ pop(rcx); 16.17
17.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 17.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 17.3 @@ -39,6 +39,8 @@ 17.4 RuntimeStub* SharedRuntime::_resolve_virtual_call_blob; 17.5 RuntimeStub* SharedRuntime::_resolve_static_call_blob; 17.6 17.7 +const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; 17.8 + 17.9 class RegisterSaver { 17.10 enum { FPU_regs_live = 8 /*for the FPU stack*/+8/*eight more for XMM registers*/ }; 17.11 // Capture info about frame layout 17.12 @@ -1299,7 +1301,7 @@ 17.13 17.14 // Now compute actual number of stack words we need rounding to make 17.15 // stack properly aligned. 17.16 - stack_slots = round_to(stack_slots, 2 * VMRegImpl::slots_per_word); 17.17 + stack_slots = round_to(stack_slots, StackAlignmentInSlots); 17.18 17.19 int stack_size = stack_slots * VMRegImpl::stack_slot_size; 17.20 17.21 @@ -1793,7 +1795,7 @@ 17.22 // reset handle block 17.23 __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); 17.24 17.25 - __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); 17.26 + __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); 17.27 17.28 // Any exception pending? 17.29 __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); 17.30 @@ -1865,7 +1867,7 @@ 17.31 // Save pending exception around call to VM (which contains an EXCEPTION_MARK) 17.32 17.33 __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset()))); 17.34 - __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); 17.35 + __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); 17.36 17.37 17.38 // should be a peal 17.39 @@ -2431,7 +2433,7 @@ 17.40 __ get_thread(rdi); 17.41 __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset())); 17.42 __ movptr(Address(rbp, wordSize), rdx); 17.43 - __ movptr(Address(rdi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); 17.44 + __ movptr(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD); 17.45 17.46 #ifdef ASSERT 17.47 // verify that there is really an exception oop in JavaThread 17.48 @@ -2489,8 +2491,8 @@ 17.49 __ jcc(Assembler::notEqual, noException); 17.50 __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); 17.51 __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); 17.52 - __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); 17.53 - __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); 17.54 + __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD); 17.55 + __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD); 17.56 17.57 __ verify_oop(rax); 17.58 17.59 @@ -2582,7 +2584,7 @@ 17.60 rbx); // Make it walkable 17.61 #else /* CC_INTERP */ 17.62 // This value is corrected by layout_activation_impl 17.63 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); 17.64 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 17.65 __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable 17.66 #endif /* CC_INTERP */ 17.67 __ movptr(sp_temp, rsp); // pass to next frame 17.68 @@ -2802,7 +2804,7 @@ 17.69 rbx); // Make it walkable 17.70 #else /* CC_INTERP */ 17.71 // This value is corrected by layout_activation_impl 17.72 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); 17.73 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD ); 17.74 __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable 17.75 #endif /* CC_INTERP */ 17.76 __ movptr(sp_temp, rsp); // pass to next frame 17.77 @@ -3020,7 +3022,7 @@ 17.78 // exception pending => remove activation and forward to exception handler 17.79 17.80 __ get_thread(thread); 17.81 - __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 17.82 + __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); 17.83 __ movptr(rax, Address(thread, Thread::pending_exception_offset())); 17.84 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); 17.85
18.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Jan 29 13:20:56 2009 -0800 18.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jan 30 15:28:00 2009 -0800 18.3 @@ -39,6 +39,8 @@ 18.4 RuntimeStub* SharedRuntime::_resolve_virtual_call_blob; 18.5 RuntimeStub* SharedRuntime::_resolve_static_call_blob; 18.6 18.7 +const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; 18.8 + 18.9 #define __ masm-> 18.10 18.11 class SimpleRuntimeFrame { 18.12 @@ -1286,7 +1288,7 @@ 18.13 18.14 // Now compute actual number of stack words we need rounding to make 18.15 // stack properly aligned. 18.16 - stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); 18.17 + stack_slots = round_to(stack_slots, StackAlignmentInSlots); 18.18 18.19 int stack_size = stack_slots * VMRegImpl::stack_slot_size; 18.20 18.21 @@ -2954,10 +2956,16 @@ 18.22 __ pushptr(Address(rcx, 0)); // Save return address 18.23 __ enter(); // Save old & set new rbp 18.24 __ subptr(rsp, rbx); // Prolog 18.25 +#ifdef CC_INTERP 18.26 + __ movptr(Address(rbp, 18.27 + -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), 18.28 + sender_sp); // Make it walkable 18.29 +#else // CC_INTERP 18.30 __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), 18.31 sender_sp); // Make it walkable 18.32 // This value is corrected by layout_activation_impl 18.33 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); 18.34 +#endif // CC_INTERP 18.35 __ mov(sender_sp, rsp); // Pass sender_sp to next frame 18.36 __ addptr(rsi, wordSize); // Bump array pointer (sizes) 18.37 __ addptr(rcx, wordSize); // Bump array pointer (pcs)
19.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 19.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 19.3 @@ -407,7 +407,7 @@ 19.4 __ get_thread(rcx); 19.5 __ pop(rdx); 19.6 __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); 19.7 - __ movptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 19.8 + __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); 19.9 19.10 #ifdef ASSERT 19.11 // make sure exception is set
20.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jan 29 13:20:56 2009 -0800 20.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jan 30 15:28:00 2009 -0800 20.3 @@ -472,7 +472,7 @@ 20.4 // setup rax & rdx, remove return address & clear pending exception 20.5 __ pop(rdx); 20.6 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); 20.7 - __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int)NULL_WORD); 20.8 + __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 20.9 20.10 #ifdef ASSERT 20.11 // make sure exception is set 20.12 @@ -954,9 +954,9 @@ 20.13 __ jcc(Assembler::zero, exit); // if obj is NULL it is OK 20.14 // Check if the oop is in the right area of memory 20.15 __ movptr(c_rarg2, rax); 20.16 - __ movptr(c_rarg3, (int64_t) Universe::verify_oop_mask()); 20.17 + __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask()); 20.18 __ andptr(c_rarg2, c_rarg3); 20.19 - __ movptr(c_rarg3, (int64_t) Universe::verify_oop_bits()); 20.20 + __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits()); 20.21 __ cmpptr(c_rarg2, c_rarg3); 20.22 __ jcc(Assembler::notZero, error); 20.23 20.24 @@ -969,9 +969,9 @@ 20.25 __ jcc(Assembler::zero, error); // if klass is NULL it is broken 20.26 // Check if the klass is in the right area of memory 20.27 __ mov(c_rarg2, rax); 20.28 - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); 20.29 + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask()); 20.30 __ andptr(c_rarg2, c_rarg3); 20.31 - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); 20.32 + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits()); 20.33 __ cmpptr(c_rarg2, c_rarg3); 20.34 __ jcc(Assembler::notZero, error); 20.35 20.36 @@ -980,9 +980,9 @@ 20.37 __ testptr(rax, rax); 20.38 __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken 20.39 // Check if the klass' klass is in the right area of memory 20.40 - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); 20.41 + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask()); 20.42 __ andptr(rax, c_rarg3); 20.43 - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); 20.44 + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits()); 20.45 __ cmpptr(rax, c_rarg3); 20.46 __ jcc(Assembler::notZero, error); 20.47
21.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 21.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 21.3 @@ -110,7 +110,7 @@ 21.4 if (message != NULL) { 21.5 __ lea(rbx, ExternalAddress((address)message)); 21.6 } else { 21.7 - __ movptr(rbx, (int32_t)NULL_WORD); 21.8 + __ movptr(rbx, NULL_WORD); 21.9 } 21.10 __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), rax, rbx); 21.11 } 21.12 @@ -123,7 +123,7 @@ 21.13 address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { 21.14 address entry = __ pc(); 21.15 // NULL last_sp until next java call 21.16 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 21.17 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 21.18 __ dispatch_next(state); 21.19 return entry; 21.20 } 21.21 @@ -176,7 +176,7 @@ 21.22 // Restore stack bottom in case i2c adjusted stack 21.23 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 21.24 // and NULL it as marker that rsp is now tos until next java call 21.25 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 21.26 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 21.27 21.28 __ restore_bcp(); 21.29 __ restore_locals(); 21.30 @@ -211,7 +211,7 @@ 21.31 21.32 // The stack is not extended by deopt but we must NULL last_sp as this 21.33 // entry is like a "return". 21.34 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 21.35 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 21.36 __ restore_bcp(); 21.37 __ restore_locals(); 21.38 // handle exceptions 21.39 @@ -382,7 +382,7 @@ 21.40 // indicating if the counter overflow occurs at a backwards branch (non-NULL bcp). 21.41 // The call returns the address of the verified entry point for the method or NULL 21.42 // if the compilation did not complete (either went background or bailed out). 21.43 - __ movptr(rax, (int32_t)false); 21.44 + __ movptr(rax, (intptr_t)false); 21.45 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), rax); 21.46 21.47 __ movptr(rbx, Address(rbp, method_offset)); // restore methodOop 21.48 @@ -1028,7 +1028,7 @@ 21.49 21.50 // reset handle block 21.51 __ movptr(t, Address(thread, JavaThread::active_handles_offset())); 21.52 - __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); 21.53 + __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD); 21.54 21.55 // If result was an oop then unbox and save it in the frame 21.56 { Label L; 21.57 @@ -1488,7 +1488,7 @@ 21.58 21.59 // Restore sp to interpreter_frame_last_sp even though we are going 21.60 // to empty the expression stack for the exception processing. 21.61 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 21.62 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 21.63 // rax,: exception 21.64 // rdx: return address/pc that threw exception 21.65 __ restore_bcp(); // rsi points to call/send 21.66 @@ -1608,7 +1608,7 @@ 21.67 __ reset_last_Java_frame(rcx, true, true); 21.68 // Restore the last_sp and null it out 21.69 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); 21.70 - __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); 21.71 + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); 21.72 21.73 __ restore_bcp(); 21.74 __ restore_locals(); 21.75 @@ -1636,7 +1636,7 @@ 21.76 // restore exception 21.77 __ get_thread(rcx); 21.78 __ movptr(rax, Address(rcx, JavaThread::vm_result_offset())); 21.79 - __ movptr(Address(rcx, JavaThread::vm_result_offset()), (int32_t)NULL_WORD); 21.80 + __ movptr(Address(rcx, JavaThread::vm_result_offset()), NULL_WORD); 21.81 __ verify_oop(rax); 21.82 21.83 // Inbetween activations - previous activation type unknown yet
22.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Jan 29 13:20:56 2009 -0800 22.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Jan 30 15:28:00 2009 -0800 22.3 @@ -137,7 +137,7 @@ 22.4 // Do the actual store 22.5 // noreg means NULL 22.6 if (val == noreg) { 22.7 - __ movl(Address(rdx, 0), NULL_WORD); 22.8 + __ movptr(Address(rdx, 0), NULL_WORD); 22.9 // No post barrier for NULL 22.10 } else { 22.11 __ movl(Address(rdx, 0), val); 22.12 @@ -152,7 +152,7 @@ 22.13 case BarrierSet::CardTableExtension: 22.14 { 22.15 if (val == noreg) { 22.16 - __ movl(obj, NULL_WORD); 22.17 + __ movptr(obj, NULL_WORD); 22.18 } else { 22.19 __ movl(obj, val); 22.20 // flatten object address if needed 22.21 @@ -168,7 +168,7 @@ 22.22 case BarrierSet::ModRef: 22.23 case BarrierSet::Other: 22.24 if (val == noreg) { 22.25 - __ movl(obj, NULL_WORD); 22.26 + __ movptr(obj, NULL_WORD); 22.27 } else { 22.28 __ movl(obj, val); 22.29 }
23.1 --- a/src/cpu/x86/vm/x86_32.ad Thu Jan 29 13:20:56 2009 -0800 23.2 +++ b/src/cpu/x86/vm/x86_32.ad Fri Jan 30 15:28:00 2009 -0800 23.3 @@ -3371,7 +3371,7 @@ 23.4 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 23.5 masm.get_thread (scrReg) ; 23.6 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 23.7 - masm.movptr(tmpReg, 0); // consider: xor vs mov 23.8 + masm.movptr(tmpReg, NULL_WORD); // consider: xor vs mov 23.9 if (os::is_MP()) { masm.lock(); } 23.10 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 23.11 } else 23.12 @@ -3387,7 +3387,7 @@ 23.13 23.14 if ((EmitSync & 64) == 0) { 23.15 // Optimistic form: consider XORL tmpReg,tmpReg 23.16 - masm.movptr(tmpReg, 0 ) ; 23.17 + masm.movptr(tmpReg, NULL_WORD) ; 23.18 } else { 23.19 // Can suffer RTS->RTO upgrades on shared or cold $ lines 23.20 // Test-And-CAS instead of CAS 23.21 @@ -3587,7 +3587,7 @@ 23.22 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 23.23 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 23.24 masm.jccb (Assembler::notZero, DONE_LABEL) ; 23.25 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 23.26 + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 23.27 masm.jmpb (DONE_LABEL) ; 23.28 } else { 23.29 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 23.30 @@ -3596,7 +3596,7 @@ 23.31 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 23.32 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 23.33 masm.jccb (Assembler::notZero, CheckSucc) ; 23.34 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 23.35 + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 23.36 masm.jmpb (DONE_LABEL) ; 23.37 } 23.38 23.39 @@ -3644,7 +3644,7 @@ 23.40 // We currently use (3), although it's likely that switching to (2) 23.41 // is correct for the future. 23.42 23.43 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), 0) ; 23.44 + masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 23.45 if (os::is_MP()) { 23.46 if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 23.47 masm.mfence();
24.1 --- a/src/os/linux/vm/os_linux.cpp Thu Jan 29 13:20:56 2009 -0800 24.2 +++ b/src/os/linux/vm/os_linux.cpp Fri Jan 30 15:28:00 2009 -0800 24.3 @@ -279,7 +279,11 @@ 24.4 * ... 24.5 * 7: The default directories, normally /lib and /usr/lib. 24.6 */ 24.7 +#if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390)) 24.8 +#define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib" 24.9 +#else 24.10 #define DEFAULT_LIBPATH "/lib:/usr/lib" 24.11 +#endif 24.12 24.13 #define EXTENSIONS_DIR "/lib/ext" 24.14 #define ENDORSED_DIR "/lib/endorsed" 24.15 @@ -1160,7 +1164,10 @@ 24.16 24.17 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ 24.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 */ 24.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", 24.20 + i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " 24.21 + UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT 24.22 + " %lu " 24.23 + UINTX_FORMAT UINTX_FORMAT UINTX_FORMAT, 24.24 &state, /* 3 %c */ 24.25 &ppid, /* 4 %d */ 24.26 &pgrp, /* 5 %d */ 24.27 @@ -1180,13 +1187,13 @@ 24.28 &nice, /* 19 %ld */ 24.29 &junk, /* 20 %ld */ 24.30 &it_real, /* 21 %ld */ 24.31 - &start, /* 22 %lu */ 24.32 - &vsize, /* 23 %lu */ 24.33 - &rss, /* 24 %ld */ 24.34 + &start, /* 22 UINTX_FORMAT */ 24.35 + &vsize, /* 23 UINTX_FORMAT */ 24.36 + &rss, /* 24 UINTX_FORMAT */ 24.37 &rsslim, /* 25 %lu */ 24.38 - &scodes, /* 26 %lu */ 24.39 - &ecode, /* 27 %lu */ 24.40 - &stack_start); /* 28 %lu */ 24.41 + &scodes, /* 26 UINTX_FORMAT */ 24.42 + &ecode, /* 27 UINTX_FORMAT */ 24.43 + &stack_start); /* 28 UINTX_FORMAT */ 24.44 } 24.45 24.46 if (i != 28 - 2) { 24.47 @@ -2024,7 +2031,8 @@ 24.48 CAST_FROM_FN_PTR(address, os::jvm_path), 24.49 dli_fname, sizeof(dli_fname), NULL); 24.50 assert(ret != 0, "cannot locate libjvm"); 24.51 - realpath(dli_fname, buf); 24.52 + if (realpath(dli_fname, buf) == NULL) 24.53 + return; 24.54 24.55 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { 24.56 // Support for the gamma launcher. Typical value for buf is 24.57 @@ -2048,7 +2056,8 @@ 24.58 assert(strstr(p, "/libjvm") == p, "invalid library name"); 24.59 p = strstr(p, "_g") ? "_g" : ""; 24.60 24.61 - realpath(java_home_var, buf); 24.62 + if (realpath(java_home_var, buf) == NULL) 24.63 + return; 24.64 sprintf(buf + strlen(buf), "/jre/lib/%s", cpu_arch); 24.65 if (0 == access(buf, F_OK)) { 24.66 // Use current module name "libjvm[_g].so" instead of 24.67 @@ -2059,7 +2068,8 @@ 24.68 sprintf(buf + strlen(buf), "/hotspot/libjvm%s.so", p); 24.69 } else { 24.70 // Go back to path of .so 24.71 - realpath(dli_fname, buf); 24.72 + if (realpath(dli_fname, buf) == NULL) 24.73 + return; 24.74 } 24.75 } 24.76 } 24.77 @@ -4184,11 +4194,11 @@ 24.78 // Skip blank chars 24.79 do s++; while (isspace(*s)); 24.80 24.81 - count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", 24.82 - &idummy, &idummy, &idummy, &idummy, &idummy, &idummy, 24.83 + count = sscanf(s,"%*c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", 24.84 + &idummy, &idummy, &idummy, &idummy, &idummy, 24.85 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, 24.86 &user_time, &sys_time); 24.87 - if ( count != 13 ) return -1; 24.88 + if ( count != 12 ) return -1; 24.89 if (user_sys_cpu_time) { 24.90 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); 24.91 } else {
25.1 --- a/src/share/vm/classfile/classFileParser.cpp Thu Jan 29 13:20:56 2009 -0800 25.2 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Jan 30 15:28:00 2009 -0800 25.3 @@ -232,7 +232,9 @@ 25.4 length >= 1, "Illegal constant pool size %u in class file %s", 25.5 length, CHECK_(nullHandle)); 25.6 constantPoolOop constant_pool = 25.7 - oopFactory::new_constantPool(length, CHECK_(nullHandle)); 25.8 + oopFactory::new_constantPool(length, 25.9 + methodOopDesc::IsSafeConc, 25.10 + CHECK_(nullHandle)); 25.11 constantPoolHandle cp (THREAD, constant_pool); 25.12 25.13 cp->set_partially_loaded(); // Enables heap verify to work on partial constantPoolOops 25.14 @@ -1675,7 +1677,8 @@ 25.15 // All sizing information for a methodOop is finally available, now create it 25.16 methodOop m_oop = oopFactory::new_method( 25.17 code_length, access_flags, linenumber_table_length, 25.18 - total_lvt_length, checked_exceptions_length, CHECK_(nullHandle)); 25.19 + total_lvt_length, checked_exceptions_length, 25.20 + methodOopDesc::IsSafeConc, CHECK_(nullHandle)); 25.21 methodHandle m (THREAD, m_oop); 25.22 25.23 ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
26.1 --- a/src/share/vm/classfile/javaClasses.cpp Thu Jan 29 13:20:56 2009 -0800 26.2 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Jan 30 15:28:00 2009 -0800 26.3 @@ -441,6 +441,7 @@ 26.4 26.5 bool java_lang_Class::offsets_computed = false; 26.6 int java_lang_Class::classRedefinedCount_offset = -1; 26.7 +int java_lang_Class::parallelCapable_offset = -1; 26.8 26.9 void java_lang_Class::compute_offsets() { 26.10 assert(!offsets_computed, "offsets should be initialized only once"); 26.11 @@ -451,6 +452,23 @@ 26.12 // so don't go fatal. 26.13 compute_optional_offset(classRedefinedCount_offset, 26.14 k, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); 26.15 + 26.16 + // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, 26.17 + klassOop k1 = SystemDictionary::classloader_klass(); 26.18 + compute_optional_offset(parallelCapable_offset, 26.19 + k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); 26.20 +} 26.21 + 26.22 +// For class loader classes, parallelCapable defined 26.23 +// based on non-null field 26.24 +// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it 26.25 +bool java_lang_Class::parallelCapable(oop class_loader) { 26.26 + if (!JDK_Version::is_gte_jdk17x_version() 26.27 + || parallelCapable_offset == -1) { 26.28 + // Default for backward compatibility is false 26.29 + return false; 26.30 + } 26.31 + return (class_loader->obj_field(parallelCapable_offset) != NULL); 26.32 } 26.33 26.34 int java_lang_Class::classRedefinedCount(oop the_class_mirror) { 26.35 @@ -866,7 +884,7 @@ 26.36 } 26.37 nmethod* nm = method->code(); 26.38 if (WizardMode && nm != NULL) { 26.39 - sprintf(buf + (int)strlen(buf), "(nmethod %#x)", nm); 26.40 + sprintf(buf + (int)strlen(buf), "(nmethod " PTR_FORMAT ")", (intptr_t)nm); 26.41 } 26.42 } 26.43
27.1 --- a/src/share/vm/classfile/javaClasses.hpp Thu Jan 29 13:20:56 2009 -0800 27.2 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Jan 30 15:28:00 2009 -0800 27.3 @@ -141,6 +141,7 @@ 27.4 static void compute_offsets(); 27.5 static bool offsets_computed; 27.6 static int classRedefinedCount_offset; 27.7 + static int parallelCapable_offset; 27.8 27.9 public: 27.10 // Instance creation 27.11 @@ -168,6 +169,8 @@ 27.12 // Support for classRedefinedCount field 27.13 static int classRedefinedCount(oop the_class_mirror); 27.14 static void set_classRedefinedCount(oop the_class_mirror, int value); 27.15 + // Support for parallelCapable field 27.16 + static bool parallelCapable(oop the_class_mirror); 27.17 // Debugging 27.18 friend class JavaClasses; 27.19 friend class instanceKlass; // verification code accesses offsets
28.1 --- a/src/share/vm/classfile/systemDictionary.cpp Thu Jan 29 13:20:56 2009 -0800 28.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Jan 30 15:28:00 2009 -0800 28.3 @@ -90,6 +90,14 @@ 28.4 #endif 28.5 28.6 // ---------------------------------------------------------------------------- 28.7 +// Parallel class loading check 28.8 + 28.9 +bool SystemDictionary::is_parallelCapable(Handle class_loader) { 28.10 + if (UnsyncloadClass || class_loader.is_null()) return true; 28.11 + if (AlwaysLockClassLoader) return false; 28.12 + return java_lang_Class::parallelCapable(class_loader()); 28.13 +} 28.14 +// ---------------------------------------------------------------------------- 28.15 // Resolving of classes 28.16 28.17 // Forwards to resolve_or_null 28.18 @@ -196,7 +204,8 @@ 28.19 // super-class callers: 28.20 // ClassFileParser - for defineClass & jvmtiRedefineClasses 28.21 // load_shared_class - while loading a class from shared archive 28.22 -// resolve_instance_class_or_fail: 28.23 +// resolve_instance_class_or_null: 28.24 +// via: handle_parallel_super_load 28.25 // when resolving a class that has an existing placeholder with 28.26 // a saved superclass [i.e. a defineClass is currently in progress] 28.27 // if another thread is trying to resolve the class, it must do 28.28 @@ -283,12 +292,9 @@ 28.29 if (probe && probe->check_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER)) { 28.30 throw_circularity_error = true; 28.31 } 28.32 - 28.33 - // add placeholder entry even if error - callers will remove on error 28.34 + } 28.35 + if (!throw_circularity_error) { 28.36 PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, child_name, class_loader, PlaceholderTable::LOAD_SUPER, class_name, THREAD); 28.37 - if (throw_circularity_error) { 28.38 - newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER); 28.39 - } 28.40 } 28.41 } 28.42 if (throw_circularity_error) { 28.43 @@ -325,7 +331,6 @@ 28.44 return superk_h(); 28.45 } 28.46 28.47 - 28.48 void SystemDictionary::validate_protection_domain(instanceKlassHandle klass, 28.49 Handle class_loader, 28.50 Handle protection_domain, 28.51 @@ -421,7 +426,7 @@ 28.52 bool calledholdinglock 28.53 = ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject); 28.54 assert(calledholdinglock,"must hold lock for notify"); 28.55 - assert(!UnsyncloadClass, "unexpected double_lock_wait"); 28.56 + assert((!(lockObject() == _system_loader_lock_obj) && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); 28.57 ObjectSynchronizer::notifyall(lockObject, THREAD); 28.58 intptr_t recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD); 28.59 SystemDictionary_lock->wait(); 28.60 @@ -439,7 +444,7 @@ 28.61 // even in non-circularity situations. 28.62 // Note: only one thread can define the class, but multiple can resolve 28.63 // Note: must call resolve_super_or_fail even if null super - 28.64 -// to force placeholder entry creation for this class 28.65 +// to force placeholder entry creation for this class for circularity detection 28.66 // Caller must check for pending exception 28.67 // Returns non-null klassOop if other thread has completed load 28.68 // and we are done, 28.69 @@ -477,9 +482,9 @@ 28.70 SystemDictionary_lock->notify_all(); 28.71 } 28.72 28.73 - // UnsyncloadClass does NOT wait for parallel superclass loads to complete 28.74 - // Bootstrap classloader does wait for parallel superclass loads 28.75 - if (UnsyncloadClass) { 28.76 + // parallelCapable class loaders do NOT wait for parallel superclass loads to complete 28.77 + // Serial class loaders and bootstrap classloader do wait for superclass loads 28.78 + if (!class_loader.is_null() && is_parallelCapable(class_loader)) { 28.79 MutexLocker mu(SystemDictionary_lock, THREAD); 28.80 // Check if classloading completed while we were loading superclass or waiting 28.81 klassOop check = find_class(d_index, d_hash, name, class_loader); 28.82 @@ -566,10 +571,10 @@ 28.83 // This lock must be acquired here so the waiter will find 28.84 // any successful result in the SystemDictionary and not attempt 28.85 // the define 28.86 - // Classloaders that support parallelism, e.g. bootstrap classloader, 28.87 + // ParallelCapable Classloaders and the bootstrap classloader, 28.88 // or all classloaders with UnsyncloadClass do not acquire lock here 28.89 bool DoObjectLock = true; 28.90 - if (UnsyncloadClass || (class_loader.is_null())) { 28.91 + if (is_parallelCapable(class_loader)) { 28.92 DoObjectLock = false; 28.93 } 28.94 28.95 @@ -627,6 +632,9 @@ 28.96 // Five cases: 28.97 // All cases need to prevent modifying bootclasssearchpath 28.98 // in parallel with a classload of same classname 28.99 + // Redefineclasses uses existence of the placeholder for the duration 28.100 + // of the class load to prevent concurrent redefinition of not completely 28.101 + // defined classes. 28.102 // case 1. traditional classloaders that rely on the classloader object lock 28.103 // - no other need for LOAD_INSTANCE 28.104 // case 2. traditional classloaders that break the classloader object lock 28.105 @@ -642,12 +650,13 @@ 28.106 // This classloader supports parallelism at the classloader level, 28.107 // but only allows a single load of a class/classloader pair. 28.108 // No performance benefit and no deadlock issues. 28.109 - // case 5. Future: parallel user level classloaders - without objectLocker 28.110 + // case 5. parallelCapable user level classloaders - without objectLocker 28.111 + // Allow parallel classloading of a class/classloader pair 28.112 symbolHandle nullsymbolHandle; 28.113 bool throw_circularity_error = false; 28.114 { 28.115 MutexLocker mu(SystemDictionary_lock, THREAD); 28.116 - if (!UnsyncloadClass) { 28.117 + if (class_loader.is_null() || !is_parallelCapable(class_loader)) { 28.118 PlaceholderEntry* oldprobe = placeholders()->get_entry(p_index, p_hash, name, class_loader); 28.119 if (oldprobe) { 28.120 // only need check_seen_thread once, not on each loop 28.121 @@ -681,25 +690,25 @@ 28.122 } 28.123 } 28.124 // All cases: add LOAD_INSTANCE 28.125 - // case 3: UnsyncloadClass: allow competing threads to try 28.126 + // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try 28.127 // LOAD_INSTANCE in parallel 28.128 // add placeholder entry even if error - callers will remove on error 28.129 - if (!class_has_been_loaded) { 28.130 + if (!throw_circularity_error && !class_has_been_loaded) { 28.131 PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, class_loader, PlaceholderTable::LOAD_INSTANCE, nullsymbolHandle, THREAD); 28.132 - if (throw_circularity_error) { 28.133 - newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE); 28.134 - } 28.135 // For class loaders that do not acquire the classloader object lock, 28.136 // if they did not catch another thread holding LOAD_INSTANCE, 28.137 // need a check analogous to the acquire ObjectLocker/find_class 28.138 // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL 28.139 // one final check if the load has already completed 28.140 + // class loaders holding the ObjectLock shouldn't find the class here 28.141 klassOop check = find_class(d_index, d_hash, name, class_loader); 28.142 if (check != NULL) { 28.143 // Klass is already loaded, so just return it 28.144 k = instanceKlassHandle(THREAD, check); 28.145 class_has_been_loaded = true; 28.146 newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE); 28.147 + placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD); 28.148 + SystemDictionary_lock->notify_all(); 28.149 } 28.150 } 28.151 } 28.152 @@ -714,18 +723,14 @@ 28.153 // Do actual loading 28.154 k = load_instance_class(name, class_loader, THREAD); 28.155 28.156 - // In custom class loaders, the usual findClass calls 28.157 - // findLoadedClass, which directly searches the SystemDictionary, then 28.158 - // defineClass. If these are not atomic with respect to other threads, 28.159 - // the findLoadedClass can fail, but the defineClass can get a 28.160 - // LinkageError:: duplicate class definition. 28.161 + // For UnsyncloadClass and AllowParallelDefineClass only: 28.162 // If they got a linkageError, check if a parallel class load succeeded. 28.163 // If it did, then for bytecode resolution the specification requires 28.164 // that we return the same result we did for the other thread, i.e. the 28.165 // successfully loaded instanceKlass 28.166 - // Note: Class can not be unloaded as long as any classloader refs exist 28.167 // Should not get here for classloaders that support parallelism 28.168 - // with the new cleaner mechanism, e.g. bootstrap classloader 28.169 + // with the new cleaner mechanism 28.170 + // Bootstrap goes through here to allow for an extra guarantee check 28.171 if (UnsyncloadClass || (class_loader.is_null())) { 28.172 if (k.is_null() && HAS_PENDING_EXCEPTION 28.173 && PENDING_EXCEPTION->is_a(SystemDictionary::linkageError_klass())) { 28.174 @@ -955,10 +960,10 @@ 28.175 instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, 28.176 class_loader, 28.177 protection_domain, 28.178 - cp_patches, 28.179 parsed_name, 28.180 THREAD); 28.181 28.182 + 28.183 // We don't redefine the class, so we just need to clean up whether there 28.184 // was an error or not (don't want to modify any system dictionary 28.185 // data structures). 28.186 @@ -1013,11 +1018,17 @@ 28.187 ClassFileStream* st, 28.188 TRAPS) { 28.189 28.190 - // Make sure we are synchronized on the class loader before we initiate 28.191 - // loading. 28.192 + // Classloaders that support parallelism, e.g. bootstrap classloader, 28.193 + // or all classloaders with UnsyncloadClass do not acquire lock here 28.194 + bool DoObjectLock = true; 28.195 + if (is_parallelCapable(class_loader)) { 28.196 + DoObjectLock = false; 28.197 + } 28.198 + 28.199 + // Make sure we are synchronized on the class loader before we proceed 28.200 Handle lockObject = compute_loader_lock_object(class_loader, THREAD); 28.201 check_loader_lock_contention(lockObject, THREAD); 28.202 - ObjectLocker ol(lockObject, THREAD); 28.203 + ObjectLocker ol(lockObject, THREAD, DoObjectLock); 28.204 28.205 symbolHandle parsed_name; 28.206 28.207 @@ -1069,7 +1080,13 @@ 28.208 "external class name format used internally"); 28.209 28.210 // Add class just loaded 28.211 - define_instance_class(k, THREAD); 28.212 + // If a class loader supports parallel classloading handle parallel define requests 28.213 + // find_or_define_instance_class may return a different instanceKlass 28.214 + if (is_parallelCapable(class_loader)) { 28.215 + k = find_or_define_instance_class(class_name, class_loader, k, THREAD); 28.216 + } else { 28.217 + define_instance_class(k, THREAD); 28.218 + } 28.219 } 28.220 28.221 // If parsing the class file or define_instance_class failed, we 28.222 @@ -1299,7 +1316,7 @@ 28.223 } 28.224 #endif // KERNEL 28.225 28.226 - // find_or_define_instance_class may return a different k 28.227 + // find_or_define_instance_class may return a different instanceKlass 28.228 if (!k.is_null()) { 28.229 k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh)); 28.230 } 28.231 @@ -1316,14 +1333,24 @@ 28.232 28.233 KlassHandle spec_klass (THREAD, SystemDictionary::classloader_klass()); 28.234 28.235 - // UnsyncloadClass option means don't synchronize loadClass() calls. 28.236 - // loadClassInternal() is synchronized and public loadClass(String) is not. 28.237 - // This flag is for diagnostic purposes only. It is risky to call 28.238 + // Call public unsynchronized loadClass(String) directly for all class loaders 28.239 + // for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will 28.240 + // acquire a class-name based lock rather than the class loader object lock. 28.241 + // JDK < 7 already acquire the class loader lock in loadClass(String, boolean), 28.242 + // so the call to loadClassInternal() was not required. 28.243 + // 28.244 + // UnsyncloadClass flag means both call loadClass(String) and do 28.245 + // not acquire the class loader lock even for class loaders that are 28.246 + // not parallelCapable. This was a risky transitional 28.247 + // flag for diagnostic purposes only. It is risky to call 28.248 // custom class loaders without synchronization. 28.249 // WARNING If a custom class loader does NOT synchronizer findClass, or callers of 28.250 - // findClass, this flag risks unexpected timing bugs in the field. 28.251 + // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field. 28.252 // Do NOT assume this will be supported in future releases. 28.253 - if (!UnsyncloadClass && has_loadClassInternal()) { 28.254 + // 28.255 + // Added MustCallLoadClassInternal in case we discover in the field 28.256 + // a customer that counts on this call 28.257 + if (MustCallLoadClassInternal && has_loadClassInternal()) { 28.258 JavaCalls::call_special(&result, 28.259 class_loader, 28.260 spec_klass, 28.261 @@ -1365,14 +1392,17 @@ 28.262 28.263 Handle class_loader_h(THREAD, k->class_loader()); 28.264 28.265 - // for bootstrap classloader don't acquire lock 28.266 - if (!class_loader_h.is_null()) { 28.267 + // for bootstrap and other parallel classloaders don't acquire lock, 28.268 + // use placeholder token 28.269 + // If a parallelCapable class loader calls define_instance_class instead of 28.270 + // find_or_define_instance_class to get here, we have a timing 28.271 + // hole with systemDictionary updates and check_constraints 28.272 + if (!class_loader_h.is_null() && !is_parallelCapable(class_loader_h)) { 28.273 assert(ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, 28.274 compute_loader_lock_object(class_loader_h, THREAD)), 28.275 "define called without lock"); 28.276 } 28.277 28.278 - 28.279 // Check class-loading constraints. Throw exception if violation is detected. 28.280 // Grabs and releases SystemDictionary_lock 28.281 // The check_constraints/find_class call and update_dictionary sequence 28.282 @@ -1427,59 +1457,63 @@ 28.283 28.284 // Support parallel classloading 28.285 // Initial implementation for bootstrap classloader 28.286 -// For future: 28.287 // For custom class loaders that support parallel classloading, 28.288 -// in case they do not synchronize around 28.289 -// FindLoadedClass/DefineClass calls, we check for parallel 28.290 +// With AllowParallelDefine flag==true, in case they do not synchronize around 28.291 +// FindLoadedClass/DefineClass, calls, we check for parallel 28.292 // loading for them, wait if a defineClass is in progress 28.293 // and return the initial requestor's results 28.294 +// With AllowParallelDefine flag==false, call through to define_instance_class 28.295 +// which will throw LinkageError: duplicate class definition. 28.296 // For better performance, the class loaders should synchronize 28.297 -// findClass(), i.e. FindLoadedClass/DefineClass or they 28.298 +// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they 28.299 // potentially waste time reading and parsing the bytestream. 28.300 // Note: VM callers should ensure consistency of k/class_name,class_loader 28.301 instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle class_name, Handle class_loader, instanceKlassHandle k, TRAPS) { 28.302 28.303 instanceKlassHandle nh = instanceKlassHandle(); // null Handle 28.304 + symbolHandle name_h(THREAD, k->name()); // passed in class_name may be null 28.305 28.306 - unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader); 28.307 + unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader); 28.308 int d_index = dictionary()->hash_to_index(d_hash); 28.309 28.310 // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS 28.311 - unsigned int p_hash = placeholders()->compute_hash(class_name, class_loader); 28.312 + unsigned int p_hash = placeholders()->compute_hash(name_h, class_loader); 28.313 int p_index = placeholders()->hash_to_index(p_hash); 28.314 PlaceholderEntry* probe; 28.315 28.316 { 28.317 MutexLocker mu(SystemDictionary_lock, THREAD); 28.318 // First check if class already defined 28.319 - klassOop check = find_class(d_index, d_hash, class_name, class_loader); 28.320 + klassOop check = find_class(d_index, d_hash, name_h, class_loader); 28.321 if (check != NULL) { 28.322 return(instanceKlassHandle(THREAD, check)); 28.323 } 28.324 28.325 // Acquire define token for this class/classloader 28.326 symbolHandle nullsymbolHandle; 28.327 - probe = placeholders()->find_and_add(p_index, p_hash, class_name, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD); 28.328 - // Check if another thread defining in parallel 28.329 - if (probe->definer() == NULL) { 28.330 - // Thread will define the class 28.331 + probe = placeholders()->find_and_add(p_index, p_hash, name_h, class_loader, PlaceholderTable::DEFINE_CLASS, nullsymbolHandle, THREAD); 28.332 + // Wait if another thread defining in parallel 28.333 + // All threads wait - even those that will throw duplicate class: otherwise 28.334 + // caller is surprised by LinkageError: duplicate, but findLoadedClass fails 28.335 + // if other thread has not finished updating dictionary 28.336 + while (probe->definer() != NULL) { 28.337 + SystemDictionary_lock->wait(); 28.338 + } 28.339 + // Only special cases allow parallel defines and can use other thread's results 28.340 + // Other cases fall through, and may run into duplicate defines 28.341 + // caught by finding an entry in the SystemDictionary 28.342 + if ((UnsyncloadClass || AllowParallelDefineClass) && (probe->instanceKlass() != NULL)) { 28.343 + probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); 28.344 + placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD); 28.345 + SystemDictionary_lock->notify_all(); 28.346 +#ifdef ASSERT 28.347 + klassOop check = find_class(d_index, d_hash, name_h, class_loader); 28.348 + assert(check != NULL, "definer missed recording success"); 28.349 +#endif 28.350 + return(instanceKlassHandle(THREAD, probe->instanceKlass())); 28.351 + } else { 28.352 + // This thread will define the class (even if earlier thread tried and had an error) 28.353 probe->set_definer(THREAD); 28.354 - } else { 28.355 - // Wait for defining thread to finish and return results 28.356 - while (probe->definer() != NULL) { 28.357 - SystemDictionary_lock->wait(); 28.358 - } 28.359 - if (probe->instanceKlass() != NULL) { 28.360 - probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); 28.361 - return(instanceKlassHandle(THREAD, probe->instanceKlass())); 28.362 - } else { 28.363 - // If definer had an error, try again as any new thread would 28.364 - probe->set_definer(THREAD); 28.365 -#ifdef ASSERT 28.366 - klassOop check = find_class(d_index, d_hash, class_name, class_loader); 28.367 - assert(check == NULL, "definer missed recording success"); 28.368 -#endif 28.369 - } 28.370 } 28.371 } 28.372 28.373 @@ -1490,7 +1524,7 @@ 28.374 // definer must notify any waiting threads 28.375 { 28.376 MutexLocker mu(SystemDictionary_lock, THREAD); 28.377 - PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, class_name, class_loader); 28.378 + PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name_h, class_loader); 28.379 assert(probe != NULL, "DEFINE_CLASS placeholder lost?"); 28.380 if (probe != NULL) { 28.381 if (HAS_PENDING_EXCEPTION) { 28.382 @@ -1501,6 +1535,7 @@ 28.383 } 28.384 probe->set_definer(NULL); 28.385 probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); 28.386 + placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD); 28.387 SystemDictionary_lock->notify_all(); 28.388 } 28.389 } 28.390 @@ -1512,7 +1547,6 @@ 28.391 28.392 return k; 28.393 } 28.394 - 28.395 Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) { 28.396 // If class_loader is NULL we synchronize on _system_loader_lock_obj 28.397 if (class_loader.is_null()) { 28.398 @@ -1902,11 +1936,11 @@ 28.399 warning("Cannot find sun/jkernel/DownloadManager"); 28.400 } 28.401 #endif // KERNEL 28.402 + 28.403 { // Compute whether we should use loadClass or loadClassInternal when loading classes. 28.404 methodOop method = instanceKlass::cast(classloader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature()); 28.405 _has_loadClassInternal = (method != NULL); 28.406 } 28.407 - 28.408 { // Compute whether we should use checkPackageAccess or NOT 28.409 methodOop method = instanceKlass::cast(classloader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature()); 28.410 _has_checkPackageAccess = (method != NULL);
29.1 --- a/src/share/vm/classfile/systemDictionary.hpp Thu Jan 29 13:20:56 2009 -0800 29.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jan 30 15:28:00 2009 -0800 29.3 @@ -526,6 +526,7 @@ 29.4 static instanceKlassHandle load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS); 29.5 static Handle compute_loader_lock_object(Handle class_loader, TRAPS); 29.6 static void check_loader_lock_contention(Handle loader_lock, TRAPS); 29.7 + static bool is_parallelCapable(Handle class_loader); 29.8 29.9 static klassOop find_shared_class(symbolHandle class_name); 29.10
30.1 --- a/src/share/vm/classfile/vmSymbols.hpp Thu Jan 29 13:20:56 2009 -0800 30.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jan 30 15:28:00 2009 -0800 30.3 @@ -362,6 +362,7 @@ 30.4 template(class_signature, "Ljava/lang/Class;") \ 30.5 template(string_signature, "Ljava/lang/String;") \ 30.6 template(reference_signature, "Ljava/lang/ref/Reference;") \ 30.7 + template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ 30.8 /* signature symbols needed by intrinsics */ \ 30.9 VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \ 30.10 \ 30.11 @@ -374,6 +375,9 @@ 30.12 /* used by ClassFormatError when class name is not known yet */ \ 30.13 template(unknown_class_name, "<Unknown>") \ 30.14 \ 30.15 + /* used to identify class loaders handling parallel class loading */ \ 30.16 + template(parallelCapable_name, "parallelLockMap;") \ 30.17 + \ 30.18 /* JVM monitoring and management support */ \ 30.19 template(java_lang_StackTraceElement_array, "[Ljava/lang/StackTraceElement;") \ 30.20 template(java_lang_management_ThreadState, "java/lang/management/ThreadState") \
31.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Jan 29 13:20:56 2009 -0800 31.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Jan 30 15:28:00 2009 -0800 31.3 @@ -706,6 +706,30 @@ 31.4 } 31.5 } 31.6 31.7 +// Apply the given closure to each live object in the space 31.8 +// The usage of CompactibleFreeListSpace 31.9 +// by the ConcurrentMarkSweepGeneration for concurrent GC's allows 31.10 +// objects in the space with references to objects that are no longer 31.11 +// valid. For example, an object may reference another object 31.12 +// that has already been sweep up (collected). This method uses 31.13 +// obj_is_alive() to determine whether it is safe to apply the closure to 31.14 +// an object. See obj_is_alive() for details on how liveness of an 31.15 +// object is decided. 31.16 + 31.17 +void CompactibleFreeListSpace::safe_object_iterate(ObjectClosure* blk) { 31.18 + assert_lock_strong(freelistLock()); 31.19 + NOT_PRODUCT(verify_objects_initialized()); 31.20 + HeapWord *cur, *limit; 31.21 + size_t curSize; 31.22 + for (cur = bottom(), limit = end(); cur < limit; 31.23 + cur += curSize) { 31.24 + curSize = block_size(cur); 31.25 + if (block_is_obj(cur) && obj_is_alive(cur)) { 31.26 + blk->do_object(oop(cur)); 31.27 + } 31.28 + } 31.29 +} 31.30 + 31.31 void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr, 31.32 UpwardsObjectClosure* cl) { 31.33 assert_locked(); 31.34 @@ -861,7 +885,9 @@ 31.35 } else { 31.36 // must read from what 'p' points to in each loop. 31.37 klassOop k = ((volatile oopDesc*)p)->klass_or_null(); 31.38 - if (k != NULL && ((oopDesc*)p)->is_parsable()) { 31.39 + if (k != NULL && 31.40 + ((oopDesc*)p)->is_parsable() && 31.41 + ((oopDesc*)p)->is_conc_safe()) { 31.42 assert(k->is_oop(), "Should really be klass oop."); 31.43 oop o = (oop)p; 31.44 assert(o->is_oop(), "Should be an oop");
32.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Thu Jan 29 13:20:56 2009 -0800 32.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Fri Jan 30 15:28:00 2009 -0800 32.3 @@ -481,6 +481,15 @@ 32.4 void oop_iterate(OopClosure* cl); 32.5 32.6 void object_iterate(ObjectClosure* blk); 32.7 + // Apply the closure to each object in the space whose references 32.8 + // point to objects in the heap. The usage of CompactibleFreeListSpace 32.9 + // by the ConcurrentMarkSweepGeneration for concurrent GC's allows 32.10 + // objects in the space with references to objects that are no longer 32.11 + // valid. For example, an object may reference another object 32.12 + // that has already been sweep up (collected). This method uses 32.13 + // obj_is_alive() to determine whether it is safe to iterate of 32.14 + // an object. 32.15 + void safe_object_iterate(ObjectClosure* blk); 32.16 void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl); 32.17 32.18 // Requires that "mr" be entirely within the space.
33.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 29 13:20:56 2009 -0800 33.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Jan 30 15:28:00 2009 -0800 33.3 @@ -3018,6 +3018,16 @@ 33.4 } 33.5 33.6 void 33.7 +ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) { 33.8 + if (freelistLock()->owned_by_self()) { 33.9 + Generation::safe_object_iterate(cl); 33.10 + } else { 33.11 + MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag); 33.12 + Generation::safe_object_iterate(cl); 33.13 + } 33.14 +} 33.15 + 33.16 +void 33.17 ConcurrentMarkSweepGeneration::pre_adjust_pointers() { 33.18 } 33.19 33.20 @@ -6623,7 +6633,11 @@ 33.21 if (_bitMap->isMarked(addr)) { 33.22 // it's marked; is it potentially uninitialized? 33.23 if (p->klass_or_null() != NULL) { 33.24 - if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) { 33.25 + // If is_conc_safe is false, the object may be undergoing 33.26 + // change by the VM outside a safepoint. Don't try to 33.27 + // scan it, but rather leave it for the remark phase. 33.28 + if (CMSPermGenPrecleaningEnabled && 33.29 + (!p->is_conc_safe() || !p->is_parsable())) { 33.30 // Signal precleaning to redirty the card since 33.31 // the klass pointer is already installed. 33.32 assert(size == 0, "Initial value"); 33.33 @@ -7001,7 +7015,6 @@ 33.34 _mut->clear_range(mr); 33.35 } 33.36 DEBUG_ONLY(}) 33.37 - 33.38 // Note: the finger doesn't advance while we drain 33.39 // the stack below. 33.40 PushOrMarkClosure pushOrMarkClosure(_collector, 33.41 @@ -8062,9 +8075,13 @@ 33.42 #ifdef DEBUG 33.43 if (oop(addr)->klass_or_null() != NULL && 33.44 ( !_collector->should_unload_classes() 33.45 - || oop(addr)->is_parsable())) { 33.46 + || (oop(addr)->is_parsable()) && 33.47 + oop(addr)->is_conc_safe())) { 33.48 // Ignore mark word because we are running concurrent with mutators 33.49 assert(oop(addr)->is_oop(true), "live block should be an oop"); 33.50 + // is_conc_safe is checked before performing this assertion 33.51 + // because an object that is not is_conc_safe may yet have 33.52 + // the return from size() correct. 33.53 assert(size == 33.54 CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size()), 33.55 "P-mark and computed size do not agree"); 33.56 @@ -8077,6 +8094,13 @@ 33.57 (!_collector->should_unload_classes() 33.58 || oop(addr)->is_parsable()), 33.59 "Should be an initialized object"); 33.60 + // Note that there are objects used during class redefinition 33.61 + // (e.g., merge_cp in VM_RedefineClasses::merge_cp_and_rewrite() 33.62 + // which are discarded with their is_conc_safe state still 33.63 + // false. These object may be floating garbage so may be 33.64 + // seen here. If they are floating garbage their size 33.65 + // should be attainable from their klass. Do not that 33.66 + // is_conc_safe() is true for oop(addr). 33.67 // Ignore mark word because we are running concurrent with mutators 33.68 assert(oop(addr)->is_oop(true), "live block should be an oop"); 33.69 // Verify that the bit map has no bits marked between 33.70 @@ -8484,7 +8508,7 @@ 33.71 size_t i = num; 33.72 oop cur = _overflow_list; 33.73 const markOop proto = markOopDesc::prototype(); 33.74 - NOT_PRODUCT(size_t n = 0;) 33.75 + NOT_PRODUCT(ssize_t n = 0;) 33.76 for (oop next; i > 0 && cur != NULL; cur = next, i--) { 33.77 next = oop(cur->mark()); 33.78 cur->set_mark(proto); // until proven otherwise 33.79 @@ -8501,45 +8525,131 @@ 33.80 return !stack->isEmpty(); 33.81 } 33.82 33.83 -// Multi-threaded; use CAS to break off a prefix 33.84 +#define BUSY (oop(0x1aff1aff)) 33.85 +// (MT-safe) Get a prefix of at most "num" from the list. 33.86 +// The overflow list is chained through the mark word of 33.87 +// each object in the list. We fetch the entire list, 33.88 +// break off a prefix of the right size and return the 33.89 +// remainder. If other threads try to take objects from 33.90 +// the overflow list at that time, they will wait for 33.91 +// some time to see if data becomes available. If (and 33.92 +// only if) another thread places one or more object(s) 33.93 +// on the global list before we have returned the suffix 33.94 +// to the global list, we will walk down our local list 33.95 +// to find its end and append the global list to 33.96 +// our suffix before returning it. This suffix walk can 33.97 +// prove to be expensive (quadratic in the amount of traffic) 33.98 +// when there are many objects in the overflow list and 33.99 +// there is much producer-consumer contention on the list. 33.100 +// *NOTE*: The overflow list manipulation code here and 33.101 +// in ParNewGeneration:: are very similar in shape, 33.102 +// except that in the ParNew case we use the old (from/eden) 33.103 +// copy of the object to thread the list via its klass word. 33.104 +// Because of the common code, if you make any changes in 33.105 +// the code below, please check the ParNew version to see if 33.106 +// similar changes might be needed. 33.107 +// CR 6797058 has been filed to consolidate the common code. 33.108 bool CMSCollector::par_take_from_overflow_list(size_t num, 33.109 OopTaskQueue* work_q) { 33.110 - assert(work_q->size() == 0, "That's the current policy"); 33.111 + assert(work_q->size() == 0, "First empty local work queue"); 33.112 assert(num < work_q->max_elems(), "Can't bite more than we can chew"); 33.113 if (_overflow_list == NULL) { 33.114 return false; 33.115 } 33.116 // Grab the entire list; we'll put back a suffix 33.117 - oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list); 33.118 - if (prefix == NULL) { // someone grabbed it before we did ... 33.119 - // ... we could spin for a short while, but for now we don't 33.120 - return false; 33.121 - } 33.122 + oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); 33.123 + Thread* tid = Thread::current(); 33.124 + size_t CMSOverflowSpinCount = (size_t)ParallelGCThreads; 33.125 + size_t sleep_time_millis = MAX2((size_t)1, num/100); 33.126 + // If the list is busy, we spin for a short while, 33.127 + // sleeping between attempts to get the list. 33.128 + for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) { 33.129 + os::sleep(tid, sleep_time_millis, false); 33.130 + if (_overflow_list == NULL) { 33.131 + // Nothing left to take 33.132 + return false; 33.133 + } else if (_overflow_list != BUSY) { 33.134 + // Try and grab the prefix 33.135 + prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); 33.136 + } 33.137 + } 33.138 + // If the list was found to be empty, or we spun long 33.139 + // enough, we give up and return empty-handed. If we leave 33.140 + // the list in the BUSY state below, it must be the case that 33.141 + // some other thread holds the overflow list and will set it 33.142 + // to a non-BUSY state in the future. 33.143 + if (prefix == NULL || prefix == BUSY) { 33.144 + // Nothing to take or waited long enough 33.145 + if (prefix == NULL) { 33.146 + // Write back the NULL in case we overwrote it with BUSY above 33.147 + // and it is still the same value. 33.148 + (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); 33.149 + } 33.150 + return false; 33.151 + } 33.152 + assert(prefix != NULL && prefix != BUSY, "Error"); 33.153 size_t i = num; 33.154 oop cur = prefix; 33.155 + // Walk down the first "num" objects, unless we reach the end. 33.156 for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--); 33.157 - if (cur->mark() != NULL) { 33.158 + if (cur->mark() == NULL) { 33.159 + // We have "num" or fewer elements in the list, so there 33.160 + // is nothing to return to the global list. 33.161 + // Write back the NULL in lieu of the BUSY we wrote 33.162 + // above, if it is still the same value. 33.163 + if (_overflow_list == BUSY) { 33.164 + (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); 33.165 + } 33.166 + } else { 33.167 + // Chop off the suffix and rerturn it to the global list. 33.168 + assert(cur->mark() != BUSY, "Error"); 33.169 oop suffix_head = cur->mark(); // suffix will be put back on global list 33.170 cur->set_mark(NULL); // break off suffix 33.171 - // Find tail of suffix so we can prepend suffix to global list 33.172 - for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark())); 33.173 - oop suffix_tail = cur; 33.174 - assert(suffix_tail != NULL && suffix_tail->mark() == NULL, 33.175 - "Tautology"); 33.176 + // It's possible that the list is still in the empty(busy) state 33.177 + // we left it in a short while ago; in that case we may be 33.178 + // able to place back the suffix without incurring the cost 33.179 + // of a walk down the list. 33.180 oop observed_overflow_list = _overflow_list; 33.181 - do { 33.182 - cur = observed_overflow_list; 33.183 - suffix_tail->set_mark(markOop(cur)); 33.184 + oop cur_overflow_list = observed_overflow_list; 33.185 + bool attached = false; 33.186 + while (observed_overflow_list == BUSY || observed_overflow_list == NULL) { 33.187 observed_overflow_list = 33.188 - (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur); 33.189 - } while (cur != observed_overflow_list); 33.190 + (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list); 33.191 + if (cur_overflow_list == observed_overflow_list) { 33.192 + attached = true; 33.193 + break; 33.194 + } else cur_overflow_list = observed_overflow_list; 33.195 + } 33.196 + if (!attached) { 33.197 + // Too bad, someone else sneaked in (at least) an element; we'll need 33.198 + // to do a splice. Find tail of suffix so we can prepend suffix to global 33.199 + // list. 33.200 + for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark())); 33.201 + oop suffix_tail = cur; 33.202 + assert(suffix_tail != NULL && suffix_tail->mark() == NULL, 33.203 + "Tautology"); 33.204 + observed_overflow_list = _overflow_list; 33.205 + do { 33.206 + cur_overflow_list = observed_overflow_list; 33.207 + if (cur_overflow_list != BUSY) { 33.208 + // Do the splice ... 33.209 + suffix_tail->set_mark(markOop(cur_overflow_list)); 33.210 + } else { // cur_overflow_list == BUSY 33.211 + suffix_tail->set_mark(NULL); 33.212 + } 33.213 + // ... and try to place spliced list back on overflow_list ... 33.214 + observed_overflow_list = 33.215 + (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list); 33.216 + } while (cur_overflow_list != observed_overflow_list); 33.217 + // ... until we have succeeded in doing so. 33.218 + } 33.219 } 33.220 33.221 // Push the prefix elements on work_q 33.222 assert(prefix != NULL, "control point invariant"); 33.223 const markOop proto = markOopDesc::prototype(); 33.224 oop next; 33.225 - NOT_PRODUCT(size_t n = 0;) 33.226 + NOT_PRODUCT(ssize_t n = 0;) 33.227 for (cur = prefix; cur != NULL; cur = next) { 33.228 next = oop(cur->mark()); 33.229 cur->set_mark(proto); // until proven otherwise 33.230 @@ -8573,11 +8683,16 @@ 33.231 oop cur_overflow_list; 33.232 do { 33.233 cur_overflow_list = observed_overflow_list; 33.234 - p->set_mark(markOop(cur_overflow_list)); 33.235 + if (cur_overflow_list != BUSY) { 33.236 + p->set_mark(markOop(cur_overflow_list)); 33.237 + } else { 33.238 + p->set_mark(NULL); 33.239 + } 33.240 observed_overflow_list = 33.241 (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list); 33.242 } while (cur_overflow_list != observed_overflow_list); 33.243 } 33.244 +#undef BUSY 33.245 33.246 // Single threaded 33.247 // General Note on GrowableArray: pushes may silently fail 33.248 @@ -8586,7 +8701,7 @@ 33.249 // a lot of code in the JVM. The prudent thing for GrowableArray 33.250 // to do (for now) is to exit with an error. However, that may 33.251 // be too draconian in some cases because the caller may be 33.252 -// able to recover without much harm. For suych cases, we 33.253 +// able to recover without much harm. For such cases, we 33.254 // should probably introduce a "soft_push" method which returns 33.255 // an indication of success or failure with the assumption that 33.256 // the caller may be able to recover from a failure; code in 33.257 @@ -8594,8 +8709,6 @@ 33.258 // failures where possible, thus, incrementally hardening the VM 33.259 // in such low resource situations. 33.260 void CMSCollector::preserve_mark_work(oop p, markOop m) { 33.261 - int PreserveMarkStackSize = 128; 33.262 - 33.263 if (_preserved_oop_stack == NULL) { 33.264 assert(_preserved_mark_stack == NULL, 33.265 "bijection with preserved_oop_stack");
34.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Jan 29 13:20:56 2009 -0800 34.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Jan 30 15:28:00 2009 -0800 34.3 @@ -595,7 +595,7 @@ 34.4 size_t _ser_kac_preclean_ovflw; 34.5 size_t _ser_kac_ovflw; 34.6 size_t _par_kac_ovflw; 34.7 - NOT_PRODUCT(size_t _num_par_pushes;) 34.8 + NOT_PRODUCT(ssize_t _num_par_pushes;) 34.9 34.10 // ("Weak") Reference processing support 34.11 ReferenceProcessor* _ref_processor; 34.12 @@ -1212,6 +1212,7 @@ 34.13 // More iteration support 34.14 virtual void oop_iterate(MemRegion mr, OopClosure* cl); 34.15 virtual void oop_iterate(OopClosure* cl); 34.16 + virtual void safe_object_iterate(ObjectClosure* cl); 34.17 virtual void object_iterate(ObjectClosure* cl); 34.18 34.19 // Need to declare the full complement of closures, whether we'll
35.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 29 13:20:56 2009 -0800 35.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jan 30 15:28:00 2009 -0800 35.3 @@ -1285,7 +1285,9 @@ 35.4 _unclean_regions_coming(false), 35.5 _young_list(new YoungList(this)), 35.6 _gc_time_stamp(0), 35.7 - _surviving_young_words(NULL) 35.8 + _surviving_young_words(NULL), 35.9 + _in_cset_fast_test(NULL), 35.10 + _in_cset_fast_test_base(NULL) 35.11 { 35.12 _g1h = this; // To catch bugs. 35.13 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 35.14 @@ -2485,6 +2487,19 @@ 35.15 g1_policy()->record_collection_pause_start(start_time_sec, 35.16 start_used_bytes); 35.17 35.18 + guarantee(_in_cset_fast_test == NULL, "invariant"); 35.19 + guarantee(_in_cset_fast_test_base == NULL, "invariant"); 35.20 + _in_cset_fast_test_length = n_regions(); 35.21 + _in_cset_fast_test_base = 35.22 + NEW_C_HEAP_ARRAY(bool, _in_cset_fast_test_length); 35.23 + memset(_in_cset_fast_test_base, false, 35.24 + _in_cset_fast_test_length * sizeof(bool)); 35.25 + // We're biasing _in_cset_fast_test to avoid subtracting the 35.26 + // beginning of the heap every time we want to index; basically 35.27 + // it's the same with what we do with the card table. 35.28 + _in_cset_fast_test = _in_cset_fast_test_base - 35.29 + ((size_t) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes); 35.30 + 35.31 #if SCAN_ONLY_VERBOSE 35.32 _young_list->print(); 35.33 #endif // SCAN_ONLY_VERBOSE 35.34 @@ -2553,6 +2568,12 @@ 35.35 free_collection_set(g1_policy()->collection_set()); 35.36 g1_policy()->clear_collection_set(); 35.37 35.38 + FREE_C_HEAP_ARRAY(bool, _in_cset_fast_test_base); 35.39 + // this is more for peace of mind; we're nulling them here and 35.40 + // we're expecting them to be null at the beginning of the next GC 35.41 + _in_cset_fast_test = NULL; 35.42 + _in_cset_fast_test_base = NULL; 35.43 + 35.44 if (popular_region != NULL) { 35.45 // We have to wait until now, because we don't want the region to 35.46 // be rescheduled for pop-evac during RS update. 35.47 @@ -3560,6 +3581,9 @@ 35.48 size_t undo_waste() { return _undo_waste; } 35.49 35.50 void push_on_queue(oop* ref) { 35.51 + assert(ref != NULL, "invariant"); 35.52 + assert(has_partial_array_mask(ref) || _g1h->obj_in_cs(*ref), "invariant"); 35.53 + 35.54 if (!refs()->push(ref)) { 35.55 overflowed_refs()->push(ref); 35.56 IF_G1_DETAILED_STATS(note_overflow_push()); 35.57 @@ -3572,6 +3596,10 @@ 35.58 if (!refs()->pop_local(ref)) { 35.59 ref = NULL; 35.60 } else { 35.61 + assert(ref != NULL, "invariant"); 35.62 + assert(has_partial_array_mask(ref) || _g1h->obj_in_cs(*ref), 35.63 + "invariant"); 35.64 + 35.65 IF_G1_DETAILED_STATS(note_pop()); 35.66 } 35.67 } 35.68 @@ -3601,8 +3629,7 @@ 35.69 35.70 obj = alloc_buf->allocate(word_sz); 35.71 assert(obj != NULL, "buffer was definitely big enough..."); 35.72 - } 35.73 - else { 35.74 + } else { 35.75 obj = _g1h->par_allocate_during_gc(purpose, word_sz); 35.76 } 35.77 return obj; 35.78 @@ -3695,24 +3722,57 @@ 35.79 } 35.80 } 35.81 35.82 +private: 35.83 + void deal_with_reference(oop* ref_to_scan) { 35.84 + if (has_partial_array_mask(ref_to_scan)) { 35.85 + _partial_scan_cl->do_oop_nv(ref_to_scan); 35.86 + } else { 35.87 + // Note: we can use "raw" versions of "region_containing" because 35.88 + // "obj_to_scan" is definitely in the heap, and is not in a 35.89 + // humongous region. 35.90 + HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan); 35.91 + _evac_cl->set_region(r); 35.92 + _evac_cl->do_oop_nv(ref_to_scan); 35.93 + } 35.94 + } 35.95 + 35.96 +public: 35.97 void trim_queue() { 35.98 + // I've replicated the loop twice, first to drain the overflow 35.99 + // queue, second to drain the task queue. This is better than 35.100 + // having a single loop, which checks both conditions and, inside 35.101 + // it, either pops the overflow queue or the task queue, as each 35.102 + // loop is tighter. Also, the decision to drain the overflow queue 35.103 + // first is not arbitrary, as the overflow queue is not visible 35.104 + // to the other workers, whereas the task queue is. So, we want to 35.105 + // drain the "invisible" entries first, while allowing the other 35.106 + // workers to potentially steal the "visible" entries. 35.107 + 35.108 while (refs_to_scan() > 0 || overflowed_refs_to_scan() > 0) { 35.109 - oop *ref_to_scan = NULL; 35.110 - if (overflowed_refs_to_scan() == 0) { 35.111 + while (overflowed_refs_to_scan() > 0) { 35.112 + oop *ref_to_scan = NULL; 35.113 + pop_from_overflow_queue(ref_to_scan); 35.114 + assert(ref_to_scan != NULL, "invariant"); 35.115 + // We shouldn't have pushed it on the queue if it was not 35.116 + // pointing into the CSet. 35.117 + assert(ref_to_scan != NULL, "sanity"); 35.118 + assert(has_partial_array_mask(ref_to_scan) || 35.119 + _g1h->obj_in_cs(*ref_to_scan), "sanity"); 35.120 + 35.121 + deal_with_reference(ref_to_scan); 35.122 + } 35.123 + 35.124 + while (refs_to_scan() > 0) { 35.125 + oop *ref_to_scan = NULL; 35.126 pop_from_queue(ref_to_scan); 35.127 - } else { 35.128 - pop_from_overflow_queue(ref_to_scan); 35.129 - } 35.130 - if (ref_to_scan != NULL) { 35.131 - if ((intptr_t)ref_to_scan & G1_PARTIAL_ARRAY_MASK) { 35.132 - _partial_scan_cl->do_oop_nv(ref_to_scan); 35.133 - } else { 35.134 - // Note: we can use "raw" versions of "region_containing" because 35.135 - // "obj_to_scan" is definitely in the heap, and is not in a 35.136 - // humongous region. 35.137 - HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan); 35.138 - _evac_cl->set_region(r); 35.139 - _evac_cl->do_oop_nv(ref_to_scan); 35.140 + 35.141 + if (ref_to_scan != NULL) { 35.142 + // We shouldn't have pushed it on the queue if it was not 35.143 + // pointing into the CSet. 35.144 + assert(has_partial_array_mask(ref_to_scan) || 35.145 + _g1h->obj_in_cs(*ref_to_scan), "sanity"); 35.146 + 35.147 + deal_with_reference(ref_to_scan); 35.148 } 35.149 } 35.150 } 35.151 @@ -3728,16 +3788,25 @@ 35.152 // Should probably be made inline and moved in g1OopClosures.inline.hpp. 35.153 void G1ParScanClosure::do_oop_nv(oop* p) { 35.154 oop obj = *p; 35.155 + 35.156 if (obj != NULL) { 35.157 - if (_g1->obj_in_cs(obj)) { 35.158 - if (obj->is_forwarded()) { 35.159 - *p = obj->forwardee(); 35.160 - } else { 35.161 - _par_scan_state->push_on_queue(p); 35.162 - return; 35.163 - } 35.164 + if (_g1->in_cset_fast_test(obj)) { 35.165 + // We're not going to even bother checking whether the object is 35.166 + // already forwarded or not, as this usually causes an immediate 35.167 + // stall. We'll try to prefetch the object (for write, given that 35.168 + // we might need to install the forwarding reference) and we'll 35.169 + // get back to it when pop it from the queue 35.170 + Prefetch::write(obj->mark_addr(), 0); 35.171 + Prefetch::read(obj->mark_addr(), (HeapWordSize*2)); 35.172 + 35.173 + // slightly paranoid test; I'm trying to catch potential 35.174 + // problems before we go into push_on_queue to know where the 35.175 + // problem is coming from 35.176 + assert(obj == *p, "the value of *p should not have changed"); 35.177 + _par_scan_state->push_on_queue(p); 35.178 + } else { 35.179 + _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num()); 35.180 } 35.181 - _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num()); 35.182 } 35.183 } 35.184 35.185 @@ -3777,13 +3846,36 @@ 35.186 return _g1->handle_evacuation_failure_par(cl, old); 35.187 } 35.188 35.189 + // We're going to allocate linearly, so might as well prefetch ahead. 35.190 + Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); 35.191 + 35.192 oop forward_ptr = old->forward_to_atomic(obj); 35.193 if (forward_ptr == NULL) { 35.194 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); 35.195 + if (g1p->track_object_age(alloc_purpose)) { 35.196 + // We could simply do obj->incr_age(). However, this causes a 35.197 + // performance issue. obj->incr_age() will first check whether 35.198 + // the object has a displaced mark by checking its mark word; 35.199 + // getting the mark word from the new location of the object 35.200 + // stalls. So, given that we already have the mark word and we 35.201 + // are about to install it anyway, it's better to increase the 35.202 + // age on the mark word, when the object does not have a 35.203 + // displaced mark word. We're not expecting many objects to have 35.204 + // a displaced marked word, so that case is not optimized 35.205 + // further (it could be...) and we simply call obj->incr_age(). 35.206 + 35.207 + if (m->has_displaced_mark_helper()) { 35.208 + // in this case, we have to install the mark word first, 35.209 + // otherwise obj looks to be forwarded (the old mark word, 35.210 + // which contains the forward pointer, was copied) 35.211 + obj->set_mark(m); 35.212 + obj->incr_age(); 35.213 + } else { 35.214 + m = m->incr_age(); 35.215 + } 35.216 + } 35.217 obj->set_mark(m); 35.218 - if (g1p->track_object_age(alloc_purpose)) { 35.219 - obj->incr_age(); 35.220 - } 35.221 + 35.222 // preserve "next" mark bit 35.223 if (_g1->mark_in_progress() && !_g1->is_obj_ill(old)) { 35.224 if (!use_local_bitmaps || 35.225 @@ -3805,9 +3897,11 @@ 35.226 35.227 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { 35.228 arrayOop(old)->set_length(0); 35.229 - _par_scan_state->push_on_queue((oop*) ((intptr_t)old | G1_PARTIAL_ARRAY_MASK)); 35.230 + _par_scan_state->push_on_queue(set_partial_array_mask(old)); 35.231 } else { 35.232 - _scanner->set_region(_g1->heap_region_containing(obj)); 35.233 + // No point in using the slower heap_region_containing() method, 35.234 + // given that we know obj is in the heap. 35.235 + _scanner->set_region(_g1->heap_region_containing_raw(obj)); 35.236 obj->oop_iterate_backwards(_scanner); 35.237 } 35.238 } else { 35.239 @@ -3817,47 +3911,55 @@ 35.240 return obj; 35.241 } 35.242 35.243 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee> 35.244 -void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_forwardee>::do_oop_work(oop* p) { 35.245 +template<bool do_gen_barrier, G1Barrier barrier, 35.246 + bool do_mark_forwardee, bool skip_cset_test> 35.247 +void G1ParCopyClosure<do_gen_barrier, barrier, 35.248 + do_mark_forwardee, skip_cset_test>::do_oop_work(oop* p) { 35.249 oop obj = *p; 35.250 assert(barrier != G1BarrierRS || obj != NULL, 35.251 "Precondition: G1BarrierRS implies obj is nonNull"); 35.252 35.253 - if (obj != NULL) { 35.254 - if (_g1->obj_in_cs(obj)) { 35.255 + // The only time we skip the cset test is when we're scanning 35.256 + // references popped from the queue. And we only push on the queue 35.257 + // references that we know point into the cset, so no point in 35.258 + // checking again. But we'll leave an assert here for peace of mind. 35.259 + assert(!skip_cset_test || _g1->obj_in_cs(obj), "invariant"); 35.260 + 35.261 + // here the null check is implicit in the cset_fast_test() test 35.262 + if (skip_cset_test || _g1->in_cset_fast_test(obj)) { 35.263 #if G1_REM_SET_LOGGING 35.264 - gclog_or_tty->print_cr("Loc "PTR_FORMAT" contains pointer "PTR_FORMAT" into CS.", 35.265 - p, (void*) obj); 35.266 + gclog_or_tty->print_cr("Loc "PTR_FORMAT" contains pointer "PTR_FORMAT" " 35.267 + "into CS.", p, (void*) obj); 35.268 #endif 35.269 - if (obj->is_forwarded()) { 35.270 - *p = obj->forwardee(); 35.271 - } else { 35.272 - *p = copy_to_survivor_space(obj); 35.273 - } 35.274 - // When scanning the RS, we only care about objs in CS. 35.275 - if (barrier == G1BarrierRS) { 35.276 - _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num()); 35.277 - } 35.278 + if (obj->is_forwarded()) { 35.279 + *p = obj->forwardee(); 35.280 + } else { 35.281 + *p = copy_to_survivor_space(obj); 35.282 } 35.283 - // When scanning moved objs, must look at all oops. 35.284 - if (barrier == G1BarrierEvac) { 35.285 + // When scanning the RS, we only care about objs in CS. 35.286 + if (barrier == G1BarrierRS) { 35.287 _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num()); 35.288 } 35.289 - 35.290 - if (do_gen_barrier) { 35.291 - par_do_barrier(p); 35.292 - } 35.293 - } 35.294 -} 35.295 - 35.296 -template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); 35.297 - 35.298 -template <class T> void G1ParScanPartialArrayClosure::process_array_chunk( 35.299 + } 35.300 + 35.301 + // When scanning moved objs, must look at all oops. 35.302 + if (barrier == G1BarrierEvac && obj != NULL) { 35.303 + _g1_rem->par_write_ref(_from, p, _par_scan_state->queue_num()); 35.304 + } 35.305 + 35.306 + if (do_gen_barrier && obj != NULL) { 35.307 + par_do_barrier(p); 35.308 + } 35.309 +} 35.310 + 35.311 +template void G1ParCopyClosure<false, G1BarrierEvac, false, true>::do_oop_work(oop* p); 35.312 + 35.313 +template<class T> void G1ParScanPartialArrayClosure::process_array_chunk( 35.314 oop obj, int start, int end) { 35.315 // process our set of indices (include header in first chunk) 35.316 assert(start < end, "invariant"); 35.317 T* const base = (T*)objArrayOop(obj)->base(); 35.318 - T* const start_addr = base + start; 35.319 + T* const start_addr = (start == 0) ? (T*) obj : base + start; 35.320 T* const end_addr = base + end; 35.321 MemRegion mr((HeapWord*)start_addr, (HeapWord*)end_addr); 35.322 _scanner.set_region(_g1->heap_region_containing(obj)); 35.323 @@ -3866,7 +3968,8 @@ 35.324 35.325 void G1ParScanPartialArrayClosure::do_oop_nv(oop* p) { 35.326 assert(!UseCompressedOops, "Needs to be fixed to work with compressed oops"); 35.327 - oop old = oop((intptr_t)p & ~G1_PARTIAL_ARRAY_MASK); 35.328 + assert(has_partial_array_mask(p), "invariant"); 35.329 + oop old = clear_partial_array_mask(p); 35.330 assert(old->is_objArray(), "must be obj array"); 35.331 assert(old->is_forwarded(), "must be forwarded"); 35.332 assert(Universe::heap()->is_in_reserved(old), "must be in heap."); 35.333 @@ -3884,7 +3987,7 @@ 35.334 end = start + ParGCArrayScanChunk; 35.335 arrayOop(old)->set_length(end); 35.336 // Push remainder. 35.337 - _par_scan_state->push_on_queue((oop*) ((intptr_t) old | G1_PARTIAL_ARRAY_MASK)); 35.338 + _par_scan_state->push_on_queue(set_partial_array_mask(old)); 35.339 } else { 35.340 // Restore length so that the heap remains parsable in 35.341 // case of evacuation failure. 35.342 @@ -3893,11 +3996,6 @@ 35.343 35.344 // process our set of indices (include header in first chunk) 35.345 process_array_chunk<oop>(obj, start, end); 35.346 - oop* start_addr = start == 0 ? (oop*)obj : obj->obj_at_addr<oop>(start); 35.347 - oop* end_addr = (oop*)(obj->base()) + end; // obj_at_addr(end) asserts end < length 35.348 - MemRegion mr((HeapWord*)start_addr, (HeapWord*)end_addr); 35.349 - _scanner.set_region(_g1->heap_region_containing(obj)); 35.350 - obj->oop_iterate(&_scanner, mr); 35.351 } 35.352 35.353 int G1ScanAndBalanceClosure::_nq = 0; 35.354 @@ -3931,6 +4029,13 @@ 35.355 pss->hash_seed(), 35.356 ref_to_scan)) { 35.357 IF_G1_DETAILED_STATS(pss->note_steal()); 35.358 + 35.359 + // slightly paranoid tests; I'm trying to catch potential 35.360 + // problems before we go into push_on_queue to know where the 35.361 + // problem is coming from 35.362 + assert(ref_to_scan != NULL, "invariant"); 35.363 + assert(has_partial_array_mask(ref_to_scan) || 35.364 + _g1h->obj_in_cs(*ref_to_scan), "invariant"); 35.365 pss->push_on_queue(ref_to_scan); 35.366 continue; 35.367 } 35.368 @@ -3976,10 +4081,10 @@ 35.369 ResourceMark rm; 35.370 HandleMark hm; 35.371 35.372 - G1ParScanThreadState pss(_g1h, i); 35.373 - G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss); 35.374 - G1ParScanHeapEvacClosure evac_failure_cl(_g1h, &pss); 35.375 - G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss); 35.376 + G1ParScanThreadState pss(_g1h, i); 35.377 + G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss); 35.378 + G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss); 35.379 + G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss); 35.380 35.381 pss.set_evac_closure(&scan_evac_cl); 35.382 pss.set_evac_failure_closure(&evac_failure_cl);
36.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 29 13:20:56 2009 -0800 36.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Jan 30 15:28:00 2009 -0800 36.3 @@ -247,6 +247,27 @@ 36.4 NumberSeq _pop_obj_rc_at_copy; 36.5 void print_popularity_summary_info() const; 36.6 36.7 + // This is used for a quick test on whether a reference points into 36.8 + // the collection set or not. Basically, we have an array, with one 36.9 + // byte per region, and that byte denotes whether the corresponding 36.10 + // region is in the collection set or not. The entry corresponding 36.11 + // the bottom of the heap, i.e., region 0, is pointed to by 36.12 + // _in_cset_fast_test_base. The _in_cset_fast_test field has been 36.13 + // biased so that it actually points to address 0 of the address 36.14 + // space, to make the test as fast as possible (we can simply shift 36.15 + // the address to address into it, instead of having to subtract the 36.16 + // bottom of the heap from the address before shifting it; basically 36.17 + // it works in the same way the card table works). 36.18 + bool* _in_cset_fast_test; 36.19 + 36.20 + // The allocated array used for the fast test on whether a reference 36.21 + // points into the collection set or not. This field is also used to 36.22 + // free the array. 36.23 + bool* _in_cset_fast_test_base; 36.24 + 36.25 + // The length of the _in_cset_fast_test_base array. 36.26 + size_t _in_cset_fast_test_length; 36.27 + 36.28 volatile unsigned _gc_time_stamp; 36.29 36.30 size_t* _surviving_young_words; 36.31 @@ -368,6 +389,38 @@ 36.32 virtual void gc_prologue(bool full); 36.33 virtual void gc_epilogue(bool full); 36.34 36.35 + // We register a region with the fast "in collection set" test. We 36.36 + // simply set to true the array slot corresponding to this region. 36.37 + void register_region_with_in_cset_fast_test(HeapRegion* r) { 36.38 + assert(_in_cset_fast_test_base != NULL, "sanity"); 36.39 + assert(r->in_collection_set(), "invariant"); 36.40 + int index = r->hrs_index(); 36.41 + assert(0 <= (size_t) index && (size_t) index < _in_cset_fast_test_length, 36.42 + "invariant"); 36.43 + assert(!_in_cset_fast_test_base[index], "invariant"); 36.44 + _in_cset_fast_test_base[index] = true; 36.45 + } 36.46 + 36.47 + // This is a fast test on whether a reference points into the 36.48 + // collection set or not. It does not assume that the reference 36.49 + // points into the heap; if it doesn't, it will return false. 36.50 + bool in_cset_fast_test(oop obj) { 36.51 + assert(_in_cset_fast_test != NULL, "sanity"); 36.52 + if (_g1_committed.contains((HeapWord*) obj)) { 36.53 + // no need to subtract the bottom of the heap from obj, 36.54 + // _in_cset_fast_test is biased 36.55 + size_t index = ((size_t) obj) >> HeapRegion::LogOfHRGrainBytes; 36.56 + bool ret = _in_cset_fast_test[index]; 36.57 + // let's make sure the result is consistent with what the slower 36.58 + // test returns 36.59 + assert( ret || !obj_in_cs(obj), "sanity"); 36.60 + assert(!ret || obj_in_cs(obj), "sanity"); 36.61 + return ret; 36.62 + } else { 36.63 + return false; 36.64 + } 36.65 + } 36.66 + 36.67 protected: 36.68 36.69 // Shrink the garbage-first heap by at most the given size (in bytes!). 36.70 @@ -850,6 +903,7 @@ 36.71 36.72 // Iterate over all objects, calling "cl.do_object" on each. 36.73 virtual void object_iterate(ObjectClosure* cl); 36.74 + virtual void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); } 36.75 36.76 // Iterate over all objects allocated since the last collection, calling 36.77 // "cl.do_object" on each. The heap must have been initialized properly
37.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Thu Jan 29 13:20:56 2009 -0800 37.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Fri Jan 30 15:28:00 2009 -0800 37.3 @@ -36,8 +36,11 @@ 37.4 37.5 inline HeapRegion* 37.6 G1CollectedHeap::heap_region_containing_raw(const void* addr) const { 37.7 - HeapRegion* res = _hrs->addr_to_region(addr); 37.8 - assert(res != NULL, "addr outside of heap?"); 37.9 + assert(_g1_reserved.contains(addr), "invariant"); 37.10 + size_t index = ((intptr_t) addr - (intptr_t) _g1_reserved.start()) 37.11 + >> HeapRegion::LogOfHRGrainBytes; 37.12 + HeapRegion* res = _hrs->at(index); 37.13 + assert(res == _hrs->addr_to_region(addr), "sanity"); 37.14 return res; 37.15 } 37.16
38.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Jan 29 13:20:56 2009 -0800 38.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jan 30 15:28:00 2009 -0800 38.3 @@ -2985,6 +2985,7 @@ 38.4 _collection_set = hr; 38.5 _collection_set_size++; 38.6 _collection_set_bytes_used_before += hr->used(); 38.7 + _g1->register_region_with_in_cset_fast_test(hr); 38.8 } 38.9 38.10 void
39.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Thu Jan 29 13:20:56 2009 -0800 39.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Fri Jan 30 15:28:00 2009 -0800 39.3 @@ -77,6 +77,18 @@ 39.4 39.5 #define G1_PARTIAL_ARRAY_MASK 1 39.6 39.7 +inline bool has_partial_array_mask(oop* ref) { 39.8 + return (intptr_t) ref & G1_PARTIAL_ARRAY_MASK; 39.9 +} 39.10 + 39.11 +inline oop* set_partial_array_mask(oop obj) { 39.12 + return (oop*) ((intptr_t) obj | G1_PARTIAL_ARRAY_MASK); 39.13 +} 39.14 + 39.15 +inline oop clear_partial_array_mask(oop* ref) { 39.16 + return oop((intptr_t) ref & ~G1_PARTIAL_ARRAY_MASK); 39.17 +} 39.18 + 39.19 class G1ParScanPartialArrayClosure : public G1ParClosureSuper { 39.20 G1ParScanClosure _scanner; 39.21 template <class T> void process_array_chunk(oop obj, int start, int end); 39.22 @@ -101,7 +113,8 @@ 39.23 G1ParClosureSuper(g1, par_scan_state), _scanner(scanner) { } 39.24 }; 39.25 39.26 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee> 39.27 +template<bool do_gen_barrier, G1Barrier barrier, 39.28 + bool do_mark_forwardee, bool skip_cset_test> 39.29 class G1ParCopyClosure : public G1ParCopyHelper { 39.30 G1ParScanClosure _scanner; 39.31 void do_oop_work(oop* p); 39.32 @@ -119,14 +132,22 @@ 39.33 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } 39.34 }; 39.35 39.36 -typedef G1ParCopyClosure<false, G1BarrierNone, false> G1ParScanExtRootClosure; 39.37 -typedef G1ParCopyClosure<true, G1BarrierNone, false> G1ParScanPermClosure; 39.38 -typedef G1ParCopyClosure<false, G1BarrierNone, true> G1ParScanAndMarkExtRootClosure; 39.39 -typedef G1ParCopyClosure<true, G1BarrierNone, true> G1ParScanAndMarkPermClosure; 39.40 -typedef G1ParCopyClosure<false, G1BarrierRS, false> G1ParScanHeapRSClosure; 39.41 -typedef G1ParCopyClosure<false, G1BarrierRS, true> G1ParScanAndMarkHeapRSClosure; 39.42 -typedef G1ParCopyClosure<false, G1BarrierEvac, false> G1ParScanHeapEvacClosure; 39.43 - 39.44 +typedef G1ParCopyClosure<false, G1BarrierNone, false, false> G1ParScanExtRootClosure; 39.45 +typedef G1ParCopyClosure<true, G1BarrierNone, false, false> G1ParScanPermClosure; 39.46 +typedef G1ParCopyClosure<false, G1BarrierNone, true, false> G1ParScanAndMarkExtRootClosure; 39.47 +typedef G1ParCopyClosure<true, G1BarrierNone, true, false> G1ParScanAndMarkPermClosure; 39.48 +typedef G1ParCopyClosure<false, G1BarrierRS, false, false> G1ParScanHeapRSClosure; 39.49 +typedef G1ParCopyClosure<false, G1BarrierRS, true, false> G1ParScanAndMarkHeapRSClosure; 39.50 +// This is the only case when we set skip_cset_test. Basically, this 39.51 +// closure is (should?) only be called directly while we're draining 39.52 +// the overflow and task queues. In that case we know that the 39.53 +// reference in question points into the collection set, otherwise we 39.54 +// would not have pushed it on the queue. 39.55 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, true> G1ParScanHeapEvacClosure; 39.56 +// We need a separate closure to handle references during evacuation 39.57 +// failure processing, as it cannot asume that the reference already 39.58 + // points to the collection set (like G1ParScanHeapEvacClosure does). 39.59 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, false> G1ParScanHeapEvacFailureClosure; 39.60 39.61 class FilterIntoCSClosure: public OopClosure { 39.62 G1CollectedHeap* _g1;
40.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Jan 29 13:20:56 2009 -0800 40.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Jan 30 15:28:00 2009 -0800 40.3 @@ -28,7 +28,7 @@ 40.4 40.5 #define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \ 40.6 \ 40.7 - product(intx, ParallelGCG1AllocBufferSize, 4*K, \ 40.8 + product(intx, ParallelGCG1AllocBufferSize, 8*K, \ 40.9 "Size of parallel G1 allocation buffers in to-space.") \ 40.10 \ 40.11 product(intx, G1TimeSliceMS, 500, \
41.1 --- a/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Thu Jan 29 13:20:56 2009 -0800 41.2 +++ b/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp Fri Jan 30 15:28:00 2009 -0800 41.3 @@ -32,11 +32,13 @@ 41.4 G1BarrierNone, G1BarrierRS, G1BarrierEvac 41.5 }; 41.6 41.7 -template<bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee> 41.8 +template<bool do_gen_barrier, G1Barrier barrier, 41.9 + bool do_mark_forwardee, bool skip_cset_test> 41.10 class G1ParCopyClosure; 41.11 class G1ParScanClosure; 41.12 41.13 -typedef G1ParCopyClosure<false, G1BarrierEvac, false> G1ParScanHeapEvacClosure; 41.14 +typedef G1ParCopyClosure<false, G1BarrierEvac, false, true> 41.15 + G1ParScanHeapEvacClosure; 41.16 41.17 class FilterIntoCSClosure; 41.18 class FilterOutOfRegionClosure;
42.1 --- a/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep Thu Jan 29 13:20:56 2009 -0800 42.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep Fri Jan 30 15:28:00 2009 -0800 42.3 @@ -28,6 +28,7 @@ 42.4 binaryTreeDictionary.cpp binaryTreeDictionary.hpp 42.5 binaryTreeDictionary.cpp globals.hpp 42.6 binaryTreeDictionary.cpp ostream.hpp 42.7 +binaryTreeDictionary.cpp space.inline.hpp 42.8 binaryTreeDictionary.cpp spaceDecorator.hpp 42.9 42.10 binaryTreeDictionary.hpp freeBlockDictionary.hpp
43.1 --- a/src/share/vm/gc_implementation/includeDB_gc_g1 Thu Jan 29 13:20:56 2009 -0800 43.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_g1 Fri Jan 30 15:28:00 2009 -0800 43.3 @@ -31,9 +31,10 @@ 43.4 cardTableRS.cpp concurrentMark.hpp 43.5 cardTableRS.cpp g1SATBCardTableModRefBS.hpp 43.6 43.7 -collectionSetChooser.cpp g1CollectedHeap.hpp 43.8 +collectionSetChooser.cpp g1CollectedHeap.inline.hpp 43.9 collectionSetChooser.cpp g1CollectorPolicy.hpp 43.10 collectionSetChooser.cpp collectionSetChooser.hpp 43.11 +collectionSetChooser.cpp space.inline.hpp 43.12 43.13 collectionSetChooser.hpp heapRegion.hpp 43.14 collectionSetChooser.hpp growableArray.hpp 43.15 @@ -42,14 +43,15 @@ 43.16 concurrentG1Refine.cpp concurrentG1Refine.hpp 43.17 concurrentG1Refine.cpp concurrentG1RefineThread.hpp 43.18 concurrentG1Refine.cpp copy.hpp 43.19 -concurrentG1Refine.cpp g1CollectedHeap.hpp 43.20 +concurrentG1Refine.cpp g1CollectedHeap.inline.hpp 43.21 concurrentG1Refine.cpp g1RemSet.hpp 43.22 +concurrentG1Refine.cpp space.inline.hpp 43.23 43.24 concurrentG1Refine.hpp globalDefinitions.hpp 43.25 43.26 concurrentG1RefineThread.cpp concurrentG1Refine.hpp 43.27 concurrentG1RefineThread.cpp concurrentG1RefineThread.hpp 43.28 -concurrentG1RefineThread.cpp g1CollectedHeap.hpp 43.29 +concurrentG1RefineThread.cpp g1CollectedHeap.inline.hpp 43.30 concurrentG1RefineThread.cpp g1CollectorPolicy.hpp 43.31 concurrentG1RefineThread.cpp handles.inline.hpp 43.32 concurrentG1RefineThread.cpp mutexLocker.hpp 43.33 @@ -166,7 +168,7 @@ 43.34 g1CollectorPolicy.cpp concurrentMarkThread.inline.hpp 43.35 g1CollectorPolicy.cpp debug.hpp 43.36 g1CollectorPolicy.cpp java.hpp 43.37 -g1CollectorPolicy.cpp g1CollectedHeap.hpp 43.38 +g1CollectorPolicy.cpp g1CollectedHeap.inline.hpp 43.39 g1CollectorPolicy.cpp g1CollectorPolicy.hpp 43.40 g1CollectorPolicy.cpp heapRegionRemSet.hpp 43.41 g1CollectorPolicy.cpp mutexLocker.hpp 43.42 @@ -187,7 +189,7 @@ 43.43 g1MarkSweep.cpp codeCache.hpp 43.44 g1MarkSweep.cpp events.hpp 43.45 g1MarkSweep.cpp fprofiler.hpp 43.46 -g1MarkSweep.hpp g1CollectedHeap.hpp 43.47 +g1MarkSweep.hpp g1CollectedHeap.inline.hpp 43.48 g1MarkSweep.cpp g1MarkSweep.hpp 43.49 g1MarkSweep.cpp gcLocker.hpp 43.50 g1MarkSweep.cpp genCollectedHeap.hpp 43.51 @@ -264,7 +266,7 @@ 43.52 heapRegion.cpp iterator.hpp 43.53 heapRegion.cpp oop.inline.hpp 43.54 43.55 -heapRegion.hpp space.hpp 43.56 +heapRegion.hpp space.inline.hpp 43.57 heapRegion.hpp spaceDecorator.hpp 43.58 heapRegion.hpp g1BlockOffsetTable.inline.hpp 43.59 heapRegion.hpp watermark.hpp 43.60 @@ -283,7 +285,7 @@ 43.61 heapRegionRemSet.cpp space.inline.hpp 43.62 43.63 heapRegionSeq.cpp allocation.hpp 43.64 -heapRegionSeq.cpp g1CollectedHeap.hpp 43.65 +heapRegionSeq.cpp g1CollectedHeap.inline.hpp 43.66 heapRegionSeq.cpp heapRegionSeq.hpp 43.67 43.68 heapRegionSeq.hpp growableArray.hpp 43.69 @@ -334,18 +336,18 @@ 43.70 survRateGroup.hpp numberSeq.hpp 43.71 43.72 survRateGroup.cpp allocation.hpp 43.73 -survRateGroup.cpp g1CollectedHeap.hpp 43.74 +survRateGroup.cpp g1CollectedHeap.inline.hpp 43.75 survRateGroup.cpp g1CollectorPolicy.hpp 43.76 survRateGroup.cpp heapRegion.hpp 43.77 survRateGroup.cpp survRateGroup.hpp 43.78 43.79 thread.cpp concurrentMarkThread.inline.hpp 43.80 43.81 -universe.cpp g1CollectedHeap.hpp 43.82 +universe.cpp g1CollectedHeap.inline.hpp 43.83 universe.cpp g1CollectorPolicy.hpp 43.84 43.85 vm_operations_g1.hpp vmGCOperations.hpp 43.86 43.87 vm_operations_g1.cpp vm_operations_g1.hpp 43.88 -vm_operations_g1.cpp g1CollectedHeap.hpp 43.89 +vm_operations_g1.cpp g1CollectedHeap.inline.hpp 43.90 vm_operations_g1.cpp isGCActiveMark.hpp
44.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parNew Thu Jan 29 13:20:56 2009 -0800 44.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parNew Fri Jan 30 15:28:00 2009 -0800 44.3 @@ -29,6 +29,8 @@ 44.4 asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp 44.5 asParNewGeneration.cpp cmsGCAdaptivePolicyCounters.hpp 44.6 asParNewGeneration.cpp defNewGeneration.inline.hpp 44.7 +asParNewGeneration.cpp markOop.inline.hpp 44.8 +asParNewGeneration.cpp markSweep.inline.hpp 44.9 asParNewGeneration.cpp oop.pcgc.inline.hpp 44.10 asParNewGeneration.cpp parNewGeneration.hpp 44.11 asParNewGeneration.cpp referencePolicy.hpp 44.12 @@ -40,7 +42,7 @@ 44.13 parCardTableModRefBS.cpp java.hpp 44.14 parCardTableModRefBS.cpp mutexLocker.hpp 44.15 parCardTableModRefBS.cpp sharedHeap.hpp 44.16 -parCardTableModRefBS.cpp space.hpp 44.17 +parCardTableModRefBS.cpp space.inline.hpp 44.18 parCardTableModRefBS.cpp universe.hpp 44.19 parCardTableModRefBS.cpp virtualspace.hpp 44.20 44.21 @@ -77,6 +79,7 @@ 44.22 parNewGeneration.cpp sharedHeap.hpp 44.23 parNewGeneration.cpp space.hpp 44.24 parNewGeneration.cpp spaceDecorator.hpp 44.25 +parNewGeneration.cpp thread.hpp 44.26 parNewGeneration.cpp workgroup.hpp 44.27 44.28 parNewGeneration.hpp defNewGeneration.hpp
45.1 --- a/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Thu Jan 29 13:20:56 2009 -0800 45.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Fri Jan 30 15:28:00 2009 -0800 45.3 @@ -302,6 +302,8 @@ 45.4 psOldGen.hpp spaceCounters.hpp 45.5 45.6 psPermGen.cpp gcUtil.hpp 45.7 +psPermGen.cpp markOop.inline.hpp 45.8 +psPermGen.cpp markSweep.inline.hpp 45.9 psPermGen.cpp parallelScavengeHeap.hpp 45.10 psPermGen.cpp psMarkSweepDecorator.hpp 45.11 psPermGen.cpp psParallelCompact.hpp
46.1 --- a/src/share/vm/gc_implementation/includeDB_gc_shared Thu Jan 29 13:20:56 2009 -0800 46.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_shared Fri Jan 30 15:28:00 2009 -0800 46.3 @@ -100,4 +100,4 @@ 46.4 spaceCounters.hpp perfData.hpp 46.5 spaceCounters.hpp generationCounters.hpp 46.6 46.7 -vmGCOperations.cpp g1CollectedHeap.hpp 46.8 +vmGCOperations.cpp g1CollectedHeap.inline.hpp
47.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Jan 29 13:20:56 2009 -0800 47.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Jan 30 15:28:00 2009 -0800 47.3 @@ -404,6 +404,8 @@ 47.4 if (terminator()->offer_termination()) break; 47.5 par_scan_state()->end_term_time(); 47.6 } 47.7 + assert(par_gen()->_overflow_list == NULL && par_gen()->_num_par_pushes == 0, 47.8 + "Broken overflow list?"); 47.9 // Finish the last termination pause. 47.10 par_scan_state()->end_term_time(); 47.11 } 47.12 @@ -456,6 +458,8 @@ 47.13 _is_alive_closure(this), 47.14 _plab_stats(YoungPLABSize, PLABWeight) 47.15 { 47.16 + NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;) 47.17 + NOT_PRODUCT(_num_par_pushes = 0;) 47.18 _task_queues = new ObjToScanQueueSet(ParallelGCThreads); 47.19 guarantee(_task_queues != NULL, "task_queues allocation failure."); 47.20 47.21 @@ -993,12 +997,19 @@ 47.22 "push forwarded object"); 47.23 } 47.24 // Push it on one of the queues of to-be-scanned objects. 47.25 - if (!par_scan_state->work_queue()->push(obj_to_push)) { 47.26 + bool simulate_overflow = false; 47.27 + NOT_PRODUCT( 47.28 + if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) { 47.29 + // simulate a stack overflow 47.30 + simulate_overflow = true; 47.31 + } 47.32 + ) 47.33 + if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) { 47.34 // Add stats for overflow pushes. 47.35 if (Verbose && PrintGCDetails) { 47.36 gclog_or_tty->print("queue overflow!\n"); 47.37 } 47.38 - push_on_overflow_list(old); 47.39 + push_on_overflow_list(old, par_scan_state); 47.40 par_scan_state->note_overflow_push(); 47.41 } 47.42 par_scan_state->note_push(); 47.43 @@ -1110,9 +1121,16 @@ 47.44 "push forwarded object"); 47.45 } 47.46 // Push it on one of the queues of to-be-scanned objects. 47.47 - if (!par_scan_state->work_queue()->push(obj_to_push)) { 47.48 + bool simulate_overflow = false; 47.49 + NOT_PRODUCT( 47.50 + if (ParGCWorkQueueOverflowALot && should_simulate_overflow()) { 47.51 + // simulate a stack overflow 47.52 + simulate_overflow = true; 47.53 + } 47.54 + ) 47.55 + if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) { 47.56 // Add stats for overflow pushes. 47.57 - push_on_overflow_list(old); 47.58 + push_on_overflow_list(old, par_scan_state); 47.59 par_scan_state->note_overflow_push(); 47.60 } 47.61 par_scan_state->note_push(); 47.62 @@ -1135,89 +1153,190 @@ 47.63 return forward_ptr; 47.64 } 47.65 47.66 -void ParNewGeneration::push_on_overflow_list(oop from_space_obj) { 47.67 - oop cur_overflow_list = _overflow_list; 47.68 +#ifndef PRODUCT 47.69 +// It's OK to call this multi-threaded; the worst thing 47.70 +// that can happen is that we'll get a bunch of closely 47.71 +// spaced simulated oveflows, but that's OK, in fact 47.72 +// probably good as it would exercise the overflow code 47.73 +// under contention. 47.74 +bool ParNewGeneration::should_simulate_overflow() { 47.75 + if (_overflow_counter-- <= 0) { // just being defensive 47.76 + _overflow_counter = ParGCWorkQueueOverflowInterval; 47.77 + return true; 47.78 + } else { 47.79 + return false; 47.80 + } 47.81 +} 47.82 +#endif 47.83 + 47.84 +#define BUSY (oop(0x1aff1aff)) 47.85 +void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) { 47.86 // if the object has been forwarded to itself, then we cannot 47.87 // use the klass pointer for the linked list. Instead we have 47.88 // to allocate an oopDesc in the C-Heap and use that for the linked list. 47.89 + // XXX This is horribly inefficient when a promotion failure occurs 47.90 + // and should be fixed. XXX FIX ME !!! 47.91 +#ifndef PRODUCT 47.92 + Atomic::inc_ptr(&_num_par_pushes); 47.93 + assert(_num_par_pushes > 0, "Tautology"); 47.94 +#endif 47.95 if (from_space_obj->forwardee() == from_space_obj) { 47.96 oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1); 47.97 listhead->forward_to(from_space_obj); 47.98 from_space_obj = listhead; 47.99 } 47.100 - while (true) { 47.101 - from_space_obj->set_klass_to_list_ptr(cur_overflow_list); 47.102 - oop observed_overflow_list = 47.103 + oop observed_overflow_list = _overflow_list; 47.104 + oop cur_overflow_list; 47.105 + do { 47.106 + cur_overflow_list = observed_overflow_list; 47.107 + if (cur_overflow_list != BUSY) { 47.108 + from_space_obj->set_klass_to_list_ptr(cur_overflow_list); 47.109 + } else { 47.110 + from_space_obj->set_klass_to_list_ptr(NULL); 47.111 + } 47.112 + observed_overflow_list = 47.113 (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list); 47.114 - if (observed_overflow_list == cur_overflow_list) break; 47.115 - // Otherwise... 47.116 - cur_overflow_list = observed_overflow_list; 47.117 - } 47.118 + } while (cur_overflow_list != observed_overflow_list); 47.119 } 47.120 47.121 +// *NOTE*: The overflow list manipulation code here and 47.122 +// in CMSCollector:: are very similar in shape, 47.123 +// except that in the CMS case we thread the objects 47.124 +// directly into the list via their mark word, and do 47.125 +// not need to deal with special cases below related 47.126 +// to chunking of object arrays and promotion failure 47.127 +// handling. 47.128 +// CR 6797058 has been filed to attempt consolidation of 47.129 +// the common code. 47.130 +// Because of the common code, if you make any changes in 47.131 +// the code below, please check the CMS version to see if 47.132 +// similar changes might be needed. 47.133 +// See CMSCollector::par_take_from_overflow_list() for 47.134 +// more extensive documentation comments. 47.135 bool 47.136 ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) { 47.137 ObjToScanQueue* work_q = par_scan_state->work_queue(); 47.138 + assert(work_q->size() == 0, "Should first empty local work queue"); 47.139 // How many to take? 47.140 - int objsFromOverflow = MIN2(work_q->max_elems()/4, 47.141 - (juint)ParGCDesiredObjsFromOverflowList); 47.142 + size_t objsFromOverflow = MIN2((size_t)work_q->max_elems()/4, 47.143 + (size_t)ParGCDesiredObjsFromOverflowList); 47.144 47.145 if (_overflow_list == NULL) return false; 47.146 47.147 // Otherwise, there was something there; try claiming the list. 47.148 - oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list); 47.149 - 47.150 - if (prefix == NULL) { 47.151 - return false; 47.152 + oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); 47.153 + // Trim off a prefix of at most objsFromOverflow items 47.154 + Thread* tid = Thread::current(); 47.155 + size_t spin_count = (size_t)ParallelGCThreads; 47.156 + size_t sleep_time_millis = MAX2((size_t)1, objsFromOverflow/100); 47.157 + for (size_t spin = 0; prefix == BUSY && spin < spin_count; spin++) { 47.158 + // someone grabbed it before we did ... 47.159 + // ... we spin for a short while... 47.160 + os::sleep(tid, sleep_time_millis, false); 47.161 + if (_overflow_list == NULL) { 47.162 + // nothing left to take 47.163 + return false; 47.164 + } else if (_overflow_list != BUSY) { 47.165 + // try and grab the prefix 47.166 + prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); 47.167 + } 47.168 } 47.169 - // Trim off a prefix of at most objsFromOverflow items 47.170 - int i = 1; 47.171 + if (prefix == NULL || prefix == BUSY) { 47.172 + // Nothing to take or waited long enough 47.173 + if (prefix == NULL) { 47.174 + // Write back the NULL in case we overwrote it with BUSY above 47.175 + // and it is still the same value. 47.176 + (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); 47.177 + } 47.178 + return false; 47.179 + } 47.180 + assert(prefix != NULL && prefix != BUSY, "Error"); 47.181 + size_t i = 1; 47.182 oop cur = prefix; 47.183 while (i < objsFromOverflow && cur->klass_or_null() != NULL) { 47.184 i++; cur = oop(cur->klass()); 47.185 } 47.186 47.187 // Reattach remaining (suffix) to overflow list 47.188 - if (cur->klass_or_null() != NULL) { 47.189 - oop suffix = oop(cur->klass()); 47.190 - cur->set_klass_to_list_ptr(NULL); 47.191 - 47.192 - // Find last item of suffix list 47.193 - oop last = suffix; 47.194 - while (last->klass_or_null() != NULL) { 47.195 - last = oop(last->klass()); 47.196 + if (cur->klass_or_null() == NULL) { 47.197 + // Write back the NULL in lieu of the BUSY we wrote 47.198 + // above and it is still the same value. 47.199 + if (_overflow_list == BUSY) { 47.200 + (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); 47.201 } 47.202 - // Atomically prepend suffix to current overflow list 47.203 - oop cur_overflow_list = _overflow_list; 47.204 - while (true) { 47.205 - last->set_klass_to_list_ptr(cur_overflow_list); 47.206 - oop observed_overflow_list = 47.207 - (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list); 47.208 - if (observed_overflow_list == cur_overflow_list) break; 47.209 - // Otherwise... 47.210 - cur_overflow_list = observed_overflow_list; 47.211 + } else { 47.212 + assert(cur->klass_or_null() != BUSY, "Error"); 47.213 + oop suffix = oop(cur->klass()); // suffix will be put back on global list 47.214 + cur->set_klass_to_list_ptr(NULL); // break off suffix 47.215 + // It's possible that the list is still in the empty(busy) state 47.216 + // we left it in a short while ago; in that case we may be 47.217 + // able to place back the suffix. 47.218 + oop observed_overflow_list = _overflow_list; 47.219 + oop cur_overflow_list = observed_overflow_list; 47.220 + bool attached = false; 47.221 + while (observed_overflow_list == BUSY || observed_overflow_list == NULL) { 47.222 + observed_overflow_list = 47.223 + (oop) Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list); 47.224 + if (cur_overflow_list == observed_overflow_list) { 47.225 + attached = true; 47.226 + break; 47.227 + } else cur_overflow_list = observed_overflow_list; 47.228 + } 47.229 + if (!attached) { 47.230 + // Too bad, someone else got in in between; we'll need to do a splice. 47.231 + // Find the last item of suffix list 47.232 + oop last = suffix; 47.233 + while (last->klass_or_null() != NULL) { 47.234 + last = oop(last->klass()); 47.235 + } 47.236 + // Atomically prepend suffix to current overflow list 47.237 + observed_overflow_list = _overflow_list; 47.238 + do { 47.239 + cur_overflow_list = observed_overflow_list; 47.240 + if (cur_overflow_list != BUSY) { 47.241 + // Do the splice ... 47.242 + last->set_klass_to_list_ptr(cur_overflow_list); 47.243 + } else { // cur_overflow_list == BUSY 47.244 + last->set_klass_to_list_ptr(NULL); 47.245 + } 47.246 + observed_overflow_list = 47.247 + (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list); 47.248 + } while (cur_overflow_list != observed_overflow_list); 47.249 } 47.250 } 47.251 47.252 // Push objects on prefix list onto this thread's work queue 47.253 - assert(cur != NULL, "program logic"); 47.254 + assert(prefix != NULL && prefix != BUSY, "program logic"); 47.255 cur = prefix; 47.256 - int n = 0; 47.257 + ssize_t n = 0; 47.258 while (cur != NULL) { 47.259 oop obj_to_push = cur->forwardee(); 47.260 oop next = oop(cur->klass_or_null()); 47.261 cur->set_klass(obj_to_push->klass()); 47.262 - if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) { 47.263 + // This may be an array object that is self-forwarded. In that case, the list pointer 47.264 + // space, cur, is not in the Java heap, but rather in the C-heap and should be freed. 47.265 + if (!is_in_reserved(cur)) { 47.266 + // This can become a scaling bottleneck when there is work queue overflow coincident 47.267 + // with promotion failure. 47.268 + oopDesc* f = cur; 47.269 + FREE_C_HEAP_ARRAY(oopDesc, f); 47.270 + } else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) { 47.271 + assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned"); 47.272 obj_to_push = cur; 47.273 - assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned"); 47.274 } 47.275 - work_q->push(obj_to_push); 47.276 + bool ok = work_q->push(obj_to_push); 47.277 + assert(ok, "Should have succeeded"); 47.278 cur = next; 47.279 n++; 47.280 } 47.281 par_scan_state->note_overflow_refill(n); 47.282 +#ifndef PRODUCT 47.283 + assert(_num_par_pushes >= n, "Too many pops?"); 47.284 + Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes); 47.285 +#endif 47.286 return true; 47.287 } 47.288 +#undef BUSY 47.289 47.290 void ParNewGeneration::ref_processor_init() 47.291 {
48.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Jan 29 13:20:56 2009 -0800 48.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Jan 30 15:28:00 2009 -0800 48.3 @@ -278,6 +278,7 @@ 48.4 friend class ParNewRefProcTask; 48.5 friend class ParNewRefProcTaskExecutor; 48.6 friend class ParScanThreadStateSet; 48.7 + friend class ParEvacuateFollowersClosure; 48.8 48.9 private: 48.10 // XXX use a global constant instead of 64! 48.11 @@ -296,6 +297,7 @@ 48.12 // klass-pointers (klass information already copied to the forwarded 48.13 // image.) Manipulated with CAS. 48.14 oop _overflow_list; 48.15 + NOT_PRODUCT(ssize_t _num_par_pushes;) 48.16 48.17 // If true, older generation does not support promotion undo, so avoid. 48.18 static bool _avoid_promotion_undo; 48.19 @@ -372,8 +374,12 @@ 48.20 oop copy_to_survivor_space_with_undo(ParScanThreadState* par_scan_state, 48.21 oop obj, size_t obj_sz, markOop m); 48.22 48.23 + // in support of testing overflow code 48.24 + NOT_PRODUCT(int _overflow_counter;) 48.25 + NOT_PRODUCT(bool should_simulate_overflow();) 48.26 + 48.27 // Push the given (from-space) object on the global overflow list. 48.28 - void push_on_overflow_list(oop from_space_obj); 48.29 + void push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state); 48.30 48.31 // If the global overflow list is non-empty, move some tasks from it 48.32 // onto "work_q" (which must be empty). No more than 1/4 of the
49.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Jan 29 13:20:56 2009 -0800 49.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Fri Jan 30 15:28:00 2009 -0800 49.3 @@ -200,6 +200,7 @@ 49.4 49.5 void oop_iterate(OopClosure* cl); 49.6 void object_iterate(ObjectClosure* cl); 49.7 + void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); } 49.8 void permanent_oop_iterate(OopClosure* cl); 49.9 void permanent_object_iterate(ObjectClosure* cl); 49.10
50.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Thu Jan 29 13:20:56 2009 -0800 50.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Fri Jan 30 15:28:00 2009 -0800 50.3 @@ -116,7 +116,7 @@ 50.4 // ObjectSpace stuff 50.5 // 50.6 50.7 - _object_space = new MutableSpace(); 50.8 + _object_space = new MutableSpace(virtual_space()->alignment()); 50.9 50.10 if (_object_space == NULL) 50.11 vm_exit_during_initialization("Could not allocate an old gen space"); 50.12 @@ -385,10 +385,10 @@ 50.13 start_array()->set_covered_region(new_memregion); 50.14 Universe::heap()->barrier_set()->resize_covered_region(new_memregion); 50.15 50.16 - HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high(); 50.17 - 50.18 // ALWAYS do this last!! 50.19 - object_space()->set_end(virtual_space_high); 50.20 + object_space()->initialize(new_memregion, 50.21 + SpaceDecorator::DontClear, 50.22 + SpaceDecorator::DontMangle); 50.23 50.24 assert(new_word_size == heap_word_size(object_space()->capacity_in_bytes()), 50.25 "Sanity");
51.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp Thu Jan 29 13:20:56 2009 -0800 51.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp Fri Jan 30 15:28:00 2009 -0800 51.3 @@ -78,7 +78,7 @@ 51.4 _special = false; 51.5 } 51.6 51.7 -bool PSVirtualSpace::expand_by(size_t bytes, bool pre_touch) { 51.8 +bool PSVirtualSpace::expand_by(size_t bytes) { 51.9 assert(is_aligned(bytes), "arg not aligned"); 51.10 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); 51.11 51.12 @@ -92,15 +92,6 @@ 51.13 _committed_high_addr += bytes; 51.14 } 51.15 51.16 - if (pre_touch || AlwaysPreTouch) { 51.17 - for (char* curr = base_addr; 51.18 - curr < _committed_high_addr; 51.19 - curr += os::vm_page_size()) { 51.20 - char tmp = *curr; 51.21 - *curr = 0; 51.22 - } 51.23 - } 51.24 - 51.25 return result; 51.26 } 51.27 51.28 @@ -255,7 +246,7 @@ 51.29 DEBUG_ONLY(verify()); 51.30 } 51.31 51.32 -bool PSVirtualSpaceHighToLow::expand_by(size_t bytes, bool pre_touch) { 51.33 +bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) { 51.34 assert(is_aligned(bytes), "arg not aligned"); 51.35 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); 51.36 51.37 @@ -269,15 +260,6 @@ 51.38 _committed_low_addr -= bytes; 51.39 } 51.40 51.41 - if (pre_touch || AlwaysPreTouch) { 51.42 - for (char* curr = base_addr; 51.43 - curr < _committed_high_addr; 51.44 - curr += os::vm_page_size()) { 51.45 - char tmp = *curr; 51.46 - *curr = 0; 51.47 - } 51.48 - } 51.49 - 51.50 return result; 51.51 } 51.52
52.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp Thu Jan 29 13:20:56 2009 -0800 52.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp Fri Jan 30 15:28:00 2009 -0800 52.3 @@ -80,7 +80,7 @@ 52.4 inline void set_reserved(char* low_addr, char* high_addr, bool special); 52.5 inline void set_reserved(ReservedSpace rs); 52.6 inline void set_committed(char* low_addr, char* high_addr); 52.7 - virtual bool expand_by(size_t bytes, bool pre_touch = false); 52.8 + virtual bool expand_by(size_t bytes); 52.9 virtual bool shrink_by(size_t bytes); 52.10 virtual size_t expand_into(PSVirtualSpace* space, size_t bytes); 52.11 void release(); 52.12 @@ -127,7 +127,7 @@ 52.13 PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment); 52.14 PSVirtualSpaceHighToLow(ReservedSpace rs); 52.15 52.16 - virtual bool expand_by(size_t bytes, bool pre_touch = false); 52.17 + virtual bool expand_by(size_t bytes); 52.18 virtual bool shrink_by(size_t bytes); 52.19 virtual size_t expand_into(PSVirtualSpace* space, size_t bytes); 52.20
53.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Thu Jan 29 13:20:56 2009 -0800 53.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Fri Jan 30 15:28:00 2009 -0800 53.3 @@ -64,12 +64,12 @@ 53.4 } 53.5 53.6 if (UseNUMA) { 53.7 - _eden_space = new MutableNUMASpace(); 53.8 + _eden_space = new MutableNUMASpace(virtual_space()->alignment()); 53.9 } else { 53.10 - _eden_space = new MutableSpace(); 53.11 + _eden_space = new MutableSpace(virtual_space()->alignment()); 53.12 } 53.13 - _from_space = new MutableSpace(); 53.14 - _to_space = new MutableSpace(); 53.15 + _from_space = new MutableSpace(virtual_space()->alignment()); 53.16 + _to_space = new MutableSpace(virtual_space()->alignment()); 53.17 53.18 if (_eden_space == NULL || _from_space == NULL || _to_space == NULL) { 53.19 vm_exit_during_initialization("Could not allocate a young gen space");
54.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Thu Jan 29 13:20:56 2009 -0800 54.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Fri Jan 30 15:28:00 2009 -0800 54.3 @@ -27,7 +27,7 @@ 54.4 # include "incls/_mutableNUMASpace.cpp.incl" 54.5 54.6 54.7 -MutableNUMASpace::MutableNUMASpace() { 54.8 +MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) { 54.9 _lgrp_spaces = new (ResourceObj::C_HEAP) GrowableArray<LGRPSpace*>(0, true); 54.10 _page_size = os::vm_page_size(); 54.11 _adaptation_cycles = 0; 54.12 @@ -221,7 +221,7 @@ 54.13 } 54.14 } 54.15 if (!found) { 54.16 - lgrp_spaces()->append(new LGRPSpace(lgrp_ids[i])); 54.17 + lgrp_spaces()->append(new LGRPSpace(lgrp_ids[i], alignment())); 54.18 } 54.19 } 54.20 54.21 @@ -443,10 +443,10 @@ 54.22 // Is there bottom? 54.23 if (new_region.start() < intersection.start()) { // Yes 54.24 // Try to coalesce small pages into a large one. 54.25 - if (UseLargePages && page_size() >= os::large_page_size()) { 54.26 - HeapWord* p = (HeapWord*)round_to((intptr_t) intersection.start(), os::large_page_size()); 54.27 + if (UseLargePages && page_size() >= alignment()) { 54.28 + HeapWord* p = (HeapWord*)round_to((intptr_t) intersection.start(), alignment()); 54.29 if (new_region.contains(p) 54.30 - && pointer_delta(p, new_region.start(), sizeof(char)) >= os::large_page_size()) { 54.31 + && pointer_delta(p, new_region.start(), sizeof(char)) >= alignment()) { 54.32 if (intersection.contains(p)) { 54.33 intersection = MemRegion(p, intersection.end()); 54.34 } else { 54.35 @@ -462,10 +462,10 @@ 54.36 // Is there top? 54.37 if (intersection.end() < new_region.end()) { // Yes 54.38 // Try to coalesce small pages into a large one. 54.39 - if (UseLargePages && page_size() >= os::large_page_size()) { 54.40 - HeapWord* p = (HeapWord*)round_down((intptr_t) intersection.end(), os::large_page_size()); 54.41 + if (UseLargePages && page_size() >= alignment()) { 54.42 + HeapWord* p = (HeapWord*)round_down((intptr_t) intersection.end(), alignment()); 54.43 if (new_region.contains(p) 54.44 - && pointer_delta(new_region.end(), p, sizeof(char)) >= os::large_page_size()) { 54.45 + && pointer_delta(new_region.end(), p, sizeof(char)) >= alignment()) { 54.46 if (intersection.contains(p)) { 54.47 intersection = MemRegion(intersection.start(), p); 54.48 } else { 54.49 @@ -504,12 +504,12 @@ 54.50 // That's the only case we have to make an additional bias_region() call. 54.51 HeapWord* start = invalid_region->start(); 54.52 HeapWord* end = invalid_region->end(); 54.53 - if (UseLargePages && page_size() >= os::large_page_size()) { 54.54 - HeapWord *p = (HeapWord*)round_down((intptr_t) start, os::large_page_size()); 54.55 + if (UseLargePages && page_size() >= alignment()) { 54.56 + HeapWord *p = (HeapWord*)round_down((intptr_t) start, alignment()); 54.57 if (new_region.contains(p)) { 54.58 start = p; 54.59 } 54.60 - p = (HeapWord*)round_to((intptr_t) end, os::large_page_size()); 54.61 + p = (HeapWord*)round_to((intptr_t) end, alignment()); 54.62 if (new_region.contains(end)) { 54.63 end = p; 54.64 } 54.65 @@ -526,7 +526,8 @@ 54.66 54.67 void MutableNUMASpace::initialize(MemRegion mr, 54.68 bool clear_space, 54.69 - bool mangle_space) { 54.70 + bool mangle_space, 54.71 + bool setup_pages) { 54.72 assert(clear_space, "Reallocation will destory data!"); 54.73 assert(lgrp_spaces()->length() > 0, "There should be at least one space"); 54.74 54.75 @@ -538,7 +539,7 @@ 54.76 54.77 // Compute chunk sizes 54.78 size_t prev_page_size = page_size(); 54.79 - set_page_size(UseLargePages ? os::large_page_size() : os::vm_page_size()); 54.80 + set_page_size(UseLargePages ? alignment() : os::vm_page_size()); 54.81 HeapWord* rounded_bottom = (HeapWord*)round_to((intptr_t) bottom(), page_size()); 54.82 HeapWord* rounded_end = (HeapWord*)round_down((intptr_t) end(), page_size()); 54.83 size_t base_space_size_pages = pointer_delta(rounded_end, rounded_bottom, sizeof(char)) / page_size(); 54.84 @@ -666,7 +667,7 @@ 54.85 } 54.86 54.87 // Clear space (set top = bottom) but never mangle. 54.88 - s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle); 54.89 + s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle, MutableSpace::DontSetupPages); 54.90 54.91 set_adaptation_cycles(samples_count()); 54.92 }
55.1 --- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Thu Jan 29 13:20:56 2009 -0800 55.2 +++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Fri Jan 30 15:28:00 2009 -0800 55.3 @@ -82,8 +82,8 @@ 55.4 char* last_page_scanned() { return _last_page_scanned; } 55.5 void set_last_page_scanned(char* p) { _last_page_scanned = p; } 55.6 public: 55.7 - LGRPSpace(int l) : _lgrp_id(l), _last_page_scanned(NULL), _allocation_failed(false) { 55.8 - _space = new MutableSpace(); 55.9 + LGRPSpace(int l, size_t alignment) : _lgrp_id(l), _last_page_scanned(NULL), _allocation_failed(false) { 55.10 + _space = new MutableSpace(alignment); 55.11 _alloc_rate = new AdaptiveWeightedAverage(NUMAChunkResizeWeight); 55.12 } 55.13 ~LGRPSpace() { 55.14 @@ -183,10 +183,10 @@ 55.15 55.16 public: 55.17 GrowableArray<LGRPSpace*>* lgrp_spaces() const { return _lgrp_spaces; } 55.18 - MutableNUMASpace(); 55.19 + MutableNUMASpace(size_t alignment); 55.20 virtual ~MutableNUMASpace(); 55.21 // Space initialization. 55.22 - virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); 55.23 + virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space, bool setup_pages = SetupPages); 55.24 // Update space layout if necessary. Do all adaptive resizing job. 55.25 virtual void update(); 55.26 // Update allocation rate averages.
56.1 --- a/src/share/vm/gc_implementation/shared/mutableSpace.cpp Thu Jan 29 13:20:56 2009 -0800 56.2 +++ b/src/share/vm/gc_implementation/shared/mutableSpace.cpp Fri Jan 30 15:28:00 2009 -0800 56.3 @@ -25,7 +25,10 @@ 56.4 # include "incls/_precompiled.incl" 56.5 # include "incls/_mutableSpace.cpp.incl" 56.6 56.7 -MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) { 56.8 +MutableSpace::MutableSpace(size_t alignment): ImmutableSpace(), _top(NULL), _alignment(alignment) { 56.9 + assert(MutableSpace::alignment() >= 0 && 56.10 + MutableSpace::alignment() % os::vm_page_size() == 0, 56.11 + "Space should be aligned"); 56.12 _mangler = new MutableSpaceMangler(this); 56.13 } 56.14 56.15 @@ -33,16 +36,88 @@ 56.16 delete _mangler; 56.17 } 56.18 56.19 +void MutableSpace::numa_setup_pages(MemRegion mr, bool clear_space) { 56.20 + if (!mr.is_empty()) { 56.21 + size_t page_size = UseLargePages ? alignment() : os::vm_page_size(); 56.22 + HeapWord *start = (HeapWord*)round_to((intptr_t) mr.start(), page_size); 56.23 + HeapWord *end = (HeapWord*)round_down((intptr_t) mr.end(), page_size); 56.24 + if (end > start) { 56.25 + size_t size = pointer_delta(end, start, sizeof(char)); 56.26 + if (clear_space) { 56.27 + // Prefer page reallocation to migration. 56.28 + os::free_memory((char*)start, size); 56.29 + } 56.30 + os::numa_make_global((char*)start, size); 56.31 + } 56.32 + } 56.33 +} 56.34 + 56.35 +void MutableSpace::pretouch_pages(MemRegion mr) { 56.36 + for (volatile char *p = (char*)mr.start(); p < (char*)mr.end(); p += os::vm_page_size()) { 56.37 + char t = *p; *p = t; 56.38 + } 56.39 +} 56.40 + 56.41 void MutableSpace::initialize(MemRegion mr, 56.42 bool clear_space, 56.43 - bool mangle_space) { 56.44 - HeapWord* bottom = mr.start(); 56.45 - HeapWord* end = mr.end(); 56.46 + bool mangle_space, 56.47 + bool setup_pages) { 56.48 56.49 - assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end), 56.50 + assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), 56.51 "invalid space boundaries"); 56.52 - set_bottom(bottom); 56.53 - set_end(end); 56.54 + 56.55 + if (setup_pages && (UseNUMA || AlwaysPreTouch)) { 56.56 + // The space may move left and right or expand/shrink. 56.57 + // We'd like to enforce the desired page placement. 56.58 + MemRegion head, tail; 56.59 + if (last_setup_region().is_empty()) { 56.60 + // If it's the first initialization don't limit the amount of work. 56.61 + head = mr; 56.62 + tail = MemRegion(mr.end(), mr.end()); 56.63 + } else { 56.64 + // Is there an intersection with the address space? 56.65 + MemRegion intersection = last_setup_region().intersection(mr); 56.66 + if (intersection.is_empty()) { 56.67 + intersection = MemRegion(mr.end(), mr.end()); 56.68 + } 56.69 + // All the sizes below are in words. 56.70 + size_t head_size = 0, tail_size = 0; 56.71 + if (mr.start() <= intersection.start()) { 56.72 + head_size = pointer_delta(intersection.start(), mr.start()); 56.73 + } 56.74 + if(intersection.end() <= mr.end()) { 56.75 + tail_size = pointer_delta(mr.end(), intersection.end()); 56.76 + } 56.77 + // Limit the amount of page manipulation if necessary. 56.78 + if (NUMASpaceResizeRate > 0 && !AlwaysPreTouch) { 56.79 + const size_t change_size = head_size + tail_size; 56.80 + const float setup_rate_words = NUMASpaceResizeRate >> LogBytesPerWord; 56.81 + head_size = MIN2((size_t)(setup_rate_words * head_size / change_size), 56.82 + head_size); 56.83 + tail_size = MIN2((size_t)(setup_rate_words * tail_size / change_size), 56.84 + tail_size); 56.85 + } 56.86 + head = MemRegion(intersection.start() - head_size, intersection.start()); 56.87 + tail = MemRegion(intersection.end(), intersection.end() + tail_size); 56.88 + } 56.89 + assert(mr.contains(head) && mr.contains(tail), "Sanity"); 56.90 + 56.91 + if (UseNUMA) { 56.92 + numa_setup_pages(head, clear_space); 56.93 + numa_setup_pages(tail, clear_space); 56.94 + } 56.95 + 56.96 + if (AlwaysPreTouch) { 56.97 + pretouch_pages(head); 56.98 + pretouch_pages(tail); 56.99 + } 56.100 + 56.101 + // Remember where we stopped so that we can continue later. 56.102 + set_last_setup_region(MemRegion(head.start(), tail.end())); 56.103 + } 56.104 + 56.105 + set_bottom(mr.start()); 56.106 + set_end(mr.end()); 56.107 56.108 if (clear_space) { 56.109 clear(mangle_space);
57.1 --- a/src/share/vm/gc_implementation/shared/mutableSpace.hpp Thu Jan 29 13:20:56 2009 -0800 57.2 +++ b/src/share/vm/gc_implementation/shared/mutableSpace.hpp Fri Jan 30 15:28:00 2009 -0800 57.3 @@ -25,7 +25,10 @@ 57.4 // A MutableSpace is a subtype of ImmutableSpace that supports the 57.5 // concept of allocation. This includes the concepts that a space may 57.6 // be only partially full, and the querry methods that go with such 57.7 -// an assumption. 57.8 +// an assumption. MutableSpace is also responsible for minimizing the 57.9 +// page allocation time by having the memory pretouched (with 57.10 +// AlwaysPretouch) and for optimizing page placement on NUMA systems 57.11 +// by make the underlying region interleaved (with UseNUMA). 57.12 // 57.13 // Invariant: (ImmutableSpace +) bottom() <= top() <= end() 57.14 // top() is inclusive and end() is exclusive. 57.15 @@ -37,15 +40,23 @@ 57.16 57.17 // Helper for mangling unused space in debug builds 57.18 MutableSpaceMangler* _mangler; 57.19 - 57.20 + // The last region which page had been setup to be interleaved. 57.21 + MemRegion _last_setup_region; 57.22 + size_t _alignment; 57.23 protected: 57.24 HeapWord* _top; 57.25 57.26 MutableSpaceMangler* mangler() { return _mangler; } 57.27 57.28 + void numa_setup_pages(MemRegion mr, bool clear_space); 57.29 + void pretouch_pages(MemRegion mr); 57.30 + 57.31 + void set_last_setup_region(MemRegion mr) { _last_setup_region = mr; } 57.32 + MemRegion last_setup_region() const { return _last_setup_region; } 57.33 + 57.34 public: 57.35 virtual ~MutableSpace(); 57.36 - MutableSpace(); 57.37 + MutableSpace(size_t page_size); 57.38 57.39 // Accessors 57.40 HeapWord* top() const { return _top; } 57.41 @@ -57,13 +68,20 @@ 57.42 virtual void set_bottom(HeapWord* value) { _bottom = value; } 57.43 virtual void set_end(HeapWord* value) { _end = value; } 57.44 57.45 + size_t alignment() { return _alignment; } 57.46 + 57.47 // Returns a subregion containing all objects in this space. 57.48 MemRegion used_region() { return MemRegion(bottom(), top()); } 57.49 57.50 + static const bool SetupPages = true; 57.51 + static const bool DontSetupPages = false; 57.52 + 57.53 // Initialization 57.54 virtual void initialize(MemRegion mr, 57.55 bool clear_space, 57.56 - bool mangle_space); 57.57 + bool mangle_space, 57.58 + bool setup_pages = SetupPages); 57.59 + 57.60 virtual void clear(bool mangle_space); 57.61 // Does the usual initialization but optionally resets top to bottom. 57.62 #if 0 // MANGLE_SPACE
58.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp Thu Jan 29 13:20:56 2009 -0800 58.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Fri Jan 30 15:28:00 2009 -0800 58.3 @@ -466,6 +466,10 @@ 58.4 // This includes objects in permanent memory. 58.5 virtual void object_iterate(ObjectClosure* cl) = 0; 58.6 58.7 + // Similar to object_iterate() except iterates only 58.8 + // over live objects. 58.9 + virtual void safe_object_iterate(ObjectClosure* cl) = 0; 58.10 + 58.11 // Behaves the same as oop_iterate, except only traverses 58.12 // interior pointers contained in permanent memory. If there 58.13 // is no permanent memory, does nothing.
59.1 --- a/src/share/vm/includeDB_compiler2 Thu Jan 29 13:20:56 2009 -0800 59.2 +++ b/src/share/vm/includeDB_compiler2 Fri Jan 30 15:28:00 2009 -0800 59.3 @@ -140,6 +140,7 @@ 59.4 c2_globals_<os_family>.hpp macros.hpp 59.5 59.6 c2_init_<arch>.cpp compile.hpp 59.7 +c2_init_<arch>.cpp node.hpp 59.8 59.9 c2compiler.cpp ad_<arch_model>.hpp 59.10 c2compiler.cpp c2compiler.hpp 59.11 @@ -839,6 +840,7 @@ 59.12 phase.cpp compile.hpp 59.13 phase.cpp compileBroker.hpp 59.14 phase.cpp nmethod.hpp 59.15 +phase.cpp node.hpp 59.16 phase.cpp phase.hpp 59.17 59.18 phase.hpp port.hpp
60.1 --- a/src/share/vm/includeDB_core Thu Jan 29 13:20:56 2009 -0800 60.2 +++ b/src/share/vm/includeDB_core Fri Jan 30 15:28:00 2009 -0800 60.3 @@ -1311,6 +1311,7 @@ 60.4 cppInterpreter_<arch>.cpp debug.hpp 60.5 cppInterpreter_<arch>.cpp deoptimization.hpp 60.6 cppInterpreter_<arch>.cpp frame.inline.hpp 60.7 +cppInterpreter_<arch>.cpp interfaceSupport.hpp 60.8 cppInterpreter_<arch>.cpp interpreterRuntime.hpp 60.9 cppInterpreter_<arch>.cpp interpreter.hpp 60.10 cppInterpreter_<arch>.cpp interpreterGenerator.hpp 60.11 @@ -2014,7 +2015,7 @@ 60.12 instanceKlass.cpp vmSymbols.hpp 60.13 60.14 instanceKlass.hpp accessFlags.hpp 60.15 -instanceKlass.hpp bitMap.hpp 60.16 +instanceKlass.hpp bitMap.inline.hpp 60.17 instanceKlass.hpp constMethodOop.hpp 60.18 instanceKlass.hpp constantPoolOop.hpp 60.19 instanceKlass.hpp handles.hpp 60.20 @@ -3771,6 +3772,7 @@ 60.21 60.22 spaceDecorator.cpp copy.hpp 60.23 spaceDecorator.cpp spaceDecorator.hpp 60.24 +spaceDecorator.cpp space.inline.hpp 60.25 60.26 specialized_oop_closures.cpp ostream.hpp 60.27 specialized_oop_closures.cpp specialized_oop_closures.hpp
61.1 --- a/src/share/vm/includeDB_features Thu Jan 29 13:20:56 2009 -0800 61.2 +++ b/src/share/vm/includeDB_features Fri Jan 30 15:28:00 2009 -0800 61.3 @@ -59,6 +59,8 @@ 61.4 61.5 dump_<arch_model>.cpp assembler_<arch>.inline.hpp 61.6 dump_<arch_model>.cpp compactingPermGenGen.hpp 61.7 +dump_<arch_model>.cpp generation.inline.hpp 61.8 +dump_<arch_model>.cpp space.inline.hpp 61.9 61.10 forte.cpp collectedHeap.inline.hpp 61.11 forte.cpp debugInfoRec.hpp
62.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Jan 29 13:20:56 2009 -0800 62.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Jan 30 15:28:00 2009 -0800 62.3 @@ -163,7 +163,7 @@ 62.4 #ifdef USELABELS 62.5 // Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an 62.6 // initialization (which is is the initialization of the table pointer...) 62.7 -#define DISPATCH(opcode) goto *dispatch_table[opcode] 62.8 +#define DISPATCH(opcode) goto *(void*)dispatch_table[opcode] 62.9 #define CONTINUE { \ 62.10 opcode = *pc; \ 62.11 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ 62.12 @@ -341,7 +341,7 @@ 62.13 */ 62.14 #undef CHECK_NULL 62.15 #define CHECK_NULL(obj_) \ 62.16 - if ((obj_) == 0) { \ 62.17 + if ((obj_) == NULL) { \ 62.18 VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \ 62.19 } 62.20 62.21 @@ -1362,7 +1362,7 @@ 62.22 62.23 #define NULL_COMPARISON_NOT_OP(name) \ 62.24 CASE(_if##name): { \ 62.25 - int skip = (!(STACK_OBJECT(-1) == 0)) \ 62.26 + int skip = (!(STACK_OBJECT(-1) == NULL)) \ 62.27 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ 62.28 address branch_pc = pc; \ 62.29 UPDATE_PC_AND_TOS(skip, -1); \ 62.30 @@ -1372,7 +1372,7 @@ 62.31 62.32 #define NULL_COMPARISON_OP(name) \ 62.33 CASE(_if##name): { \ 62.34 - int skip = ((STACK_OBJECT(-1) == 0)) \ 62.35 + int skip = ((STACK_OBJECT(-1) == NULL)) \ 62.36 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ 62.37 address branch_pc = pc; \ 62.38 UPDATE_PC_AND_TOS(skip, -1); \
63.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.hpp Thu Jan 29 13:20:56 2009 -0800 63.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp Fri Jan 30 15:28:00 2009 -0800 63.3 @@ -66,7 +66,6 @@ 63.4 friend class InterpreterGenerator; 63.5 friend class InterpreterMacroAssembler; 63.6 friend class frame; 63.7 -friend class SharedRuntime; 63.8 friend class VMStructs; 63.9 63.10 public:
64.1 --- a/src/share/vm/libadt/port.hpp Thu Jan 29 13:20:56 2009 -0800 64.2 +++ b/src/share/vm/libadt/port.hpp Fri Jan 30 15:28:00 2009 -0800 64.3 @@ -34,17 +34,6 @@ 64.4 #include <stddef.h> 64.5 #include <stdlib.h> 64.6 #include <string.h> 64.7 -#undef bzero 64.8 -inline void bzero(void *b, int len) { memset(b,0,len); } 64.9 -#undef bcopy 64.10 -inline void bcopy(const void *s, void *d, size_t len) { memmove(d,s,len); } 64.11 -#undef bcmp 64.12 -inline int bcmp(const void *s,const void *t,int len) { return memcmp(s,t,len);} 64.13 -extern "C" unsigned long strtoul(const char *s, char **end, int base); 64.14 - 64.15 -// Definition for sys_errlist varies from Sun 4.1 & Solaris. 64.16 -// We use the new Solaris definition. 64.17 -#include <string.h> 64.18 64.19 // Access to the C++ class virtual function pointer 64.20 // Put the class in the macro
65.1 --- a/src/share/vm/memory/genCollectedHeap.cpp Thu Jan 29 13:20:56 2009 -0800 65.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp Fri Jan 30 15:28:00 2009 -0800 65.3 @@ -910,6 +910,13 @@ 65.4 perm_gen()->object_iterate(cl); 65.5 } 65.6 65.7 +void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) { 65.8 + for (int i = 0; i < _n_gens; i++) { 65.9 + _gens[i]->safe_object_iterate(cl); 65.10 + } 65.11 + perm_gen()->safe_object_iterate(cl); 65.12 +} 65.13 + 65.14 void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { 65.15 for (int i = 0; i < _n_gens; i++) { 65.16 _gens[i]->object_iterate_since_last_GC(cl);
66.1 --- a/src/share/vm/memory/genCollectedHeap.hpp Thu Jan 29 13:20:56 2009 -0800 66.2 +++ b/src/share/vm/memory/genCollectedHeap.hpp Fri Jan 30 15:28:00 2009 -0800 66.3 @@ -215,6 +215,7 @@ 66.4 void oop_iterate(OopClosure* cl); 66.5 void oop_iterate(MemRegion mr, OopClosure* cl); 66.6 void object_iterate(ObjectClosure* cl); 66.7 + void safe_object_iterate(ObjectClosure* cl); 66.8 void object_iterate_since_last_GC(ObjectClosure* cl); 66.9 Space* space_containing(const void* addr) const; 66.10
67.1 --- a/src/share/vm/memory/generation.cpp Thu Jan 29 13:20:56 2009 -0800 67.2 +++ b/src/share/vm/memory/generation.cpp Fri Jan 30 15:28:00 2009 -0800 67.3 @@ -319,6 +319,21 @@ 67.4 space_iterate(&blk); 67.5 } 67.6 67.7 +class GenerationSafeObjIterateClosure : public SpaceClosure { 67.8 + private: 67.9 + ObjectClosure* _cl; 67.10 + public: 67.11 + virtual void do_space(Space* s) { 67.12 + s->safe_object_iterate(_cl); 67.13 + } 67.14 + GenerationSafeObjIterateClosure(ObjectClosure* cl) : _cl(cl) {} 67.15 +}; 67.16 + 67.17 +void Generation::safe_object_iterate(ObjectClosure* cl) { 67.18 + GenerationSafeObjIterateClosure blk(cl); 67.19 + space_iterate(&blk); 67.20 +} 67.21 + 67.22 void Generation::prepare_for_compaction(CompactPoint* cp) { 67.23 // Generic implementation, can be specialized 67.24 CompactibleSpace* space = first_compaction_space();
68.1 --- a/src/share/vm/memory/generation.hpp Thu Jan 29 13:20:56 2009 -0800 68.2 +++ b/src/share/vm/memory/generation.hpp Fri Jan 30 15:28:00 2009 -0800 68.3 @@ -518,6 +518,11 @@ 68.4 // each. 68.5 virtual void object_iterate(ObjectClosure* cl); 68.6 68.7 + // Iterate over all safe objects in the generation, calling "cl.do_object" on 68.8 + // each. An object is safe if its references point to other objects in 68.9 + // the heap. This defaults to object_iterate() unless overridden. 68.10 + virtual void safe_object_iterate(ObjectClosure* cl); 68.11 + 68.12 // Iterate over all objects allocated in the generation since the last 68.13 // collection, calling "cl.do_object" on each. The generation must have 68.14 // been initialized properly to support this function, or else this call
69.1 --- a/src/share/vm/memory/heapInspection.cpp Thu Jan 29 13:20:56 2009 -0800 69.2 +++ b/src/share/vm/memory/heapInspection.cpp Fri Jan 30 15:28:00 2009 -0800 69.3 @@ -263,6 +263,9 @@ 69.4 if (!cit.allocation_failed()) { 69.5 // Iterate over objects in the heap 69.6 RecordInstanceClosure ric(&cit); 69.7 + // If this operation encounters a bad object when using CMS, 69.8 + // consider using safe_object_iterate() which avoids perm gen 69.9 + // objects that may contain bad references. 69.10 Universe::heap()->object_iterate(&ric); 69.11 69.12 // Report if certain classes are not counted because of 69.13 @@ -317,5 +320,8 @@ 69.14 69.15 // Iterate over objects in the heap 69.16 FindInstanceClosure fic(k, result); 69.17 + // If this operation encounters a bad object when using CMS, 69.18 + // consider using safe_object_iterate() which avoids perm gen 69.19 + // objects that may contain bad references. 69.20 Universe::heap()->object_iterate(&fic); 69.21 }
70.1 --- a/src/share/vm/memory/oopFactory.cpp Thu Jan 29 13:20:56 2009 -0800 70.2 +++ b/src/share/vm/memory/oopFactory.cpp Fri Jan 30 15:28:00 2009 -0800 70.3 @@ -82,9 +82,11 @@ 70.4 } 70.5 70.6 70.7 -constantPoolOop oopFactory::new_constantPool(int length, TRAPS) { 70.8 +constantPoolOop oopFactory::new_constantPool(int length, 70.9 + bool is_conc_safe, 70.10 + TRAPS) { 70.11 constantPoolKlass* ck = constantPoolKlass::cast(Universe::constantPoolKlassObj()); 70.12 - return ck->allocate(length, CHECK_NULL); 70.13 + return ck->allocate(length, is_conc_safe, CHECK_NULL); 70.14 } 70.15 70.16 70.17 @@ -105,11 +107,13 @@ 70.18 int compressed_line_number_size, 70.19 int localvariable_table_length, 70.20 int checked_exceptions_length, 70.21 + bool is_conc_safe, 70.22 TRAPS) { 70.23 klassOop cmkObj = Universe::constMethodKlassObj(); 70.24 constMethodKlass* cmk = constMethodKlass::cast(cmkObj); 70.25 return cmk->allocate(byte_code_size, compressed_line_number_size, 70.26 localvariable_table_length, checked_exceptions_length, 70.27 + is_conc_safe, 70.28 CHECK_NULL); 70.29 } 70.30 70.31 @@ -117,14 +121,17 @@ 70.32 methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags, 70.33 int compressed_line_number_size, 70.34 int localvariable_table_length, 70.35 - int checked_exceptions_length, TRAPS) { 70.36 + int checked_exceptions_length, 70.37 + bool is_conc_safe, 70.38 + TRAPS) { 70.39 methodKlass* mk = methodKlass::cast(Universe::methodKlassObj()); 70.40 assert(!access_flags.is_native() || byte_code_size == 0, 70.41 "native methods should not contain byte codes"); 70.42 constMethodOop cm = new_constMethod(byte_code_size, 70.43 compressed_line_number_size, 70.44 localvariable_table_length, 70.45 - checked_exceptions_length, CHECK_NULL); 70.46 + checked_exceptions_length, 70.47 + is_conc_safe, CHECK_NULL); 70.48 constMethodHandle rw(THREAD, cm); 70.49 return mk->allocate(rw, access_flags, CHECK_NULL); 70.50 }
71.1 --- a/src/share/vm/memory/oopFactory.hpp Thu Jan 29 13:20:56 2009 -0800 71.2 +++ b/src/share/vm/memory/oopFactory.hpp Fri Jan 30 15:28:00 2009 -0800 71.3 @@ -81,7 +81,9 @@ 71.4 static symbolHandle new_symbol_handle(const char* name, TRAPS) { return new_symbol_handle(name, (int)strlen(name), CHECK_(symbolHandle())); } 71.5 71.6 // Constant pools 71.7 - static constantPoolOop new_constantPool (int length, TRAPS); 71.8 + static constantPoolOop new_constantPool (int length, 71.9 + bool is_conc_safe, 71.10 + TRAPS); 71.11 static constantPoolCacheOop new_constantPoolCache(int length, TRAPS); 71.12 71.13 // Instance classes 71.14 @@ -93,9 +95,20 @@ 71.15 static constMethodOop new_constMethod(int byte_code_size, 71.16 int compressed_line_number_size, 71.17 int localvariable_table_length, 71.18 - int checked_exceptions_length, TRAPS); 71.19 + int checked_exceptions_length, 71.20 + bool is_conc_safe, 71.21 + TRAPS); 71.22 public: 71.23 - 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); 71.24 + // Set is_conc_safe for methods which cannot safely be 71.25 + // processed by concurrent GC even after the return of 71.26 + // the method. 71.27 + static methodOop new_method(int byte_code_size, 71.28 + AccessFlags access_flags, 71.29 + int compressed_line_number_size, 71.30 + int localvariable_table_length, 71.31 + int checked_exceptions_length, 71.32 + bool is_conc_safe, 71.33 + TRAPS); 71.34 71.35 // Method Data containers 71.36 static methodDataOop new_methodData(methodHandle method, TRAPS);
72.1 --- a/src/share/vm/memory/referenceProcessor.cpp Thu Jan 29 13:20:56 2009 -0800 72.2 +++ b/src/share/vm/memory/referenceProcessor.cpp Fri Jan 30 15:28:00 2009 -0800 72.3 @@ -721,12 +721,6 @@ 72.4 iter.obj(), iter.obj()->blueprint()->internal_name()); 72.5 } 72.6 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); 72.7 - // If discovery is concurrent, we may have objects with null referents, 72.8 - // being those that were concurrently cleared after they were discovered 72.9 - // (and not subsequently precleaned). 72.10 - assert( (discovery_is_atomic() && iter.referent()->is_oop()) 72.11 - || (!discovery_is_atomic() && iter.referent()->is_oop_or_null(UseConcMarkSweepGC)), 72.12 - "Adding a bad referent"); 72.13 iter.next(); 72.14 } 72.15 // Remember to keep sentinel pointer around
73.1 --- a/src/share/vm/memory/space.cpp Thu Jan 29 13:20:56 2009 -0800 73.2 +++ b/src/share/vm/memory/space.cpp Fri Jan 30 15:28:00 2009 -0800 73.3 @@ -569,7 +569,15 @@ 73.4 if (prev > mr.start()) { 73.5 region_start_addr = prev; 73.6 blk_start_addr = prev; 73.7 - assert(blk_start_addr == block_start(region_start_addr), "invariant"); 73.8 + // The previous invocation may have pushed "prev" beyond the 73.9 + // last allocated block yet there may be still be blocks 73.10 + // in this region due to a particular coalescing policy. 73.11 + // Relax the assertion so that the case where the unallocated 73.12 + // block is maintained and "prev" is beyond the unallocated 73.13 + // block does not cause the assertion to fire. 73.14 + assert((BlockOffsetArrayUseUnallocatedBlock && 73.15 + (!is_in(prev))) || 73.16 + (blk_start_addr == block_start(region_start_addr)), "invariant"); 73.17 } else { 73.18 region_start_addr = mr.start(); 73.19 blk_start_addr = block_start(region_start_addr); 73.20 @@ -705,6 +713,12 @@ 73.21 object_iterate_from(bm, blk); 73.22 } 73.23 73.24 +// For a continguous space object_iterate() and safe_object_iterate() 73.25 +// are the same. 73.26 +void ContiguousSpace::safe_object_iterate(ObjectClosure* blk) { 73.27 + object_iterate(blk); 73.28 +} 73.29 + 73.30 void ContiguousSpace::object_iterate_from(WaterMark mark, ObjectClosure* blk) { 73.31 assert(mark.space() == this, "Mark does not match space"); 73.32 HeapWord* p = mark.point();
74.1 --- a/src/share/vm/memory/space.hpp Thu Jan 29 13:20:56 2009 -0800 74.2 +++ b/src/share/vm/memory/space.hpp Fri Jan 30 15:28:00 2009 -0800 74.3 @@ -193,6 +193,9 @@ 74.4 // each. Objects allocated by applications of the closure are not 74.5 // included in the iteration. 74.6 virtual void object_iterate(ObjectClosure* blk) = 0; 74.7 + // Similar to object_iterate() except only iterates over 74.8 + // objects whose internal references point to objects in the space. 74.9 + virtual void safe_object_iterate(ObjectClosure* blk) = 0; 74.10 74.11 // Iterate over all objects that intersect with mr, calling "cl->do_object" 74.12 // on each. There is an exception to this: if this closure has already 74.13 @@ -843,6 +846,9 @@ 74.14 void oop_iterate(OopClosure* cl); 74.15 void oop_iterate(MemRegion mr, OopClosure* cl); 74.16 void object_iterate(ObjectClosure* blk); 74.17 + // For contiguous spaces this method will iterate safely over objects 74.18 + // in the space (i.e., between bottom and top) when at a safepoint. 74.19 + void safe_object_iterate(ObjectClosure* blk); 74.20 void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl); 74.21 // iterates on objects up to the safe limit 74.22 HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
75.1 --- a/src/share/vm/oops/constMethodKlass.cpp Thu Jan 29 13:20:56 2009 -0800 75.2 +++ b/src/share/vm/oops/constMethodKlass.cpp Fri Jan 30 15:28:00 2009 -0800 75.3 @@ -49,10 +49,16 @@ 75.4 return constMethodOop(obj)->object_is_parsable(); 75.5 } 75.6 75.7 +bool constMethodKlass::oop_is_conc_safe(oop obj) const { 75.8 + assert(obj->is_constMethod(), "must be constMethod oop"); 75.9 + return constMethodOop(obj)->is_conc_safe(); 75.10 +} 75.11 + 75.12 constMethodOop constMethodKlass::allocate(int byte_code_size, 75.13 int compressed_line_number_size, 75.14 int localvariable_table_length, 75.15 int checked_exceptions_length, 75.16 + bool is_conc_safe, 75.17 TRAPS) { 75.18 75.19 int size = constMethodOopDesc::object_size(byte_code_size, 75.20 @@ -75,6 +81,7 @@ 75.21 compressed_line_number_size, 75.22 localvariable_table_length); 75.23 assert(cm->size() == size, "wrong size for object"); 75.24 + cm->set_is_conc_safe(is_conc_safe); 75.25 cm->set_partially_loaded(); 75.26 assert(cm->is_parsable(), "Is safely parsable by gc"); 75.27 return cm;
76.1 --- a/src/share/vm/oops/constMethodKlass.hpp Thu Jan 29 13:20:56 2009 -0800 76.2 +++ b/src/share/vm/oops/constMethodKlass.hpp Fri Jan 30 15:28:00 2009 -0800 76.3 @@ -32,12 +32,16 @@ 76.4 // Testing 76.5 bool oop_is_constMethod() const { return true; } 76.6 virtual bool oop_is_parsable(oop obj) const; 76.7 + virtual bool oop_is_conc_safe(oop obj) const; 76.8 + 76.9 76.10 // Allocation 76.11 DEFINE_ALLOCATE_PERMANENT(constMethodKlass); 76.12 constMethodOop allocate(int byte_code_size, int compressed_line_number_size, 76.13 int localvariable_table_length, 76.14 - int checked_exceptions_length, TRAPS); 76.15 + int checked_exceptions_length, 76.16 + bool is_conc_safe, 76.17 + TRAPS); 76.18 static klassOop create_klass(TRAPS); 76.19 76.20 // Sizing
77.1 --- a/src/share/vm/oops/constMethodOop.hpp Thu Jan 29 13:20:56 2009 -0800 77.2 +++ b/src/share/vm/oops/constMethodOop.hpp Fri Jan 30 15:28:00 2009 -0800 77.3 @@ -104,6 +104,7 @@ 77.4 // loads and stores. This value may updated and read without a lock by 77.5 // multiple threads, so is volatile. 77.6 volatile uint64_t _fingerprint; 77.7 + volatile bool _is_conc_safe; // if true, safe for concurrent GC processing 77.8 77.9 public: 77.10 oop* oop_block_beg() const { return adr_method(); } 77.11 @@ -273,6 +274,8 @@ 77.12 oop* adr_method() const { return (oop*)&_method; } 77.13 oop* adr_stackmap_data() const { return (oop*)&_stackmap_data; } 77.14 oop* adr_exception_table() const { return (oop*)&_exception_table; } 77.15 + bool is_conc_safe() { return _is_conc_safe; } 77.16 + void set_is_conc_safe(bool v) { _is_conc_safe = v; } 77.17 77.18 // Unique id for the method 77.19 static const u2 MAX_IDNUM;
78.1 --- a/src/share/vm/oops/constantPoolKlass.cpp Thu Jan 29 13:20:56 2009 -0800 78.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp Fri Jan 30 15:28:00 2009 -0800 78.3 @@ -25,7 +25,7 @@ 78.4 # include "incls/_precompiled.incl" 78.5 # include "incls/_constantPoolKlass.cpp.incl" 78.6 78.7 -constantPoolOop constantPoolKlass::allocate(int length, TRAPS) { 78.8 +constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS) { 78.9 int size = constantPoolOopDesc::object_size(length); 78.10 KlassHandle klass (THREAD, as_klassOop()); 78.11 constantPoolOop c = 78.12 @@ -38,6 +38,9 @@ 78.13 c->set_flags(0); 78.14 // only set to non-zero if constant pool is merged by RedefineClasses 78.15 c->set_orig_length(0); 78.16 + // if constant pool may change during RedefineClasses, it is created 78.17 + // unsafe for GC concurrent processing. 78.18 + c->set_is_conc_safe(is_conc_safe); 78.19 // all fields are initialized; needed for GC 78.20 78.21 // initialize tag array 78.22 @@ -207,6 +210,11 @@ 78.23 return size; 78.24 } 78.25 78.26 +bool constantPoolKlass::oop_is_conc_safe(oop obj) const { 78.27 + assert(obj->is_constantPool(), "must be constantPool"); 78.28 + return constantPoolOop(obj)->is_conc_safe(); 78.29 +} 78.30 + 78.31 #ifndef SERIALGC 78.32 int constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 78.33 assert (obj->is_constantPool(), "obj must be constant pool");
79.1 --- a/src/share/vm/oops/constantPoolKlass.hpp Thu Jan 29 13:20:56 2009 -0800 79.2 +++ b/src/share/vm/oops/constantPoolKlass.hpp Fri Jan 30 15:28:00 2009 -0800 79.3 @@ -34,7 +34,7 @@ 79.4 79.5 // Allocation 79.6 DEFINE_ALLOCATE_PERMANENT(constantPoolKlass); 79.7 - constantPoolOop allocate(int length, TRAPS); 79.8 + constantPoolOop allocate(int length, bool is_conc_safe, TRAPS); 79.9 static klassOop create_klass(TRAPS); 79.10 79.11 // Casting from klassOop 79.12 @@ -48,6 +48,8 @@ 79.13 int object_size() const { return align_object_size(header_size()); } 79.14 79.15 // Garbage collection 79.16 + // Returns true is the object is safe for GC concurrent processing. 79.17 + virtual bool oop_is_conc_safe(oop obj) const; 79.18 void oop_follow_contents(oop obj); 79.19 int oop_adjust_pointers(oop obj); 79.20
80.1 --- a/src/share/vm/oops/constantPoolOop.cpp Thu Jan 29 13:20:56 2009 -0800 80.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Fri Jan 30 15:28:00 2009 -0800 80.3 @@ -962,7 +962,7 @@ 80.4 } 80.5 case JVM_CONSTANT_Long: { 80.6 u8 val = Bytes::get_Java_u8(bytes); 80.7 - printf("long %lldl", *(jlong *) &val); 80.8 + printf("long "INT64_FORMAT, *(jlong *) &val); 80.9 ent_size = 8; 80.10 idx++; // Long takes two cpool slots 80.11 break;
81.1 --- a/src/share/vm/oops/constantPoolOop.hpp Thu Jan 29 13:20:56 2009 -0800 81.2 +++ b/src/share/vm/oops/constantPoolOop.hpp Fri Jan 30 15:28:00 2009 -0800 81.3 @@ -43,6 +43,8 @@ 81.4 klassOop _pool_holder; // the corresponding class 81.5 int _flags; // a few header bits to describe contents for GC 81.6 int _length; // number of elements in the array 81.7 + volatile bool _is_conc_safe; // if true, safe for concurrent 81.8 + // GC processing 81.9 // only set to non-zero if constant pool is merged by RedefineClasses 81.10 int _orig_length; 81.11 81.12 @@ -379,6 +381,9 @@ 81.13 static int object_size(int length) { return align_object_size(header_size() + length); } 81.14 int object_size() { return object_size(length()); } 81.15 81.16 + bool is_conc_safe() { return _is_conc_safe; } 81.17 + void set_is_conc_safe(bool v) { _is_conc_safe = v; } 81.18 + 81.19 friend class constantPoolKlass; 81.20 friend class ClassFileParser; 81.21 friend class SystemDictionary;
82.1 --- a/src/share/vm/oops/klass.hpp Thu Jan 29 13:20:56 2009 -0800 82.2 +++ b/src/share/vm/oops/klass.hpp Fri Jan 30 15:28:00 2009 -0800 82.3 @@ -606,8 +606,19 @@ 82.4 #undef assert_same_query 82.5 82.6 // Unless overridden, oop is parsable if it has a klass pointer. 82.7 + // Parsability of an object is object specific. 82.8 virtual bool oop_is_parsable(oop obj) const { return true; } 82.9 82.10 + // Unless overridden, oop is safe for concurrent GC processing 82.11 + // after its allocation is complete. The exception to 82.12 + // this is the case where objects are changed after allocation. 82.13 + // Class redefinition is one of the known exceptions. During 82.14 + // class redefinition, an allocated class can changed in order 82.15 + // order to create a merged class (the combiniation of the 82.16 + // old class definition that has to be perserved and the new class 82.17 + // definition which is being created. 82.18 + virtual bool oop_is_conc_safe(oop obj) const { return true; } 82.19 + 82.20 // Access flags 82.21 AccessFlags access_flags() const { return _access_flags; } 82.22 void set_access_flags(AccessFlags flags) { _access_flags = flags; }
83.1 --- a/src/share/vm/oops/methodOop.cpp Thu Jan 29 13:20:56 2009 -0800 83.2 +++ b/src/share/vm/oops/methodOop.cpp Fri Jan 30 15:28:00 2009 -0800 83.3 @@ -792,15 +792,34 @@ 83.4 AccessFlags flags = m->access_flags(); 83.5 int checked_exceptions_len = m->checked_exceptions_length(); 83.6 int localvariable_len = m->localvariable_table_length(); 83.7 - methodOop newm_oop = oopFactory::new_method(new_code_length, flags, new_compressed_linenumber_size, localvariable_len, checked_exceptions_len, CHECK_(methodHandle())); 83.8 + // Allocate newm_oop with the is_conc_safe parameter set 83.9 + // to IsUnsafeConc to indicate that newm_oop is not yet 83.10 + // safe for concurrent processing by a GC. 83.11 + methodOop newm_oop = oopFactory::new_method(new_code_length, 83.12 + flags, 83.13 + new_compressed_linenumber_size, 83.14 + localvariable_len, 83.15 + checked_exceptions_len, 83.16 + IsUnsafeConc, 83.17 + CHECK_(methodHandle())); 83.18 methodHandle newm (THREAD, newm_oop); 83.19 int new_method_size = newm->method_size(); 83.20 // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop 83.21 constMethodOop newcm = newm->constMethod(); 83.22 int new_const_method_size = newm->constMethod()->object_size(); 83.23 + 83.24 memcpy(newm(), m(), sizeof(methodOopDesc)); 83.25 // Create shallow copy of constMethodOopDesc, but be careful to preserve the methodOop 83.26 + // is_conc_safe is set to false because that is the value of 83.27 + // is_conc_safe initialzied into newcm and the copy should 83.28 + // not overwrite that value. During the window during which it is 83.29 + // tagged as unsafe, some extra work could be needed during precleaning 83.30 + // or concurrent marking but those phases will be correct. Setting and 83.31 + // resetting is done in preference to a careful copying into newcm to 83.32 + // avoid having to know the precise layout of a constMethodOop. 83.33 + m->constMethod()->set_is_conc_safe(false); 83.34 memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc)); 83.35 + m->constMethod()->set_is_conc_safe(true); 83.36 // Reset correct method/const method, method size, and parameter info 83.37 newcm->set_method(newm()); 83.38 newm->set_constMethod(newcm); 83.39 @@ -831,6 +850,10 @@ 83.40 m->localvariable_table_start(), 83.41 localvariable_len * sizeof(LocalVariableTableElement)); 83.42 } 83.43 + 83.44 + // Only set is_conc_safe to true when changes to newcm are 83.45 + // complete. 83.46 + newcm->set_is_conc_safe(true); 83.47 return newm; 83.48 } 83.49
84.1 --- a/src/share/vm/oops/methodOop.hpp Thu Jan 29 13:20:56 2009 -0800 84.2 +++ b/src/share/vm/oops/methodOop.hpp Fri Jan 30 15:28:00 2009 -0800 84.3 @@ -129,6 +129,10 @@ 84.4 volatile address _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry 84.5 84.6 public: 84.7 + 84.8 + static const bool IsUnsafeConc = false; 84.9 + static const bool IsSafeConc = true; 84.10 + 84.11 // accessors for instance variables 84.12 constMethodOop constMethod() const { return _constMethod; } 84.13 void set_constMethod(constMethodOop xconst) { oop_store_without_check((oop*)&_constMethod, (oop)xconst); }
85.1 --- a/src/share/vm/oops/oop.hpp Thu Jan 29 13:20:56 2009 -0800 85.2 +++ b/src/share/vm/oops/oop.hpp Fri Jan 30 15:28:00 2009 -0800 85.3 @@ -108,6 +108,13 @@ 85.4 // installation of their klass pointer. 85.5 bool is_parsable(); 85.6 85.7 + // Some perm gen objects that have been allocated and initialized 85.8 + // can be changed by the VM when not at a safe point (class rededfinition 85.9 + // is an example). Such objects should not be examined by the 85.10 + // concurrent processing of a garbage collector if is_conc_safe() 85.11 + // returns false. 85.12 + bool is_conc_safe(); 85.13 + 85.14 // type test operations (inlined in oop.inline.h) 85.15 bool is_instance() const; 85.16 bool is_instanceRef() const;
86.1 --- a/src/share/vm/oops/oop.inline.hpp Thu Jan 29 13:20:56 2009 -0800 86.2 +++ b/src/share/vm/oops/oop.inline.hpp Fri Jan 30 15:28:00 2009 -0800 86.3 @@ -435,6 +435,10 @@ 86.4 return blueprint()->oop_is_parsable(this); 86.5 } 86.6 86.7 +inline bool oopDesc::is_conc_safe() { 86.8 + return blueprint()->oop_is_conc_safe(this); 86.9 +} 86.10 + 86.11 inline void update_barrier_set(void* p, oop v) { 86.12 assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!"); 86.13 oopDesc::bs()->write_ref_field(p, v);
87.1 --- a/src/share/vm/oops/oopsHierarchy.hpp Thu Jan 29 13:20:56 2009 -0800 87.2 +++ b/src/share/vm/oops/oopsHierarchy.hpp Fri Jan 30 15:28:00 2009 -0800 87.3 @@ -126,8 +126,11 @@ 87.4 operator jobject () const { return (jobject)obj(); } 87.5 // from javaClasses.cpp 87.6 operator JavaThread* () const { return (JavaThread*)obj(); } 87.7 + 87.8 +#ifndef _LP64 87.9 // from jvm.cpp 87.10 operator jlong* () const { return (jlong*)obj(); } 87.11 +#endif 87.12 87.13 // from parNewGeneration and other things that want to get to the end of 87.14 // an oop for stuff (like constMethodKlass.cpp, objArrayKlass.cpp)
88.1 --- a/src/share/vm/opto/idealGraphPrinter.cpp Thu Jan 29 13:20:56 2009 -0800 88.2 +++ b/src/share/vm/opto/idealGraphPrinter.cpp Fri Jan 30 15:28:00 2009 -0800 88.3 @@ -557,7 +557,7 @@ 88.4 88.5 // max. 2 chars allowed 88.6 if (value >= -9 && value <= 99) { 88.7 - sprintf(buffer, "%d", value); 88.8 + sprintf(buffer, INT64_FORMAT, value); 88.9 print_prop(short_name, buffer); 88.10 } else { 88.11 print_prop(short_name, "L");
89.1 --- a/src/share/vm/prims/jni.cpp Thu Jan 29 13:20:56 2009 -0800 89.2 +++ b/src/share/vm/prims/jni.cpp Fri Jan 30 15:28:00 2009 -0800 89.3 @@ -2691,8 +2691,13 @@ 89.4 89.5 directBufferSupportInitializeEnded = 1; 89.6 } else { 89.7 - ThreadInVMfromNative tivn(thread); // set state as yield_all can call os:sleep 89.8 while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) { 89.9 + // Set state as yield_all can call os:sleep. On Solaris, yield_all calls 89.10 + // os::sleep which requires the VM state transition. On other platforms, it 89.11 + // is not necessary. The following call to change the VM state is purposely 89.12 + // put inside the loop to avoid potential deadlock when multiple threads 89.13 + // try to call this method. See 6791815 for more details. 89.14 + ThreadInVMfromNative tivn(thread); 89.15 os::yield_all(); 89.16 } 89.17 }
90.1 --- a/src/share/vm/prims/jvm.cpp Thu Jan 29 13:20:56 2009 -0800 90.2 +++ b/src/share/vm/prims/jvm.cpp Fri Jan 30 15:28:00 2009 -0800 90.3 @@ -2475,7 +2475,8 @@ 90.4 if (Arguments::vfprintf_hook() != NULL) { 90.5 jio_fprintf(defaultStream::output_stream(), "%s", s); 90.6 } else { 90.7 - ::write(defaultStream::output_fd(), s, (int)strlen(s)); 90.8 + // Make an unused local variable to avoid warning from gcc 4.x compiler. 90.9 + size_t count = ::write(defaultStream::output_fd(), s, (int)strlen(s)); 90.10 } 90.11 } 90.12
91.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 29 13:20:56 2009 -0800 91.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jan 30 15:28:00 2009 -0800 91.3 @@ -1230,8 +1230,14 @@ 91.4 91.5 // Constant pools are not easily reused so we allocate a new one 91.6 // each time. 91.7 + // merge_cp is created unsafe for concurrent GC processing. It 91.8 + // should be marked safe before discarding it because, even if 91.9 + // garbage. If it crosses a card boundary, it may be scanned 91.10 + // in order to find the start of the first complete object on the card. 91.11 constantPoolHandle merge_cp(THREAD, 91.12 - oopFactory::new_constantPool(merge_cp_length, THREAD)); 91.13 + oopFactory::new_constantPool(merge_cp_length, 91.14 + methodOopDesc::IsUnsafeConc, 91.15 + THREAD)); 91.16 int orig_length = old_cp->orig_length(); 91.17 if (orig_length == 0) { 91.18 // This old_cp is an actual original constant pool. We save 91.19 @@ -1274,6 +1280,7 @@ 91.20 // rewriting so we can't use the old constant pool with the new 91.21 // class. 91.22 91.23 + merge_cp()->set_is_conc_safe(true); 91.24 merge_cp = constantPoolHandle(); // toss the merged constant pool 91.25 } else if (old_cp->length() < scratch_cp->length()) { 91.26 // The old constant pool has fewer entries than the new constant 91.27 @@ -1283,6 +1290,7 @@ 91.28 // rewriting so we can't use the new constant pool with the old 91.29 // class. 91.30 91.31 + merge_cp()->set_is_conc_safe(true); 91.32 merge_cp = constantPoolHandle(); // toss the merged constant pool 91.33 } else { 91.34 // The old constant pool has more entries than the new constant 91.35 @@ -1296,6 +1304,7 @@ 91.36 set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true, 91.37 THREAD); 91.38 // drop local ref to the merged constant pool 91.39 + merge_cp()->set_is_conc_safe(true); 91.40 merge_cp = constantPoolHandle(); 91.41 } 91.42 } else { 91.43 @@ -1325,7 +1334,10 @@ 91.44 // GCed. 91.45 set_new_constant_pool(scratch_class, merge_cp, merge_cp_length, true, 91.46 THREAD); 91.47 + merge_cp()->set_is_conc_safe(true); 91.48 } 91.49 + assert(old_cp()->is_conc_safe(), "Just checking"); 91.50 + assert(scratch_cp()->is_conc_safe(), "Just checking"); 91.51 91.52 return JVMTI_ERROR_NONE; 91.53 } // end merge_cp_and_rewrite() 91.54 @@ -2314,13 +2326,16 @@ 91.55 // worst case merge situation. We want to associate the minimum 91.56 // sized constant pool with the klass to save space. 91.57 constantPoolHandle smaller_cp(THREAD, 91.58 - oopFactory::new_constantPool(scratch_cp_length, THREAD)); 91.59 + oopFactory::new_constantPool(scratch_cp_length, 91.60 + methodOopDesc::IsUnsafeConc, 91.61 + THREAD)); 91.62 // preserve orig_length() value in the smaller copy 91.63 int orig_length = scratch_cp->orig_length(); 91.64 assert(orig_length != 0, "sanity check"); 91.65 smaller_cp->set_orig_length(orig_length); 91.66 scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); 91.67 scratch_cp = smaller_cp; 91.68 + smaller_cp()->set_is_conc_safe(true); 91.69 } 91.70 91.71 // attach new constant pool to klass 91.72 @@ -2516,6 +2531,7 @@ 91.73 91.74 rewrite_cp_refs_in_stack_map_table(method, THREAD); 91.75 } // end for each method 91.76 + assert(scratch_cp()->is_conc_safe(), "Just checking"); 91.77 } // end set_new_constant_pool() 91.78 91.79
92.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp Thu Jan 29 13:20:56 2009 -0800 92.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Fri Jan 30 15:28:00 2009 -0800 92.3 @@ -1320,6 +1320,9 @@ 92.4 } 92.5 92.6 // do the iteration 92.7 + // If this operation encounters a bad object when using CMS, 92.8 + // consider using safe_object_iterate() which avoids perm gen 92.9 + // objects that may contain bad references. 92.10 Universe::heap()->object_iterate(_blk); 92.11 92.12 // when sharing is enabled we must iterate over the shared spaces
93.1 --- a/src/share/vm/runtime/arguments.cpp Thu Jan 29 13:20:56 2009 -0800 93.2 +++ b/src/share/vm/runtime/arguments.cpp Fri Jan 30 15:28:00 2009 -0800 93.3 @@ -229,6 +229,7 @@ 93.4 93.5 inline void set_base(const char* base); 93.6 inline void add_prefix(const char* prefix); 93.7 + inline void add_suffix_to_prefix(const char* suffix); 93.8 inline void add_suffix(const char* suffix); 93.9 inline void reset_path(const char* base); 93.10 93.11 @@ -290,6 +291,10 @@ 93.12 _items[_scp_prefix] = add_to_path(_items[_scp_prefix], prefix, true); 93.13 } 93.14 93.15 +inline void SysClassPath::add_suffix_to_prefix(const char* suffix) { 93.16 + _items[_scp_prefix] = add_to_path(_items[_scp_prefix], suffix, false); 93.17 +} 93.18 + 93.19 inline void SysClassPath::add_suffix(const char* suffix) { 93.20 _items[_scp_suffix] = add_to_path(_items[_scp_suffix], suffix, false); 93.21 } 93.22 @@ -512,7 +517,6 @@ 93.23 return CommandLineFlags::boolAtPut(name, &value, origin); 93.24 } 93.25 93.26 - 93.27 static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) { 93.28 double v; 93.29 if (sscanf(value, "%lf", &v) != 1) { 93.30 @@ -525,7 +529,6 @@ 93.31 return false; 93.32 } 93.33 93.34 - 93.35 static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) { 93.36 julong v; 93.37 intx intx_v; 93.38 @@ -555,7 +558,6 @@ 93.39 return false; 93.40 } 93.41 93.42 - 93.43 static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) { 93.44 if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false; 93.45 // Contract: CommandLineFlags always returns a pointer that needs freeing. 93.46 @@ -591,7 +593,6 @@ 93.47 return true; 93.48 } 93.49 93.50 - 93.51 bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) { 93.52 93.53 // range of acceptable characters spelled out for portability reasons 93.54 @@ -652,7 +653,6 @@ 93.55 return false; 93.56 } 93.57 93.58 - 93.59 void Arguments::add_string(char*** bldarray, int* count, const char* arg) { 93.60 assert(bldarray != NULL, "illegal argument"); 93.61 93.62 @@ -756,7 +756,6 @@ 93.63 return true; 93.64 } 93.65 93.66 - 93.67 bool Arguments::process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized) { 93.68 FILE* stream = fopen(file_name, "rb"); 93.69 if (stream == NULL) { 93.70 @@ -932,7 +931,6 @@ 93.71 } 93.72 } 93.73 93.74 - 93.75 // Conflict: required to use shared spaces (-Xshare:on), but 93.76 // incompatible command line options were chosen. 93.77 93.78 @@ -946,7 +944,6 @@ 93.79 } 93.80 } 93.81 93.82 - 93.83 // If the user has chosen ParallelGCThreads > 0, we set UseParNewGC 93.84 // if it's not explictly set or unset. If the user has chosen 93.85 // UseParNewGC and not explicitly set ParallelGCThreads we 93.86 @@ -1361,7 +1358,7 @@ 93.87 93.88 // Feed the cache size setting into the JDK 93.89 char buffer[1024]; 93.90 - sprintf(buffer, "java.lang.Integer.IntegerCache.high=%d", AutoBoxCacheMax); 93.91 + sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax); 93.92 add_property(buffer); 93.93 } 93.94 if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) { 93.95 @@ -1714,6 +1711,21 @@ 93.96 return result; 93.97 } 93.98 93.99 + if (AggressiveOpts) { 93.100 + // Insert alt-rt.jar between user-specified bootclasspath 93.101 + // prefix and the default bootclasspath. os::set_boot_path() 93.102 + // uses meta_index_dir as the default bootclasspath directory. 93.103 + const char* altclasses_jar = "alt-rt.jar"; 93.104 + size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + 93.105 + strlen(altclasses_jar); 93.106 + char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len); 93.107 + strcpy(altclasses_path, get_meta_index_dir()); 93.108 + strcat(altclasses_path, altclasses_jar); 93.109 + scp.add_suffix_to_prefix(altclasses_path); 93.110 + scp_assembly_required = true; 93.111 + FREE_C_HEAP_ARRAY(char, altclasses_path); 93.112 + } 93.113 + 93.114 // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) 93.115 result = parse_java_options_environment_variable(&scp, &scp_assembly_required); 93.116 if (result != JNI_OK) { 93.117 @@ -1729,7 +1741,6 @@ 93.118 return JNI_OK; 93.119 } 93.120 93.121 - 93.122 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, 93.123 SysClassPath* scp_p, 93.124 bool* scp_assembly_required_p, 93.125 @@ -1795,7 +1806,7 @@ 93.126 *scp_assembly_required_p = true; 93.127 // -Xrun 93.128 } else if (match_option(option, "-Xrun", &tail)) { 93.129 - if(tail != NULL) { 93.130 + if (tail != NULL) { 93.131 const char* pos = strchr(tail, ':'); 93.132 size_t len = (pos == NULL) ? strlen(tail) : pos - tail; 93.133 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len); 93.134 @@ -2558,7 +2569,6 @@ 93.135 } 93.136 } 93.137 93.138 - 93.139 // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS 93.140 jint result = parse_vm_init_args(args); 93.141 if (result != JNI_OK) {
94.1 --- a/src/share/vm/runtime/globals.hpp Thu Jan 29 13:20:56 2009 -0800 94.2 +++ b/src/share/vm/runtime/globals.hpp Fri Jan 30 15:28:00 2009 -0800 94.3 @@ -835,8 +835,21 @@ 94.4 "Prints the system dictionary at exit") \ 94.5 \ 94.6 diagnostic(bool, UnsyncloadClass, false, \ 94.7 - "Unstable: VM calls loadClass unsynchronized. Custom classloader "\ 94.8 - "must call VM synchronized for findClass & defineClass") \ 94.9 + "Unstable: VM calls loadClass unsynchronized. Custom " \ 94.10 + "class loader must call VM synchronized for findClass " \ 94.11 + "and defineClass.") \ 94.12 + \ 94.13 + product(bool, AlwaysLockClassLoader, false, \ 94.14 + "Require the VM to acquire the class loader lock before calling " \ 94.15 + "loadClass() even for class loaders registering " \ 94.16 + "as parallel capable. Default false. ") \ 94.17 + \ 94.18 + product(bool, AllowParallelDefineClass, false, \ 94.19 + "Allow parallel defineClass requests for class loaders " \ 94.20 + "registering as parallel capable. Default false") \ 94.21 + \ 94.22 + product(bool, MustCallLoadClassInternal, false, \ 94.23 + "Call loadClassInternal() rather than loadClass().Default false") \ 94.24 \ 94.25 product_pd(bool, DontYieldALot, \ 94.26 "Throw away obvious excess yield calls (for SOLARIS only)") \ 94.27 @@ -1294,7 +1307,14 @@ 94.28 product(intx, ParGCArrayScanChunk, 50, \ 94.29 "Scan a subset and push remainder, if array is bigger than this") \ 94.30 \ 94.31 - product(intx, ParGCDesiredObjsFromOverflowList, 20, \ 94.32 + notproduct(bool, ParGCWorkQueueOverflowALot, false, \ 94.33 + "Whether we should simulate work queue overflow in ParNew") \ 94.34 + \ 94.35 + notproduct(uintx, ParGCWorkQueueOverflowInterval, 1000, \ 94.36 + "An `interval' counter that determines how frequently" \ 94.37 + " we simulate overflow; a smaller number increases frequency") \ 94.38 + \ 94.39 + product(uintx, ParGCDesiredObjsFromOverflowList, 20, \ 94.40 "The desired number of objects to claim from the overflow list") \ 94.41 \ 94.42 product(uintx, CMSParPromoteBlocksToClaim, 50, \ 94.43 @@ -1416,8 +1436,8 @@ 94.44 "Whether we should simulate frequent marking stack / work queue" \ 94.45 " overflow") \ 94.46 \ 94.47 - notproduct(intx, CMSMarkStackOverflowInterval, 1000, \ 94.48 - "A per-thread `interval' counter that determines how frequently" \ 94.49 + notproduct(uintx, CMSMarkStackOverflowInterval, 1000, \ 94.50 + "An `interval' counter that determines how frequently" \ 94.51 " we simulate overflow; a smaller number increases frequency") \ 94.52 \ 94.53 product(uintx, CMSMaxAbortablePrecleanLoops, 0, \ 94.54 @@ -1635,7 +1655,7 @@ 94.55 develop(uintx, WorkStealingYieldsBeforeSleep, 1000, \ 94.56 "Number of yields before a sleep is done during workstealing") \ 94.57 \ 94.58 - product(uintx, PreserveMarkStackSize, 40, \ 94.59 + product(uintx, PreserveMarkStackSize, 1024, \ 94.60 "Size for stack used in promotion failure handling") \ 94.61 \ 94.62 product_pd(bool, UseTLAB, "Use thread-local object allocation") \
95.1 --- a/src/share/vm/runtime/memprofiler.cpp Thu Jan 29 13:20:56 2009 -0800 95.2 +++ b/src/share/vm/runtime/memprofiler.cpp Fri Jan 30 15:28:00 2009 -0800 95.3 @@ -104,21 +104,22 @@ 95.4 } 95.5 95.6 // Print trace line in log 95.7 - fprintf(_log_fp, "%6.1f,%5d,%5d,%6ld,%6ld,%6ld,%6ld,", 95.8 - os::elapsedTime(), 95.9 - Threads::number_of_threads(), 95.10 - SystemDictionary::number_of_classes(), 95.11 - Universe::heap()->used() / K, 95.12 - Universe::heap()->capacity() / K, 95.13 - Universe::heap()->permanent_used() / HWperKB, 95.14 - Universe::heap()->permanent_capacity() / HWperKB); 95.15 + fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) "," 95.16 + UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",", 95.17 + os::elapsedTime(), 95.18 + Threads::number_of_threads(), 95.19 + SystemDictionary::number_of_classes(), 95.20 + Universe::heap()->used() / K, 95.21 + Universe::heap()->capacity() / K, 95.22 + Universe::heap()->permanent_used() / HWperKB, 95.23 + Universe::heap()->permanent_capacity() / HWperKB); 95.24 95.25 - fprintf(_log_fp, "%6ld,", CodeCache::capacity() / K); 95.26 + fprintf(_log_fp, UINTX_FORMAT_W(6) ",", CodeCache::capacity() / K); 95.27 95.28 - fprintf(_log_fp, "%6ld,%6ld,%6ld\n", 95.29 - handles_memory_usage / K, 95.30 - resource_memory_usage / K, 95.31 - OopMapCache::memory_usage() / K); 95.32 + fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",%6ld\n", 95.33 + handles_memory_usage / K, 95.34 + resource_memory_usage / K, 95.35 + OopMapCache::memory_usage() / K); 95.36 fflush(_log_fp); 95.37 } 95.38
96.1 --- a/src/share/vm/runtime/safepoint.cpp Thu Jan 29 13:20:56 2009 -0800 96.2 +++ b/src/share/vm/runtime/safepoint.cpp Fri Jan 30 15:28:00 2009 -0800 96.3 @@ -730,7 +730,7 @@ 96.4 if (DieOnSafepointTimeout) { 96.5 char msg[1024]; 96.6 VM_Operation *op = VMThread::vm_operation(); 96.7 - sprintf(msg, "Safepoint sync time longer than %d ms detected when executing %s.", 96.8 + sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.", 96.9 SafepointTimeoutDelay, 96.10 op != NULL ? op->name() : "no vm operation"); 96.11 fatal(msg);
97.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Jan 29 13:20:56 2009 -0800 97.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Jan 30 15:28:00 2009 -0800 97.3 @@ -192,64 +192,46 @@ 97.4 97.5 97.6 JRT_LEAF(jint, SharedRuntime::f2i(jfloat x)) 97.7 - if (g_isnan(x)) {return 0;} 97.8 - jlong lltmp = (jlong)x; 97.9 - jint ltmp = (jint)lltmp; 97.10 - if (ltmp == lltmp) { 97.11 - return ltmp; 97.12 - } else { 97.13 - if (x < 0) { 97.14 - return min_jint; 97.15 - } else { 97.16 - return max_jint; 97.17 - } 97.18 - } 97.19 + if (g_isnan(x)) 97.20 + return 0; 97.21 + if (x >= (jfloat) max_jint) 97.22 + return max_jint; 97.23 + if (x <= (jfloat) min_jint) 97.24 + return min_jint; 97.25 + return (jint) x; 97.26 JRT_END 97.27 97.28 97.29 JRT_LEAF(jlong, SharedRuntime::f2l(jfloat x)) 97.30 - if (g_isnan(x)) {return 0;} 97.31 - jlong lltmp = (jlong)x; 97.32 - if (lltmp != min_jlong) { 97.33 - return lltmp; 97.34 - } else { 97.35 - if (x < 0) { 97.36 - return min_jlong; 97.37 - } else { 97.38 - return max_jlong; 97.39 - } 97.40 - } 97.41 + if (g_isnan(x)) 97.42 + return 0; 97.43 + if (x >= (jfloat) max_jlong) 97.44 + return max_jlong; 97.45 + if (x <= (jfloat) min_jlong) 97.46 + return min_jlong; 97.47 + return (jlong) x; 97.48 JRT_END 97.49 97.50 97.51 JRT_LEAF(jint, SharedRuntime::d2i(jdouble x)) 97.52 - if (g_isnan(x)) {return 0;} 97.53 - jlong lltmp = (jlong)x; 97.54 - jint ltmp = (jint)lltmp; 97.55 - if (ltmp == lltmp) { 97.56 - return ltmp; 97.57 - } else { 97.58 - if (x < 0) { 97.59 - return min_jint; 97.60 - } else { 97.61 - return max_jint; 97.62 - } 97.63 - } 97.64 + if (g_isnan(x)) 97.65 + return 0; 97.66 + if (x >= (jdouble) max_jint) 97.67 + return max_jint; 97.68 + if (x <= (jdouble) min_jint) 97.69 + return min_jint; 97.70 + return (jint) x; 97.71 JRT_END 97.72 97.73 97.74 JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x)) 97.75 - if (g_isnan(x)) {return 0;} 97.76 - jlong lltmp = (jlong)x; 97.77 - if (lltmp != min_jlong) { 97.78 - return lltmp; 97.79 - } else { 97.80 - if (x < 0) { 97.81 - return min_jlong; 97.82 - } else { 97.83 - return max_jlong; 97.84 - } 97.85 - } 97.86 + if (g_isnan(x)) 97.87 + return 0; 97.88 + if (x >= (jdouble) max_jlong) 97.89 + return max_jlong; 97.90 + if (x <= (jdouble) min_jlong) 97.91 + return min_jlong; 97.92 + return (jlong) x; 97.93 JRT_END 97.94 97.95
98.1 --- a/src/share/vm/runtime/synchronizer.cpp Thu Jan 29 13:20:56 2009 -0800 98.2 +++ b/src/share/vm/runtime/synchronizer.cpp Fri Jan 30 15:28:00 2009 -0800 98.3 @@ -424,7 +424,7 @@ 98.4 // asserts is that error message -- often something about negative array 98.5 // indices -- is opaque. 98.6 98.7 -#define CTASSERT(x) { int tag[1-(2*!(x))]; printf ("Tag @%X\n", tag); } 98.8 +#define CTASSERT(x) { int tag[1-(2*!(x))]; printf ("Tag @" INTPTR_FORMAT "\n", (intptr_t)tag); } 98.9 98.10 void ObjectMonitor::ctAsserts() { 98.11 CTASSERT(offset_of (ObjectMonitor, _header) == 0);
99.1 --- a/src/share/vm/services/heapDumper.cpp Thu Jan 29 13:20:56 2009 -0800 99.2 +++ b/src/share/vm/services/heapDumper.cpp Fri Jan 30 15:28:00 2009 -0800 99.3 @@ -1700,7 +1700,7 @@ 99.4 // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk 99.5 // of the heap dump. 99.6 HeapObjectDumper obj_dumper(this, writer()); 99.7 - Universe::heap()->object_iterate(&obj_dumper); 99.8 + Universe::heap()->safe_object_iterate(&obj_dumper); 99.9 99.10 // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals 99.11 do_threads();
100.1 --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 29 13:20:56 2009 -0800 100.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp Fri Jan 30 15:28:00 2009 -0800 100.3 @@ -1087,15 +1087,24 @@ 100.4 // Format macros that allow the field width to be specified. The width must be 100.5 // a string literal (e.g., "8") or a macro that evaluates to one. 100.6 #ifdef _LP64 100.7 +#define UINTX_FORMAT_W(width) UINT64_FORMAT_W(width) 100.8 #define SSIZE_FORMAT_W(width) INT64_FORMAT_W(width) 100.9 #define SIZE_FORMAT_W(width) UINT64_FORMAT_W(width) 100.10 #else 100.11 +#define UINTX_FORMAT_W(width) UINT32_FORMAT_W(width) 100.12 #define SSIZE_FORMAT_W(width) INT32_FORMAT_W(width) 100.13 #define SIZE_FORMAT_W(width) UINT32_FORMAT_W(width) 100.14 #endif // _LP64 100.15 100.16 // Format pointers and size_t (or size_t-like integer types) which change size 100.17 -// between 32- and 64-bit. 100.18 +// between 32- and 64-bit. The pointer format theoretically should be "%p", 100.19 +// however, it has different output on different platforms. On Windows, the data 100.20 +// will be padded with zeros automatically. On Solaris, we can use "%016p" & 100.21 +// "%08p" on 64 bit & 32 bit platforms to make the data padded with extra zeros. 100.22 +// On Linux, "%016p" or "%08p" is not be allowed, at least on the latest GCC 100.23 +// 4.3.2. So we have to use "%016x" or "%08x" to simulate the printing format. 100.24 +// GCC 4.3.2, however requires the data to be converted to "intptr_t" when 100.25 +// using "%x". 100.26 #ifdef _LP64 100.27 #define PTR_FORMAT PTR64_FORMAT 100.28 #define UINTX_FORMAT UINT64_FORMAT
101.1 --- a/src/share/vm/utilities/globalDefinitions_gcc.hpp Thu Jan 29 13:20:56 2009 -0800 101.2 +++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp Fri Jan 30 15:28:00 2009 -0800 101.3 @@ -116,7 +116,9 @@ 101.4 #ifdef _LP64 101.5 #define NULL_WORD 0L 101.6 #else 101.7 - #define NULL_WORD 0 101.8 + // Cast 0 to intptr_t rather than int32_t since they are not the same type 101.9 + // on platforms such as Mac OS X. 101.10 + #define NULL_WORD ((intptr_t)0) 101.11 #endif 101.12 #else 101.13 #define NULL_WORD NULL
102.1 --- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Thu Jan 29 13:20:56 2009 -0800 102.2 +++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Fri Jan 30 15:28:00 2009 -0800 102.3 @@ -115,7 +115,9 @@ 102.4 #ifdef _LP64 102.5 #define NULL_WORD 0L 102.6 #else 102.7 - #define NULL_WORD 0 102.8 + // Cast 0 to intptr_t rather than int32_t since they are not the same type 102.9 + // on some platforms. 102.10 + #define NULL_WORD ((intptr_t)0) 102.11 #endif 102.12 #else 102.13 #define NULL_WORD NULL
103.1 --- a/src/share/vm/utilities/ostream.cpp Thu Jan 29 13:20:56 2009 -0800 103.2 +++ b/src/share/vm/utilities/ostream.cpp Fri Jan 30 15:28:00 2009 -0800 103.3 @@ -300,7 +300,10 @@ 103.4 } 103.5 103.6 void fileStream::write(const char* s, size_t len) { 103.7 - if (_file != NULL) fwrite(s, 1, len, _file); 103.8 + if (_file != NULL) { 103.9 + // Make an unused local variable to avoid warning from gcc 4.x compiler. 103.10 + size_t count = fwrite(s, 1, len, _file); 103.11 + } 103.12 update_position(s, len); 103.13 } 103.14 103.15 @@ -328,7 +331,10 @@ 103.16 } 103.17 103.18 void fdStream::write(const char* s, size_t len) { 103.19 - if (_fd != -1) ::write(_fd, s, (int)len); 103.20 + if (_fd != -1) { 103.21 + // Make an unused local variable to avoid warning from gcc 4.x compiler. 103.22 + size_t count = ::write(_fd, s, (int)len); 103.23 + } 103.24 update_position(s, len); 103.25 } 103.26
104.1 --- a/src/share/vm/utilities/vmError.cpp Thu Jan 29 13:20:56 2009 -0800 104.2 +++ b/src/share/vm/utilities/vmError.cpp Fri Jan 30 15:28:00 2009 -0800 104.3 @@ -674,6 +674,11 @@ 104.4 reset_signal_handlers(); 104.5 104.6 } else { 104.7 + // If UseOsErrorReporting we call this for each level of the call stack 104.8 + // while searching for the exception handler. Only the first level needs 104.9 + // to be reported. 104.10 + if (UseOSErrorReporting && log_done) return; 104.11 + 104.12 // This is not the first error, see if it happened in a different thread 104.13 // or in the same thread during error reporting. 104.14 if (first_error_tid != mytid) {
105.1 --- a/src/share/vm/utilities/vmError.hpp Thu Jan 29 13:20:56 2009 -0800 105.2 +++ b/src/share/vm/utilities/vmError.hpp Fri Jan 30 15:28:00 2009 -0800 105.3 @@ -50,7 +50,7 @@ 105.4 105.5 // additional info for VM internal errors 105.6 const char * _filename; 105.7 - int _lineno; 105.8 + size_t _lineno; 105.9 105.10 // used by fatal error handler 105.11 int _current_step;
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 106.2 +++ b/test/compiler/6778657/Test.java Fri Jan 30 15:28:00 2009 -0800 106.3 @@ -0,0 +1,75 @@ 106.4 +/* 106.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 106.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 106.7 + * 106.8 + * This code is free software; you can redistribute it and/or modify it 106.9 + * under the terms of the GNU General Public License version 2 only, as 106.10 + * published by the Free Software Foundation. 106.11 + * 106.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 106.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 106.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 106.15 + * version 2 for more details (a copy is included in the LICENSE file that 106.16 + * accompanied this code). 106.17 + * 106.18 + * You should have received a copy of the GNU General Public License version 106.19 + * 2 along with this work; if not, write to the Free Software Foundation, 106.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 106.21 + * 106.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 106.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 106.24 + * have any questions. 106.25 + * 106.26 + */ 106.27 + 106.28 +/* 106.29 + * @test 106.30 + * @bug 6778657 106.31 + * @summary Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour 106.32 + */ 106.33 + 106.34 +public class Test { 106.35 + public static void check_f2i(int expect) { 106.36 + float check = expect; 106.37 + check *= 2; 106.38 + int actual = (int) check; 106.39 + if (actual != expect) 106.40 + throw new RuntimeException("expecting " + expect + ", got " + actual); 106.41 + } 106.42 + 106.43 + public static void check_f2l(long expect) { 106.44 + float check = expect; 106.45 + check *= 2; 106.46 + long actual = (long) check; 106.47 + if (actual != expect) 106.48 + throw new RuntimeException("expecting " + expect + ", got " + actual); 106.49 + } 106.50 + 106.51 + public static void check_d2i(int expect) { 106.52 + double check = expect; 106.53 + check *= 2; 106.54 + int actual = (int) check; 106.55 + if (actual != expect) 106.56 + throw new RuntimeException("expecting " + expect + ", got " + actual); 106.57 + } 106.58 + 106.59 + public static void check_d2l(long expect) { 106.60 + double check = expect; 106.61 + check *= 2; 106.62 + long actual = (long) check; 106.63 + if (actual != expect) 106.64 + throw new RuntimeException("expecting " + expect + ", got " + actual); 106.65 + } 106.66 + 106.67 + public static void main(String[] args) { 106.68 + check_f2i(Integer.MAX_VALUE); 106.69 + check_f2i(Integer.MIN_VALUE); 106.70 + check_f2l(Long.MAX_VALUE); 106.71 + check_f2l(Long.MIN_VALUE); 106.72 + check_d2i(Integer.MAX_VALUE); 106.73 + check_d2i(Integer.MIN_VALUE); 106.74 + check_d2l(Long.MAX_VALUE); 106.75 + check_d2l(Long.MIN_VALUE); 106.76 + } 106.77 +} 106.78 +