Wed, 09 Apr 2014 12:23:29 -0700
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
make/hotspot_version | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Wed Apr 02 09:59:18 2014 -0700 1.2 +++ b/.hgtags Wed Apr 09 12:23:29 2014 -0700 1.3 @@ -453,3 +453,5 @@ 1.4 f0ea4d3df1299b6c958e1a72f892c695fca055ad jdk8u20-b07 1.5 2627c7be4279478b880d7f643a252d185e4915ec hs25.20-b08 1.6 e9ffa408f7af28205a7114ca78bce29846f5a8df jdk8u20-b08 1.7 +5186bc5047c1725888ed99f423bdfaa116e05abe hs25.20-b09 1.8 +4d73f1e99f97d1444e16ee5ef4634eb2129969ad jdk8u20-b09
2.1 --- a/make/hotspot_version Wed Apr 02 09:59:18 2014 -0700 2.2 +++ b/make/hotspot_version Wed Apr 09 12:23:29 2014 -0700 2.3 @@ -35,7 +35,7 @@ 2.4 2.5 HS_MAJOR_VER=25 2.6 HS_MINOR_VER=20 2.7 -HS_BUILD_NUMBER=08 2.8 +HS_BUILD_NUMBER=09 2.9 2.10 JDK_MAJOR_VER=1 2.11 JDK_MINOR_VER=8
3.1 --- a/make/linux/Makefile Wed Apr 02 09:59:18 2014 -0700 3.2 +++ b/make/linux/Makefile Wed Apr 09 12:23:29 2014 -0700 3.3 @@ -66,8 +66,8 @@ 3.4 FORCE_TIERED=1 3.5 endif 3.6 endif 3.7 -# C1 is not ported on ppc64(le), so we cannot build a tiered VM: 3.8 -ifneq (,$(filter $(ARCH),ppc64 pp64le)) 3.9 +# C1 is not ported on ppc64, so we cannot build a tiered VM: 3.10 +ifeq ($(ARCH),ppc64) 3.11 FORCE_TIERED=0 3.12 endif 3.13
4.1 --- a/make/linux/makefiles/defs.make Wed Apr 02 09:59:18 2014 -0700 4.2 +++ b/make/linux/makefiles/defs.make Wed Apr 09 12:23:29 2014 -0700 4.3 @@ -33,6 +33,11 @@ 4.4 # ARCH can be set explicitly in spec.gmk 4.5 ifndef ARCH 4.6 ARCH := $(shell uname -m) 4.7 + # Fold little endian PowerPC64 into big-endian (if ARCH is set in 4.8 + # hotspot-spec.gmk, this will be done by the configure script). 4.9 + ifeq ($(ARCH),ppc64le) 4.10 + ARCH := ppc64 4.11 + endif 4.12 endif 4.13 4.14 PATH_SEP ?= :
5.1 --- a/make/linux/makefiles/ppc64.make Wed Apr 02 09:59:18 2014 -0700 5.2 +++ b/make/linux/makefiles/ppc64.make Wed Apr 09 12:23:29 2014 -0700 5.3 @@ -26,14 +26,26 @@ 5.4 # make c code know it is on a 64 bit platform. 5.5 CFLAGS += -D_LP64=1 5.6 5.7 -# fixes `relocation truncated to fit' error for gcc 4.1. 5.8 -CFLAGS += -mminimal-toc 5.9 +ifeq ($(origin OPENJDK_TARGET_CPU_ENDIAN),undefined) 5.10 + # This can happen during hotspot standalone build. Set endianness from 5.11 + # uname. We assume build and target machines are the same. 5.12 + OPENJDK_TARGET_CPU_ENDIAN:=$(if $(filter ppc64le,$(shell uname -m)),little,big) 5.13 +endif 5.14 5.15 -# finds use ppc64 instructions, but schedule for power5 5.16 -CFLAGS += -mcpu=powerpc64 -mtune=power5 -minsert-sched-nops=regroup_exact -mno-multiple -mno-string 5.17 +ifeq ($(filter $(OPENJDK_TARGET_CPU_ENDIAN),big little),) 5.18 + $(error OPENJDK_TARGET_CPU_ENDIAN value should be 'big' or 'little') 5.19 +endif 5.20 5.21 -# let linker find external 64 bit libs. 5.22 -LFLAGS_VM += -L/lib64 5.23 +ifeq ($(OPENJDK_TARGET_CPU_ENDIAN),big) 5.24 + # fixes `relocation truncated to fit' error for gcc 4.1. 5.25 + CFLAGS += -mminimal-toc 5.26 5.27 -# specify lib format. 5.28 -LFLAGS_VM += -Wl,-melf64ppc 5.29 + # finds use ppc64 instructions, but schedule for power5 5.30 + CFLAGS += -mcpu=powerpc64 -mtune=power5 -minsert-sched-nops=regroup_exact -mno-multiple -mno-string 5.31 +else 5.32 + # Little endian machine uses ELFv2 ABI. 5.33 + CFLAGS += -DVM_LITTLE_ENDIAN -DABI_ELFv2 5.34 + 5.35 + # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI. 5.36 + CFLAGS += -mcpu=power7 -mtune=power8 -minsert-sched-nops=regroup_exact -mno-multiple -mno-string 5.37 +endif
6.1 --- a/make/windows/makefiles/defs.make Wed Apr 02 09:59:18 2014 -0700 6.2 +++ b/make/windows/makefiles/defs.make Wed Apr 09 12:23:29 2014 -0700 6.3 @@ -260,7 +260,6 @@ 6.4 EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map 6.5 endif 6.6 endif 6.7 - EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib 6.8 endif 6.9 ifeq ($(JVM_VARIANT_CLIENT),true) 6.10 EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt 6.11 @@ -275,6 +274,8 @@ 6.12 endif 6.13 endif 6.14 6.15 +EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib 6.16 + 6.17 ifeq ($(BUILD_WIN_SA), 1) 6.18 EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX) 6.19 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
7.1 --- a/src/cpu/ppc/vm/assembler_ppc.hpp Wed Apr 02 09:59:18 2014 -0700 7.2 +++ b/src/cpu/ppc/vm/assembler_ppc.hpp Wed Apr 09 12:23:29 2014 -0700 7.3 @@ -1025,15 +1025,14 @@ 7.4 } 7.5 7.6 static void set_imm(int* instr, short s) { 7.7 - short* p = ((short *)instr) + 1; 7.8 - *p = s; 7.9 + // imm is always in the lower 16 bits of the instruction, 7.10 + // so this is endian-neutral. Same for the get_imm below. 7.11 + uint32_t w = *(uint32_t *)instr; 7.12 + *instr = (int)((w & ~0x0000FFFF) | (s & 0x0000FFFF)); 7.13 } 7.14 7.15 static int get_imm(address a, int instruction_number) { 7.16 - short imm; 7.17 - short *p =((short *)a)+2*instruction_number+1; 7.18 - imm = *p; 7.19 - return (int)imm; 7.20 + return (short)((int *)a)[instruction_number]; 7.21 } 7.22 7.23 static inline int hi16_signed( int x) { return (int)(int16_t)(x >> 16); }
8.1 --- a/src/cpu/ppc/vm/bytes_ppc.hpp Wed Apr 02 09:59:18 2014 -0700 8.2 +++ b/src/cpu/ppc/vm/bytes_ppc.hpp Wed Apr 09 12:23:29 2014 -0700 8.3 @@ -35,6 +35,126 @@ 8.4 8.5 // Can I count on address always being a pointer to an unsigned char? Yes. 8.6 8.7 +#if defined(VM_LITTLE_ENDIAN) 8.8 + 8.9 + // Returns true, if the byte ordering used by Java is different from the native byte ordering 8.10 + // of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc. 8.11 + static inline bool is_Java_byte_ordering_different() { return true; } 8.12 + 8.13 + // Forward declarations of the compiler-dependent implementation 8.14 + static inline u2 swap_u2(u2 x); 8.15 + static inline u4 swap_u4(u4 x); 8.16 + static inline u8 swap_u8(u8 x); 8.17 + 8.18 + static inline u2 get_native_u2(address p) { 8.19 + return (intptr_t(p) & 1) == 0 8.20 + ? *(u2*)p 8.21 + : ( u2(p[1]) << 8 ) 8.22 + | ( u2(p[0]) ); 8.23 + } 8.24 + 8.25 + static inline u4 get_native_u4(address p) { 8.26 + switch (intptr_t(p) & 3) { 8.27 + case 0: return *(u4*)p; 8.28 + 8.29 + case 2: return ( u4( ((u2*)p)[1] ) << 16 ) 8.30 + | ( u4( ((u2*)p)[0] ) ); 8.31 + 8.32 + default: return ( u4(p[3]) << 24 ) 8.33 + | ( u4(p[2]) << 16 ) 8.34 + | ( u4(p[1]) << 8 ) 8.35 + | u4(p[0]); 8.36 + } 8.37 + } 8.38 + 8.39 + static inline u8 get_native_u8(address p) { 8.40 + switch (intptr_t(p) & 7) { 8.41 + case 0: return *(u8*)p; 8.42 + 8.43 + case 4: return ( u8( ((u4*)p)[1] ) << 32 ) 8.44 + | ( u8( ((u4*)p)[0] ) ); 8.45 + 8.46 + case 2: return ( u8( ((u2*)p)[3] ) << 48 ) 8.47 + | ( u8( ((u2*)p)[2] ) << 32 ) 8.48 + | ( u8( ((u2*)p)[1] ) << 16 ) 8.49 + | ( u8( ((u2*)p)[0] ) ); 8.50 + 8.51 + default: return ( u8(p[7]) << 56 ) 8.52 + | ( u8(p[6]) << 48 ) 8.53 + | ( u8(p[5]) << 40 ) 8.54 + | ( u8(p[4]) << 32 ) 8.55 + | ( u8(p[3]) << 24 ) 8.56 + | ( u8(p[2]) << 16 ) 8.57 + | ( u8(p[1]) << 8 ) 8.58 + | u8(p[0]); 8.59 + } 8.60 + } 8.61 + 8.62 + 8.63 + 8.64 + static inline void put_native_u2(address p, u2 x) { 8.65 + if ( (intptr_t(p) & 1) == 0 ) *(u2*)p = x; 8.66 + else { 8.67 + p[1] = x >> 8; 8.68 + p[0] = x; 8.69 + } 8.70 + } 8.71 + 8.72 + static inline void put_native_u4(address p, u4 x) { 8.73 + switch ( intptr_t(p) & 3 ) { 8.74 + case 0: *(u4*)p = x; 8.75 + break; 8.76 + 8.77 + case 2: ((u2*)p)[1] = x >> 16; 8.78 + ((u2*)p)[0] = x; 8.79 + break; 8.80 + 8.81 + default: ((u1*)p)[3] = x >> 24; 8.82 + ((u1*)p)[2] = x >> 16; 8.83 + ((u1*)p)[1] = x >> 8; 8.84 + ((u1*)p)[0] = x; 8.85 + break; 8.86 + } 8.87 + } 8.88 + 8.89 + static inline void put_native_u8(address p, u8 x) { 8.90 + switch ( intptr_t(p) & 7 ) { 8.91 + case 0: *(u8*)p = x; 8.92 + break; 8.93 + 8.94 + case 4: ((u4*)p)[1] = x >> 32; 8.95 + ((u4*)p)[0] = x; 8.96 + break; 8.97 + 8.98 + case 2: ((u2*)p)[3] = x >> 48; 8.99 + ((u2*)p)[2] = x >> 32; 8.100 + ((u2*)p)[1] = x >> 16; 8.101 + ((u2*)p)[0] = x; 8.102 + break; 8.103 + 8.104 + default: ((u1*)p)[7] = x >> 56; 8.105 + ((u1*)p)[6] = x >> 48; 8.106 + ((u1*)p)[5] = x >> 40; 8.107 + ((u1*)p)[4] = x >> 32; 8.108 + ((u1*)p)[3] = x >> 24; 8.109 + ((u1*)p)[2] = x >> 16; 8.110 + ((u1*)p)[1] = x >> 8; 8.111 + ((u1*)p)[0] = x; 8.112 + } 8.113 + } 8.114 + 8.115 + // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering) 8.116 + // (no byte-order reversal is needed since Power CPUs are big-endian oriented). 8.117 + static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); } 8.118 + static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); } 8.119 + static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); } 8.120 + 8.121 + static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); } 8.122 + static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); } 8.123 + static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); } 8.124 + 8.125 +#else // !defined(VM_LITTLE_ENDIAN) 8.126 + 8.127 // Returns true, if the byte ordering used by Java is different from the nativ byte ordering 8.128 // of the underlying machine. For example, true for Intel x86, False, for Solaris on Sparc. 8.129 static inline bool is_Java_byte_ordering_different() { return false; } 8.130 @@ -150,6 +270,12 @@ 8.131 static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, x); } 8.132 static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, x); } 8.133 static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, x); } 8.134 + 8.135 +#endif // VM_LITTLE_ENDIAN 8.136 }; 8.137 8.138 +#if defined(TARGET_OS_ARCH_linux_ppc) 8.139 +#include "bytes_linux_ppc.inline.hpp" 8.140 +#endif 8.141 + 8.142 #endif // CPU_PPC_VM_BYTES_PPC_HPP
9.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Apr 02 09:59:18 2014 -0700 9.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Apr 09 12:23:29 2014 -0700 9.3 @@ -801,7 +801,13 @@ 9.4 if (UseCompressedOops && !wide) { 9.5 __ movl(as_Address(addr), (int32_t)NULL_WORD); 9.6 } else { 9.7 +#ifdef _LP64 9.8 + __ xorptr(rscratch1, rscratch1); 9.9 + null_check_here = code_offset(); 9.10 + __ movptr(as_Address(addr), rscratch1); 9.11 +#else 9.12 __ movptr(as_Address(addr), NULL_WORD); 9.13 +#endif 9.14 } 9.15 } else { 9.16 if (is_literal_address(addr)) {
10.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp Wed Apr 02 09:59:18 2014 -0700 10.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Wed Apr 09 12:23:29 2014 -0700 10.3 @@ -59,9 +59,9 @@ 10.4 static const int stub_size = 600; 10.5 10.6 extern "C" { 10.7 - typedef void (*getPsrInfo_stub_t)(void*); 10.8 + typedef void (*get_cpu_info_stub_t)(void*); 10.9 } 10.10 -static getPsrInfo_stub_t getPsrInfo_stub = NULL; 10.11 +static get_cpu_info_stub_t get_cpu_info_stub = NULL; 10.12 10.13 10.14 class VM_Version_StubGenerator: public StubCodeGenerator { 10.15 @@ -69,7 +69,7 @@ 10.16 10.17 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 10.18 10.19 - address generate_getPsrInfo() { 10.20 + address generate_get_cpu_info() { 10.21 // Flags to test CPU type. 10.22 const uint32_t HS_EFL_AC = 0x40000; 10.23 const uint32_t HS_EFL_ID = 0x200000; 10.24 @@ -81,13 +81,13 @@ 10.25 Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; 10.26 Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done; 10.27 10.28 - StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); 10.29 + StubCodeMark mark(this, "VM_Version", "get_cpu_info_stub"); 10.30 # define __ _masm-> 10.31 10.32 address start = __ pc(); 10.33 10.34 // 10.35 - // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); 10.36 + // void get_cpu_info(VM_Version::CpuidInfo* cpuid_info); 10.37 // 10.38 // LP64: rcx and rdx are first and second argument registers on windows 10.39 10.40 @@ -385,6 +385,14 @@ 10.41 }; 10.42 10.43 10.44 +void VM_Version::get_cpu_info_wrapper() { 10.45 + get_cpu_info_stub(&_cpuid_info); 10.46 +} 10.47 + 10.48 +#ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED 10.49 + #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f() 10.50 +#endif 10.51 + 10.52 void VM_Version::get_processor_features() { 10.53 10.54 _cpu = 4; // 486 by default 10.55 @@ -395,7 +403,11 @@ 10.56 10.57 if (!Use486InstrsOnly) { 10.58 // Get raw processor info 10.59 - getPsrInfo_stub(&_cpuid_info); 10.60 + 10.61 + // Some platforms (like Win*) need a wrapper around here 10.62 + // in order to properly handle SEGV for YMM registers test. 10.63 + CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(get_cpu_info_wrapper); 10.64 + 10.65 assert_is_initialized(); 10.66 _cpu = extended_cpu_family(); 10.67 _model = extended_cpu_model(); 10.68 @@ -986,14 +998,14 @@ 10.69 ResourceMark rm; 10.70 // Making this stub must be FIRST use of assembler 10.71 10.72 - stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size); 10.73 + stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size); 10.74 if (stub_blob == NULL) { 10.75 - vm_exit_during_initialization("Unable to allocate getPsrInfo_stub"); 10.76 + vm_exit_during_initialization("Unable to allocate get_cpu_info_stub"); 10.77 } 10.78 CodeBuffer c(stub_blob); 10.79 VM_Version_StubGenerator g(&c); 10.80 - getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t, 10.81 - g.generate_getPsrInfo()); 10.82 + get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t, 10.83 + g.generate_get_cpu_info()); 10.84 10.85 get_processor_features(); 10.86 }
11.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp Wed Apr 02 09:59:18 2014 -0700 11.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Wed Apr 09 12:23:29 2014 -0700 11.3 @@ -507,6 +507,7 @@ 11.4 // The value used to check ymm register after signal handle 11.5 static int ymm_test_value() { return 0xCAFEBABE; } 11.6 11.7 + static void get_cpu_info_wrapper(); 11.8 static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } 11.9 static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; } 11.10 static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; }
12.1 --- a/src/os/linux/vm/os_linux.cpp Wed Apr 02 09:59:18 2014 -0700 12.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Apr 09 12:23:29 2014 -0700 12.3 @@ -1963,7 +1963,11 @@ 12.4 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, 12.5 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, 12.6 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, 12.7 +#if defined(VM_LITTLE_ENDIAN) 12.8 + {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2LSB, (char*)"Power PC 64"}, 12.9 +#else 12.10 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, 12.11 +#endif 12.12 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, 12.13 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, 12.14 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
13.1 --- a/src/os/windows/vm/os_windows.cpp Wed Apr 02 09:59:18 2014 -0700 13.2 +++ b/src/os/windows/vm/os_windows.cpp Wed Apr 09 12:23:29 2014 -0700 13.3 @@ -2716,7 +2716,6 @@ 13.4 } 13.5 #endif 13.6 13.7 -#ifndef PRODUCT 13.8 void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) { 13.9 // Install a win32 structured exception handler around the test 13.10 // function call so the VM can generate an error dump if needed. 13.11 @@ -2727,7 +2726,6 @@ 13.12 // Nothing to do. 13.13 } 13.14 } 13.15 -#endif 13.16 13.17 // Virtual Memory 13.18
14.1 --- a/src/os/windows/vm/os_windows.hpp Wed Apr 02 09:59:18 2014 -0700 14.2 +++ b/src/os/windows/vm/os_windows.hpp Wed Apr 09 12:23:29 2014 -0700 14.3 @@ -97,9 +97,7 @@ 14.4 static address fast_jni_accessor_wrapper(BasicType); 14.5 #endif 14.6 14.7 -#ifndef PRODUCT 14.8 static void call_test_func_with_wrapper(void (*funcPtr)(void)); 14.9 -#endif 14.10 14.11 // filter function to ignore faults on serializations page 14.12 static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
15.1 --- a/src/os/windows/vm/os_windows.inline.hpp Wed Apr 02 09:59:18 2014 -0700 15.2 +++ b/src/os/windows/vm/os_windows.inline.hpp Wed Apr 09 12:23:29 2014 -0700 15.3 @@ -107,9 +107,7 @@ 15.4 return ::close(fd); 15.5 } 15.6 15.7 -#ifndef PRODUCT 15.8 - #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \ 15.9 - os::win32::call_test_func_with_wrapper(f) 15.10 -#endif 15.11 +#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \ 15.12 + os::win32::call_test_func_with_wrapper(f) 15.13 15.14 #endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/os_cpu/linux_ppc/vm/bytes_linux_ppc.inline.hpp Wed Apr 09 12:23:29 2014 -0700 16.3 @@ -0,0 +1,39 @@ 16.4 +/* 16.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright 2014 Google Inc. All rights reserved. 16.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 + * 16.9 + * This code is free software; you can redistribute it and/or modify it 16.10 + * under the terms of the GNU General Public License version 2 only, as 16.11 + * published by the Free Software Foundation. 16.12 + * 16.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 16.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.16 + * version 2 for more details (a copy is included in the LICENSE file that 16.17 + * accompanied this code). 16.18 + * 16.19 + * You should have received a copy of the GNU General Public License version 16.20 + * 2 along with this work; if not, write to the Free Software Foundation, 16.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.22 + * 16.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 16.24 + * or visit www.oracle.com if you need additional information or have any 16.25 + * questions. 16.26 + * 16.27 + */ 16.28 + 16.29 +#ifndef OS_CPU_LINUX_PPC_VM_BYTES_LINUX_PPC_INLINE_HPP 16.30 +#define OS_CPU_LINUX_PPC_VM_BYTES_LINUX_PPC_INLINE_HPP 16.31 + 16.32 +#if defined(VM_LITTLE_ENDIAN) 16.33 +#include <byteswap.h> 16.34 + 16.35 +// Efficient swapping of data bytes from Java byte 16.36 +// ordering to native byte ordering and vice versa. 16.37 +inline u2 Bytes::swap_u2(u2 x) { return bswap_16(x); } 16.38 +inline u4 Bytes::swap_u4(u4 x) { return bswap_32(x); } 16.39 +inline u8 Bytes::swap_u8(u8 x) { return bswap_64(x); } 16.40 +#endif // VM_LITTLE_ENDIAN 16.41 + 16.42 +#endif // OS_CPU_LINUX_PPC_VM_BYTES_LINUX_PPC_INLINE_HPP
17.1 --- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Wed Apr 02 09:59:18 2014 -0700 17.2 +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Wed Apr 09 12:23:29 2014 -0700 17.3 @@ -24,6 +24,7 @@ 17.4 17.5 #include "precompiled.hpp" 17.6 #include "gc_implementation/g1/dirtyCardQueue.hpp" 17.7 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 17.8 #include "gc_implementation/g1/heapRegionRemSet.hpp" 17.9 #include "runtime/atomic.hpp" 17.10 #include "runtime/mutexLocker.hpp"
18.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Apr 02 09:59:18 2014 -0700 18.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Apr 09 12:23:29 2014 -0700 18.3 @@ -3547,6 +3547,29 @@ 18.4 } 18.5 }; 18.6 18.7 +bool G1CollectedHeap::is_obj_dead_cond(const oop obj, 18.8 + const HeapRegion* hr, 18.9 + const VerifyOption vo) const { 18.10 + switch (vo) { 18.11 + case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr); 18.12 + case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr); 18.13 + case VerifyOption_G1UseMarkWord: return !obj->is_gc_marked(); 18.14 + default: ShouldNotReachHere(); 18.15 + } 18.16 + return false; // keep some compilers happy 18.17 +} 18.18 + 18.19 +bool G1CollectedHeap::is_obj_dead_cond(const oop obj, 18.20 + const VerifyOption vo) const { 18.21 + switch (vo) { 18.22 + case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj); 18.23 + case VerifyOption_G1UseNextMarking: return is_obj_ill(obj); 18.24 + case VerifyOption_G1UseMarkWord: return !obj->is_gc_marked(); 18.25 + default: ShouldNotReachHere(); 18.26 + } 18.27 + return false; // keep some compilers happy 18.28 +} 18.29 + 18.30 void G1CollectedHeap::print_on(outputStream* st) const { 18.31 st->print(" %-20s", "garbage-first heap"); 18.32 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
19.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Apr 02 09:59:18 2014 -0700 19.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Apr 09 12:23:29 2014 -0700 19.3 @@ -706,19 +706,7 @@ 19.4 // This is a fast test on whether a reference points into the 19.5 // collection set or not. Assume that the reference 19.6 // points into the heap. 19.7 - bool in_cset_fast_test(oop obj) { 19.8 - assert(_in_cset_fast_test != NULL, "sanity"); 19.9 - assert(_g1_committed.contains((HeapWord*) obj), err_msg("Given reference outside of heap, is "PTR_FORMAT, (HeapWord*)obj)); 19.10 - // no need to subtract the bottom of the heap from obj, 19.11 - // _in_cset_fast_test is biased 19.12 - uintx index = cast_from_oop<uintx>(obj) >> HeapRegion::LogOfHRGrainBytes; 19.13 - bool ret = _in_cset_fast_test[index]; 19.14 - // let's make sure the result is consistent with what the slower 19.15 - // test returns 19.16 - assert( ret || !obj_in_cs(obj), "sanity"); 19.17 - assert(!ret || obj_in_cs(obj), "sanity"); 19.18 - return ret; 19.19 - } 19.20 + inline bool in_cset_fast_test(oop obj); 19.21 19.22 void clear_cset_fast_test() { 19.23 assert(_in_cset_fast_test_base != NULL, "sanity"); 19.24 @@ -1264,9 +1252,7 @@ 19.25 } 19.26 } 19.27 19.28 - void old_set_remove(HeapRegion* hr) { 19.29 - _old_set.remove(hr); 19.30 - } 19.31 + inline void old_set_remove(HeapRegion* hr); 19.32 19.33 size_t non_young_capacity_bytes() { 19.34 return _old_set.total_capacity_bytes() + _humongous_set.total_capacity_bytes(); 19.35 @@ -1357,7 +1343,7 @@ 19.36 void heap_region_iterate(HeapRegionClosure* blk) const; 19.37 19.38 // Return the region with the given index. It assumes the index is valid. 19.39 - HeapRegion* region_at(uint index) const { return _hrs.at(index); } 19.40 + inline HeapRegion* region_at(uint index) const; 19.41 19.42 // Divide the heap region sequence into "chunks" of some size (the number 19.43 // of regions divided by the number of parallel threads times some 19.44 @@ -1486,10 +1472,7 @@ 19.45 return true; 19.46 } 19.47 19.48 - bool is_in_young(const oop obj) { 19.49 - HeapRegion* hr = heap_region_containing(obj); 19.50 - return hr != NULL && hr->is_young(); 19.51 - } 19.52 + inline bool is_in_young(const oop obj); 19.53 19.54 #ifdef ASSERT 19.55 virtual bool is_in_partial_collection(const void* p); 19.56 @@ -1502,9 +1485,7 @@ 19.57 // pre-value that needs to be remembered; for the remembered-set 19.58 // update logging post-barrier, we don't maintain remembered set 19.59 // information for young gen objects. 19.60 - virtual bool can_elide_initializing_store_barrier(oop new_obj) { 19.61 - return is_in_young(new_obj); 19.62 - } 19.63 + virtual inline bool can_elide_initializing_store_barrier(oop new_obj); 19.64 19.65 // Returns "true" iff the given word_size is "very large". 19.66 static bool isHumongous(size_t word_size) { 19.67 @@ -1598,23 +1579,9 @@ 19.68 19.69 // Added if it is NULL it isn't dead. 19.70 19.71 - bool is_obj_dead(const oop obj) const { 19.72 - const HeapRegion* hr = heap_region_containing(obj); 19.73 - if (hr == NULL) { 19.74 - if (obj == NULL) return false; 19.75 - else return true; 19.76 - } 19.77 - else return is_obj_dead(obj, hr); 19.78 - } 19.79 + inline bool is_obj_dead(const oop obj) const; 19.80 19.81 - bool is_obj_ill(const oop obj) const { 19.82 - const HeapRegion* hr = heap_region_containing(obj); 19.83 - if (hr == NULL) { 19.84 - if (obj == NULL) return false; 19.85 - else return true; 19.86 - } 19.87 - else return is_obj_ill(obj, hr); 19.88 - } 19.89 + inline bool is_obj_ill(const oop obj) const; 19.90 19.91 bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo); 19.92 HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo); 19.93 @@ -1708,26 +1675,10 @@ 19.94 19.95 bool is_obj_dead_cond(const oop obj, 19.96 const HeapRegion* hr, 19.97 - const VerifyOption vo) const { 19.98 - switch (vo) { 19.99 - case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr); 19.100 - case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr); 19.101 - case VerifyOption_G1UseMarkWord: return !obj->is_gc_marked(); 19.102 - default: ShouldNotReachHere(); 19.103 - } 19.104 - return false; // keep some compilers happy 19.105 - } 19.106 + const VerifyOption vo) const; 19.107 19.108 bool is_obj_dead_cond(const oop obj, 19.109 - const VerifyOption vo) const { 19.110 - switch (vo) { 19.111 - case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj); 19.112 - case VerifyOption_G1UseNextMarking: return is_obj_ill(obj); 19.113 - case VerifyOption_G1UseMarkWord: return !obj->is_gc_marked(); 19.114 - default: ShouldNotReachHere(); 19.115 - } 19.116 - return false; // keep some compilers happy 19.117 - } 19.118 + const VerifyOption vo) const; 19.119 19.120 // Printing 19.121 19.122 @@ -1821,11 +1772,7 @@ 19.123 DirtyCardQueue& dirty_card_queue() { return _dcq; } 19.124 G1SATBCardTableModRefBS* ctbs() { return _ct_bs; } 19.125 19.126 - template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) { 19.127 - if (!from->is_survivor()) { 19.128 - _g1_rem->par_write_ref(from, p, tid); 19.129 - } 19.130 - } 19.131 + template <class T> inline void immediate_rs_update(HeapRegion* from, T* p, int tid); 19.132 19.133 template <class T> void deferred_rs_update(HeapRegion* from, T* p, int tid) { 19.134 // If the new value of the field points to the same region or 19.135 @@ -1867,13 +1814,7 @@ 19.136 refs()->push(ref); 19.137 } 19.138 19.139 - template <class T> void update_rs(HeapRegion* from, T* p, int tid) { 19.140 - if (G1DeferredRSUpdate) { 19.141 - deferred_rs_update(from, p, tid); 19.142 - } else { 19.143 - immediate_rs_update(from, p, tid); 19.144 - } 19.145 - } 19.146 + template <class T> inline void update_rs(HeapRegion* from, T* p, int tid); 19.147 19.148 HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) { 19.149 HeapWord* obj = NULL; 19.150 @@ -1997,54 +1938,7 @@ 19.151 return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK); 19.152 } 19.153 19.154 - void do_oop_partial_array(oop* p) { 19.155 - assert(has_partial_array_mask(p), "invariant"); 19.156 - oop from_obj = clear_partial_array_mask(p); 19.157 - 19.158 - assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap."); 19.159 - assert(from_obj->is_objArray(), "must be obj array"); 19.160 - objArrayOop from_obj_array = objArrayOop(from_obj); 19.161 - // The from-space object contains the real length. 19.162 - int length = from_obj_array->length(); 19.163 - 19.164 - assert(from_obj->is_forwarded(), "must be forwarded"); 19.165 - oop to_obj = from_obj->forwardee(); 19.166 - assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); 19.167 - objArrayOop to_obj_array = objArrayOop(to_obj); 19.168 - // We keep track of the next start index in the length field of the 19.169 - // to-space object. 19.170 - int next_index = to_obj_array->length(); 19.171 - assert(0 <= next_index && next_index < length, 19.172 - err_msg("invariant, next index: %d, length: %d", next_index, length)); 19.173 - 19.174 - int start = next_index; 19.175 - int end = length; 19.176 - int remainder = end - start; 19.177 - // We'll try not to push a range that's smaller than ParGCArrayScanChunk. 19.178 - if (remainder > 2 * ParGCArrayScanChunk) { 19.179 - end = start + ParGCArrayScanChunk; 19.180 - to_obj_array->set_length(end); 19.181 - // Push the remainder before we process the range in case another 19.182 - // worker has run out of things to do and can steal it. 19.183 - oop* from_obj_p = set_partial_array_mask(from_obj); 19.184 - push_on_queue(from_obj_p); 19.185 - } else { 19.186 - assert(length == end, "sanity"); 19.187 - // We'll process the final range for this object. Restore the length 19.188 - // so that the heap remains parsable in case of evacuation failure. 19.189 - to_obj_array->set_length(end); 19.190 - } 19.191 - _scanner.set_region(_g1h->heap_region_containing_raw(to_obj)); 19.192 - // Process indexes [start,end). It will also process the header 19.193 - // along with the first chunk (i.e., the chunk with start == 0). 19.194 - // Note that at this point the length field of to_obj_array is not 19.195 - // correct given that we are using it to keep track of the next 19.196 - // start index. oop_iterate_range() (thankfully!) ignores the length 19.197 - // field and only relies on the start / end parameters. It does 19.198 - // however return the size of the object which will be incorrect. So 19.199 - // we have to ignore it even if we wanted to use it. 19.200 - to_obj_array->oop_iterate_range(&_scanner, start, end); 19.201 - } 19.202 + inline void do_oop_partial_array(oop* p); 19.203 19.204 // This method is applied to the fields of the objects that have just been copied. 19.205 template <class T> void do_oop_evac(T* p, HeapRegion* from) { 19.206 @@ -2074,26 +1968,9 @@ 19.207 19.208 oop copy_to_survivor_space(oop const obj); 19.209 19.210 - template <class T> void deal_with_reference(T* ref_to_scan) { 19.211 - if (!has_partial_array_mask(ref_to_scan)) { 19.212 - // Note: we can use "raw" versions of "region_containing" because 19.213 - // "obj_to_scan" is definitely in the heap, and is not in a 19.214 - // humongous region. 19.215 - HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan); 19.216 - do_oop_evac(ref_to_scan, r); 19.217 - } else { 19.218 - do_oop_partial_array((oop*)ref_to_scan); 19.219 - } 19.220 - } 19.221 + template <class T> inline void deal_with_reference(T* ref_to_scan); 19.222 19.223 - void deal_with_reference(StarTask ref) { 19.224 - assert(verify_task(ref), "sanity"); 19.225 - if (ref.is_narrow()) { 19.226 - deal_with_reference((narrowOop*)ref); 19.227 - } else { 19.228 - deal_with_reference((oop*)ref); 19.229 - } 19.230 - } 19.231 + inline void deal_with_reference(StarTask ref); 19.232 19.233 public: 19.234 void trim_queue();
20.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Wed Apr 02 09:59:18 2014 -0700 20.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Wed Apr 09 12:23:29 2014 -0700 20.3 @@ -29,6 +29,7 @@ 20.4 #include "gc_implementation/g1/g1CollectedHeap.hpp" 20.5 #include "gc_implementation/g1/g1AllocRegion.inline.hpp" 20.6 #include "gc_implementation/g1/g1CollectorPolicy.hpp" 20.7 +#include "gc_implementation/g1/g1RemSet.inline.hpp" 20.8 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" 20.9 #include "gc_implementation/g1/heapRegionSet.inline.hpp" 20.10 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" 20.11 @@ -36,6 +37,9 @@ 20.12 20.13 // Inline functions for G1CollectedHeap 20.14 20.15 +// Return the region with the given index. It assumes the index is valid. 20.16 +inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at(index); } 20.17 + 20.18 template <class T> 20.19 inline HeapRegion* 20.20 G1CollectedHeap::heap_region_containing(const T addr) const { 20.21 @@ -55,6 +59,10 @@ 20.22 return res; 20.23 } 20.24 20.25 +inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) { 20.26 + _old_set.remove(hr); 20.27 +} 20.28 + 20.29 inline bool G1CollectedHeap::obj_in_cs(oop obj) { 20.30 HeapRegion* r = _hrs.addr_to_region((HeapWord*) obj); 20.31 return r != NULL && r->in_collection_set(); 20.32 @@ -151,6 +159,24 @@ 20.33 return _cm->nextMarkBitMap()->isMarked((HeapWord *)obj); 20.34 } 20.35 20.36 + 20.37 +// This is a fast test on whether a reference points into the 20.38 +// collection set or not. Assume that the reference 20.39 +// points into the heap. 20.40 +inline bool G1CollectedHeap::in_cset_fast_test(oop obj) { 20.41 + assert(_in_cset_fast_test != NULL, "sanity"); 20.42 + assert(_g1_committed.contains((HeapWord*) obj), err_msg("Given reference outside of heap, is "PTR_FORMAT, (HeapWord*)obj)); 20.43 + // no need to subtract the bottom of the heap from obj, 20.44 + // _in_cset_fast_test is biased 20.45 + uintx index = cast_from_oop<uintx>(obj) >> HeapRegion::LogOfHRGrainBytes; 20.46 + bool ret = _in_cset_fast_test[index]; 20.47 + // let's make sure the result is consistent with what the slower 20.48 + // test returns 20.49 + assert( ret || !obj_in_cs(obj), "sanity"); 20.50 + assert(!ret || obj_in_cs(obj), "sanity"); 20.51 + return ret; 20.52 +} 20.53 + 20.54 #ifndef PRODUCT 20.55 // Support for G1EvacuationFailureALot 20.56 20.57 @@ -224,4 +250,121 @@ 20.58 } 20.59 #endif // #ifndef PRODUCT 20.60 20.61 +inline bool G1CollectedHeap::is_in_young(const oop obj) { 20.62 + HeapRegion* hr = heap_region_containing(obj); 20.63 + return hr != NULL && hr->is_young(); 20.64 +} 20.65 + 20.66 +// We don't need barriers for initializing stores to objects 20.67 +// in the young gen: for the SATB pre-barrier, there is no 20.68 +// pre-value that needs to be remembered; for the remembered-set 20.69 +// update logging post-barrier, we don't maintain remembered set 20.70 +// information for young gen objects. 20.71 +inline bool G1CollectedHeap::can_elide_initializing_store_barrier(oop new_obj) { 20.72 + return is_in_young(new_obj); 20.73 +} 20.74 + 20.75 +inline bool G1CollectedHeap::is_obj_dead(const oop obj) const { 20.76 + const HeapRegion* hr = heap_region_containing(obj); 20.77 + if (hr == NULL) { 20.78 + if (obj == NULL) return false; 20.79 + else return true; 20.80 + } 20.81 + else return is_obj_dead(obj, hr); 20.82 +} 20.83 + 20.84 +inline bool G1CollectedHeap::is_obj_ill(const oop obj) const { 20.85 + const HeapRegion* hr = heap_region_containing(obj); 20.86 + if (hr == NULL) { 20.87 + if (obj == NULL) return false; 20.88 + else return true; 20.89 + } 20.90 + else return is_obj_ill(obj, hr); 20.91 +} 20.92 + 20.93 +template <class T> inline void G1ParScanThreadState::immediate_rs_update(HeapRegion* from, T* p, int tid) { 20.94 + if (!from->is_survivor()) { 20.95 + _g1_rem->par_write_ref(from, p, tid); 20.96 + } 20.97 +} 20.98 + 20.99 +template <class T> void G1ParScanThreadState::update_rs(HeapRegion* from, T* p, int tid) { 20.100 + if (G1DeferredRSUpdate) { 20.101 + deferred_rs_update(from, p, tid); 20.102 + } else { 20.103 + immediate_rs_update(from, p, tid); 20.104 + } 20.105 +} 20.106 + 20.107 + 20.108 +inline void G1ParScanThreadState::do_oop_partial_array(oop* p) { 20.109 + assert(has_partial_array_mask(p), "invariant"); 20.110 + oop from_obj = clear_partial_array_mask(p); 20.111 + 20.112 + assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap."); 20.113 + assert(from_obj->is_objArray(), "must be obj array"); 20.114 + objArrayOop from_obj_array = objArrayOop(from_obj); 20.115 + // The from-space object contains the real length. 20.116 + int length = from_obj_array->length(); 20.117 + 20.118 + assert(from_obj->is_forwarded(), "must be forwarded"); 20.119 + oop to_obj = from_obj->forwardee(); 20.120 + assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); 20.121 + objArrayOop to_obj_array = objArrayOop(to_obj); 20.122 + // We keep track of the next start index in the length field of the 20.123 + // to-space object. 20.124 + int next_index = to_obj_array->length(); 20.125 + assert(0 <= next_index && next_index < length, 20.126 + err_msg("invariant, next index: %d, length: %d", next_index, length)); 20.127 + 20.128 + int start = next_index; 20.129 + int end = length; 20.130 + int remainder = end - start; 20.131 + // We'll try not to push a range that's smaller than ParGCArrayScanChunk. 20.132 + if (remainder > 2 * ParGCArrayScanChunk) { 20.133 + end = start + ParGCArrayScanChunk; 20.134 + to_obj_array->set_length(end); 20.135 + // Push the remainder before we process the range in case another 20.136 + // worker has run out of things to do and can steal it. 20.137 + oop* from_obj_p = set_partial_array_mask(from_obj); 20.138 + push_on_queue(from_obj_p); 20.139 + } else { 20.140 + assert(length == end, "sanity"); 20.141 + // We'll process the final range for this object. Restore the length 20.142 + // so that the heap remains parsable in case of evacuation failure. 20.143 + to_obj_array->set_length(end); 20.144 + } 20.145 + _scanner.set_region(_g1h->heap_region_containing_raw(to_obj)); 20.146 + // Process indexes [start,end). It will also process the header 20.147 + // along with the first chunk (i.e., the chunk with start == 0). 20.148 + // Note that at this point the length field of to_obj_array is not 20.149 + // correct given that we are using it to keep track of the next 20.150 + // start index. oop_iterate_range() (thankfully!) ignores the length 20.151 + // field and only relies on the start / end parameters. It does 20.152 + // however return the size of the object which will be incorrect. So 20.153 + // we have to ignore it even if we wanted to use it. 20.154 + to_obj_array->oop_iterate_range(&_scanner, start, end); 20.155 +} 20.156 + 20.157 +template <class T> inline void G1ParScanThreadState::deal_with_reference(T* ref_to_scan) { 20.158 + if (!has_partial_array_mask(ref_to_scan)) { 20.159 + // Note: we can use "raw" versions of "region_containing" because 20.160 + // "obj_to_scan" is definitely in the heap, and is not in a 20.161 + // humongous region. 20.162 + HeapRegion* r = _g1h->heap_region_containing_raw(ref_to_scan); 20.163 + do_oop_evac(ref_to_scan, r); 20.164 + } else { 20.165 + do_oop_partial_array((oop*)ref_to_scan); 20.166 + } 20.167 +} 20.168 + 20.169 +inline void G1ParScanThreadState::deal_with_reference(StarTask ref) { 20.170 + assert(verify_task(ref), "sanity"); 20.171 + if (ref.is_narrow()) { 20.172 + deal_with_reference((narrowOop*)ref); 20.173 + } else { 20.174 + deal_with_reference((oop*)ref); 20.175 + } 20.176 +} 20.177 + 20.178 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_INLINE_HPP
21.1 --- a/src/share/vm/gc_implementation/g1/sparsePRT.hpp Wed Apr 02 09:59:18 2014 -0700 21.2 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.hpp Wed Apr 09 12:23:29 2014 -0700 21.3 @@ -25,7 +25,7 @@ 21.4 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_SPARSEPRT_HPP 21.5 #define SHARE_VM_GC_IMPLEMENTATION_G1_SPARSEPRT_HPP 21.6 21.7 -#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 21.8 +#include "gc_implementation/g1/g1CollectedHeap.hpp" 21.9 #include "gc_implementation/g1/heapRegion.hpp" 21.10 #include "memory/allocation.hpp" 21.11 #include "memory/cardTableModRefBS.hpp"
22.1 --- a/src/share/vm/prims/jni.cpp Wed Apr 02 09:59:18 2014 -0700 22.2 +++ b/src/share/vm/prims/jni.cpp Wed Apr 09 12:23:29 2014 -0700 22.3 @@ -5208,7 +5208,7 @@ 22.4 } 22.5 22.6 #ifndef PRODUCT 22.7 - #ifndef TARGET_OS_FAMILY_windows 22.8 + #ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED 22.9 #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f() 22.10 #endif 22.11
23.1 --- a/src/share/vm/runtime/arguments.cpp Wed Apr 02 09:59:18 2014 -0700 23.2 +++ b/src/share/vm/runtime/arguments.cpp Wed Apr 09 12:23:29 2014 -0700 23.3 @@ -1880,24 +1880,22 @@ 23.4 // check if do gclog rotation 23.5 // +UseGCLogFileRotation is a must, 23.6 // no gc log rotation when log file not supplied or 23.7 -// NumberOfGCLogFiles is 0, or GCLogFileSize is 0 23.8 +// NumberOfGCLogFiles is 0 23.9 void check_gclog_consistency() { 23.10 if (UseGCLogFileRotation) { 23.11 - if ((Arguments::gc_log_filename() == NULL) || 23.12 - (NumberOfGCLogFiles == 0) || 23.13 - (GCLogFileSize == 0)) { 23.14 + if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) { 23.15 jio_fprintf(defaultStream::output_stream(), 23.16 - "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>[k|K|m|M|g|G]\n" 23.17 - "where num_of_file > 0 and num_of_size > 0\n" 23.18 + "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n" 23.19 + "where num_of_file > 0\n" 23.20 "GC log rotation is turned off\n"); 23.21 UseGCLogFileRotation = false; 23.22 } 23.23 } 23.24 23.25 - if (UseGCLogFileRotation && GCLogFileSize < 8*K) { 23.26 - FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K); 23.27 - jio_fprintf(defaultStream::output_stream(), 23.28 - "GCLogFileSize changed to minimum 8K\n"); 23.29 + if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) { 23.30 + FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K); 23.31 + jio_fprintf(defaultStream::output_stream(), 23.32 + "GCLogFileSize changed to minimum 8K\n"); 23.33 } 23.34 } 23.35
24.1 --- a/src/share/vm/runtime/globals.cpp Wed Apr 02 09:59:18 2014 -0700 24.2 +++ b/src/share/vm/runtime/globals.cpp Wed Apr 09 12:23:29 2014 -0700 24.3 @@ -325,7 +325,7 @@ 24.4 else st->print("%-16s", ""); 24.5 } 24.6 24.7 - st->print("%-20"); 24.8 + st->print("%-20s", " "); 24.9 print_kind(st); 24.10 24.11 if (withComments) {
25.1 --- a/src/share/vm/runtime/globals.hpp Wed Apr 02 09:59:18 2014 -0700 25.2 +++ b/src/share/vm/runtime/globals.hpp Wed Apr 09 12:23:29 2014 -0700 25.3 @@ -2422,9 +2422,9 @@ 25.4 "Number of gclog files in rotation " \ 25.5 "(default: 0, no rotation)") \ 25.6 \ 25.7 - product(uintx, GCLogFileSize, 0, \ 25.8 - "GC log file size (default: 0 bytes, no rotation). " \ 25.9 - "It requires UseGCLogFileRotation") \ 25.10 + product(uintx, GCLogFileSize, 8*K, \ 25.11 + "GC log file size, requires UseGCLogFileRotation. " \ 25.12 + "Set to 0 to only trigger rotation via jcmd") \ 25.13 \ 25.14 /* JVMTI heap profiling */ \ 25.15 \
26.1 --- a/src/share/vm/runtime/safepoint.cpp Wed Apr 02 09:59:18 2014 -0700 26.2 +++ b/src/share/vm/runtime/safepoint.cpp Wed Apr 09 12:23:29 2014 -0700 26.3 @@ -535,7 +535,7 @@ 26.4 26.5 // rotate log files? 26.6 if (UseGCLogFileRotation) { 26.7 - gclog_or_tty->rotate_log(); 26.8 + gclog_or_tty->rotate_log(false); 26.9 } 26.10 26.11 if (MemTracker::is_on()) {
27.1 --- a/src/share/vm/runtime/vm_operations.hpp Wed Apr 02 09:59:18 2014 -0700 27.2 +++ b/src/share/vm/runtime/vm_operations.hpp Wed Apr 09 12:23:29 2014 -0700 27.3 @@ -94,6 +94,7 @@ 27.4 template(JFRCheckpoint) \ 27.5 template(Exit) \ 27.6 template(LinuxDllLoad) \ 27.7 + template(RotateGCLog) \ 27.8 27.9 class VM_Operation: public CHeapObj<mtInternal> { 27.10 public: 27.11 @@ -397,4 +398,15 @@ 27.12 void doit(); 27.13 }; 27.14 27.15 + 27.16 +class VM_RotateGCLog: public VM_Operation { 27.17 + private: 27.18 + outputStream* _out; 27.19 + 27.20 + public: 27.21 + VM_RotateGCLog(outputStream* st) : _out(st) {} 27.22 + VMOp_Type type() const { return VMOp_RotateGCLog; } 27.23 + void doit() { gclog_or_tty->rotate_log(true, _out); } 27.24 +}; 27.25 + 27.26 #endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
28.1 --- a/src/share/vm/services/diagnosticCommand.cpp Wed Apr 02 09:59:18 2014 -0700 28.2 +++ b/src/share/vm/services/diagnosticCommand.cpp Wed Apr 09 12:23:29 2014 -0700 28.3 @@ -53,6 +53,7 @@ 28.4 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false)); 28.5 #endif // INCLUDE_SERVICES 28.6 DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false)); 28.7 + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false)); 28.8 28.9 // Enhanced JMX Agent Support 28.10 // These commands won't be exported via the DiagnosticCommandMBean until an 28.11 @@ -650,3 +651,11 @@ 28.12 JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); 28.13 } 28.14 28.15 +void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) { 28.16 + if (UseGCLogFileRotation) { 28.17 + VM_RotateGCLog rotateop(output()); 28.18 + VMThread::execute(&rotateop); 28.19 + } else { 28.20 + output()->print_cr("Target VM does not support GC log file rotation."); 28.21 + } 28.22 +}
29.1 --- a/src/share/vm/services/diagnosticCommand.hpp Wed Apr 02 09:59:18 2014 -0700 29.2 +++ b/src/share/vm/services/diagnosticCommand.hpp Wed Apr 09 12:23:29 2014 -0700 29.3 @@ -360,4 +360,21 @@ 29.4 virtual void execute(DCmdSource source, TRAPS); 29.5 }; 29.6 29.7 +class RotateGCLogDCmd : public DCmd { 29.8 +public: 29.9 + RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} 29.10 + static const char* name() { return "GC.rotate_log"; } 29.11 + static const char* description() { 29.12 + return "Force the GC log file to be rotated."; 29.13 + } 29.14 + static const char* impact() { return "Low"; } 29.15 + virtual void execute(DCmdSource source, TRAPS); 29.16 + static int num_arguments() { return 0; } 29.17 + static const JavaPermission permission() { 29.18 + JavaPermission p = {"java.lang.management.ManagementPermission", 29.19 + "control", NULL}; 29.20 + return p; 29.21 + } 29.22 +}; 29.23 + 29.24 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
30.1 --- a/src/share/vm/utilities/ostream.cpp Wed Apr 02 09:59:18 2014 -0700 30.2 +++ b/src/share/vm/utilities/ostream.cpp Wed Apr 09 12:23:29 2014 -0700 30.3 @@ -662,13 +662,13 @@ 30.4 // write to gc log file at safepoint. If in future, changes made for mutator threads or 30.5 // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log 30.6 // must be synchronized. 30.7 -void gcLogFileStream::rotate_log() { 30.8 +void gcLogFileStream::rotate_log(bool force, outputStream* out) { 30.9 char time_msg[FILENAMEBUFLEN]; 30.10 char time_str[EXTRACHARLEN]; 30.11 char current_file_name[FILENAMEBUFLEN]; 30.12 char renamed_file_name[FILENAMEBUFLEN]; 30.13 30.14 - if (_bytes_written < (jlong)GCLogFileSize) { 30.15 + if (!should_rotate(force)) { 30.16 return; 30.17 } 30.18 30.19 @@ -685,6 +685,11 @@ 30.20 jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n", 30.21 _file_name, os::local_time_string((char *)time_str, sizeof(time_str))); 30.22 write(time_msg, strlen(time_msg)); 30.23 + 30.24 + if (out != NULL) { 30.25 + out->print(time_msg); 30.26 + } 30.27 + 30.28 dump_loggc_header(); 30.29 return; 30.30 } 30.31 @@ -706,12 +711,18 @@ 30.32 _file_name, _cur_file_num); 30.33 jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, 30.34 _file_name, _cur_file_num); 30.35 - jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the" 30.36 - " maximum size. Saved as %s\n", 30.37 - os::local_time_string((char *)time_str, sizeof(time_str)), 30.38 - renamed_file_name); 30.39 + 30.40 + const char* msg = force ? "GC log rotation request has been received." 30.41 + : "GC log file has reached the maximum size."; 30.42 + jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n", 30.43 + os::local_time_string((char *)time_str, sizeof(time_str)), 30.44 + msg, renamed_file_name); 30.45 write(time_msg, strlen(time_msg)); 30.46 30.47 + if (out != NULL) { 30.48 + out->print(time_msg); 30.49 + } 30.50 + 30.51 fclose(_file); 30.52 _file = NULL; 30.53 30.54 @@ -752,6 +763,11 @@ 30.55 os::local_time_string((char *)time_str, sizeof(time_str)), 30.56 current_file_name); 30.57 write(time_msg, strlen(time_msg)); 30.58 + 30.59 + if (out != NULL) { 30.60 + out->print(time_msg); 30.61 + } 30.62 + 30.63 dump_loggc_header(); 30.64 // remove the existing file 30.65 if (access(current_file_name, F_OK) == 0) {
31.1 --- a/src/share/vm/utilities/ostream.hpp Wed Apr 02 09:59:18 2014 -0700 31.2 +++ b/src/share/vm/utilities/ostream.hpp Wed Apr 09 12:23:29 2014 -0700 31.3 @@ -115,7 +115,7 @@ 31.4 // flushing 31.5 virtual void flush() {} 31.6 virtual void write(const char* str, size_t len) = 0; 31.7 - virtual void rotate_log() {} // GC log rotation 31.8 + virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation 31.9 virtual ~outputStream() {} // close properly on deletion 31.10 31.11 void dec_cr() { dec(); cr(); } 31.12 @@ -240,8 +240,15 @@ 31.13 gcLogFileStream(const char* file_name); 31.14 ~gcLogFileStream(); 31.15 virtual void write(const char* c, size_t len); 31.16 - virtual void rotate_log(); 31.17 + virtual void rotate_log(bool force, outputStream* out = NULL); 31.18 void dump_loggc_header(); 31.19 + 31.20 + /* If "force" sets true, force log file rotation from outside JVM */ 31.21 + bool should_rotate(bool force) { 31.22 + return force || 31.23 + ((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize)); 31.24 + } 31.25 + 31.26 }; 31.27 31.28 #ifndef PRODUCT
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/compiler/codegen/C1NullCheckOfNullStore.java Wed Apr 09 12:23:29 2014 -0700 32.3 @@ -0,0 +1,57 @@ 32.4 +/* 32.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.23 + * or visit www.oracle.com if you need additional information or have any 32.24 + * questions. 32.25 + */ 32.26 + 32.27 +/* 32.28 + * @test 32.29 + * @bug 8039043 32.30 + * @summary Null check is placed in a wrong place when storing a null to an object field on x64 with compressed oops off 32.31 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CompileCommand=compileonly,C1NullCheckOfNullStore::test -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:-UseCompressedOops C1NullCheckOfNullStore 32.32 + * 32.33 + */ 32.34 + 32.35 +public class C1NullCheckOfNullStore { 32.36 + private static class Foo { 32.37 + Object bar; 32.38 + } 32.39 + static private void test(Foo x) { 32.40 + x.bar = null; 32.41 + } 32.42 + static public void main(String args[]) { 32.43 + Foo x = new Foo(); 32.44 + for (int i = 0; i < 10000; i++) { 32.45 + test(x); 32.46 + } 32.47 + boolean gotNPE = false; 32.48 + try { 32.49 + for (int i = 0; i < 10000; i++) { 32.50 + test(null); 32.51 + } 32.52 + } 32.53 + catch(NullPointerException e) { 32.54 + gotNPE = true; 32.55 + } 32.56 + if (!gotNPE) { 32.57 + throw new Error("Expecting a NullPointerException"); 32.58 + } 32.59 + } 32.60 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/gc/TestGCLogRotationViaJcmd.java Wed Apr 09 12:23:29 2014 -0700 33.3 @@ -0,0 +1,77 @@ 33.4 +/* 33.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. 33.11 + * 33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 + * version 2 for more details (a copy is included in the LICENSE file that 33.16 + * accompanied this code). 33.17 + * 33.18 + * You should have received a copy of the GNU General Public License version 33.19 + * 2 along with this work; if not, write to the Free Software Foundation, 33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 + * 33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 + * or visit www.oracle.com if you need additional information or have any 33.24 + * questions. 33.25 + */ 33.26 + 33.27 +/* 33.28 + * @test TestGCLogRotationViaJcmd.java 33.29 + * @bug 7090324 33.30 + * @summary test for gc log rotation via jcmd 33.31 + * @library /testlibrary 33.32 + * @run main/othervm -Xloggc:test.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 TestGCLogRotationViaJcmd 33.33 + * 33.34 + */ 33.35 +import com.oracle.java.testlibrary.*; 33.36 +import java.io.File; 33.37 +import java.io.FilenameFilter; 33.38 + 33.39 +public class TestGCLogRotationViaJcmd { 33.40 + 33.41 + static final File currentDirectory = new File("."); 33.42 + static final String LOG_FILE_NAME = "test.log"; 33.43 + static final int NUM_LOGS = 3; 33.44 + 33.45 + static FilenameFilter logFilter = new FilenameFilter() { 33.46 + @Override 33.47 + public boolean accept(File dir, String name) { 33.48 + return name.startsWith(LOG_FILE_NAME); 33.49 + } 33.50 + }; 33.51 + 33.52 + public static void main(String[] args) throws Exception { 33.53 + // Grab the pid from the current java process 33.54 + String pid = Integer.toString(ProcessTools.getProcessId()); 33.55 + 33.56 + // Create a JDKToolLauncher 33.57 + JDKToolLauncher jcmd = JDKToolLauncher.create("jcmd") 33.58 + .addToolArg(pid) 33.59 + .addToolArg("GC.rotate_log"); 33.60 + 33.61 + for (int times = 1; times < NUM_LOGS; times++) { 33.62 + // Run jcmd <pid> GC.rotate_log 33.63 + ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand()); 33.64 + 33.65 + // Make sure we didn't crash 33.66 + OutputAnalyzer output = new OutputAnalyzer(pb.start()); 33.67 + output.shouldHaveExitValue(0); 33.68 + } 33.69 + 33.70 + // GC log check 33.71 + File[] logs = currentDirectory.listFiles(logFilter); 33.72 + if (logs.length != NUM_LOGS) { 33.73 + throw new Error("There are only " + logs.length 33.74 + + " logs instead " + NUM_LOGS); 33.75 + } 33.76 + 33.77 + } 33.78 + 33.79 +} 33.80 +