Fri, 08 Feb 2013 09:14:06 -0800
Merge
1.1 --- a/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 10:08:40 2013 +0100 1.2 +++ b/agent/src/os/bsd/MacosxDebuggerLocal.m Fri Feb 08 09:14:06 2013 -0800 1.3 @@ -97,7 +97,8 @@ 1.4 * Method: init0 1.5 * Signature: ()V 1.6 */ 1.7 -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { 1.8 +JNIEXPORT void JNICALL 1.9 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { 1.10 symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); 1.11 taskID = (*env)->GetFieldID(env, cls, "task", "J"); 1.12 CHECK_EXCEPTION; 1.13 @@ -108,7 +109,11 @@ 1.14 * Method: lookupByName0 1.15 * Signature: (Ljava/lang/String;Ljava/lang/String;)J 1.16 */ 1.17 -JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { 1.18 +JNIEXPORT jlong JNICALL 1.19 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0( 1.20 + JNIEnv *env, jobject this_obj, 1.21 + jstring objectName, jstring symbolName) 1.22 +{ 1.23 jlong address = 0; 1.24 1.25 JNF_COCOA_ENTER(env); 1.26 @@ -137,7 +142,11 @@ 1.27 * Method: readBytesFromProcess0 1.28 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; 1.29 */ 1.30 -JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) { 1.31 +JNIEXPORT jbyteArray JNICALL 1.32 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( 1.33 + JNIEnv *env, jobject this_obj, 1.34 + jlong addr, jlong numBytes) 1.35 +{ 1.36 if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); 1.37 1.38 // must allocate storage instead of using former parameter buf 1.39 @@ -209,12 +218,74 @@ 1.40 return array; 1.41 } 1.42 1.43 + 1.44 /* 1.45 - * Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal 1.46 + * Lookup the thread_t that corresponds to the given thread_id. 1.47 + * The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO 1.48 + * and reading the m_ident_info.thread_id returned. 1.49 + * The returned thread_t is the mach send right to the kernel port for the corresponding thread. 1.50 + * 1.51 + * We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self() 1.52 + * in the VM, but that thread port is not valid for a remote debugger to access the thread. 1.53 + */ 1.54 +thread_t 1.55 +lookupThreadFromThreadId(task_t task, jlong thread_id) { 1.56 + if (debug) { 1.57 + printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); 1.58 + } 1.59 + 1.60 + thread_array_t thread_list = NULL; 1.61 + mach_msg_type_number_t thread_list_count = 0; 1.62 + thread_t result_thread = 0; 1.63 + int i; 1.64 + 1.65 + // get the list of all the send rights 1.66 + kern_return_t result = task_threads(task, &thread_list, &thread_list_count); 1.67 + if (result != KERN_SUCCESS) { 1.68 + if (debug) { 1.69 + printf("task_threads returned 0x%x\n", result); 1.70 + } 1.71 + return 0; 1.72 + } 1.73 + 1.74 + for(i = 0 ; i < thread_list_count; i++) { 1.75 + thread_identifier_info_data_t m_ident_info; 1.76 + mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; 1.77 + 1.78 + // get the THREAD_IDENTIFIER_INFO for the send right 1.79 + result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count); 1.80 + if (result != KERN_SUCCESS) { 1.81 + if (debug) { 1.82 + printf("thread_info returned 0x%x\n", result); 1.83 + } 1.84 + break; 1.85 + } 1.86 + 1.87 + // if this is the one we're looking for, return the send right 1.88 + if (thread_id == m_ident_info.thread_id) 1.89 + { 1.90 + result_thread = thread_list[i]; 1.91 + break; 1.92 + } 1.93 + } 1.94 + 1.95 + vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t)); 1.96 + vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count); 1.97 + 1.98 + return result_thread; 1.99 +} 1.100 + 1.101 + 1.102 +/* 1.103 + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 1.104 * Method: getThreadIntegerRegisterSet0 1.105 - * Signature: (I)[J 1.106 + * Signature: (J)[J 1.107 */ 1.108 -JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(JNIEnv *env, jobject this_obj, jint lwp_id) { 1.109 +JNIEXPORT jlongArray JNICALL 1.110 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( 1.111 + JNIEnv *env, jobject this_obj, 1.112 + jlong thread_id) 1.113 +{ 1.114 if (debug) 1.115 printf("getThreadRegisterSet0 called\n"); 1.116 1.117 @@ -226,8 +297,9 @@ 1.118 int i; 1.119 jlongArray registerArray; 1.120 jlong *primitiveArray; 1.121 + task_t gTask = getTask(env, this_obj); 1.122 1.123 - tid = lwp_id; 1.124 + tid = lookupThreadFromThreadId(gTask, thread_id); 1.125 1.126 result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); 1.127 1.128 @@ -328,19 +400,21 @@ 1.129 } 1.130 1.131 /* 1.132 - * Class: sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal 1.133 + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 1.134 * Method: translateTID0 1.135 * Signature: (I)I 1.136 */ 1.137 JNIEXPORT jint JNICALL 1.138 -Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0(JNIEnv *env, jobject this_obj, jint tid) { 1.139 +Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( 1.140 + JNIEnv *env, jobject this_obj, jint tid) 1.141 +{ 1.142 if (debug) 1.143 printf("translateTID0 called on tid = 0x%x\n", (int)tid); 1.144 1.145 kern_return_t result; 1.146 thread_t foreign_tid, usable_tid; 1.147 mach_msg_type_name_t type; 1.148 - 1.149 + 1.150 foreign_tid = tid; 1.151 1.152 task_t gTask = getTask(env, this_obj); 1.153 @@ -361,7 +435,10 @@ 1.154 * Method: attach0 1.155 * Signature: (I)V 1.156 */ 1.157 -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(JNIEnv *env, jobject this_obj, jint jpid) { 1.158 +JNIEXPORT void JNICALL 1.159 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( 1.160 + JNIEnv *env, jobject this_obj, jint jpid) 1.161 +{ 1.162 JNF_COCOA_ENTER(env); 1.163 if (getenv("JAVA_SAPROC_DEBUG") != NULL) 1.164 debug = JNI_TRUE; 1.165 @@ -401,7 +478,10 @@ 1.166 * Method: detach0 1.167 * Signature: ()V 1.168 */ 1.169 -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(JNIEnv *env, jobject this_obj) { 1.170 +JNIEXPORT void JNICALL 1.171 +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( 1.172 + JNIEnv *env, jobject this_obj) 1.173 +{ 1.174 JNF_COCOA_ENTER(env); 1.175 if (debug) printf("detach0 called\n"); 1.176 1.177 @@ -419,10 +499,13 @@ 1.178 * Method: load_library 1.179 * Signature: (Ljava/lang/String;)L 1.180 */ 1.181 -JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIEnv * env, 1.182 - jclass disclass, 1.183 - jstring jrepath_s, 1.184 - jstring libname_s) { 1.185 +JNIEXPORT jlong JNICALL 1.186 +Java_sun_jvm_hotspot_asm_Disassembler_load_1library( 1.187 + JNIEnv * env, 1.188 + jclass disclass, 1.189 + jstring jrepath_s, 1.190 + jstring libname_s) 1.191 +{ 1.192 uintptr_t func = 0; 1.193 const char* error_message = NULL; 1.194 const char* java_home; 1.195 @@ -533,13 +616,16 @@ 1.196 * Method: decode 1.197 * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V 1.198 */ 1.199 -JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env, 1.200 - jobject dis, 1.201 - jobject visitor, 1.202 - jlong startPc, 1.203 - jbyteArray code, 1.204 - jstring options_s, 1.205 - jlong decode_instructions_virtual) { 1.206 +JNIEXPORT void JNICALL 1.207 +Java_sun_jvm_hotspot_asm_Disassembler_decode( 1.208 + JNIEnv * env, 1.209 + jobject dis, 1.210 + jobject visitor, 1.211 + jlong startPc, 1.212 + jbyteArray code, 1.213 + jstring options_s, 1.214 + jlong decode_instructions_virtual) 1.215 +{ 1.216 jboolean isCopy; 1.217 jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy); 1.218 jbyte* end = start + (*env)->GetArrayLength(env, code);
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 10:08:40 2013 +0100 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebugger.java Fri Feb 08 09:14:06 2013 -0800 2.3 @@ -49,7 +49,7 @@ 2.4 public BsdAddress readCompKlassAddress(long address) throws DebuggerException; 2.5 public BsdOopHandle readOopHandle(long address) throws DebuggerException; 2.6 public BsdOopHandle readCompOopHandle(long address) throws DebuggerException; 2.7 - public long[] getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException; 2.8 + public long[] getThreadIntegerRegisterSet(long unique_thread_id) throws DebuggerException; 2.9 public long getAddressValue(Address addr) throws DebuggerException; 2.10 public Address newAddress(long value) throws DebuggerException; 2.11
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 10:08:40 2013 +0100 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Fri Feb 08 09:14:06 2013 -0800 3.3 @@ -90,7 +90,7 @@ 3.4 throws DebuggerException; 3.5 private native ClosestSymbol lookupByAddress0(long address) 3.6 throws DebuggerException; 3.7 - private native long[] getThreadIntegerRegisterSet0(int lwp_id) 3.8 + private native long[] getThreadIntegerRegisterSet0(long unique_thread_id) 3.9 throws DebuggerException; 3.10 private native byte[] readBytesFromProcess0(long address, long numBytes) 3.11 throws DebuggerException; 3.12 @@ -400,10 +400,15 @@ 3.13 // 3.14 3.15 /** From the ThreadAccess interface via Debugger and JVMDebugger */ 3.16 + public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) { 3.17 + return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr); 3.18 + } 3.19 + @Override 3.20 public ThreadProxy getThreadForIdentifierAddress(Address addr) { 3.21 - return new BsdThread(this, addr); 3.22 + throw new RuntimeException("unimplemented"); 3.23 } 3.24 3.25 + 3.26 /** From the ThreadAccess interface via Debugger and JVMDebugger */ 3.27 public ThreadProxy getThreadForThreadId(long id) { 3.28 return new BsdThread(this, id); 3.29 @@ -455,22 +460,22 @@ 3.30 // Thread context access 3.31 // 3.32 3.33 - public synchronized long[] getThreadIntegerRegisterSet(int lwp_id) 3.34 + public synchronized long[] getThreadIntegerRegisterSet(long unique_thread_id) 3.35 throws DebuggerException { 3.36 requireAttach(); 3.37 if (isCore) { 3.38 - return getThreadIntegerRegisterSet0(lwp_id); 3.39 + return getThreadIntegerRegisterSet0(unique_thread_id); 3.40 } else { 3.41 class GetThreadIntegerRegisterSetTask implements WorkerThreadTask { 3.42 - int lwp_id; 3.43 + long unique_thread_id; 3.44 long[] result; 3.45 public void doit(BsdDebuggerLocal debugger) { 3.46 - result = debugger.getThreadIntegerRegisterSet0(lwp_id); 3.47 + result = debugger.getThreadIntegerRegisterSet0(unique_thread_id); 3.48 } 3.49 } 3.50 3.51 GetThreadIntegerRegisterSetTask task = new GetThreadIntegerRegisterSetTask(); 3.52 - task.lwp_id = lwp_id; 3.53 + task.unique_thread_id = unique_thread_id; 3.54 workerThread.execute(task); 3.55 return task.result; 3.56 }
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 10:08:40 2013 +0100 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java Fri Feb 08 09:14:06 2013 -0800 4.3 @@ -28,21 +28,23 @@ 4.4 4.5 class BsdThread implements ThreadProxy { 4.6 private BsdDebugger debugger; 4.7 - private int lwp_id; 4.8 + private int thread_id; 4.9 + private long unique_thread_id; 4.10 4.11 /** The address argument must be the address of the _thread_id in the 4.12 OSThread. It's value is result ::gettid() call. */ 4.13 - BsdThread(BsdDebugger debugger, Address addr) { 4.14 + BsdThread(BsdDebugger debugger, Address threadIdAddr, Address uniqueThreadIdAddr) { 4.15 this.debugger = debugger; 4.16 // FIXME: size of data fetched here should be configurable. 4.17 // However, making it so would produce a dependency on the "types" 4.18 // package from the debugger package, which is not desired. 4.19 - this.lwp_id = (int) addr.getCIntegerAt(0, 4, true); 4.20 + this.thread_id = (int) threadIdAddr.getCIntegerAt(0, 4, true); 4.21 + this.unique_thread_id = uniqueThreadIdAddr.getCIntegerAt(0, 8, true); 4.22 } 4.23 4.24 BsdThread(BsdDebugger debugger, long id) { 4.25 this.debugger = debugger; 4.26 - this.lwp_id = (int) id; 4.27 + this.thread_id = (int) id; 4.28 } 4.29 4.30 public boolean equals(Object obj) { 4.31 @@ -50,19 +52,19 @@ 4.32 return false; 4.33 } 4.34 4.35 - return (((BsdThread) obj).lwp_id == lwp_id); 4.36 + return (((BsdThread) obj).thread_id == thread_id); 4.37 } 4.38 4.39 public int hashCode() { 4.40 - return lwp_id; 4.41 + return thread_id; 4.42 } 4.43 4.44 public String toString() { 4.45 - return Integer.toString(lwp_id); 4.46 + return Integer.toString(thread_id); 4.47 } 4.48 4.49 public ThreadContext getContext() throws IllegalThreadStateException { 4.50 - long[] data = debugger.getThreadIntegerRegisterSet(lwp_id); 4.51 + long[] data = debugger.getThreadIntegerRegisterSet(unique_thread_id); 4.52 ThreadContext context = BsdThreadContextFactory.createThreadContext(debugger); 4.53 for (int i = 0; i < data.length; i++) { 4.54 context.setRegister(i, data[i]);
5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 10:08:40 2013 +0100 5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_amd64/BsdAMD64JavaThreadPDAccess.java Fri Feb 08 09:14:06 2013 -0800 5.3 @@ -28,6 +28,8 @@ 5.4 import java.util.*; 5.5 import sun.jvm.hotspot.debugger.*; 5.6 import sun.jvm.hotspot.debugger.amd64.*; 5.7 +import sun.jvm.hotspot.debugger.bsd.BsdDebugger; 5.8 +import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; 5.9 import sun.jvm.hotspot.runtime.*; 5.10 import sun.jvm.hotspot.runtime.amd64.*; 5.11 import sun.jvm.hotspot.runtime.x86.*; 5.12 @@ -38,8 +40,9 @@ 5.13 private static AddressField lastJavaFPField; 5.14 private static AddressField osThreadField; 5.15 5.16 - // Field from OSThread 5.17 + // Fields from OSThread 5.18 private static CIntegerField osThreadThreadIDField; 5.19 + private static CIntegerField osThreadUniqueThreadIDField; 5.20 5.21 // This is currently unneeded but is being kept in case we change 5.22 // the currentFrameGuess algorithm 5.23 @@ -61,7 +64,8 @@ 5.24 lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); 5.25 5.26 Type osThreadType = db.lookupType("OSThread"); 5.27 - osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); 5.28 + osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); 5.29 + osThreadUniqueThreadIDField = osThreadType.getCIntegerField("_unique_thread_id"); 5.30 } 5.31 5.32 public Address getLastJavaFP(Address addr) { 5.33 @@ -125,8 +129,9 @@ 5.34 Address osThreadAddr = osThreadField.getValue(addr); 5.35 // Get the address of the _thread_id from the OSThread 5.36 Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); 5.37 + Address uniqueThreadIdAddr = osThreadAddr.addOffsetTo(osThreadUniqueThreadIDField.getOffset()); 5.38 5.39 - JVMDebugger debugger = VM.getVM().getDebugger(); 5.40 - return debugger.getThreadForIdentifierAddress(threadIdAddr); 5.41 + BsdDebuggerLocal debugger = (BsdDebuggerLocal) VM.getVM().getDebugger(); 5.42 + return debugger.getThreadForIdentifierAddress(threadIdAddr, uniqueThreadIdAddr); 5.43 } 5.44 }
6.1 --- a/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 10:08:40 2013 +0100 6.2 +++ b/src/os/bsd/vm/osThread_bsd.hpp Fri Feb 08 09:14:06 2013 -0800 6.3 @@ -49,6 +49,11 @@ 6.4 // (e.g. pthread_kill). 6.5 pthread_t _pthread_id; 6.6 6.7 + // This is the "thread_id" from struct thread_identifier_info. According to a 6.8 + // comment in thread_info.h, this is a "system-wide unique 64-bit thread id". 6.9 + // The value is used by SA to correlate threads. 6.10 + uint64_t _unique_thread_id; 6.11 + 6.12 sigset_t _caller_sigmask; // Caller's signal mask 6.13 6.14 public: 6.15 @@ -77,6 +82,10 @@ 6.16 _pthread_id = tid; 6.17 } 6.18 6.19 + void set_unique_thread_id(uint64_t id) { 6.20 + _unique_thread_id = id; 6.21 + } 6.22 + 6.23 // *************************************************************** 6.24 // suspension support. 6.25 // ***************************************************************
7.1 --- a/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 10:08:40 2013 +0100 7.2 +++ b/src/os/bsd/vm/os_bsd.cpp Fri Feb 08 09:14:06 2013 -0800 7.3 @@ -657,6 +657,18 @@ 7.4 objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL; 7.5 #endif 7.6 7.7 +#ifdef __APPLE__ 7.8 +static uint64_t locate_unique_thread_id() { 7.9 + // Additional thread_id used to correlate threads in SA 7.10 + thread_identifier_info_data_t m_ident_info; 7.11 + mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; 7.12 + 7.13 + thread_info(::mach_thread_self(), THREAD_IDENTIFIER_INFO, 7.14 + (thread_info_t) &m_ident_info, &count); 7.15 + return m_ident_info.thread_id; 7.16 +} 7.17 +#endif 7.18 + 7.19 // Thread start routine for all newly created threads 7.20 static void *java_start(Thread *thread) { 7.21 // Try to randomize the cache line index of hot stack frames. 7.22 @@ -685,6 +697,7 @@ 7.23 #ifdef __APPLE__ 7.24 // thread_id is mach thread on macos 7.25 osthread->set_thread_id(::mach_thread_self()); 7.26 + osthread->set_unique_thread_id(locate_unique_thread_id()); 7.27 #else 7.28 // thread_id is pthread_id on BSD 7.29 osthread->set_thread_id(::pthread_self()); 7.30 @@ -847,6 +860,7 @@ 7.31 // Store pthread info into the OSThread 7.32 #ifdef __APPLE__ 7.33 osthread->set_thread_id(::mach_thread_self()); 7.34 + osthread->set_unique_thread_id(locate_unique_thread_id()); 7.35 #else 7.36 osthread->set_thread_id(::pthread_self()); 7.37 #endif
8.1 --- a/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 10:08:40 2013 +0100 8.2 +++ b/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Fri Feb 08 09:14:06 2013 -0800 8.3 @@ -35,17 +35,16 @@ 8.4 /* Threads (NOTE: incomplete) */ \ 8.5 /******************************/ \ 8.6 nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ 8.7 - nonstatic_field(OSThread, _pthread_id, pthread_t) 8.8 + nonstatic_field(OSThread, _unique_thread_id, uint64_t) 8.9 8.10 8.11 #define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ 8.12 \ 8.13 /**********************/ \ 8.14 - /* Posix Thread IDs */ \ 8.15 + /* Thread IDs */ \ 8.16 /**********************/ \ 8.17 \ 8.18 - declare_unsigned_integer_type(OSThread::thread_id_t) \ 8.19 - declare_unsigned_integer_type(pthread_t) 8.20 + declare_unsigned_integer_type(OSThread::thread_id_t) 8.21 8.22 #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) 8.23
9.1 --- a/src/share/vm/oops/cpCache.cpp Fri Feb 08 10:08:40 2013 +0100 9.2 +++ b/src/share/vm/oops/cpCache.cpp Fri Feb 08 09:14:06 2013 -0800 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -402,8 +402,9 @@ 9.11 } 9.12 9.13 9.14 +#if INCLUDE_JVMTI 9.15 // RedefineClasses() API support: 9.16 -// If this constantPoolCacheEntry refers to old_method then update it 9.17 +// If this ConstantPoolCacheEntry refers to old_method then update it 9.18 // to refer to new_method. 9.19 bool ConstantPoolCacheEntry::adjust_method_entry(Method* old_method, 9.20 Method* new_method, bool * trace_name_printed) { 9.21 @@ -461,16 +462,24 @@ 9.22 return false; 9.23 } 9.24 9.25 -#ifndef PRODUCT 9.26 -bool ConstantPoolCacheEntry::check_no_old_entries() { 9.27 +// a constant pool cache entry should never contain old or obsolete methods 9.28 +bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { 9.29 if (is_vfinal()) { 9.30 + // virtual and final so _f2 contains method ptr instead of vtable index 9.31 Metadata* f2 = (Metadata*)_f2; 9.32 - return (f2->is_valid() && f2->is_method() && !((Method*)f2)->is_old()); 9.33 - } else { 9.34 - return (_f1 == NULL || (_f1->is_valid() && _f1->is_method() && !((Method*)_f1)->is_old())); 9.35 + // Return false if _f2 refers to an old or an obsolete method. 9.36 + // _f2 == NULL || !_f2->is_method() are just as unexpected here. 9.37 + return (f2 != NULL NOT_PRODUCT(&& f2->is_valid()) && f2->is_method() && 9.38 + !((Method*)f2)->is_old() && !((Method*)f2)->is_obsolete()); 9.39 + } else if (_f1 == NULL || 9.40 + (NOT_PRODUCT(_f1->is_valid() &&) !_f1->is_method())) { 9.41 + // _f1 == NULL || !_f1->is_method() are OK here 9.42 + return true; 9.43 } 9.44 + // return false if _f1 refers to an old or an obsolete method 9.45 + return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && 9.46 + !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete()); 9.47 } 9.48 -#endif 9.49 9.50 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { 9.51 if (!is_method_entry()) { 9.52 @@ -503,13 +512,15 @@ 9.53 // the method is in the interesting class so the entry is interesting 9.54 return true; 9.55 } 9.56 +#endif // INCLUDE_JVMTI 9.57 9.58 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { 9.59 // print separator 9.60 if (index == 0) st->print_cr(" -------------"); 9.61 // print entry 9.62 st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this); 9.63 - st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); 9.64 + st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), 9.65 + constant_pool_index()); 9.66 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f1); 9.67 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2); 9.68 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags); 9.69 @@ -553,8 +564,9 @@ 9.70 } 9.71 } 9.72 9.73 +#if INCLUDE_JVMTI 9.74 // RedefineClasses() API support: 9.75 -// If any entry of this constantPoolCache points to any of 9.76 +// If any entry of this ConstantPoolCache points to any of 9.77 // old_methods, replace it with the corresponding new_method. 9.78 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods, 9.79 int methods_length, bool * trace_name_printed) { 9.80 @@ -573,7 +585,7 @@ 9.81 continue; 9.82 } 9.83 9.84 - // The constantPoolCache contains entries for several different 9.85 + // The ConstantPoolCache contains entries for several different 9.86 // things, but we only care about methods. In fact, we only care 9.87 // about methods in the same class as the one that contains the 9.88 // old_methods. At this point, we have an interesting entry. 9.89 @@ -592,17 +604,25 @@ 9.90 } 9.91 } 9.92 9.93 -#ifndef PRODUCT 9.94 -bool ConstantPoolCache::check_no_old_entries() { 9.95 +// the constant pool cache should never contain old or obsolete methods 9.96 +bool ConstantPoolCache::check_no_old_or_obsolete_entries() { 9.97 for (int i = 1; i < length(); i++) { 9.98 if (entry_at(i)->is_interesting_method_entry(NULL) && 9.99 - !entry_at(i)->check_no_old_entries()) { 9.100 + !entry_at(i)->check_no_old_or_obsolete_entries()) { 9.101 return false; 9.102 } 9.103 } 9.104 return true; 9.105 } 9.106 -#endif // PRODUCT 9.107 + 9.108 +void ConstantPoolCache::dump_cache() { 9.109 + for (int i = 1; i < length(); i++) { 9.110 + if (entry_at(i)->is_interesting_method_entry(NULL)) { 9.111 + entry_at(i)->print(tty, i); 9.112 + } 9.113 + } 9.114 +} 9.115 +#endif // INCLUDE_JVMTI 9.116 9.117 9.118 // Printing
10.1 --- a/src/share/vm/oops/cpCache.hpp Fri Feb 08 10:08:40 2013 +0100 10.2 +++ b/src/share/vm/oops/cpCache.hpp Fri Feb 08 09:14:06 2013 -0800 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -337,16 +337,18 @@ 10.11 static ByteSize f2_offset() { return byte_offset_of(ConstantPoolCacheEntry, _f2); } 10.12 static ByteSize flags_offset() { return byte_offset_of(ConstantPoolCacheEntry, _flags); } 10.13 10.14 +#if INCLUDE_JVMTI 10.15 // RedefineClasses() API support: 10.16 - // If this constantPoolCacheEntry refers to old_method then update it 10.17 + // If this ConstantPoolCacheEntry refers to old_method then update it 10.18 // to refer to new_method. 10.19 // trace_name_printed is set to true if the current call has 10.20 // printed the klass name so that other routines in the adjust_* 10.21 // group don't print the klass name. 10.22 bool adjust_method_entry(Method* old_method, Method* new_method, 10.23 bool * trace_name_printed); 10.24 - NOT_PRODUCT(bool check_no_old_entries();) 10.25 + bool check_no_old_or_obsolete_entries(); 10.26 bool is_interesting_method_entry(Klass* k); 10.27 +#endif // INCLUDE_JVMTI 10.28 10.29 // Debugging & Printing 10.30 void print (outputStream* st, int index) const; 10.31 @@ -423,15 +425,18 @@ 10.32 return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index); 10.33 } 10.34 10.35 +#if INCLUDE_JVMTI 10.36 // RedefineClasses() API support: 10.37 - // If any entry of this constantPoolCache points to any of 10.38 + // If any entry of this ConstantPoolCache points to any of 10.39 // old_methods, replace it with the corresponding new_method. 10.40 // trace_name_printed is set to true if the current call has 10.41 // printed the klass name so that other routines in the adjust_* 10.42 // group don't print the klass name. 10.43 void adjust_method_entries(Method** old_methods, Method** new_methods, 10.44 int methods_length, bool * trace_name_printed); 10.45 - NOT_PRODUCT(bool check_no_old_entries();) 10.46 + bool check_no_old_or_obsolete_entries(); 10.47 + void dump_cache(); 10.48 +#endif // INCLUDE_JVMTI 10.49 10.50 // Deallocate - no fields to deallocate 10.51 DEBUG_ONLY(bool on_stack() { return false; })
11.1 --- a/src/share/vm/oops/klassVtable.cpp Fri Feb 08 10:08:40 2013 +0100 11.2 +++ b/src/share/vm/oops/klassVtable.cpp Fri Feb 08 09:14:06 2013 -0800 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -610,6 +610,7 @@ 11.11 Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); 11.12 } 11.13 11.14 +#if INCLUDE_JVMTI 11.15 void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods, 11.16 int methods_length, bool * trace_name_printed) { 11.17 // search the vtable for uses of either obsolete or EMCP methods 11.18 @@ -638,11 +639,39 @@ 11.19 new_method->name()->as_C_string(), 11.20 new_method->signature()->as_C_string())); 11.21 } 11.22 + // cannot 'break' here; see for-loop comment above. 11.23 } 11.24 } 11.25 } 11.26 } 11.27 11.28 +// a vtable should never contain old or obsolete methods 11.29 +bool klassVtable::check_no_old_or_obsolete_entries() { 11.30 + for (int i = 0; i < length(); i++) { 11.31 + Method* m = unchecked_method_at(i); 11.32 + if (m != NULL && 11.33 + (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { 11.34 + return false; 11.35 + } 11.36 + } 11.37 + return true; 11.38 +} 11.39 + 11.40 +void klassVtable::dump_vtable() { 11.41 + tty->print_cr("vtable dump --"); 11.42 + for (int i = 0; i < length(); i++) { 11.43 + Method* m = unchecked_method_at(i); 11.44 + if (m != NULL) { 11.45 + tty->print(" (%5d) ", i); 11.46 + m->access_flags().print_on(tty); 11.47 + tty->print(" -- "); 11.48 + m->print_name(tty); 11.49 + tty->cr(); 11.50 + } 11.51 + } 11.52 +} 11.53 +#endif // INCLUDE_JVMTI 11.54 + 11.55 // CDS/RedefineClasses support - clear vtables so they can be reinitialized 11.56 void klassVtable::clear_vtable() { 11.57 for (int i = 0; i < _length; i++) table()[i].clear(); 11.58 @@ -805,6 +834,7 @@ 11.59 } 11.60 } 11.61 11.62 +#if INCLUDE_JVMTI 11.63 void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods, 11.64 int methods_length, bool * trace_name_printed) { 11.65 // search the itable for uses of either obsolete or EMCP methods 11.66 @@ -833,13 +863,44 @@ 11.67 new_method->name()->as_C_string(), 11.68 new_method->signature()->as_C_string())); 11.69 } 11.70 - // Cannot break because there might be another entry for this method 11.71 + // cannot 'break' here; see for-loop comment above. 11.72 } 11.73 ime++; 11.74 } 11.75 } 11.76 } 11.77 11.78 +// an itable should never contain old or obsolete methods 11.79 +bool klassItable::check_no_old_or_obsolete_entries() { 11.80 + itableMethodEntry* ime = method_entry(0); 11.81 + for (int i = 0; i < _size_method_table; i++) { 11.82 + Method* m = ime->method(); 11.83 + if (m != NULL && 11.84 + (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { 11.85 + return false; 11.86 + } 11.87 + ime++; 11.88 + } 11.89 + return true; 11.90 +} 11.91 + 11.92 +void klassItable::dump_itable() { 11.93 + itableMethodEntry* ime = method_entry(0); 11.94 + tty->print_cr("itable dump --"); 11.95 + for (int i = 0; i < _size_method_table; i++) { 11.96 + Method* m = ime->method(); 11.97 + if (m != NULL) { 11.98 + tty->print(" (%5d) ", i); 11.99 + m->access_flags().print_on(tty); 11.100 + tty->print(" -- "); 11.101 + m->print_name(tty); 11.102 + tty->cr(); 11.103 + } 11.104 + ime++; 11.105 + } 11.106 +} 11.107 +#endif // INCLUDE_JVMTI 11.108 + 11.109 11.110 // Setup 11.111 class InterfaceVisiterClosure : public StackObj { 11.112 @@ -1126,43 +1187,6 @@ 11.113 tty->print_cr("%6d bytes total", total); 11.114 } 11.115 11.116 -bool klassVtable::check_no_old_entries() { 11.117 - // Check that there really is no entry 11.118 - for (int i = 0; i < length(); i++) { 11.119 - Method* m = unchecked_method_at(i); 11.120 - if (m != NULL) { 11.121 - if (!m->is_valid() || m->is_old()) { 11.122 - return false; 11.123 - } 11.124 - } 11.125 - } 11.126 - return true; 11.127 -} 11.128 - 11.129 -void klassVtable::dump_vtable() { 11.130 - tty->print_cr("vtable dump --"); 11.131 - for (int i = 0; i < length(); i++) { 11.132 - Method* m = unchecked_method_at(i); 11.133 - if (m != NULL) { 11.134 - tty->print(" (%5d) ", i); 11.135 - m->access_flags().print_on(tty); 11.136 - tty->print(" -- "); 11.137 - m->print_name(tty); 11.138 - tty->cr(); 11.139 - } 11.140 - } 11.141 -} 11.142 - 11.143 -bool klassItable::check_no_old_entries() { 11.144 - itableMethodEntry* ime = method_entry(0); 11.145 - for(int i = 0; i < _size_method_table; i++) { 11.146 - Method* m = ime->method(); 11.147 - if (m != NULL && (!m->is_valid() || m->is_old())) return false; 11.148 - ime++; 11.149 - } 11.150 - return true; 11.151 -} 11.152 - 11.153 int klassItable::_total_classes; // Total no. of classes with itables 11.154 long klassItable::_total_size; // Total no. of bytes used for itables 11.155
12.1 --- a/src/share/vm/oops/klassVtable.hpp Fri Feb 08 10:08:40 2013 +0100 12.2 +++ b/src/share/vm/oops/klassVtable.hpp Fri Feb 08 09:14:06 2013 -0800 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -90,6 +90,7 @@ 12.11 Array<Method*>* methods, AccessFlags class_flags, Handle classloader, 12.12 Symbol* classname, Array<Klass*>* local_interfaces, TRAPS); 12.13 12.14 +#if INCLUDE_JVMTI 12.15 // RedefineClasses() API support: 12.16 // If any entry of this vtable points to any of old_methods, 12.17 // replace it with the corresponding new_method. 12.18 @@ -98,17 +99,15 @@ 12.19 // group don't print the klass name. 12.20 void adjust_method_entries(Method** old_methods, Method** new_methods, 12.21 int methods_length, bool * trace_name_printed); 12.22 + bool check_no_old_or_obsolete_entries(); 12.23 + void dump_vtable(); 12.24 +#endif // INCLUDE_JVMTI 12.25 12.26 // Debugging code 12.27 void print() PRODUCT_RETURN; 12.28 void verify(outputStream* st, bool force = false); 12.29 static void print_statistics() PRODUCT_RETURN; 12.30 12.31 -#ifndef PRODUCT 12.32 - bool check_no_old_entries(); 12.33 - void dump_vtable(); 12.34 -#endif 12.35 - 12.36 protected: 12.37 friend class vtableEntry; 12.38 private: 12.39 @@ -275,6 +274,7 @@ 12.40 // Updates 12.41 void initialize_with_method(Method* m); 12.42 12.43 +#if INCLUDE_JVMTI 12.44 // RedefineClasses() API support: 12.45 // if any entry of this itable points to any of old_methods, 12.46 // replace it with the corresponding new_method. 12.47 @@ -283,6 +283,9 @@ 12.48 // group don't print the klass name. 12.49 void adjust_method_entries(Method** old_methods, Method** new_methods, 12.50 int methods_length, bool * trace_name_printed); 12.51 + bool check_no_old_or_obsolete_entries(); 12.52 + void dump_itable(); 12.53 +#endif // INCLUDE_JVMTI 12.54 12.55 // Setup of itable 12.56 static int compute_itable_size(Array<Klass*>* transitive_interfaces); 12.57 @@ -307,11 +310,6 @@ 12.58 NOT_PRODUCT(static long _total_size;) // Total no. of bytes used for itables 12.59 12.60 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; }) 12.61 - 12.62 - public: 12.63 -#ifndef PRODUCT 12.64 - bool check_no_old_entries(); 12.65 -#endif 12.66 }; 12.67 12.68 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP
13.1 --- a/src/share/vm/oops/method.cpp Fri Feb 08 10:08:40 2013 +0100 13.2 +++ b/src/share/vm/oops/method.cpp Fri Feb 08 09:14:06 2013 -0800 13.3 @@ -1393,9 +1393,9 @@ 13.4 13.5 13.6 //----------------------------------------------------------------------------------- 13.7 -// Non-product code 13.8 +// Non-product code unless JVM/TI needs it 13.9 13.10 -#ifndef PRODUCT 13.11 +#if !defined(PRODUCT) || INCLUDE_JVMTI 13.12 class SignatureTypePrinter : public SignatureTypeNames { 13.13 private: 13.14 outputStream* _st; 13.15 @@ -1430,8 +1430,13 @@ 13.16 sig.print_parameters(); 13.17 st->print(")"); 13.18 } 13.19 +#endif // !PRODUCT || INCLUDE_JVMTI 13.20 13.21 13.22 +//----------------------------------------------------------------------------------- 13.23 +// Non-product code 13.24 + 13.25 +#ifndef PRODUCT 13.26 void Method::print_codes_on(outputStream* st) const { 13.27 print_codes_on(0, code_size(), st); 13.28 }
14.1 --- a/src/share/vm/oops/method.hpp Fri Feb 08 10:08:40 2013 +0100 14.2 +++ b/src/share/vm/oops/method.hpp Fri Feb 08 09:14:06 2013 -0800 14.3 @@ -800,8 +800,12 @@ 14.4 static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS); 14.5 14.6 // Printing 14.7 - void print_short_name(outputStream* st = tty) /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM 14.8 + void print_short_name(outputStream* st = tty); // prints as klassname::methodname; Exposed so field engineers can debug VM 14.9 +#if INCLUDE_JVMTI 14.10 + void print_name(outputStream* st = tty); // prints as "virtual void foo(int)"; exposed for TraceRedefineClasses 14.11 +#else 14.12 void print_name(outputStream* st = tty) PRODUCT_RETURN; // prints as "virtual void foo(int)" 14.13 +#endif 14.14 14.15 // Helper routine used for method sorting 14.16 static void sort_methods(Array<Method*>* methods,
15.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Feb 08 10:08:40 2013 +0100 15.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Feb 08 09:14:06 2013 -0800 15.3 @@ -154,8 +154,15 @@ 15.4 // See jvmtiExport.hpp for detailed explanation. 15.5 JvmtiExport::set_has_redefined_a_class(); 15.6 15.7 -#ifdef ASSERT 15.8 - SystemDictionary::classes_do(check_class, thread); 15.9 +// check_class() is optionally called for product bits, but is 15.10 +// always called for non-product bits. 15.11 +#ifdef PRODUCT 15.12 + if (RC_TRACE_ENABLED(0x00004000)) { 15.13 +#endif 15.14 + RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class")); 15.15 + SystemDictionary::classes_do(check_class, thread); 15.16 +#ifdef PRODUCT 15.17 + } 15.18 #endif 15.19 } 15.20 15.21 @@ -1564,9 +1571,9 @@ 15.22 bcp, cp_index, new_index)); 15.23 // Rewriter::rewrite_method() uses put_native_u2() in this 15.24 // situation because it is reusing the constant pool index 15.25 - // location for a native index into the constantPoolCache. 15.26 + // location for a native index into the ConstantPoolCache. 15.27 // Since we are updating the constant pool index prior to 15.28 - // verification and constantPoolCache initialization, we 15.29 + // verification and ConstantPoolCache initialization, we 15.30 // need to keep the new index in Java byte order. 15.31 Bytes::put_Java_u2(p, new_index); 15.32 } 15.33 @@ -3371,7 +3378,6 @@ 15.34 } 15.35 } 15.36 15.37 -#ifndef PRODUCT 15.38 void VM_RedefineClasses::check_class(Klass* k_oop, 15.39 ClassLoaderData* initiating_loader, 15.40 TRAPS) { 15.41 @@ -3379,82 +3385,110 @@ 15.42 if (k->oop_is_instance()) { 15.43 HandleMark hm(THREAD); 15.44 InstanceKlass *ik = (InstanceKlass *) k; 15.45 - 15.46 - if (ik->vtable_length() > 0) { 15.47 - ResourceMark rm(THREAD); 15.48 - if (!ik->vtable()->check_no_old_entries()) { 15.49 - tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name()); 15.50 + bool no_old_methods = true; // be optimistic 15.51 + ResourceMark rm(THREAD); 15.52 + 15.53 + // a vtable should never contain old or obsolete methods 15.54 + if (ik->vtable_length() > 0 && 15.55 + !ik->vtable()->check_no_old_or_obsolete_entries()) { 15.56 + if (RC_TRACE_ENABLED(0x00004000)) { 15.57 + RC_TRACE_WITH_THREAD(0x00004000, THREAD, 15.58 + ("klassVtable::check_no_old_or_obsolete_entries failure" 15.59 + " -- OLD or OBSOLETE method found -- class: %s", 15.60 + ik->signature_name())); 15.61 ik->vtable()->dump_vtable(); 15.62 - assert(false, "OLD method found"); 15.63 } 15.64 + no_old_methods = false; 15.65 } 15.66 - if (ik->itable_length() > 0) { 15.67 - ResourceMark rm(THREAD); 15.68 - if (!ik->itable()->check_no_old_entries()) { 15.69 - tty->print_cr("klassItable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name()); 15.70 - assert(false, "OLD method found"); 15.71 + 15.72 + // an itable should never contain old or obsolete methods 15.73 + if (ik->itable_length() > 0 && 15.74 + !ik->itable()->check_no_old_or_obsolete_entries()) { 15.75 + if (RC_TRACE_ENABLED(0x00004000)) { 15.76 + RC_TRACE_WITH_THREAD(0x00004000, THREAD, 15.77 + ("klassItable::check_no_old_or_obsolete_entries failure" 15.78 + " -- OLD or OBSOLETE method found -- class: %s", 15.79 + ik->signature_name())); 15.80 + ik->itable()->dump_itable(); 15.81 } 15.82 + no_old_methods = false; 15.83 } 15.84 - // Check that the constant pool cache has no deleted entries. 15.85 + 15.86 + // the constant pool cache should never contain old or obsolete methods 15.87 if (ik->constants() != NULL && 15.88 ik->constants()->cache() != NULL && 15.89 - !ik->constants()->cache()->check_no_old_entries()) { 15.90 - tty->print_cr("klassVtable::check_no_old_entries failure -- OLD method found -- class: %s", ik->signature_name()); 15.91 - assert(false, "OLD method found"); 15.92 + !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { 15.93 + if (RC_TRACE_ENABLED(0x00004000)) { 15.94 + RC_TRACE_WITH_THREAD(0x00004000, THREAD, 15.95 + ("cp-cache::check_no_old_or_obsolete_entries failure" 15.96 + " -- OLD or OBSOLETE method found -- class: %s", 15.97 + ik->signature_name())); 15.98 + ik->constants()->cache()->dump_cache(); 15.99 + } 15.100 + no_old_methods = false; 15.101 + } 15.102 + 15.103 + if (!no_old_methods) { 15.104 + if (RC_TRACE_ENABLED(0x00004000)) { 15.105 + dump_methods(); 15.106 + } else { 15.107 + tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option " 15.108 + "to see more info about the following guarantee() failure."); 15.109 + } 15.110 + guarantee(false, "OLD and/or OBSOLETE method(s) found"); 15.111 } 15.112 } 15.113 } 15.114 15.115 void VM_RedefineClasses::dump_methods() { 15.116 - int j; 15.117 - tty->print_cr("_old_methods --"); 15.118 - for (j = 0; j < _old_methods->length(); ++j) { 15.119 - Method* m = _old_methods->at(j); 15.120 - tty->print("%4d (%5d) ", j, m->vtable_index()); 15.121 - m->access_flags().print_on(tty); 15.122 - tty->print(" -- "); 15.123 - m->print_name(tty); 15.124 - tty->cr(); 15.125 - } 15.126 - tty->print_cr("_new_methods --"); 15.127 - for (j = 0; j < _new_methods->length(); ++j) { 15.128 - Method* m = _new_methods->at(j); 15.129 - tty->print("%4d (%5d) ", j, m->vtable_index()); 15.130 - m->access_flags().print_on(tty); 15.131 - tty->print(" -- "); 15.132 - m->print_name(tty); 15.133 - tty->cr(); 15.134 - } 15.135 - tty->print_cr("_matching_(old/new)_methods --"); 15.136 - for (j = 0; j < _matching_methods_length; ++j) { 15.137 - Method* m = _matching_old_methods[j]; 15.138 - tty->print("%4d (%5d) ", j, m->vtable_index()); 15.139 - m->access_flags().print_on(tty); 15.140 - tty->print(" -- "); 15.141 - m->print_name(tty); 15.142 - tty->cr(); 15.143 - m = _matching_new_methods[j]; 15.144 - tty->print(" (%5d) ", m->vtable_index()); 15.145 - m->access_flags().print_on(tty); 15.146 - tty->cr(); 15.147 - } 15.148 - tty->print_cr("_deleted_methods --"); 15.149 - for (j = 0; j < _deleted_methods_length; ++j) { 15.150 - Method* m = _deleted_methods[j]; 15.151 - tty->print("%4d (%5d) ", j, m->vtable_index()); 15.152 - m->access_flags().print_on(tty); 15.153 - tty->print(" -- "); 15.154 - m->print_name(tty); 15.155 - tty->cr(); 15.156 - } 15.157 - tty->print_cr("_added_methods --"); 15.158 - for (j = 0; j < _added_methods_length; ++j) { 15.159 - Method* m = _added_methods[j]; 15.160 - tty->print("%4d (%5d) ", j, m->vtable_index()); 15.161 - m->access_flags().print_on(tty); 15.162 - tty->print(" -- "); 15.163 - m->print_name(tty); 15.164 - tty->cr(); 15.165 - } 15.166 + int j; 15.167 + RC_TRACE(0x00004000, ("_old_methods --")); 15.168 + for (j = 0; j < _old_methods->length(); ++j) { 15.169 + Method* m = _old_methods->at(j); 15.170 + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); 15.171 + m->access_flags().print_on(tty); 15.172 + tty->print(" -- "); 15.173 + m->print_name(tty); 15.174 + tty->cr(); 15.175 + } 15.176 + RC_TRACE(0x00004000, ("_new_methods --")); 15.177 + for (j = 0; j < _new_methods->length(); ++j) { 15.178 + Method* m = _new_methods->at(j); 15.179 + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); 15.180 + m->access_flags().print_on(tty); 15.181 + tty->print(" -- "); 15.182 + m->print_name(tty); 15.183 + tty->cr(); 15.184 + } 15.185 + RC_TRACE(0x00004000, ("_matching_(old/new)_methods --")); 15.186 + for (j = 0; j < _matching_methods_length; ++j) { 15.187 + Method* m = _matching_old_methods[j]; 15.188 + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); 15.189 + m->access_flags().print_on(tty); 15.190 + tty->print(" -- "); 15.191 + m->print_name(tty); 15.192 + tty->cr(); 15.193 + m = _matching_new_methods[j]; 15.194 + RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index())); 15.195 + m->access_flags().print_on(tty); 15.196 + tty->cr(); 15.197 + } 15.198 + RC_TRACE(0x00004000, ("_deleted_methods --")); 15.199 + for (j = 0; j < _deleted_methods_length; ++j) { 15.200 + Method* m = _deleted_methods[j]; 15.201 + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); 15.202 + m->access_flags().print_on(tty); 15.203 + tty->print(" -- "); 15.204 + m->print_name(tty); 15.205 + tty->cr(); 15.206 + } 15.207 + RC_TRACE(0x00004000, ("_added_methods --")); 15.208 + for (j = 0; j < _added_methods_length; ++j) { 15.209 + Method* m = _added_methods[j]; 15.210 + RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); 15.211 + m->access_flags().print_on(tty); 15.212 + tty->print(" -- "); 15.213 + m->print_name(tty); 15.214 + tty->cr(); 15.215 + } 15.216 } 15.217 -#endif
16.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Feb 08 10:08:40 2013 +0100 16.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Feb 08 09:14:06 2013 -0800 16.3 @@ -468,9 +468,9 @@ 16.4 16.5 void flush_dependent_code(instanceKlassHandle k_h, TRAPS); 16.6 16.7 - static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader, TRAPS) PRODUCT_RETURN; 16.8 - 16.9 - static void dump_methods() PRODUCT_RETURN; 16.10 + static void check_class(Klass* k_oop, ClassLoaderData* initiating_loader, 16.11 + TRAPS); 16.12 + static void dump_methods(); 16.13 16.14 public: 16.15 VM_RedefineClasses(jint class_count,
17.1 --- a/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Fri Feb 08 10:08:40 2013 +0100 17.2 +++ b/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Fri Feb 08 09:14:06 2013 -0800 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -54,7 +54,7 @@ 17.11 // 0x00000800 | 2048 - previous class breakpoint mgmt 17.12 // 0x00001000 | 4096 - detect calls to obsolete methods 17.13 // 0x00002000 | 8192 - fail a guarantee() in addition to detection 17.14 -// 0x00004000 | 16384 - unused 17.15 +// 0x00004000 | 16384 - detect old/obsolete methods in metadata 17.16 // 0x00008000 | 32768 - old/new method matching/add/delete 17.17 // 0x00010000 | 65536 - impl details: CP size info 17.18 // 0x00020000 | 131072 - impl details: CP merge pass info 17.19 @@ -82,6 +82,13 @@ 17.20 tty->print_cr args; \ 17.21 } while (0) 17.22 17.23 +#define RC_TRACE_NO_CR(level, args) \ 17.24 + if ((TraceRedefineClasses & level) != 0) { \ 17.25 + ResourceMark rm; \ 17.26 + tty->print("RedefineClasses-0x%x: ", level); \ 17.27 + tty->print args; \ 17.28 + } while (0) 17.29 + 17.30 #define RC_TRACE_WITH_THREAD(level, thread, args) \ 17.31 if ((TraceRedefineClasses & level) != 0) { \ 17.32 ResourceMark rm(thread); \
18.1 --- a/src/share/vm/utilities/accessFlags.cpp Fri Feb 08 10:08:40 2013 +0100 18.2 +++ b/src/share/vm/utilities/accessFlags.cpp Fri Feb 08 09:14:06 2013 -0800 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -59,7 +59,7 @@ 18.11 } while(f != old_flags); 18.12 } 18.13 18.14 -#ifndef PRODUCT 18.15 +#if !defined(PRODUCT) || INCLUDE_JVMTI 18.16 18.17 void AccessFlags::print_on(outputStream* st) const { 18.18 if (is_public ()) st->print("public " ); 18.19 @@ -80,7 +80,7 @@ 18.20 if (on_stack ()) st->print("{on_stack} " ); 18.21 } 18.22 18.23 -#endif 18.24 +#endif // !PRODUCT || INCLUDE_JVMTI 18.25 18.26 void accessFlags_init() { 18.27 assert(sizeof(AccessFlags) == sizeof(jint), "just checking size of flags");
19.1 --- a/src/share/vm/utilities/accessFlags.hpp Fri Feb 08 10:08:40 2013 +0100 19.2 +++ b/src/share/vm/utilities/accessFlags.hpp Fri Feb 08 09:14:06 2013 -0800 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -239,7 +239,11 @@ 19.11 inline friend AccessFlags accessFlags_from(jint flags); 19.12 19.13 // Printing/debugging 19.14 +#if INCLUDE_JVMTI 19.15 + void print_on(outputStream* st) const; 19.16 +#else 19.17 void print_on(outputStream* st) const PRODUCT_RETURN; 19.18 +#endif 19.19 }; 19.20 19.21 inline AccessFlags accessFlags_from(jint flags) {
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java Fri Feb 08 09:14:06 2013 -0800 20.3 @@ -0,0 +1,49 @@ 20.4 +/* 20.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.23 + * or visit www.oracle.com if you need additional information or have any 20.24 + * questions. 20.25 + */ 20.26 + 20.27 +/* 20.28 + * @test 20.29 + * @bug 8006298 20.30 + * @summary Setting an invalid value for a bool argument should result in a useful error message 20.31 + * @library /testlibrary 20.32 + */ 20.33 + 20.34 +import com.oracle.java.testlibrary.*; 20.35 + 20.36 +public class BooleanFlagWithInvalidValue { 20.37 + public static void main(String[] args) throws Exception { 20.38 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 20.39 + "-XX:+UseLargePages=8", "-version"); 20.40 + 20.41 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 20.42 + output.shouldContain("Improperly specified VM option 'UseLargePages=8'"); 20.43 + output.shouldHaveExitValue(1); 20.44 + 20.45 + pb = ProcessTools.createJavaProcessBuilder( 20.46 + "-XX:-UseLargePages=8", "-version"); 20.47 + 20.48 + output = new OutputAnalyzer(pb.start()); 20.49 + output.shouldContain("Improperly specified VM option 'UseLargePages=8'"); 20.50 + output.shouldHaveExitValue(1); 20.51 + } 20.52 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/runtime/CommandLine/FlagWithInvalidValue.java Fri Feb 08 09:14:06 2013 -0800 21.3 @@ -0,0 +1,42 @@ 21.4 +/* 21.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 + * or visit www.oracle.com if you need additional information or have any 21.24 + * questions. 21.25 + */ 21.26 + 21.27 +/* 21.28 + * @test 21.29 + * @bug 8006298 21.30 + * @summary Setting a flag to an invalid value should print a useful error message 21.31 + * @library /testlibrary 21.32 + */ 21.33 + 21.34 +import com.oracle.java.testlibrary.*; 21.35 + 21.36 +public class FlagWithInvalidValue { 21.37 + public static void main(String[] args) throws Exception { 21.38 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 21.39 + "-XX:ObjectAlignmentInBytes=v", "-version"); 21.40 + 21.41 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 21.42 + output.shouldContain("Improperly specified VM option 'ObjectAlignmentInBytes=v'"); 21.43 + output.shouldHaveExitValue(1); 21.44 + } 21.45 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java Fri Feb 08 09:14:06 2013 -0800 22.3 @@ -0,0 +1,50 @@ 22.4 +/* 22.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. 22.11 + * 22.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.15 + * version 2 for more details (a copy is included in the LICENSE file that 22.16 + * accompanied this code). 22.17 + * 22.18 + * You should have received a copy of the GNU General Public License version 22.19 + * 2 along with this work; if not, write to the Free Software Foundation, 22.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.21 + * 22.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.23 + * or visit www.oracle.com if you need additional information or have any 22.24 + * questions. 22.25 + */ 22.26 + 22.27 +/* 22.28 + * @test 22.29 + * @bug 8006298 22.30 + * @summary Using a bool (+/-) prefix on non-bool flag should result in a useful error message 22.31 + * @library /testlibrary 22.32 + */ 22.33 + 22.34 +import com.oracle.java.testlibrary.*; 22.35 + 22.36 +public class NonBooleanFlagWithInvalidBooleanPrefix { 22.37 + public static void main(String[] args) throws Exception { 22.38 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 22.39 + "-XX:-ObjectAlignmentInBytes=16", "-version"); 22.40 + 22.41 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 22.42 + output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'"); 22.43 + output.shouldHaveExitValue(1); 22.44 + 22.45 + pb = ProcessTools.createJavaProcessBuilder( 22.46 + "-XX:+ObjectAlignmentInBytes=16", "-version"); 22.47 + 22.48 + output = new OutputAnalyzer(pb.start()); 22.49 + output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'"); 22.50 + output.shouldHaveExitValue(1); 22.51 + 22.52 + } 22.53 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/runtime/CommandLine/UnrecognizedVMOption.java Fri Feb 08 09:14:06 2013 -0800 23.3 @@ -0,0 +1,42 @@ 23.4 +/* 23.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 + * 23.8 + * This code is free software; you can redistribute it and/or modify it 23.9 + * under the terms of the GNU General Public License version 2 only, as 23.10 + * published by the Free Software Foundation. 23.11 + * 23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.15 + * version 2 for more details (a copy is included in the LICENSE file that 23.16 + * accompanied this code). 23.17 + * 23.18 + * You should have received a copy of the GNU General Public License version 23.19 + * 2 along with this work; if not, write to the Free Software Foundation, 23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.21 + * 23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.23 + * or visit www.oracle.com if you need additional information or have any 23.24 + * questions. 23.25 + */ 23.26 + 23.27 +/* 23.28 + * @test 23.29 + * @bug 8006298 23.30 + * @summary Using an unrecognized VM option should print the name of the option 23.31 + * @library /testlibrary 23.32 + */ 23.33 + 23.34 +import com.oracle.java.testlibrary.*; 23.35 + 23.36 +public class UnrecognizedVMOption { 23.37 + public static void main(String[] args) throws Exception { 23.38 + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 23.39 + "-XX:bogus_option", "-version"); 23.40 + 23.41 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 23.42 + output.shouldContain("Unrecognized VM option 'bogus_option'"); 23.43 + output.shouldHaveExitValue(1); 23.44 + } 23.45 +}