Merge

Wed, 09 Apr 2014 12:23:29 -0700

author
asaha
date
Wed, 09 Apr 2014 12:23:29 -0700
changeset 6603
4d0a601553cc
parent 6602
cdcb11ccfb3b
parent 6545
e7a61fa2658b
child 6604
300e2c5eeb27

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 +

mercurial