Thu, 07 Feb 2013 12:23:51 -0800
Merge
1.1 --- a/agent/src/os/linux/LinuxDebuggerLocal.c Wed Feb 06 15:22:32 2013 -0800 1.2 +++ b/agent/src/os/linux/LinuxDebuggerLocal.c Thu Feb 07 12:23:51 2013 -0800 1.3 @@ -280,7 +280,7 @@ 1.4 return (err == PS_OK)? array : 0; 1.5 } 1.6 1.7 -#if defined(i386) || defined(ia64) || defined(amd64) || defined(sparc) || defined(sparcv9) 1.8 +#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) 1.9 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 1.10 (JNIEnv *env, jobject this_obj, jint lwp_id) { 1.11 1.12 @@ -299,9 +299,6 @@ 1.13 #ifdef i386 1.14 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG 1.15 #endif 1.16 -#ifdef ia64 1.17 -#define NPRGREG IA64_REG_COUNT 1.18 -#endif 1.19 #ifdef amd64 1.20 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG 1.21 #endif 1.22 @@ -336,13 +333,6 @@ 1.23 1.24 #endif /* i386 */ 1.25 1.26 -#if ia64 1.27 - regs = (*env)->GetLongArrayElements(env, array, &isCopy); 1.28 - for (i = 0; i < NPRGREG; i++ ) { 1.29 - regs[i] = 0xDEADDEAD; 1.30 - } 1.31 -#endif /* ia64 */ 1.32 - 1.33 #ifdef amd64 1.34 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg 1.35
2.1 --- a/agent/src/os/linux/libproc.h Wed Feb 06 15:22:32 2013 -0800 2.2 +++ b/agent/src/os/linux/libproc.h Thu Feb 07 12:23:51 2013 -0800 2.3 @@ -79,14 +79,6 @@ 2.4 2.5 *************************************************************************************/ 2.6 2.7 -#ifdef ia64 2.8 -struct user_regs_struct { 2.9 -/* copied from user.h which doesn't define this in a struct */ 2.10 - 2.11 -#define IA64_REG_COUNT (EF_SIZE/8+32) /* integer and fp regs */ 2.12 -unsigned long regs[IA64_REG_COUNT]; /* integer and fp regs */ 2.13 -}; 2.14 -#endif 2.15 2.16 #if defined(sparc) || defined(sparcv9) 2.17 #define user_regs_struct pt_regs
3.1 --- a/agent/src/os/win32/windbg/sawindbg.cpp Wed Feb 06 15:22:32 2013 -0800 3.2 +++ b/agent/src/os/win32/windbg/sawindbg.cpp Thu Feb 07 12:23:51 2013 -0800 3.3 @@ -27,10 +27,7 @@ 3.4 3.5 #include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h" 3.6 3.7 -#ifdef _M_IA64 3.8 - #include "sun_jvm_hotspot_debugger_ia64_IA64ThreadContext.h" 3.9 - #define NPRGREG sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_NPRGREG 3.10 -#elif _M_IX86 3.11 +#ifdef _M_IX86 3.12 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h" 3.13 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG 3.14 #elif _M_AMD64 3.15 @@ -491,92 +488,7 @@ 3.16 memset(&context, 0, sizeof(CONTEXT)); 3.17 3.18 #undef REG_INDEX 3.19 -#ifdef _M_IA64 3.20 - #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x 3.21 - 3.22 - context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG; 3.23 - ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); 3.24 - 3.25 - ptrRegs[REG_INDEX(GR0)] = 0; // always 0 3.26 - ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1 3.27 - ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3 3.28 - ptrRegs[REG_INDEX(GR3)] = context.IntT1; 3.29 - ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7 3.30 - ptrRegs[REG_INDEX(GR5)] = context.IntS1; 3.31 - ptrRegs[REG_INDEX(GR6)] = context.IntS2; 3.32 - ptrRegs[REG_INDEX(GR7)] = context.IntS3; 3.33 - ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8 3.34 - ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11 3.35 - ptrRegs[REG_INDEX(GR10)] = context.IntT3; 3.36 - ptrRegs[REG_INDEX(GR11)] = context.IntT4; 3.37 - ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer 3.38 - ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb 3.39 - ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31 3.40 - ptrRegs[REG_INDEX(GR15)] = context.IntT6; 3.41 - ptrRegs[REG_INDEX(GR16)] = context.IntT7; 3.42 - ptrRegs[REG_INDEX(GR17)] = context.IntT8; 3.43 - ptrRegs[REG_INDEX(GR18)] = context.IntT9; 3.44 - ptrRegs[REG_INDEX(GR19)] = context.IntT10; 3.45 - ptrRegs[REG_INDEX(GR20)] = context.IntT11; 3.46 - ptrRegs[REG_INDEX(GR21)] = context.IntT12; 3.47 - ptrRegs[REG_INDEX(GR22)] = context.IntT13; 3.48 - ptrRegs[REG_INDEX(GR23)] = context.IntT14; 3.49 - ptrRegs[REG_INDEX(GR24)] = context.IntT15; 3.50 - ptrRegs[REG_INDEX(GR25)] = context.IntT16; 3.51 - ptrRegs[REG_INDEX(GR26)] = context.IntT17; 3.52 - ptrRegs[REG_INDEX(GR27)] = context.IntT18; 3.53 - ptrRegs[REG_INDEX(GR28)] = context.IntT19; 3.54 - ptrRegs[REG_INDEX(GR29)] = context.IntT20; 3.55 - ptrRegs[REG_INDEX(GR30)] = context.IntT21; 3.56 - ptrRegs[REG_INDEX(GR31)] = context.IntT22; 3.57 - 3.58 - ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats; 3.59 - ptrRegs[REG_INDEX(PREDS)] = context.Preds; 3.60 - 3.61 - ptrRegs[REG_INDEX(BR_RP)] = context.BrRp; 3.62 - ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5 3.63 - ptrRegs[REG_INDEX(BR2)] = context.BrS1; 3.64 - ptrRegs[REG_INDEX(BR3)] = context.BrS2; 3.65 - ptrRegs[REG_INDEX(BR4)] = context.BrS3; 3.66 - ptrRegs[REG_INDEX(BR5)] = context.BrS4; 3.67 - ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7 3.68 - ptrRegs[REG_INDEX(BR7)] = context.BrT1; 3.69 - 3.70 - ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT; 3.71 - ptrRegs[REG_INDEX(AP_LC)] = context.ApLC; 3.72 - ptrRegs[REG_INDEX(AP_EC)] = context.ApEC; 3.73 - ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV; 3.74 - ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR; 3.75 - 3.76 - ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS; 3.77 - ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP; 3.78 - ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE; 3.79 - ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC; 3.80 - ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT; 3.81 - 3.82 - ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR; 3.83 - ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP; 3.84 - ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS; 3.85 - 3.86 - ptrRegs[REG_INDEX(DB_I0)] = context.DbI0; 3.87 - ptrRegs[REG_INDEX(DB_I1)] = context.DbI1; 3.88 - ptrRegs[REG_INDEX(DB_I2)] = context.DbI2; 3.89 - ptrRegs[REG_INDEX(DB_I3)] = context.DbI3; 3.90 - ptrRegs[REG_INDEX(DB_I4)] = context.DbI4; 3.91 - ptrRegs[REG_INDEX(DB_I5)] = context.DbI5; 3.92 - ptrRegs[REG_INDEX(DB_I6)] = context.DbI6; 3.93 - ptrRegs[REG_INDEX(DB_I7)] = context.DbI7; 3.94 - 3.95 - ptrRegs[REG_INDEX(DB_D0)] = context.DbD0; 3.96 - ptrRegs[REG_INDEX(DB_D1)] = context.DbD1; 3.97 - ptrRegs[REG_INDEX(DB_D2)] = context.DbD2; 3.98 - ptrRegs[REG_INDEX(DB_D3)] = context.DbD3; 3.99 - ptrRegs[REG_INDEX(DB_D4)] = context.DbD4; 3.100 - ptrRegs[REG_INDEX(DB_D5)] = context.DbD5; 3.101 - ptrRegs[REG_INDEX(DB_D6)] = context.DbD6; 3.102 - ptrRegs[REG_INDEX(DB_D7)] = context.DbD7; 3.103 - 3.104 -#elif _M_IX86 3.105 +#ifdef _M_IX86 3.106 #define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x 3.107 3.108 context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
4.1 --- a/src/cpu/sparc/vm/c2_globals_sparc.hpp Wed Feb 06 15:22:32 2013 -0800 4.2 +++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp Thu Feb 07 12:23:51 2013 -0800 4.3 @@ -42,7 +42,7 @@ 4.4 #else 4.5 define_pd_global(bool, ProfileInterpreter, true); 4.6 #endif // CC_INTERP 4.7 -define_pd_global(bool, TieredCompilation, trueInTiered); 4.8 +define_pd_global(bool, TieredCompilation, false); 4.9 define_pd_global(intx, CompileThreshold, 10000); 4.10 define_pd_global(intx, BackEdgeThreshold, 140000); 4.11
5.1 --- a/src/cpu/x86/vm/c2_globals_x86.hpp Wed Feb 06 15:22:32 2013 -0800 5.2 +++ b/src/cpu/x86/vm/c2_globals_x86.hpp Thu Feb 07 12:23:51 2013 -0800 5.3 @@ -44,7 +44,7 @@ 5.4 #else 5.5 define_pd_global(bool, ProfileInterpreter, true); 5.6 #endif // CC_INTERP 5.7 -define_pd_global(bool, TieredCompilation, trueInTiered); 5.8 +define_pd_global(bool, TieredCompilation, false); 5.9 define_pd_global(intx, CompileThreshold, 10000); 5.10 define_pd_global(intx, BackEdgeThreshold, 100000); 5.11
6.1 --- a/src/os/linux/vm/os_linux.cpp Wed Feb 06 15:22:32 2013 -0800 6.2 +++ b/src/os/linux/vm/os_linux.cpp Thu Feb 07 12:23:51 2013 -0800 6.3 @@ -1155,13 +1155,9 @@ 6.4 // for initial thread if its stack size exceeds 6M. Cap it at 2M, 6.5 // in case other parts in glibc still assumes 2M max stack size. 6.6 // FIXME: alt signal stack is gone, maybe we can relax this constraint? 6.7 -#ifndef IA64 6.8 - if (stack_size > 2 * K * K) stack_size = 2 * K * K; 6.9 -#else 6.10 // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small 6.11 - if (stack_size > 4 * K * K) stack_size = 4 * K * K; 6.12 -#endif 6.13 - 6.14 + if (stack_size > 2 * K * K IA64_ONLY(*2)) 6.15 + stack_size = 2 * K * K IA64_ONLY(*2); 6.16 // Try to figure out where the stack base (top) is. This is harder. 6.17 // 6.18 // When an application is started, glibc saves the initial stack pointer in 6.19 @@ -4367,16 +4363,12 @@ 6.20 if (is_NPTL()) { 6.21 return pthread_cond_timedwait(_cond, _mutex, _abstime); 6.22 } else { 6.23 -#ifndef IA64 6.24 // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control 6.25 // word back to default 64bit precision if condvar is signaled. Java 6.26 // wants 53bit precision. Save and restore current value. 6.27 int fpu = get_fpu_control_word(); 6.28 -#endif // IA64 6.29 int status = pthread_cond_timedwait(_cond, _mutex, _abstime); 6.30 -#ifndef IA64 6.31 set_fpu_control_word(fpu); 6.32 -#endif // IA64 6.33 return status; 6.34 } 6.35 }
7.1 --- a/src/os/windows/vm/os_windows.cpp Wed Feb 06 15:22:32 2013 -0800 7.2 +++ b/src/os/windows/vm/os_windows.cpp Thu Feb 07 12:23:51 2013 -0800 7.3 @@ -349,6 +349,33 @@ 7.4 7.5 #ifdef _M_IA64 7.6 // IA64 has memory and register stacks 7.7 + // 7.8 + // This is the stack layout you get on NT/IA64 if you specify 1MB stack limit 7.9 + // at thread creation (1MB backing store growing upwards, 1MB memory stack 7.10 + // growing downwards, 2MB summed up) 7.11 + // 7.12 + // ... 7.13 + // ------- top of stack (high address) ----- 7.14 + // | 7.15 + // | 1MB 7.16 + // | Backing Store (Register Stack) 7.17 + // | 7.18 + // | / \ 7.19 + // | | 7.20 + // | | 7.21 + // | | 7.22 + // ------------------------ stack base ----- 7.23 + // | 1MB 7.24 + // | Memory Stack 7.25 + // | 7.26 + // | | 7.27 + // | | 7.28 + // | | 7.29 + // | \ / 7.30 + // | 7.31 + // ----- bottom of stack (low address) ----- 7.32 + // ... 7.33 + 7.34 stack_size = stack_size / 2; 7.35 #endif 7.36 return stack_bottom + stack_size; 7.37 @@ -2005,17 +2032,34 @@ 7.38 JavaThread* thread = JavaThread::current(); 7.39 // Save pc in thread 7.40 #ifdef _M_IA64 7.41 - thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->StIIP); 7.42 + // Do not blow up if no thread info available. 7.43 + if (thread) { 7.44 + // Saving PRECISE pc (with slot information) in thread. 7.45 + uint64_t precise_pc = (uint64_t) exceptionInfo->ExceptionRecord->ExceptionAddress; 7.46 + // Convert precise PC into "Unix" format 7.47 + precise_pc = (precise_pc & 0xFFFFFFFFFFFFFFF0) | ((precise_pc & 0xF) >> 2); 7.48 + thread->set_saved_exception_pc((address)precise_pc); 7.49 + } 7.50 // Set pc to handler 7.51 exceptionInfo->ContextRecord->StIIP = (DWORD64)handler; 7.52 + // Clear out psr.ri (= Restart Instruction) in order to continue 7.53 + // at the beginning of the target bundle. 7.54 + exceptionInfo->ContextRecord->StIPSR &= 0xFFFFF9FFFFFFFFFF; 7.55 + assert(((DWORD64)handler & 0xF) == 0, "Target address must point to the beginning of a bundle!"); 7.56 #elif _M_AMD64 7.57 - thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Rip); 7.58 + // Do not blow up if no thread info available. 7.59 + if (thread) { 7.60 + thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); 7.61 + } 7.62 // Set pc to handler 7.63 exceptionInfo->ContextRecord->Rip = (DWORD64)handler; 7.64 #else 7.65 - thread->set_saved_exception_pc((address)exceptionInfo->ContextRecord->Eip); 7.66 + // Do not blow up if no thread info available. 7.67 + if (thread) { 7.68 + thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip); 7.69 + } 7.70 // Set pc to handler 7.71 - exceptionInfo->ContextRecord->Eip = (LONG)handler; 7.72 + exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler; 7.73 #endif 7.74 7.75 // Continue the execution 7.76 @@ -2040,6 +2084,14 @@ 7.77 // included or copied here. 7.78 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08 7.79 7.80 +// Handle NAT Bit consumption on IA64. 7.81 +#ifdef _M_IA64 7.82 +#define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION 7.83 +#endif 7.84 + 7.85 +// Windows Vista/2008 heap corruption check 7.86 +#define EXCEPTION_HEAP_CORRUPTION 0xC0000374 7.87 + 7.88 #define def_excpt(val) #val, val 7.89 7.90 struct siglabel { 7.91 @@ -2082,6 +2134,10 @@ 7.92 def_excpt(EXCEPTION_GUARD_PAGE), 7.93 def_excpt(EXCEPTION_INVALID_HANDLE), 7.94 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION), 7.95 + def_excpt(EXCEPTION_HEAP_CORRUPTION), 7.96 +#ifdef _M_IA64 7.97 + def_excpt(EXCEPTION_REG_NAT_CONSUMPTION), 7.98 +#endif 7.99 NULL, 0 7.100 }; 7.101 7.102 @@ -2206,7 +2262,14 @@ 7.103 if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; 7.104 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; 7.105 #ifdef _M_IA64 7.106 - address pc = (address) exceptionInfo->ContextRecord->StIIP; 7.107 + // On Itanium, we need the "precise pc", which has the slot number coded 7.108 + // into the least 4 bits: 0000=slot0, 0100=slot1, 1000=slot2 (Windows format). 7.109 + address pc = (address) exceptionInfo->ExceptionRecord->ExceptionAddress; 7.110 + // Convert the pc to "Unix format", which has the slot number coded 7.111 + // into the least 2 bits: 0000=slot0, 0001=slot1, 0010=slot2 7.112 + // This is needed for IA64 because "relocation" / "implicit null check" / "poll instruction" 7.113 + // information is saved in the Unix format. 7.114 + address pc_unix_format = (address) ((((uint64_t)pc) & 0xFFFFFFFFFFFFFFF0) | ((((uint64_t)pc) & 0xF) >> 2)); 7.115 #elif _M_AMD64 7.116 address pc = (address) exceptionInfo->ContextRecord->Rip; 7.117 #else 7.118 @@ -2321,29 +2384,40 @@ 7.119 if (exception_code == EXCEPTION_STACK_OVERFLOW) { 7.120 if (os::uses_stack_guard_pages()) { 7.121 #ifdef _M_IA64 7.122 - // 7.123 - // If it's a legal stack address continue, Windows will map it in. 7.124 - // 7.125 + // Use guard page for register stack. 7.126 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; 7.127 address addr = (address) exceptionRecord->ExceptionInformation[1]; 7.128 - if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) 7.129 - return EXCEPTION_CONTINUE_EXECUTION; 7.130 - 7.131 - // The register save area is the same size as the memory stack 7.132 - // and starts at the page just above the start of the memory stack. 7.133 - // If we get a fault in this area, we've run out of register 7.134 - // stack. If we are in java, try throwing a stack overflow exception. 7.135 - if (addr > thread->stack_base() && 7.136 - addr <= (thread->stack_base()+thread->stack_size()) ) { 7.137 - char buf[256]; 7.138 - jio_snprintf(buf, sizeof(buf), 7.139 - "Register stack overflow, addr:%p, stack_base:%p\n", 7.140 - addr, thread->stack_base() ); 7.141 - tty->print_raw_cr(buf); 7.142 - // If not in java code, return and hope for the best. 7.143 - return in_java ? Handle_Exception(exceptionInfo, 7.144 - SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)) 7.145 - : EXCEPTION_CONTINUE_EXECUTION; 7.146 + // Check for a register stack overflow on Itanium 7.147 + if (thread->addr_inside_register_stack_red_zone(addr)) { 7.148 + // Fatal red zone violation happens if the Java program 7.149 + // catches a StackOverflow error and does so much processing 7.150 + // that it runs beyond the unprotected yellow guard zone. As 7.151 + // a result, we are out of here. 7.152 + fatal("ERROR: Unrecoverable stack overflow happened. JVM will exit."); 7.153 + } else if(thread->addr_inside_register_stack(addr)) { 7.154 + // Disable the yellow zone which sets the state that 7.155 + // we've got a stack overflow problem. 7.156 + if (thread->stack_yellow_zone_enabled()) { 7.157 + thread->disable_stack_yellow_zone(); 7.158 + } 7.159 + // Give us some room to process the exception. 7.160 + thread->disable_register_stack_guard(); 7.161 + // Tracing with +Verbose. 7.162 + if (Verbose) { 7.163 + tty->print_cr("SOF Compiled Register Stack overflow at " INTPTR_FORMAT " (SIGSEGV)", pc); 7.164 + tty->print_cr("Register Stack access at " INTPTR_FORMAT, addr); 7.165 + tty->print_cr("Register Stack base " INTPTR_FORMAT, thread->register_stack_base()); 7.166 + tty->print_cr("Register Stack [" INTPTR_FORMAT "," INTPTR_FORMAT "]", 7.167 + thread->register_stack_base(), 7.168 + thread->register_stack_base() + thread->stack_size()); 7.169 + } 7.170 + 7.171 + // Reguard the permanent register stack red zone just to be sure. 7.172 + // We saw Windows silently disabling this without telling us. 7.173 + thread->enable_register_stack_red_zone(); 7.174 + 7.175 + return Handle_Exception(exceptionInfo, 7.176 + SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); 7.177 } 7.178 #endif 7.179 if (thread->stack_yellow_zone_enabled()) { 7.180 @@ -2418,50 +2492,33 @@ 7.181 { 7.182 // Null pointer exception. 7.183 #ifdef _M_IA64 7.184 - // We catch register stack overflows in compiled code by doing 7.185 - // an explicit compare and executing a st8(G0, G0) if the 7.186 - // BSP enters into our guard area. We test for the overflow 7.187 - // condition and fall into the normal null pointer exception 7.188 - // code if BSP hasn't overflowed. 7.189 - if ( in_java ) { 7.190 - if(thread->register_stack_overflow()) { 7.191 - assert((address)exceptionInfo->ContextRecord->IntS3 == 7.192 - thread->register_stack_limit(), 7.193 - "GR7 doesn't contain register_stack_limit"); 7.194 - // Disable the yellow zone which sets the state that 7.195 - // we've got a stack overflow problem. 7.196 - if (thread->stack_yellow_zone_enabled()) { 7.197 - thread->disable_stack_yellow_zone(); 7.198 + // Process implicit null checks in compiled code. Note: Implicit null checks 7.199 + // can happen even if "ImplicitNullChecks" is disabled, e.g. in vtable stubs. 7.200 + if (CodeCache::contains((void*) pc_unix_format) && !MacroAssembler::needs_explicit_null_check((intptr_t) addr)) { 7.201 + CodeBlob *cb = CodeCache::find_blob_unsafe(pc_unix_format); 7.202 + // Handle implicit null check in UEP method entry 7.203 + if (cb && (cb->is_frame_complete_at(pc) || 7.204 + (cb->is_nmethod() && ((nmethod *)cb)->inlinecache_check_contains(pc)))) { 7.205 + if (Verbose) { 7.206 + intptr_t *bundle_start = (intptr_t*) ((intptr_t) pc_unix_format & 0xFFFFFFFFFFFFFFF0); 7.207 + tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc_unix_format); 7.208 + tty->print_cr(" to addr " INTPTR_FORMAT, addr); 7.209 + tty->print_cr(" bundle is " INTPTR_FORMAT " (high), " INTPTR_FORMAT " (low)", 7.210 + *(bundle_start + 1), *bundle_start); 7.211 } 7.212 - // Give us some room to process the exception 7.213 - thread->disable_register_stack_guard(); 7.214 - // Update GR7 with the new limit so we can continue running 7.215 - // compiled code. 7.216 - exceptionInfo->ContextRecord->IntS3 = 7.217 - (ULONGLONG)thread->register_stack_limit(); 7.218 return Handle_Exception(exceptionInfo, 7.219 - SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW)); 7.220 - } else { 7.221 - // 7.222 - // Check for implicit null 7.223 - // We only expect null pointers in the stubs (vtable) 7.224 - // the rest are checked explicitly now. 7.225 - // 7.226 - if (((uintptr_t)addr) < os::vm_page_size() ) { 7.227 - // an access to the first page of VM--assume it is a null pointer 7.228 - address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 7.229 - if (stub != NULL) return Handle_Exception(exceptionInfo, stub); 7.230 - } 7.231 + SharedRuntime::continuation_for_implicit_exception(thread, pc_unix_format, SharedRuntime::IMPLICIT_NULL)); 7.232 } 7.233 - } // in_java 7.234 - 7.235 - // IA64 doesn't use implicit null checking yet. So we shouldn't 7.236 - // get here. 7.237 - tty->print_raw_cr("Access violation, possible null pointer exception"); 7.238 + } 7.239 + 7.240 + // Implicit null checks were processed above. Hence, we should not reach 7.241 + // here in the usual case => die! 7.242 + if (Verbose) tty->print_raw_cr("Access violation, possible null pointer exception"); 7.243 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, 7.244 exceptionInfo->ContextRecord); 7.245 return EXCEPTION_CONTINUE_SEARCH; 7.246 -#else /* !IA64 */ 7.247 + 7.248 +#else // !IA64 7.249 7.250 // Windows 98 reports faulting addresses incorrectly 7.251 if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) || 7.252 @@ -2493,7 +2550,24 @@ 7.253 report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, 7.254 exceptionInfo->ContextRecord); 7.255 return EXCEPTION_CONTINUE_SEARCH; 7.256 - } 7.257 + } // /EXCEPTION_ACCESS_VIOLATION 7.258 + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 7.259 +#if defined _M_IA64 7.260 + else if ((exception_code == EXCEPTION_ILLEGAL_INSTRUCTION || 7.261 + exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) { 7.262 + M37 handle_wrong_method_break(0, NativeJump::HANDLE_WRONG_METHOD, PR0); 7.263 + 7.264 + // Compiled method patched to be non entrant? Following conditions must apply: 7.265 + // 1. must be first instruction in bundle 7.266 + // 2. must be a break instruction with appropriate code 7.267 + if((((uint64_t) pc & 0x0F) == 0) && 7.268 + (((IPF_Bundle*) pc)->get_slot0() == handle_wrong_method_break.bits())) { 7.269 + return Handle_Exception(exceptionInfo, 7.270 + (address)SharedRuntime::get_handle_wrong_method_stub()); 7.271 + } 7.272 + } // /EXCEPTION_ILLEGAL_INSTRUCTION 7.273 +#endif 7.274 + 7.275 7.276 if (in_java) { 7.277 switch (exception_code) {
8.1 --- a/src/share/vm/adlc/adlparse.cpp Wed Feb 06 15:22:32 2013 -0800 8.2 +++ b/src/share/vm/adlc/adlparse.cpp Thu Feb 07 12:23:51 2013 -0800 8.3 @@ -168,7 +168,7 @@ 8.4 // Check for block delimiter 8.5 if ( (_curchar != '%') 8.6 || ( next_char(), (_curchar != '{')) ) { 8.7 - parse_err(SYNERR, "missing '%{' in instruction definition\n"); 8.8 + parse_err(SYNERR, "missing '%%{' in instruction definition\n"); 8.9 return; 8.10 } 8.11 next_char(); // Maintain the invariant 8.12 @@ -253,7 +253,7 @@ 8.13 } while(_curchar != '%'); 8.14 next_char(); 8.15 if (_curchar != '}') { 8.16 - parse_err(SYNERR, "missing '%}' in instruction definition\n"); 8.17 + parse_err(SYNERR, "missing '%%}' in instruction definition\n"); 8.18 return; 8.19 } 8.20 // Check for "Set" form of chain rule 8.21 @@ -423,7 +423,7 @@ 8.22 skipws(); 8.23 // Check for block delimiter 8.24 if ((_curchar != '%') || (*(_ptr+1) != '{')) { // If not open block 8.25 - parse_err(SYNERR, "missing '%c{' in operand definition\n","%"); 8.26 + parse_err(SYNERR, "missing '%%{' in operand definition\n"); 8.27 return; 8.28 } 8.29 next_char(); next_char(); // Skip over "%{" symbol 8.30 @@ -483,7 +483,7 @@ 8.31 } while(_curchar != '%'); 8.32 next_char(); 8.33 if (_curchar != '}') { 8.34 - parse_err(SYNERR, "missing '%}' in operand definition\n"); 8.35 + parse_err(SYNERR, "missing '%%}' in operand definition\n"); 8.36 return; 8.37 } 8.38 // Add operand to tail of operand list 8.39 @@ -1324,7 +1324,7 @@ 8.40 // Check for block delimiter 8.41 if ( (_curchar != '%') 8.42 || ( next_char(), (_curchar != '{')) ) { 8.43 - parse_err(SYNERR, "missing '%{' in pipeline definition\n"); 8.44 + parse_err(SYNERR, "missing '%%{' in pipeline definition\n"); 8.45 return; 8.46 } 8.47 next_char(); // Maintain the invariant 8.48 @@ -1341,7 +1341,7 @@ 8.49 skipws(); 8.50 if ( (_curchar != '%') 8.51 || ( next_char(), (_curchar != '{')) ) { 8.52 - parse_err(SYNERR, "expected '%{'\n"); 8.53 + parse_err(SYNERR, "expected '%%{'\n"); 8.54 return; 8.55 } 8.56 next_char(); skipws(); 8.57 @@ -1397,7 +1397,7 @@ 8.58 skipws(); 8.59 if ( (_curchar != '%') 8.60 || ( next_char(), (_curchar != '{')) ) { 8.61 - parse_err(SYNERR, "expected '%{'\n"); 8.62 + parse_err(SYNERR, "expected '%%{'\n"); 8.63 return; 8.64 } 8.65 next_char(); skipws(); 8.66 @@ -1586,7 +1586,7 @@ 8.67 8.68 if ( (_curchar != '%') 8.69 || ( next_char(), (_curchar != '}')) ) { 8.70 - parse_err(SYNERR, "expected '%}', found \"%c\"\n", _curchar); 8.71 + parse_err(SYNERR, "expected '%%}', found \"%c\"\n", _curchar); 8.72 } 8.73 next_char(); skipws(); 8.74 8.75 @@ -1612,7 +1612,7 @@ 8.76 8.77 next_char(); 8.78 if (_curchar != '}') { 8.79 - parse_err(SYNERR, "missing \"%}\" in pipeline definition\n"); 8.80 + parse_err(SYNERR, "missing \"%%}\" in pipeline definition\n"); 8.81 return; 8.82 } 8.83 8.84 @@ -1775,7 +1775,7 @@ 8.85 // Check for block delimiter 8.86 if ( (_curchar != '%') 8.87 || ( next_char(), (_curchar != '{')) ) { 8.88 - parse_err(SYNERR, "missing \"%{\" in pipe_class definition\n"); 8.89 + parse_err(SYNERR, "missing \"%%{\" in pipe_class definition\n"); 8.90 return; 8.91 } 8.92 next_char(); 8.93 @@ -2062,7 +2062,7 @@ 8.94 8.95 next_char(); 8.96 if (_curchar != '}') { 8.97 - parse_err(SYNERR, "missing \"%}\" in pipe_class definition\n"); 8.98 + parse_err(SYNERR, "missing \"%%}\" in pipe_class definition\n"); 8.99 return; 8.100 } 8.101 8.102 @@ -3341,12 +3341,12 @@ 8.103 char *disp = NULL; 8.104 8.105 if (_curchar != '%') { 8.106 - parse_err(SYNERR, "Missing '%{' for 'interface' block.\n"); 8.107 + parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n"); 8.108 return NULL; 8.109 } 8.110 next_char(); // Skip '%' 8.111 if (_curchar != '{') { 8.112 - parse_err(SYNERR, "Missing '%{' for 'interface' block.\n"); 8.113 + parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n"); 8.114 return NULL; 8.115 } 8.116 next_char(); // Skip '{' 8.117 @@ -3354,7 +3354,7 @@ 8.118 do { 8.119 char *field = get_ident(); 8.120 if (field == NULL) { 8.121 - parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 8.122 + parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); 8.123 return NULL; 8.124 } 8.125 if ( strcmp(field,"base") == 0 ) { 8.126 @@ -3370,13 +3370,13 @@ 8.127 disp = interface_field_parse(); 8.128 } 8.129 else { 8.130 - parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 8.131 + parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); 8.132 return NULL; 8.133 } 8.134 } while( _curchar != '%' ); 8.135 next_char(); // Skip '%' 8.136 if ( _curchar != '}' ) { 8.137 - parse_err(SYNERR, "Missing '%}' for 'interface' block.\n"); 8.138 + parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n"); 8.139 return NULL; 8.140 } 8.141 next_char(); // Skip '}' 8.142 @@ -3403,12 +3403,12 @@ 8.143 const char *greater_format = "gt"; 8.144 8.145 if (_curchar != '%') { 8.146 - parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); 8.147 + parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n"); 8.148 return NULL; 8.149 } 8.150 next_char(); // Skip '%' 8.151 if (_curchar != '{') { 8.152 - parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); 8.153 + parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n"); 8.154 return NULL; 8.155 } 8.156 next_char(); // Skip '{' 8.157 @@ -3416,7 +3416,7 @@ 8.158 do { 8.159 char *field = get_ident(); 8.160 if (field == NULL) { 8.161 - parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 8.162 + parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); 8.163 return NULL; 8.164 } 8.165 if ( strcmp(field,"equal") == 0 ) { 8.166 @@ -3438,13 +3438,13 @@ 8.167 greater = interface_field_parse(&greater_format); 8.168 } 8.169 else { 8.170 - parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 8.171 + parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); 8.172 return NULL; 8.173 } 8.174 } while( _curchar != '%' ); 8.175 next_char(); // Skip '%' 8.176 if ( _curchar != '}' ) { 8.177 - parse_err(SYNERR, "Missing '%}' for 'interface' block.\n"); 8.178 + parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n"); 8.179 return NULL; 8.180 } 8.181 next_char(); // Skip '}' 8.182 @@ -3543,7 +3543,7 @@ 8.183 } 8.184 else if ((cnstr = find_cpp_block("match constructor")) == NULL ) { 8.185 parse_err(SYNERR, "invalid construction of match rule\n" 8.186 - "Missing ';' or invalid '%{' and '%}' constructor\n"); 8.187 + "Missing ';' or invalid '%%{' and '%%}' constructor\n"); 8.188 return NULL; // No MatchRule to return 8.189 } 8.190 if (_AD._adl_debug > 1) 8.191 @@ -3646,7 +3646,7 @@ 8.192 // Check for closing '"' and '%}' in format description 8.193 skipws(); // Move to closing '%}' 8.194 if ( _curchar != '%' ) { 8.195 - parse_err(SYNERR, "non-blank characters between closing '\"' and '%' in format"); 8.196 + parse_err(SYNERR, "non-blank characters between closing '\"' and '%%' in format"); 8.197 return NULL; 8.198 } 8.199 } // Done with format description inside 8.200 @@ -3654,7 +3654,7 @@ 8.201 skipws(); 8.202 // Past format description, at '%' 8.203 if ( _curchar != '%' || *(_ptr+1) != '}' ) { 8.204 - parse_err(SYNERR, "missing '%}' at end of format block"); 8.205 + parse_err(SYNERR, "missing '%%}' at end of format block"); 8.206 return NULL; 8.207 } 8.208 next_char(); // Move past the '%' 8.209 @@ -3785,7 +3785,7 @@ 8.210 skipws(); 8.211 // Past format description, at '%' 8.212 if ( _curchar != '%' || *(_ptr+1) != '}' ) { 8.213 - parse_err(SYNERR, "missing '%}' at end of format block"); 8.214 + parse_err(SYNERR, "missing '%%}' at end of format block"); 8.215 return NULL; 8.216 } 8.217 next_char(); // Move past the '%' 8.218 @@ -3834,7 +3834,7 @@ 8.219 skipws(); // Skip leading whitespace 8.220 if ((_curchar != '%') 8.221 || (next_char(), (_curchar != '{')) ) { // If not open block 8.222 - parse_err(SYNERR, "missing '%{' in expand definition\n"); 8.223 + parse_err(SYNERR, "missing '%%{' in expand definition\n"); 8.224 return(NULL); 8.225 } 8.226 next_char(); // Maintain the invariant 8.227 @@ -3933,7 +3933,7 @@ 8.228 } while(_curchar != '%'); 8.229 next_char(); 8.230 if (_curchar != '}') { 8.231 - parse_err(SYNERR, "missing '%}' in expand rule definition\n"); 8.232 + parse_err(SYNERR, "missing '%%}' in expand rule definition\n"); 8.233 return(NULL); 8.234 } 8.235 next_char();
9.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Wed Feb 06 15:22:32 2013 -0800 9.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Feb 07 12:23:51 2013 -0800 9.3 @@ -3667,11 +3667,12 @@ 9.4 } 9.5 9.6 // now perform tests that are based on flag settings 9.7 - if (callee->force_inline() || callee->should_inline()) { 9.8 - // ignore heuristic controls on inlining 9.9 - if (callee->force_inline()) 9.10 - print_inlining(callee, "force inline by annotation"); 9.11 + if (callee->force_inline()) { 9.12 + print_inlining(callee, "force inline by annotation"); 9.13 + } else if (callee->should_inline()) { 9.14 + print_inlining(callee, "force inline by CompileOracle"); 9.15 } else { 9.16 + // use heuristic controls on inlining 9.17 if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("inlining too deep"); 9.18 if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep"); 9.19 if (callee->code_size_for_inlining() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
10.1 --- a/src/share/vm/c1/c1_Instruction.cpp Wed Feb 06 15:22:32 2013 -0800 10.2 +++ b/src/share/vm/c1/c1_Instruction.cpp Thu Feb 07 12:23:51 2013 -0800 10.3 @@ -188,7 +188,7 @@ 10.4 10.5 ciType* LoadIndexed::declared_type() const { 10.6 ciType* array_type = array()->declared_type(); 10.7 - if (array_type == NULL) { 10.8 + if (array_type == NULL || !array_type->is_loaded()) { 10.9 return NULL; 10.10 } 10.11 assert(array_type->is_array_klass(), "what else?");
11.1 --- a/src/share/vm/ci/ciEnv.cpp Wed Feb 06 15:22:32 2013 -0800 11.2 +++ b/src/share/vm/ci/ciEnv.cpp Thu Feb 07 12:23:51 2013 -0800 11.3 @@ -1168,7 +1168,7 @@ 11.4 11.5 void ciEnv::dump_replay_data(outputStream* out) { 11.6 ASSERT_IN_VM; 11.7 - 11.8 + ResourceMark rm; 11.9 #if INCLUDE_JVMTI 11.10 out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables); 11.11 out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
12.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Wed Feb 06 15:22:32 2013 -0800 12.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Thu Feb 07 12:23:51 2013 -0800 12.3 @@ -580,6 +580,7 @@ 12.4 } 12.5 void do_field(fieldDescriptor* fd) { 12.6 if (fd->is_final() && !fd->has_initial_value()) { 12.7 + ResourceMark rm; 12.8 oop mirror = fd->field_holder()->java_mirror(); 12.9 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); 12.10 switch (fd->field_type()) { 12.11 @@ -643,6 +644,8 @@ 12.12 12.13 void ciInstanceKlass::dump_replay_data(outputStream* out) { 12.14 ASSERT_IN_VM; 12.15 + ResourceMark rm; 12.16 + 12.17 InstanceKlass* ik = get_instanceKlass(); 12.18 ConstantPool* cp = ik->constants(); 12.19
13.1 --- a/src/share/vm/ci/ciMethod.cpp Wed Feb 06 15:22:32 2013 -0800 13.2 +++ b/src/share/vm/ci/ciMethod.cpp Thu Feb 07 12:23:51 2013 -0800 13.3 @@ -977,7 +977,7 @@ 13.4 // ciMethod::set_not_compilable 13.5 // 13.6 // Tell the VM that this method cannot be compiled at all. 13.7 -void ciMethod::set_not_compilable() { 13.8 +void ciMethod::set_not_compilable(const char* reason) { 13.9 check_is_loaded(); 13.10 VM_ENTRY_MARK; 13.11 ciEnv* env = CURRENT_ENV; 13.12 @@ -986,7 +986,7 @@ 13.13 } else { 13.14 _is_c2_compilable = false; 13.15 } 13.16 - get_Method()->set_not_compilable(env->comp_level()); 13.17 + get_Method()->set_not_compilable(env->comp_level(), true, reason); 13.18 } 13.19 13.20 // ------------------------------------------------------------------ 13.21 @@ -1178,6 +1178,7 @@ 13.22 13.23 void ciMethod::dump_replay_data(outputStream* st) { 13.24 ASSERT_IN_VM; 13.25 + ResourceMark rm; 13.26 Method* method = get_Method(); 13.27 Klass* holder = method->method_holder(); 13.28 st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
14.1 --- a/src/share/vm/ci/ciMethod.hpp Wed Feb 06 15:22:32 2013 -0800 14.2 +++ b/src/share/vm/ci/ciMethod.hpp Thu Feb 07 12:23:51 2013 -0800 14.3 @@ -252,7 +252,7 @@ 14.4 bool has_option(const char *option); 14.5 bool can_be_compiled(); 14.6 bool can_be_osr_compiled(int entry_bci); 14.7 - void set_not_compilable(); 14.8 + void set_not_compilable(const char* reason = NULL); 14.9 bool has_compiled_code(); 14.10 void log_nmethod_identity(xmlStream* log); 14.11 bool is_not_reached(int bci);
15.1 --- a/src/share/vm/ci/ciMethodData.cpp Wed Feb 06 15:22:32 2013 -0800 15.2 +++ b/src/share/vm/ci/ciMethodData.cpp Thu Feb 07 12:23:51 2013 -0800 15.3 @@ -374,6 +374,7 @@ 15.4 15.5 void ciMethodData::dump_replay_data(outputStream* out) { 15.6 ASSERT_IN_VM; 15.7 + ResourceMark rm; 15.8 MethodData* mdo = get_MethodData(); 15.9 Method* method = mdo->method(); 15.10 Klass* holder = method->method_holder();
16.1 --- a/src/share/vm/compiler/compileBroker.cpp Wed Feb 06 15:22:32 2013 -0800 16.2 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Feb 07 12:23:51 2013 -0800 16.3 @@ -1398,7 +1398,7 @@ 16.4 method->print_short_name(tty); 16.5 tty->cr(); 16.6 } 16.7 - method->set_not_compilable_quietly(); 16.8 + method->set_not_compilable(CompLevel_all, !quietly, "excluded by CompilerOracle"); 16.9 } 16.10 16.11 return false;
17.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Feb 06 15:22:32 2013 -0800 17.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Feb 07 12:23:51 2013 -0800 17.3 @@ -3099,9 +3099,9 @@ 17.4 tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); 17.5 tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); 17.6 #endif 17.7 -#if defined(IA64) && !defined(ZERO) 17.8 +#if !defined(ZERO) 17.9 tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); 17.10 -#endif // IA64 && !ZERO 17.11 +#endif // !ZERO 17.12 tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); 17.13 } 17.14
18.1 --- a/src/share/vm/oops/method.cpp Wed Feb 06 15:22:32 2013 -0800 18.2 +++ b/src/share/vm/oops/method.cpp Thu Feb 07 12:23:51 2013 -0800 18.3 @@ -700,7 +700,7 @@ 18.4 } 18.5 18.6 18.7 -void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report) { 18.8 +void Method::print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason) { 18.9 if (PrintCompilation && report) { 18.10 ttyLocker ttyl; 18.11 tty->print("made not %scompilable on ", is_osr ? "OSR " : ""); 18.12 @@ -714,14 +714,21 @@ 18.13 } 18.14 this->print_short_name(tty); 18.15 int size = this->code_size(); 18.16 - if (size > 0) 18.17 + if (size > 0) { 18.18 tty->print(" (%d bytes)", size); 18.19 + } 18.20 + if (reason != NULL) { 18.21 + tty->print(" %s", reason); 18.22 + } 18.23 tty->cr(); 18.24 } 18.25 if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) { 18.26 ttyLocker ttyl; 18.27 xtty->begin_elem("make_not_%scompilable thread='" UINTX_FORMAT "'", 18.28 is_osr ? "osr_" : "", os::current_thread_id()); 18.29 + if (reason != NULL) { 18.30 + xtty->print(" reason=\'%s\'", reason); 18.31 + } 18.32 xtty->method(this); 18.33 xtty->stamp(); 18.34 xtty->end_elem(); 18.35 @@ -743,8 +750,8 @@ 18.36 } 18.37 18.38 // call this when compiler finds that this method is not compilable 18.39 -void Method::set_not_compilable(int comp_level, bool report) { 18.40 - print_made_not_compilable(comp_level, /*is_osr*/ false, report); 18.41 +void Method::set_not_compilable(int comp_level, bool report, const char* reason) { 18.42 + print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason); 18.43 if (comp_level == CompLevel_all) { 18.44 set_not_c1_compilable(); 18.45 set_not_c2_compilable(); 18.46 @@ -769,8 +776,8 @@ 18.47 return false; 18.48 } 18.49 18.50 -void Method::set_not_osr_compilable(int comp_level, bool report) { 18.51 - print_made_not_compilable(comp_level, /*is_osr*/ true, report); 18.52 +void Method::set_not_osr_compilable(int comp_level, bool report, const char* reason) { 18.53 + print_made_not_compilable(comp_level, /*is_osr*/ true, report, reason); 18.54 if (comp_level == CompLevel_all) { 18.55 set_not_c1_osr_compilable(); 18.56 set_not_c2_osr_compilable();
19.1 --- a/src/share/vm/oops/method.hpp Wed Feb 06 15:22:32 2013 -0800 19.2 +++ b/src/share/vm/oops/method.hpp Thu Feb 07 12:23:51 2013 -0800 19.3 @@ -764,18 +764,18 @@ 19.4 // whether it is not compilable for another reason like having a 19.5 // breakpoint set in it. 19.6 bool is_not_compilable(int comp_level = CompLevel_any) const; 19.7 - void set_not_compilable(int comp_level = CompLevel_all, bool report = true); 19.8 + void set_not_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL); 19.9 void set_not_compilable_quietly(int comp_level = CompLevel_all) { 19.10 set_not_compilable(comp_level, false); 19.11 } 19.12 bool is_not_osr_compilable(int comp_level = CompLevel_any) const; 19.13 - void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true); 19.14 + void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true, const char* reason = NULL); 19.15 void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) { 19.16 set_not_osr_compilable(comp_level, false); 19.17 } 19.18 19.19 private: 19.20 - void print_made_not_compilable(int comp_level, bool is_osr, bool report); 19.21 + void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); 19.22 19.23 public: 19.24 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
20.1 --- a/src/share/vm/oops/methodData.hpp Wed Feb 06 15:22:32 2013 -0800 20.2 +++ b/src/share/vm/oops/methodData.hpp Thu Feb 07 12:23:51 2013 -0800 20.3 @@ -1469,7 +1469,7 @@ 20.4 void inc_decompile_count() { 20.5 _nof_decompiles += 1; 20.6 if (decompile_count() > (uint)PerMethodRecompilationCutoff) { 20.7 - method()->set_not_compilable(CompLevel_full_optimization); 20.8 + method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff"); 20.9 } 20.10 } 20.11
21.1 --- a/src/share/vm/oops/symbol.cpp Wed Feb 06 15:22:32 2013 -0800 21.2 +++ b/src/share/vm/oops/symbol.cpp Thu Feb 07 12:23:51 2013 -0800 21.3 @@ -152,6 +152,7 @@ 21.4 } 21.5 21.6 void Symbol::print_symbol_on(outputStream* st) const { 21.7 + ResourceMark rm; 21.8 st = st ? st : tty; 21.9 st->print("%s", as_quoted_ascii()); 21.10 }
22.1 --- a/src/share/vm/opto/bytecodeInfo.cpp Wed Feb 06 15:22:32 2013 -0800 22.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp Thu Feb 07 12:23:51 2013 -0800 22.3 @@ -420,14 +420,24 @@ 22.4 } 22.5 22.6 //------------------------------print_inlining--------------------------------- 22.7 -// Really, the failure_msg can be a success message also. 22.8 -void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const { 22.9 - C->print_inlining(callee_method, inline_level(), caller_bci, failure_msg ? failure_msg : "inline"); 22.10 - if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); 22.11 - if (Verbose && callee_method) { 22.12 - const InlineTree *top = this; 22.13 - while( top->caller_tree() != NULL ) { top = top->caller_tree(); } 22.14 - //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); 22.15 +void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, 22.16 + const char* msg, bool success) const { 22.17 + assert(msg != NULL, "just checking"); 22.18 + if (C->log() != NULL) { 22.19 + if (success) { 22.20 + C->log()->inline_success(msg); 22.21 + } else { 22.22 + C->log()->inline_fail(msg); 22.23 + } 22.24 + } 22.25 + if (PrintInlining) { 22.26 + C->print_inlining(callee_method, inline_level(), caller_bci, msg); 22.27 + if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); 22.28 + if (Verbose && callee_method) { 22.29 + const InlineTree *top = this; 22.30 + while( top->caller_tree() != NULL ) { top = top->caller_tree(); } 22.31 + //tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); 22.32 + } 22.33 } 22.34 } 22.35 22.36 @@ -451,23 +461,23 @@ 22.37 22.38 // Do some initial checks. 22.39 if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { 22.40 - if (PrintInlining) print_inlining(callee_method, caller_bci, "failed initial checks"); 22.41 + print_inlining(callee_method, caller_bci, "failed initial checks", 22.42 + false /* !success */); 22.43 return NULL; 22.44 } 22.45 22.46 // Do some parse checks. 22.47 failure_msg = check_can_parse(callee_method); 22.48 if (failure_msg != NULL) { 22.49 - if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg); 22.50 + print_inlining(callee_method, caller_bci, failure_msg, 22.51 + false /* !success */); 22.52 return NULL; 22.53 } 22.54 22.55 // Check if inlining policy says no. 22.56 WarmCallInfo wci = *(initial_wci); 22.57 - failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci, should_delay); 22.58 - if (failure_msg != NULL && C->log() != NULL) { 22.59 - C->log()->inline_fail(failure_msg); 22.60 - } 22.61 + failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, 22.62 + &wci, should_delay); 22.63 22.64 #ifndef PRODUCT 22.65 if (UseOldInlining && InlineWarmCalls 22.66 @@ -487,7 +497,7 @@ 22.67 wci = *(WarmCallInfo::always_hot()); 22.68 else 22.69 wci = *(WarmCallInfo::always_cold()); 22.70 - } 22.71 + } 22.72 if (!InlineWarmCalls) { 22.73 if (!wci.is_cold() && !wci.is_hot()) { 22.74 // Do not inline the warm calls. 22.75 @@ -496,11 +506,10 @@ 22.76 } 22.77 22.78 if (!wci.is_cold()) { 22.79 - // In -UseOldInlining, the failure_msg may also be a success message. 22.80 - if (failure_msg == NULL) failure_msg = "inline (hot)"; 22.81 - 22.82 // Inline! 22.83 - if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg); 22.84 + print_inlining(callee_method, caller_bci, 22.85 + failure_msg ? failure_msg : "inline (hot)", 22.86 + true /* success */); 22.87 if (UseOldInlining) 22.88 build_inline_tree_for_callee(callee_method, jvms, caller_bci); 22.89 if (InlineWarmCalls && !wci.is_hot()) 22.90 @@ -509,8 +518,9 @@ 22.91 } 22.92 22.93 // Do not inline 22.94 - if (failure_msg == NULL) failure_msg = "too cold to inline"; 22.95 - if (PrintInlining) print_inlining(callee_method, caller_bci, failure_msg); 22.96 + print_inlining(callee_method, caller_bci, 22.97 + failure_msg ? failure_msg : "too cold to inline", 22.98 + false /* !success */ ); 22.99 return NULL; 22.100 } 22.101
23.1 --- a/src/share/vm/opto/callGenerator.cpp Wed Feb 06 15:22:32 2013 -0800 23.2 +++ b/src/share/vm/opto/callGenerator.cpp Thu Feb 07 12:23:51 2013 -0800 23.3 @@ -305,11 +305,13 @@ 23.4 void LateInlineCallGenerator::do_late_inline() { 23.5 // Can't inline it 23.6 if (call_node() == NULL || call_node()->outcnt() == 0 || 23.7 - call_node()->in(0) == NULL || call_node()->in(0)->is_top()) 23.8 + call_node()->in(0) == NULL || call_node()->in(0)->is_top()) { 23.9 return; 23.10 + } 23.11 23.12 + const TypeTuple *r = call_node()->tf()->domain(); 23.13 for (int i1 = 0; i1 < method()->arg_size(); i1++) { 23.14 - if (call_node()->in(TypeFunc::Parms + i1)->is_top()) { 23.15 + if (call_node()->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) { 23.16 assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); 23.17 return; 23.18 }
24.1 --- a/src/share/vm/opto/generateOptoStub.cpp Wed Feb 06 15:22:32 2013 -0800 24.2 +++ b/src/share/vm/opto/generateOptoStub.cpp Thu Feb 07 12:23:51 2013 -0800 24.3 @@ -88,12 +88,12 @@ 24.4 thread, 24.5 in_bytes(JavaThread::frame_anchor_offset()) + 24.6 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 24.7 -#if defined(SPARC) || defined(IA64) 24.8 +#if defined(SPARC) 24.9 Node* adr_flags = basic_plus_adr(top(), 24.10 thread, 24.11 in_bytes(JavaThread::frame_anchor_offset()) + 24.12 in_bytes(JavaFrameAnchor::flags_offset())); 24.13 -#endif /* defined(SPARC) || defined(IA64) */ 24.14 +#endif /* defined(SPARC) */ 24.15 24.16 24.17 // Drop in the last_Java_sp. last_Java_fp is not touched. 24.18 @@ -102,10 +102,8 @@ 24.19 // users will look at the other fields. 24.20 // 24.21 Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset())); 24.22 -#ifndef IA64 24.23 Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS); 24.24 store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias); 24.25 -#endif 24.26 24.27 // Set _thread_in_native 24.28 // The order of stores into TLS is critical! Setting _thread_in_native MUST 24.29 @@ -210,19 +208,12 @@ 24.30 //----------------------------- 24.31 24.32 // Clear last_Java_sp 24.33 -#ifdef IA64 24.34 - if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease); 24.35 -#endif 24.36 - 24.37 store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias); 24.38 -#ifdef IA64 24.39 - if (os::is_MP() && UseMembar) insert_mem_bar(new MemBarVolatileNode()); 24.40 -#endif // def IA64 24.41 // Clear last_Java_pc and (optionally)_flags 24.42 store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias); 24.43 -#if defined(SPARC) || defined(IA64) 24.44 +#if defined(SPARC) 24.45 store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias); 24.46 -#endif /* defined(SPARC) || defined(IA64) */ 24.47 +#endif /* defined(SPARC) */ 24.48 #ifdef IA64 24.49 Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset())); 24.50 if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
25.1 --- a/src/share/vm/opto/parse.hpp Wed Feb 06 15:22:32 2013 -0800 25.2 +++ b/src/share/vm/opto/parse.hpp Thu Feb 07 12:23:51 2013 -0800 25.3 @@ -73,7 +73,8 @@ 25.4 const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); 25.5 const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; 25.6 const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; 25.7 - void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const; 25.8 + void print_inlining(ciMethod* callee_method, int caller_bci, 25.9 + const char* msg, bool success) const; 25.10 25.11 InlineTree *caller_tree() const { return _caller_tree; } 25.12 InlineTree* callee_at(int bci, ciMethod* m) const;
26.1 --- a/src/share/vm/opto/parse3.cpp Wed Feb 06 15:22:32 2013 -0800 26.2 +++ b/src/share/vm/opto/parse3.cpp Thu Feb 07 12:23:51 2013 -0800 26.3 @@ -1,5 +1,5 @@ 26.4 /* 26.5 - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 26.6 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 26.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.8 * 26.9 * This code is free software; you can redistribute it and/or modify it 26.10 @@ -487,7 +487,8 @@ 26.11 fun, NULL, TypeRawPtr::BOTTOM, 26.12 makecon(TypeKlassPtr::make(array_klass)), 26.13 length[0], length[1], length[2], 26.14 - length[3], length[4]); 26.15 + (ndimensions > 2) ? length[3] : NULL, 26.16 + (ndimensions > 3) ? length[4] : NULL); 26.17 } else { 26.18 // Create a java array for dimension sizes 26.19 Node* dims = NULL;
27.1 --- a/src/share/vm/runtime/deoptimization.cpp Wed Feb 06 15:22:32 2013 -0800 27.2 +++ b/src/share/vm/runtime/deoptimization.cpp Thu Feb 07 12:23:51 2013 -0800 27.3 @@ -1559,7 +1559,7 @@ 27.4 if (trap_method() == nm->method()) { 27.5 make_not_compilable = true; 27.6 } else { 27.7 - trap_method->set_not_compilable(CompLevel_full_optimization); 27.8 + trap_method->set_not_compilable(CompLevel_full_optimization, true, "overflow_recompile_count > PerBytecodeRecompilationCutoff"); 27.9 // But give grace to the enclosing nm->method(). 27.10 } 27.11 }
28.1 --- a/src/share/vm/runtime/os.cpp Wed Feb 06 15:22:32 2013 -0800 28.2 +++ b/src/share/vm/runtime/os.cpp Thu Feb 07 12:23:51 2013 -0800 28.3 @@ -985,15 +985,28 @@ 28.4 // if C stack is walkable beyond current frame. The check for fp() is not 28.5 // necessary on Sparc, but it's harmless. 28.6 bool os::is_first_C_frame(frame* fr) { 28.7 -#ifdef IA64 28.8 - // In order to walk native frames on Itanium, we need to access the unwind 28.9 - // table, which is inside ELF. We don't want to parse ELF after fatal error, 28.10 - // so return true for IA64. If we need to support C stack walking on IA64, 28.11 - // this function needs to be moved to CPU specific files, as fp() on IA64 28.12 - // is register stack, which grows towards higher memory address. 28.13 +#if defined(IA64) && !defined(_WIN32) 28.14 + // On IA64 we have to check if the callers bsp is still valid 28.15 + // (i.e. within the register stack bounds). 28.16 + // Notice: this only works for threads created by the VM and only if 28.17 + // we walk the current stack!!! If we want to be able to walk 28.18 + // arbitrary other threads, we'll have to somehow store the thread 28.19 + // object in the frame. 28.20 + Thread *thread = Thread::current(); 28.21 + if ((address)fr->fp() <= 28.22 + thread->register_stack_base() HPUX_ONLY(+ 0x0) LINUX_ONLY(+ 0x50)) { 28.23 + // This check is a little hacky, because on Linux the first C 28.24 + // frame's ('start_thread') register stack frame starts at 28.25 + // "register_stack_base + 0x48" while on HPUX, the first C frame's 28.26 + // ('__pthread_bound_body') register stack frame seems to really 28.27 + // start at "register_stack_base". 28.28 + return true; 28.29 + } else { 28.30 + return false; 28.31 + } 28.32 +#elif defined(IA64) && defined(_WIN32) 28.33 return true; 28.34 -#endif 28.35 - 28.36 +#else 28.37 // Load up sp, fp, sender sp and sender fp, check for reasonable values. 28.38 // Check usp first, because if that's bad the other accessors may fault 28.39 // on some architectures. Ditto ufp second, etc. 28.40 @@ -1023,6 +1036,7 @@ 28.41 if (old_fp - ufp > 64 * K) return true; 28.42 28.43 return false; 28.44 +#endif 28.45 } 28.46 28.47 #ifdef ASSERT
29.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Feb 06 15:22:32 2013 -0800 29.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Feb 07 12:23:51 2013 -0800 29.3 @@ -2816,10 +2816,6 @@ 29.4 29.5 JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) ) 29.6 29.7 -#ifdef IA64 29.8 - ShouldNotReachHere(); // NYI 29.9 -#endif /* IA64 */ 29.10 - 29.11 // 29.12 // This code is dependent on the memory layout of the interpreter local 29.13 // array and the monitors. On all of our platforms the layout is identical
30.1 --- a/src/share/vm/runtime/synchronizer.cpp Wed Feb 06 15:22:32 2013 -0800 30.2 +++ b/src/share/vm/runtime/synchronizer.cpp Thu Feb 07 12:23:51 2013 -0800 30.3 @@ -53,7 +53,7 @@ 30.4 # include "os_bsd.inline.hpp" 30.5 #endif 30.6 30.7 -#if defined(__GNUC__) && !defined(IA64) 30.8 +#if defined(__GNUC__) 30.9 // Need to inhibit inlining for older versions of GCC to avoid build-time failures 30.10 #define ATTR __attribute__((noinline)) 30.11 #else
31.1 --- a/src/share/vm/runtime/vframeArray.cpp Wed Feb 06 15:22:32 2013 -0800 31.2 +++ b/src/share/vm/runtime/vframeArray.cpp Thu Feb 07 12:23:51 2013 -0800 31.3 @@ -233,8 +233,6 @@ 31.4 // Force early return from top frame after deoptimization 31.5 #ifndef CC_INTERP 31.6 pc = Interpreter::remove_activation_early_entry(state->earlyret_tos()); 31.7 -#else 31.8 - // TBD: Need to implement ForceEarlyReturn for CC_INTERP (ia64) 31.9 #endif 31.10 } else { 31.11 // Possibly override the previous pc computation of the top (youngest) frame
32.1 --- a/test/compiler/8004741/Test8004741.java Wed Feb 06 15:22:32 2013 -0800 32.2 +++ b/test/compiler/8004741/Test8004741.java Thu Feb 07 12:23:51 2013 -0800 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -25,70 +25,160 @@ 32.11 * @test Test8004741.java 32.12 * @bug 8004741 32.13 * @summary Missing compiled exception handle table entry for multidimensional array allocation 32.14 + * @run main/othervm -Xmx64m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers -XX:+SafepointALot -XX:GuaranteedSafepointInterval=100 Test8004741 32.15 * @run main/othervm -Xmx64m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers Test8004741 32.16 - * 32.17 */ 32.18 32.19 import java.util.*; 32.20 32.21 public class Test8004741 extends Thread { 32.22 32.23 + static int passed = 0; 32.24 + 32.25 + /** 32.26 + * Loop forever allocating 2-d arrays. 32.27 + * Catches and rethrows all exceptions; in the case of ThreadDeath, increments passed. 32.28 + * Note that passed is incremented here because this is the exception handler with 32.29 + * the smallest scope; we only want to declare success in the case where it is highly 32.30 + * likely that the test condition 32.31 + * (exception in 2-d array alloc interrupted by ThreadDeath) 32.32 + * actually occurs. 32.33 + */ 32.34 static int[][] test(int a, int b) throws Exception { 32.35 - int[][] ar = null; 32.36 + int[][] ar; 32.37 try { 32.38 ar = new int[a][b]; 32.39 - } catch (Error e) { 32.40 - System.out.println("test got Error"); 32.41 - passed = true; 32.42 - throw(e); 32.43 - } catch (Exception e) { 32.44 - System.out.println("test got Exception"); 32.45 + } catch (ThreadDeath e) { 32.46 + System.out.println("test got ThreadDeath"); 32.47 + passed++; 32.48 throw(e); 32.49 } 32.50 return ar; 32.51 } 32.52 32.53 - static boolean passed = false; 32.54 + /* Cookbook wait-notify to track progress of test thread. */ 32.55 + Object progressLock = new Object(); 32.56 + private static final int NOT_STARTED = 0; 32.57 + private static final int RUNNING = 1; 32.58 + private static final int STOPPING = 2; 32.59 32.60 + int progressState = NOT_STARTED; 32.61 + 32.62 + void toState(int state) { 32.63 + synchronized (progressLock) { 32.64 + progressState = state; 32.65 + progressLock.notify(); 32.66 + } 32.67 + } 32.68 + 32.69 + void waitFor(int state) { 32.70 + synchronized (progressLock) { 32.71 + while (progressState < state) { 32.72 + try { 32.73 + progressLock.wait(); 32.74 + } catch (InterruptedException e) { 32.75 + e.printStackTrace(); 32.76 + System.out.println("unexpected InterruptedException"); 32.77 + fail(); 32.78 + } 32.79 + } 32.80 + if (progressState > state) { 32.81 + System.out.println("unexpected test state change, expected " + 32.82 + state + " but saw " + progressState); 32.83 + fail(); 32.84 + } 32.85 + } 32.86 + } 32.87 + 32.88 + /** 32.89 + * Loops running test until some sort of an exception or error, 32.90 + * expects to see ThreadDeath. 32.91 + */ 32.92 public void run() { 32.93 - System.out.println("test started"); 32.94 - try { 32.95 - while(true) { 32.96 - test(2,20000); 32.97 - } 32.98 - } catch (ThreadDeath e) { 32.99 - System.out.println("test got ThreadDeath"); 32.100 - passed = true; 32.101 - } catch (Error e) { 32.102 - e.printStackTrace(); 32.103 - System.out.println("test got Error"); 32.104 - } catch (Exception e) { 32.105 - e.printStackTrace(); 32.106 - System.out.println("test got Exception"); 32.107 + try { 32.108 + // Print before state change, so that other thread is most likely 32.109 + // to see this thread executing calls to test() in a loop. 32.110 + System.out.println("thread running"); 32.111 + toState(RUNNING); 32.112 + while (true) { 32.113 + // (2,2) (2,10) (2,100) were observed to tickle the bug; 32.114 + test(2, 100); 32.115 } 32.116 + } catch (ThreadDeath e) { 32.117 + // nothing to say, passing was incremented by the test. 32.118 + } catch (Throwable e) { 32.119 + e.printStackTrace(); 32.120 + System.out.println("unexpected Throwable " + e); 32.121 + fail(); 32.122 + } 32.123 + toState(STOPPING); 32.124 + } 32.125 + 32.126 + /** 32.127 + * Runs a single trial of the test in a thread. 32.128 + * No single trial is definitive, since the ThreadDeath 32.129 + * exception might not land in the tested region of code. 32.130 + */ 32.131 + public static void threadTest() throws InterruptedException { 32.132 + Test8004741 t = new Test8004741(); 32.133 + t.start(); 32.134 + t.waitFor(RUNNING); 32.135 + Thread.sleep(100); 32.136 + System.out.println("stopping thread"); 32.137 + t.stop(); 32.138 + t.waitFor(STOPPING); 32.139 + t.join(); 32.140 } 32.141 32.142 public static void main(String[] args) throws Exception { 32.143 + // Warm up "test" 32.144 + // t will never be started. 32.145 for (int n = 0; n < 11000; n++) { 32.146 - test(2, 20); 32.147 + test(2, 100); 32.148 } 32.149 32.150 - // First test exception catch 32.151 - Test8004741 t = new Test8004741(); 32.152 + // Will this sleep help ensure that the compiler is run? 32.153 + Thread.sleep(500); 32.154 + passed = 0; 32.155 32.156 - passed = false; 32.157 - t.start(); 32.158 - Thread.sleep(1000); 32.159 - t.stop(); 32.160 + try { 32.161 + test(-1, 100); 32.162 + System.out.println("Missing NegativeArraySizeException #1"); 32.163 + fail(); 32.164 + } catch ( java.lang.NegativeArraySizeException e ) { 32.165 + System.out.println("Saw expected NegativeArraySizeException #1"); 32.166 + } 32.167 32.168 - Thread.sleep(5000); 32.169 - t.join(); 32.170 - if (passed) { 32.171 + try { 32.172 + test(100, -1); 32.173 + fail(); 32.174 + System.out.println("Missing NegativeArraySizeException #2"); 32.175 + fail(); 32.176 + } catch ( java.lang.NegativeArraySizeException e ) { 32.177 + System.out.println("Saw expected NegativeArraySizeException #2"); 32.178 + } 32.179 + 32.180 + /* Test repetitions. If the test succeeds-mostly, it succeeds, 32.181 + * as long as it does not crash (the outcome if the exception range 32.182 + * table entry for the array allocation is missing). 32.183 + */ 32.184 + int N = 12; 32.185 + for (int n = 0; n < N; n++) { 32.186 + threadTest(); 32.187 + } 32.188 + 32.189 + if (passed > N/2) { 32.190 + System.out.println("Saw " + passed + " out of " + N + " possible ThreadDeath hits"); 32.191 System.out.println("PASSED"); 32.192 } else { 32.193 - System.out.println("FAILED"); 32.194 - System.exit(97); 32.195 + System.out.println("Too few ThreadDeath hits; expected at least " + N/2 + 32.196 + " but saw only " + passed); 32.197 + fail(); 32.198 } 32.199 } 32.200 32.201 + static void fail() { 32.202 + System.out.println("FAILED"); 32.203 + System.exit(97); 32.204 + } 32.205 };