--- a/.hgtags-top-repo Thu Oct 16 14:14:57 2014 -0700
+++ b/.hgtags-top-repo Wed Jul 05 20:04:26 2017 +0200
@@ -277,3 +277,4 @@
7e3512dae8e020d44399c0f1c579ff1fe3090ed6 jdk9-b32
e4ba01b726e263953ae129be37c94de6ed145b1d jdk9-b33
087b23f35631e68e950496a36fce8ccca612966a jdk9-b34
+c173ba994245380fb11ef077d1e59823386840eb jdk9-b35
--- a/hotspot/.hgtags Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/.hgtags Wed Jul 05 20:04:26 2017 +0200
@@ -437,3 +437,4 @@
af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32
9b3f5e4f33725f7c1d9b8e523133fe8383a54d9f jdk9-b33
821164b0131a47ca065697c7d27d8f215e608c8d jdk9-b34
+438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35
--- a/hotspot/make/aix/makefiles/fastdebug.make Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/aix/makefiles/fastdebug.make Wed Jul 05 20:04:26 2017 +0200
@@ -67,7 +67,6 @@
# not justified.
LFLAGS_QIPA=
-G_SUFFIX = _g
VERSION = optimized
SYSDEFS += -DASSERT -DFASTDEBUG
PICFLAGS = DEFAULT
--- a/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/aix/makefiles/mapfile-vers-product Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/aix/makefiles/mapfile-vers-product Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Wed Jul 05 20:04:26 2017 +0200
@@ -82,6 +82,7 @@
_JVM_EnableCompiler
_JVM_Exit
_JVM_FillInStackTrace
+ _JVM_FindClassFromCaller
_JVM_FindClassFromClass
_JVM_FindClassFromClassLoader
_JVM_FindClassFromBootLoader
@@ -115,7 +116,6 @@
_JVM_GetClassDeclaredMethods
_JVM_GetClassFieldsCount
_JVM_GetClassInterfaces
- _JVM_GetClassLoader
_JVM_GetClassMethodsCount
_JVM_GetClassModifiers
_JVM_GetClassName
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Wed Jul 05 20:04:26 2017 +0200
@@ -82,6 +82,7 @@
_JVM_EnableCompiler
_JVM_Exit
_JVM_FillInStackTrace
+ _JVM_FindClassFromCaller
_JVM_FindClassFromClass
_JVM_FindClassFromClassLoader
_JVM_FindClassFromBootLoader
@@ -115,7 +116,6 @@
_JVM_GetClassDeclaredMethods
_JVM_GetClassFieldsCount
_JVM_GetClassInterfaces
- _JVM_GetClassLoader
_JVM_GetClassMethodsCount
_JVM_GetClassModifiers
_JVM_GetClassName
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Wed Jul 05 20:04:26 2017 +0200
@@ -84,6 +84,7 @@
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
+ JVM_FindClassFromCaller;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
@@ -117,7 +118,6 @@
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
- JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -268,8 +268,35 @@
ISEL_OPCODE = (31u << OPCODE_SHIFT | 15u << 1),
- MTLR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 8 << SPR_0_4_SHIFT),
- MFLR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 8 << SPR_0_4_SHIFT),
+ // Special purpose registers
+ MTSPR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1),
+ MFSPR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1),
+
+ MTXER_OPCODE = (MTSPR_OPCODE | 1 << SPR_0_4_SHIFT),
+ MFXER_OPCODE = (MFSPR_OPCODE | 1 << SPR_0_4_SHIFT),
+
+ MTDSCR_OPCODE = (MTSPR_OPCODE | 3 << SPR_0_4_SHIFT),
+ MFDSCR_OPCODE = (MFSPR_OPCODE | 3 << SPR_0_4_SHIFT),
+
+ MTLR_OPCODE = (MTSPR_OPCODE | 8 << SPR_0_4_SHIFT),
+ MFLR_OPCODE = (MFSPR_OPCODE | 8 << SPR_0_4_SHIFT),
+
+ MTCTR_OPCODE = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT),
+ MFCTR_OPCODE = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT),
+
+ MTTFHAR_OPCODE = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT),
+ MFTFHAR_OPCODE = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT),
+ MTTFIAR_OPCODE = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT),
+ MFTFIAR_OPCODE = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT),
+ MTTEXASR_OPCODE = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT),
+ MFTEXASR_OPCODE = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT),
+ MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT),
+ MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT),
+
+ MTVRSAVE_OPCODE = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT),
+ MFVRSAVE_OPCODE = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT),
+
+ MFTB_OPCODE = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT),
MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1),
MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1),
@@ -291,9 +318,6 @@
// CTR-related opcodes
BCCTR_OPCODE = (19u << OPCODE_SHIFT | 528u << 1),
- MTCTR_OPCODE = (31u << OPCODE_SHIFT | 467u << 1 | 9 << SPR_0_4_SHIFT),
- MFCTR_OPCODE = (31u << OPCODE_SHIFT | 339u << 1 | 9 << SPR_0_4_SHIFT),
-
LWZ_OPCODE = (32u << OPCODE_SHIFT),
LWZX_OPCODE = (31u << OPCODE_SHIFT | 23u << 1),
@@ -585,6 +609,37 @@
MTVSCR_OPCODE = (4u << OPCODE_SHIFT | 1604u ),
MFVSCR_OPCODE = (4u << OPCODE_SHIFT | 1540u ),
+ // AES (introduced with Power 8)
+ VCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1288u),
+ VCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1289u),
+ VNCIPHER_OPCODE = (4u << OPCODE_SHIFT | 1352u),
+ VNCIPHERLAST_OPCODE = (4u << OPCODE_SHIFT | 1353u),
+ VSBOX_OPCODE = (4u << OPCODE_SHIFT | 1480u),
+
+ // SHA (introduced with Power 8)
+ VSHASIGMAD_OPCODE = (4u << OPCODE_SHIFT | 1730u),
+ VSHASIGMAW_OPCODE = (4u << OPCODE_SHIFT | 1666u),
+
+ // Vector Binary Polynomial Multiplication (introduced with Power 8)
+ VPMSUMB_OPCODE = (4u << OPCODE_SHIFT | 1032u),
+ VPMSUMD_OPCODE = (4u << OPCODE_SHIFT | 1224u),
+ VPMSUMH_OPCODE = (4u << OPCODE_SHIFT | 1096u),
+ VPMSUMW_OPCODE = (4u << OPCODE_SHIFT | 1160u),
+
+ // Vector Permute and Xor (introduced with Power 8)
+ VPERMXOR_OPCODE = (4u << OPCODE_SHIFT | 45u),
+
+ // Transactional Memory instructions (introduced with Power 8)
+ TBEGIN_OPCODE = (31u << OPCODE_SHIFT | 654u << 1),
+ TEND_OPCODE = (31u << OPCODE_SHIFT | 686u << 1),
+ TABORT_OPCODE = (31u << OPCODE_SHIFT | 910u << 1),
+ TABORTWC_OPCODE = (31u << OPCODE_SHIFT | 782u << 1),
+ TABORTWCI_OPCODE = (31u << OPCODE_SHIFT | 846u << 1),
+ TABORTDC_OPCODE = (31u << OPCODE_SHIFT | 814u << 1),
+ TABORTDCI_OPCODE = (31u << OPCODE_SHIFT | 878u << 1),
+ TSR_OPCODE = (31u << OPCODE_SHIFT | 750u << 1),
+ TCHECK_OPCODE = (31u << OPCODE_SHIFT | 718u << 1),
+
// Icache and dcache related instructions
DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1),
DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1),
@@ -1420,6 +1475,25 @@
inline void mcrf( ConditionRegister crd, ConditionRegister cra);
inline void mtcr( Register s);
+ // Special purpose registers
+ // Exception Register
+ inline void mtxer(Register s1);
+ inline void mfxer(Register d);
+ // Vector Register Save Register
+ inline void mtvrsave(Register s1);
+ inline void mfvrsave(Register d);
+ // Timebase
+ inline void mftb(Register d);
+ // Introduced with Power 8:
+ // Data Stream Control Register
+ inline void mtdscr(Register s1);
+ inline void mfdscr(Register d );
+ // Transactional Memory Registers
+ inline void mftfhar(Register d);
+ inline void mftfiar(Register d);
+ inline void mftexasr(Register d);
+ inline void mftexasru(Register d);
+
// PPC 1, section 2.4.1 Branch Instructions
inline void b( address a, relocInfo::relocType rt = relocInfo::none);
inline void b( Label& L);
@@ -1860,6 +1934,39 @@
inline void mtvscr( VectorRegister b);
inline void mfvscr( VectorRegister d);
+ // AES (introduced with Power 8)
+ inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vncipher( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vsbox( VectorRegister d, VectorRegister a);
+
+ // SHA (introduced with Power 8)
+ // Not yet implemented.
+
+ // Vector Binary Polynomial Multiplication (introduced with Power 8)
+ inline void vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b);
+ inline void vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b);
+
+ // Vector Permute and Xor (introduced with Power 8)
+ inline void vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
+
+ // Transactional Memory instructions (introduced with Power 8)
+ inline void tbegin_(); // R=0
+ inline void tbeginrot_(); // R=1 Rollback-Only Transaction
+ inline void tend_(); // A=0
+ inline void tendall_(); // A=1
+ inline void tabort_(Register a);
+ inline void tabortwc_(int t, Register a, Register b);
+ inline void tabortwci_(int t, Register a, int si);
+ inline void tabortdc_(int t, Register a, Register b);
+ inline void tabortdci_(int t, Register a, int si);
+ inline void tsuspend_(); // tsr with L=0
+ inline void tresume_(); // tsr with L=1
+ inline void tcheck(int f);
+
// The following encoders use r0 as second operand. These instructions
// read r0 as '0'.
inline void lwzx( Register d, Register s2);
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -312,6 +312,25 @@
{ emit_int32(MCRF_OPCODE | bf(crd) | bfa(cra)); }
inline void Assembler::mtcr( Register s) { Assembler::mtcrf(0xff, s); }
+// Special purpose registers
+// Exception Register
+inline void Assembler::mtxer(Register s1) { emit_int32(MTXER_OPCODE | rs(s1)); }
+inline void Assembler::mfxer(Register d ) { emit_int32(MFXER_OPCODE | rt(d)); }
+// Vector Register Save Register
+inline void Assembler::mtvrsave(Register s1) { emit_int32(MTVRSAVE_OPCODE | rs(s1)); }
+inline void Assembler::mfvrsave(Register d ) { emit_int32(MFVRSAVE_OPCODE | rt(d)); }
+// Timebase
+inline void Assembler::mftb(Register d ) { emit_int32(MFTB_OPCODE | rt(d)); }
+// Introduced with Power 8:
+// Data Stream Control Register
+inline void Assembler::mtdscr(Register s1) { emit_int32(MTDSCR_OPCODE | rs(s1)); }
+inline void Assembler::mfdscr(Register d ) { emit_int32(MFDSCR_OPCODE | rt(d)); }
+// Transactional Memory Registers
+inline void Assembler::mftfhar(Register d ) { emit_int32(MFTFHAR_OPCODE | rt(d)); }
+inline void Assembler::mftfiar(Register d ) { emit_int32(MFTFIAR_OPCODE | rt(d)); }
+inline void Assembler::mftexasr(Register d ) { emit_int32(MFTEXASR_OPCODE | rt(d)); }
+inline void Assembler::mftexasru(Register d ) { emit_int32(MFTEXASRU_OPCODE | rt(d)); }
+
// SAP JVM 2006-02-13 PPC branch instruction.
// PPC 1, section 2.4.1 Branch Instructions
inline void Assembler::b( address a, relocInfo::relocType rt) { emit_data(BXX_OPCODE| li(disp( intptr_t(a), intptr_t(pc()))) |aa(0)|lk(0), rt); }
@@ -735,6 +754,39 @@
inline void Assembler::mtvscr( VectorRegister b) { emit_int32( MTVSCR_OPCODE | vrb(b)); }
inline void Assembler::mfvscr( VectorRegister d) { emit_int32( MFVSCR_OPCODE | vrt(d)); }
+// AES (introduced with Power 8)
+inline void Assembler::vcipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vncipher( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHER_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vncipherlast(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VNCIPHERLAST_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vsbox( VectorRegister d, VectorRegister a) { emit_int32( VSBOX_OPCODE | vrt(d) | vra(a) ); }
+
+// SHA (introduced with Power 8)
+// Not yet implemented.
+
+// Vector Binary Polynomial Multiplication (introduced with Power 8)
+inline void Assembler::vpmsumb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vpmsumd( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMD_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vpmsumh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMH_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vpmsumw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+
+// Vector Permute and Xor (introduced with Power 8)
+inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
+
+// Transactional Memory instructions (introduced with Power 8)
+inline void Assembler::tbegin_() { emit_int32( TBEGIN_OPCODE | rc(1)); }
+inline void Assembler::tbeginrot_() { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); }
+inline void Assembler::tend_() { emit_int32( TEND_OPCODE | rc(1)); }
+inline void Assembler::tendall_() { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); }
+inline void Assembler::tabort_(Register a) { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
+inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
+inline void Assembler::tabortwci_(int t, Register a, int si) { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
+inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
+inline void Assembler::tabortdci_(int t, Register a, int si) { emit_int32( TABORTDCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
+inline void Assembler::tsuspend_() { emit_int32( TSR_OPCODE | rc(1)); }
+inline void Assembler::tresume_() { emit_int32( TSR_OPCODE | /*L=1*/ 1u << (31-10) | rc(1)); }
+inline void Assembler::tcheck(int f) { emit_int32( TCHECK_OPCODE | bf(f)); }
+
// ra0 version
inline void Assembler::lwzx( Register d, Register s2) { emit_int32( LWZX_OPCODE | rt(d) | rb(s2));}
inline void Assembler::lwz( Register d, int si16 ) { emit_int32( LWZ_OPCODE | rt(d) | d1(si16));}
--- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -37,6 +37,8 @@
// signatures accordingly.
const bool CCallingConventionRequiresIntsAsLongs = true;
+#define SUPPORTS_NATIVE_CX8
+
// The PPC CPUs are NOT multiple-copy-atomic.
#define CPU_NOT_MULTIPLE_COPY_ATOMIC
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
-#include "asm/assembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "interp_masm_ppc_64.hpp"
#include "interpreter/interpreterRuntime.hpp"
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -24,7 +24,6 @@
*/
#include "precompiled.hpp"
-#include "asm/assembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/interpreter.hpp"
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -2366,7 +2366,7 @@
#endif // INCLUDE_ALL_GCS
// Values for last_Java_pc, and last_Java_sp must comply to the rules
-// in frame_ppc64.hpp.
+// in frame_ppc.hpp.
void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) {
// Always set last_Java_pc and flags first because once last_Java_sp
// is visible has_last_Java_frame is true and users will look at the
@@ -2493,6 +2493,7 @@
}
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
+ assert(dst != R0, "Dst reg may not be R0, as R0 is used here.");
if (src == noreg) src = dst;
Register shifted_src = src;
if (Universe::narrow_klass_shift() != 0 ||
@@ -2527,14 +2528,11 @@
void MacroAssembler::reinit_heapbase(Register d, Register tmp) {
if (Universe::heap() != NULL) {
- if (Universe::narrow_oop_base() == NULL) {
- Assembler::xorr(R30, R30, R30);
- } else {
- load_const(R30, Universe::narrow_ptrs_base(), tmp);
- }
+ load_const_optimized(R30, Universe::narrow_ptrs_base(), tmp);
} else {
- load_const(R30, Universe::narrow_ptrs_base_addr(), tmp);
- ld(R30, 0, R30);
+ // Heap not yet allocated. Load indirectly.
+ int simm16_offset = load_const_optimized(R30, Universe::narrow_ptrs_base_addr(), tmp, true);
+ ld(R30, simm16_offset, R30);
}
}
--- a/hotspot/src/cpu/ppc/vm/ppc.ad Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad Wed Jul 05 20:04:26 2017 +0200
@@ -1249,6 +1249,7 @@
// Emit the trampoline stub which will be related to the branch-and-link below.
CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
+ if (Compile::current()->env()->failing()) { return offsets; } // Code cache may be full.
__ relocate(rtype);
}
@@ -1410,7 +1411,7 @@
while (bang_offset <= bang_end) {
// Need at least one stack bang at end of shadow zone.
- // Again I had to copy code, this time from assembler_ppc64.cpp,
+ // Again I had to copy code, this time from assembler_ppc.cpp,
// bang_stack_with_offset - see there for comments.
// Stack grows down, caller passes positive offset.
@@ -2000,7 +2001,7 @@
// Inline_cache contains a klass.
Register ic_klass = as_Register(Matcher::inline_cache_reg_encode());
- Register receiver_klass = R0; // tmp
+ Register receiver_klass = R12_scratch2; // tmp
assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1);
assert(R11_scratch1 == R11, "need prologue scratch register");
@@ -3484,6 +3485,7 @@
// Emit the trampoline stub which will be related to the branch-and-link below.
CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
+ if (Compile::current()->env()->failing()) { return; } // Code cache may be full.
__ relocate(_optimized_virtual ?
relocInfo::opt_virtual_call_type : relocInfo::static_call_type);
}
@@ -3527,6 +3529,7 @@
// Emit the trampoline stub which will be related to the branch-and-link below.
CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
+ if (ra_->C->env()->failing()) { return; } // Code cache may be full.
assert(_optimized_virtual, "methodHandle call should be a virtual call");
__ relocate(relocInfo::opt_virtual_call_type);
}
@@ -3577,9 +3580,7 @@
const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none);
const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const);
CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset());
-
- if (ra_->C->env()->failing())
- return;
+ if (ra_->C->env()->failing()) { return; } // Code cache may be full.
// Build relocation at call site with ic position as data.
assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) ||
@@ -5638,19 +5639,6 @@
ins_pipe(pipe_class_memory);
%}
-//// Load compressed klass and decode it if narrow_klass_shift == 0.
-//// TODO: will narrow_klass_shift ever be 0?
-//instruct decodeNKlass2Klass(iRegPdst dst, memory mem) %{
-// match(Set dst (DecodeNKlass (LoadNKlass mem)));
-// predicate(false /* TODO: PPC port Universe::narrow_klass_shift() == 0*);
-// ins_cost(MEMORY_REF_COST);
-//
-// format %{ "LWZ $dst, $mem \t// DecodeNKlass (unscaled)" %}
-// size(4);
-// ins_encode( enc_lwz(dst, mem) );
-// ins_pipe(pipe_class_memory);
-//%}
-
// Load Klass Pointer
instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{
match(Set dst (LoadKlass mem));
@@ -6070,11 +6058,15 @@
%}
%}
-instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{
+// We have seen a safepoint between the hi and lo parts, and this node was handled
+// as an oop. Therefore this needs a match rule so that build_oop_map knows this is
+// not a narrow oop.
+instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
+ match(Set dst src);
effect(DEF dst, USE src);
ins_cost(DEFAULT_COST);
- format %{ "LIS $dst, $src \t// narrow oop hi" %}
+ format %{ "LIS $dst, $src \t// narrow klass hi" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_addis);
@@ -6084,6 +6076,21 @@
ins_pipe(pipe_class_default);
%}
+// As loadConNKlass_hi this must be recognized as narrow klass, not oop!
+instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
+ match(Set dst src1);
+ effect(TEMP src2);
+ ins_cost(DEFAULT_COST);
+
+ format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask
+ size(4);
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
+ __ clrldi($dst$$Register, $src2$$Register, 0x20);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
// This needs a match rule so that build_oop_map knows this is
// not a narrow oop.
instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
@@ -6091,10 +6098,10 @@
effect(TEMP src2);
ins_cost(DEFAULT_COST);
- format %{ "ADDI $dst, $src1, $src2 \t// narrow oop lo" %}
- size(4);
- ins_encode %{
- // TODO: PPC port $archOpcode(ppc64Opcode_addi);
+ format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %}
+ size(4);
+ ins_encode %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_ori);
intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant);
assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
@@ -6125,10 +6132,11 @@
MachNode *m2 = m1;
if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) {
// Value might be 1-extended. Mask out these bits.
- m2 = new clearMs32bNode();
+ m2 = new loadConNKlass_maskNode();
m2->add_req(NULL, m1);
m2->_opnds[0] = op_dst;
- m2->_opnds[1] = op_dst;
+ m2->_opnds[1] = op_src;
+ m2->_opnds[2] = op_dst;
ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
nodes->push(m2);
}
@@ -6973,7 +6981,7 @@
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
- __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32);
+ __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32);
%}
ins_pipe(pipe_class_default);
%}
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -24,7 +24,6 @@
*/
#include "precompiled.hpp"
-#include "asm/assembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "nativeInst_ppc.hpp"
@@ -39,9 +38,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/top.hpp"
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
#include "runtime/thread.inline.hpp"
#define __ _masm->
@@ -216,7 +212,7 @@
{
BLOCK_COMMENT("Call frame manager or native entry.");
// Call frame manager or native entry.
- Register r_new_arg_entry = R14; // PPC_state;
+ Register r_new_arg_entry = R14;
assert_different_registers(r_new_arg_entry, r_top_of_arguments_addr,
r_arg_method, r_arg_thread);
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -353,7 +353,6 @@
__ sldi(Rscratch1, Rscratch1, LogBytesPerWord);
__ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Integer);
__ bne(CCR0, notInt);
- __ isync(); // Order load of constant wrt. tags.
__ lwax(R17_tos, Rcpool, Rscratch1);
__ push(itos);
__ b(exit);
@@ -365,7 +364,6 @@
__ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float);
__ asm_assert_eq("unexpected type", 0x8765);
#endif
- __ isync(); // Order load of constant wrt. tags.
__ lfsx(F15_ftos, Rcpool, Rscratch1);
__ push(ftos);
@@ -424,13 +422,11 @@
// Check out Conversions.java for an example.
// Also ConstantPool::header_size() is 20, which makes it very difficult
// to double-align double on the constant pool. SG, 11/7/97
- __ isync(); // Order load of constant wrt. tags.
__ lfdx(F15_ftos, Rcpool, Rindex);
__ push(dtos);
__ b(Lexit);
__ bind(Llong);
- __ isync(); // Order load of constant wrt. tags.
__ ldx(R17_tos, Rcpool, Rindex);
__ push(ltos);
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1020,7 +1020,3 @@
unmap_shared(addr, bytes);
}
-
-char* PerfMemory::backing_store_filename() {
- return backing_store_file_name;
-}
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1043,7 +1043,3 @@
unmap_shared(addr, bytes);
}
-
-char* PerfMemory::backing_store_filename() {
- return backing_store_file_name;
-}
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1049,7 +1049,3 @@
unmap_shared(addr, bytes);
}
-
-char* PerfMemory::backing_store_filename() {
- return backing_store_file_name;
-}
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1068,7 +1068,3 @@
unmap_shared(addr, bytes);
}
-
-char* PerfMemory::backing_store_filename() {
- return backing_store_file_name;
-}
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1846,7 +1846,3 @@
remove_file_mapping(addr);
}
}
-
-char* PerfMemory::backing_store_filename() {
- return sharedmem_fileName;
-}
--- a/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/os_cpu/linux_ppc/vm/prefetch_linux_ppc.inline.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -47,4 +47,4 @@
);
}
-#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_OJDKPPC_HPP
+#endif // OS_CPU_LINUX_PPC_VM_PREFETCH_LINUX_PPC_INLINE_HPP
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -2069,14 +2069,14 @@
LIR_Opr base_op = base.result();
LIR_Opr index_op = idx.result();
#ifndef _LP64
- if (x->base()->type()->tag() == longTag) {
+ if (base_op->type() == T_LONG) {
base_op = new_register(T_INT);
__ convert(Bytecodes::_l2i, base.result(), base_op);
}
if (x->has_index()) {
- if (x->index()->type()->tag() == longTag) {
+ if (index_op->type() == T_LONG) {
LIR_Opr long_index_op = index_op;
- if (x->index()->type()->is_constant()) {
+ if (index_op->is_constant()) {
long_index_op = new_register(T_LONG);
__ move(index_op, long_index_op);
}
@@ -2091,14 +2091,14 @@
assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
#else
if (x->has_index()) {
- if (x->index()->type()->tag() == intTag) {
- if (!x->index()->type()->is_constant()) {
+ if (index_op->type() == T_INT) {
+ if (!index_op->is_constant()) {
index_op = new_register(T_LONG);
__ convert(Bytecodes::_i2l, idx.result(), index_op);
}
} else {
- assert(x->index()->type()->tag() == longTag, "must be");
- if (x->index()->type()->is_constant()) {
+ assert(index_op->type() == T_LONG, "must be");
+ if (index_op->is_constant()) {
index_op = new_register(T_LONG);
__ move(idx.result(), index_op);
}
@@ -2179,12 +2179,12 @@
LIR_Opr index_op = idx.result();
#ifndef _LP64
- if (x->base()->type()->tag() == longTag) {
+ if (base_op->type() == T_LONG) {
base_op = new_register(T_INT);
__ convert(Bytecodes::_l2i, base.result(), base_op);
}
if (x->has_index()) {
- if (x->index()->type()->tag() == longTag) {
+ if (index_op->type() == T_LONG) {
index_op = new_register(T_INT);
__ convert(Bytecodes::_l2i, idx.result(), index_op);
}
@@ -2194,7 +2194,7 @@
assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
#else
if (x->has_index()) {
- if (x->index()->type()->tag() == intTag) {
+ if (index_op->type() == T_INT) {
index_op = new_register(T_LONG);
__ convert(Bytecodes::_i2l, idx.result(), index_op);
}
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -2859,6 +2859,11 @@
"bootstrap_method_index %u has bad constant type in class file %s",
bootstrap_method_index,
CHECK);
+
+ guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(),
+ "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s",
+ CHECK);
+
operands->at_put(operand_fill_index++, bootstrap_method_index);
operands->at_put(operand_fill_index++, argument_count);
@@ -2875,8 +2880,6 @@
}
}
- assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode");
-
u1* current_end = cfs->current();
guarantee_property(current_end == current_start + attribute_byte_length,
"Bad length on BootstrapMethods in class file %s",
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -75,6 +75,7 @@
typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
+typedef jint (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
static ZipOpen_t ZipOpen = NULL;
static ZipClose_t ZipClose = NULL;
@@ -83,6 +84,7 @@
static ReadMappedEntry_t ReadMappedEntry = NULL;
static GetNextEntry_t GetNextEntry = NULL;
static canonicalize_fn_t CanonicalizeEntry = NULL;
+static Crc32_t Crc32 = NULL;
// Globals
@@ -799,9 +801,11 @@
ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
+ Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
// ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
- if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || GetNextEntry == NULL) {
+ if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL ||
+ GetNextEntry == NULL || Crc32 == NULL) {
vm_exit_during_initialization("Corrupted ZIP library", path);
}
@@ -811,6 +815,11 @@
// This lookup only works on 1.3. Do not check for non-null here
}
+int ClassLoader::crc32(int crc, const char* buf, int len) {
+ assert(Crc32 != NULL, "ZIP_CRC32 is not found");
+ return (*Crc32)(crc, (const jbyte*)buf, len);
+}
+
// PackageInfo data exists in order to support the java.lang.Package
// class. A Package object provides information about a java package
// (version, vendor, etc.) which originates in the manifest of the jar
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -226,6 +226,7 @@
// to avoid confusing the zip library
static bool get_canonical_path(const char* orig, char* out, int len);
public:
+ static int crc32(int crc, const char* buf, int len);
static bool update_class_path_entry_list(const char *path,
bool check_for_duplicates,
bool throw_exception=true);
--- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -148,7 +148,7 @@
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
int32_t i = 0;
for (i = 0; i < len; i++) {
- if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
+ if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) {
break;
}
}
@@ -245,7 +245,7 @@
}
VerificationType top = _stack[--_stack_size];
bool subtype = type.is_assignable_from(
- top, verifier(), CHECK_(VerificationType::bogus_type()));
+ top, verifier(), false, CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset, stack_top_ctx(),
@@ -265,7 +265,7 @@
return VerificationType::bogus_type();
}
bool subtype = type.is_assignable_from(_locals[index],
- verifier(), CHECK_(VerificationType::bogus_type()));
+ verifier(), false, CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset,
@@ -288,14 +288,14 @@
"get long/double overflows locals");
return;
}
- bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
+ bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK);
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset,
TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
"Bad local variable type");
} else {
- subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
+ subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK);
if (!subtype) {
/* Unreachable? All local store routines convert a split long or double
* into a TOP during the store. So we should never end up seeing an
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -234,7 +234,7 @@
if (_stack_size != 0) {
VerificationType top = _stack[_stack_size - 1];
bool subtype = type.is_assignable_from(
- top, verifier(), CHECK_(VerificationType::bogus_type()));
+ top, verifier(), false, CHECK_(VerificationType::bogus_type()));
if (subtype) {
--_stack_size;
return top;
@@ -249,9 +249,9 @@
assert(type2.is_long() || type2.is_double(), "must be long/double_2");
if (_stack_size >= 2) {
VerificationType top1 = _stack[_stack_size - 1];
- bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK);
+ bool subtype1 = type1.is_assignable_from(top1, verifier(), false, CHECK);
VerificationType top2 = _stack[_stack_size - 2];
- bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
+ bool subtype2 = type2.is_assignable_from(top2, verifier(), false, CHECK);
if (subtype1 && subtype2) {
_stack_size -= 2;
return;
--- a/hotspot/src/share/vm/classfile/verificationType.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,8 @@
}
bool VerificationType::is_reference_assignable_from(
- const VerificationType& from, ClassVerifier* context, TRAPS) const {
+ const VerificationType& from, ClassVerifier* context,
+ bool from_field_is_protected, TRAPS) const {
instanceKlassHandle klass = context->current_class();
if (from.is_null()) {
// null is assignable to any reference
@@ -62,9 +63,11 @@
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
KlassHandle this_class(THREAD, obj);
- if (this_class->is_interface()) {
- // We treat interfaces as java.lang.Object, including
- // java.lang.Cloneable and java.io.Serializable
+ if (this_class->is_interface() && (!from_field_is_protected ||
+ from.name() != vmSymbols::java_lang_Object())) {
+ // If we are not trying to access a protected field or method in
+ // java.lang.Object then we treat interfaces as java.lang.Object,
+ // including java.lang.Cloneable and java.io.Serializable.
return true;
} else if (from.is_object()) {
Klass* from_class = SystemDictionary::resolve_or_fail(
@@ -76,7 +79,8 @@
VerificationType comp_this = get_component(context, CHECK_false);
VerificationType comp_from = from.get_component(context, CHECK_false);
if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
- return comp_this.is_assignable_from(comp_from, context, CHECK_false);
+ return comp_this.is_assignable_from(comp_from, context,
+ from_field_is_protected, CHECK_false);
}
}
return false;
--- a/hotspot/src/share/vm/classfile/verificationType.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verificationType.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -265,7 +265,8 @@
// is assignable to another. Returns true if one can assign 'from' to
// this.
bool is_assignable_from(
- const VerificationType& from, ClassVerifier* context, TRAPS) const {
+ const VerificationType& from, ClassVerifier* context,
+ bool from_field_is_protected, TRAPS) const {
if (equals(from) || is_bogus()) {
return true;
} else {
@@ -286,7 +287,9 @@
return from.is_integer();
default:
if (is_reference() && from.is_reference()) {
- return is_reference_assignable_from(from, context, CHECK_false);
+ return is_reference_assignable_from(from, context,
+ from_field_is_protected,
+ CHECK_false);
} else {
return false;
}
@@ -308,7 +311,8 @@
private:
bool is_reference_assignable_from(
- const VerificationType&, ClassVerifier*, TRAPS) const;
+ const VerificationType&, ClassVerifier*, bool from_field_is_protected,
+ TRAPS) const;
};
#endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
--- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -98,6 +98,14 @@
HandleMark hm;
ResourceMark rm(THREAD);
+ if (!is_eligible_for_verification(klass, should_verify_class)) {
+ return true;
+ }
+
+ // If the class should be verified, first see if we can use the split
+ // verifier. If not, or if verification fails and FailOverToOldVerifier
+ // is set, then call the inference verifier.
+
Symbol* exception_name = NULL;
const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
@@ -105,47 +113,42 @@
const char* klassName = klass->external_name();
bool can_failover = FailOverToOldVerifier &&
- klass->major_version() < NOFAILOVER_MAJOR_VERSION;
+ klass->major_version() < NOFAILOVER_MAJOR_VERSION;
- // If the class should be verified, first see if we can use the split
- // verifier. If not, or if verification fails and FailOverToOldVerifier
- // is set, then call the inference verifier.
- if (is_eligible_for_verification(klass, should_verify_class)) {
- if (TraceClassInitialization) {
- tty->print_cr("Start class verification for: %s", klassName);
+ if (TraceClassInitialization) {
+ tty->print_cr("Start class verification for: %s", klassName);
+ }
+ if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
+ ClassVerifier split_verifier(klass, THREAD);
+ split_verifier.verify_class(THREAD);
+ exception_name = split_verifier.result();
+ if (can_failover && !HAS_PENDING_EXCEPTION &&
+ (exception_name == vmSymbols::java_lang_VerifyError() ||
+ exception_name == vmSymbols::java_lang_ClassFormatError())) {
+ if (TraceClassInitialization || VerboseVerification) {
+ tty->print_cr(
+ "Fail over class verification to old verifier for: %s", klassName);
+ }
+ exception_name = inference_verify(
+ klass, message_buffer, message_buffer_len, THREAD);
}
- if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
- ClassVerifier split_verifier(klass, THREAD);
- split_verifier.verify_class(THREAD);
- exception_name = split_verifier.result();
- if (can_failover && !HAS_PENDING_EXCEPTION &&
- (exception_name == vmSymbols::java_lang_VerifyError() ||
- exception_name == vmSymbols::java_lang_ClassFormatError())) {
- if (TraceClassInitialization || VerboseVerification) {
- tty->print_cr(
- "Fail over class verification to old verifier for: %s", klassName);
- }
- exception_name = inference_verify(
- klass, message_buffer, message_buffer_len, THREAD);
- }
- if (exception_name != NULL) {
- exception_message = split_verifier.exception_message();
- }
- } else {
- exception_name = inference_verify(
- klass, message_buffer, message_buffer_len, THREAD);
+ if (exception_name != NULL) {
+ exception_message = split_verifier.exception_message();
}
+ } else {
+ exception_name = inference_verify(
+ klass, message_buffer, message_buffer_len, THREAD);
+ }
- if (TraceClassInitialization || VerboseVerification) {
- if (HAS_PENDING_EXCEPTION) {
- tty->print("Verification for %s has", klassName);
- tty->print_cr(" exception pending %s ",
- InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name());
- } else if (exception_name != NULL) {
- tty->print_cr("Verification for %s failed", klassName);
- }
- tty->print_cr("End class verification for: %s", klassName);
+ if (TraceClassInitialization || VerboseVerification) {
+ if (HAS_PENDING_EXCEPTION) {
+ tty->print("Verification for %s has", klassName);
+ tty->print_cr(" exception pending %s ",
+ InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name());
+ } else if (exception_name != NULL) {
+ tty->print_cr("Verification for %s failed", klassName);
}
+ tty->print_cr("End class verification for: %s", klassName);
}
if (HAS_PENDING_EXCEPTION) {
@@ -1718,7 +1721,7 @@
VerificationType throwable =
VerificationType::reference_type(vmSymbols::java_lang_Throwable());
bool is_subclass = throwable.is_assignable_from(
- catch_type, this, CHECK_VERIFY(this));
+ catch_type, this, false, CHECK_VERIFY(this));
if (!is_subclass) {
// 4286534: should throw VerifyError according to recent spec change
verify_error(ErrorContext::bad_type(handler_pc,
@@ -2171,7 +2174,7 @@
stack_object_type = current_type();
}
is_assignable = target_class_type.is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, false, CHECK_VERIFY(this));
if (!is_assignable) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(),
@@ -2198,7 +2201,7 @@
// It's protected access, check if stack object is assignable to
// current class.
is_assignable = current_type().is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, true, CHECK_VERIFY(this));
if (!is_assignable) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(),
@@ -2472,7 +2475,7 @@
instanceKlassHandle mh(THREAD, m->method_holder());
if (m->is_protected() && !mh->is_same_class_package(_klass())) {
bool assignable = current_type().is_assignable_from(
- objectref_type, this, CHECK_VERIFY(this));
+ objectref_type, this, true, CHECK_VERIFY(this));
if (!assignable) {
verify_error(ErrorContext::bad_type(bci,
TypeOrigin::cp(new_class_index, objectref_type),
@@ -2643,11 +2646,11 @@
bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
if (!current_class()->is_anonymous()) {
subtype = ref_class_type.is_assignable_from(
- current_type(), this, CHECK_VERIFY(this));
+ current_type(), this, false, CHECK_VERIFY(this));
} else {
VerificationType host_klass_type =
VerificationType::reference_type(current_class()->host_klass()->name());
- subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this));
+ subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
// If invokespecial of IMR, need to recheck for same or
// direct interface relative to the host class
@@ -2691,7 +2694,7 @@
VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
VerificationType hosttype =
VerificationType::reference_type(current_class()->host_klass()->name());
- bool subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this));
+ bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this));
if (!subtype) {
verify_error( ErrorContext::bad_type(current_frame->offset(),
current_frame->stack_top_ctx(),
@@ -2716,7 +2719,7 @@
// It's protected access, check if stack object is
// assignable to current class.
bool is_assignable = current_type().is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, true, CHECK_VERIFY(this));
if (!is_assignable) {
if (ref_class_type.name() == vmSymbols::java_lang_Object()
&& stack_object_type.is_array()
@@ -2899,7 +2902,7 @@
"Method expects a return value");
return;
}
- bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this));
+ bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this));
if (!match) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
--- a/hotspot/src/share/vm/code/codeCache.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -254,8 +254,7 @@
if (!SegmentedCodeCache) {
// No segmentation: use a single code heap
return (code_blob_type == CodeBlobType::All);
- } else if ((Arguments::mode() == Arguments::_int) ||
- (TieredStopAtLevel == CompLevel_none)) {
+ } else if (Arguments::mode() == Arguments::_int) {
// Interpreter only: we don't need any method code heaps
return (code_blob_type == CodeBlobType::NonNMethod);
} else if (TieredCompilation && (TieredStopAtLevel > CompLevel_simple)) {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1683,6 +1683,8 @@
int _failures;
bool _verbose;
+ HeapRegionClaimer _hrclaimer;
+
public:
G1ParVerifyFinalCountTask(G1CollectedHeap* g1h,
BitMap* region_bm, BitMap* card_bm,
@@ -1692,19 +1694,8 @@
_actual_region_bm(region_bm), _actual_card_bm(card_bm),
_expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm),
_failures(0), _verbose(false),
- _n_workers(0) {
+ _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
assert(VerifyDuringGC, "don't call this otherwise");
-
- // Use the value already set as the number of active threads
- // in the call to run_task().
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- assert( _g1h->workers()->active_workers() > 0,
- "Should have been previously set");
- _n_workers = _g1h->workers()->active_workers();
- } else {
- _n_workers = 1;
- }
-
assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity");
assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity");
@@ -1721,10 +1712,7 @@
_verbose);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate_chunked(&verify_cl,
- worker_id,
- _n_workers,
- HeapRegion::VerifyCountClaimValue);
+ _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
} else {
_g1h->heap_region_iterate(&verify_cl);
}
@@ -1813,22 +1801,14 @@
BitMap* _actual_card_bm;
uint _n_workers;
+ HeapRegionClaimer _hrclaimer;
public:
G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm)
: AbstractGangTask("G1 final counting"),
_g1h(g1h), _cm(_g1h->concurrent_mark()),
_actual_region_bm(region_bm), _actual_card_bm(card_bm),
- _n_workers(0) {
- // Use the value already set as the number of active threads
- // in the call to run_task().
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- assert( _g1h->workers()->active_workers() > 0,
- "Should have been previously set");
- _n_workers = _g1h->workers()->active_workers();
- } else {
- _n_workers = 1;
- }
+ _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) {
}
void work(uint worker_id) {
@@ -1839,10 +1819,7 @@
_actual_card_bm);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate_chunked(&final_update_cl,
- worker_id,
- _n_workers,
- HeapRegion::FinalCountClaimValue);
+ _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
} else {
_g1h->heap_region_iterate(&final_update_cl);
}
@@ -1929,12 +1906,12 @@
size_t _max_live_bytes;
size_t _freed_bytes;
FreeRegionList* _cleanup_list;
+ HeapRegionClaimer _hrclaimer;
public:
- G1ParNoteEndTask(G1CollectedHeap* g1h,
- FreeRegionList* cleanup_list) :
- AbstractGangTask("G1 note end"), _g1h(g1h),
- _max_live_bytes(0), _freed_bytes(0), _cleanup_list(cleanup_list) { }
+ G1ParNoteEndTask(G1CollectedHeap* g1h, FreeRegionList* cleanup_list, uint n_workers) :
+ AbstractGangTask("G1 note end"), _g1h(g1h), _max_live_bytes(0), _freed_bytes(0), _cleanup_list(cleanup_list), _hrclaimer(n_workers) {
+ }
void work(uint worker_id) {
double start = os::elapsedTime();
@@ -1943,9 +1920,7 @@
G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
&hrrs_cleanup_task);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate_chunked(&g1_note_end, worker_id,
- _g1h->workers()->active_workers(),
- HeapRegion::NoteEndClaimValue);
+ _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
} else {
_g1h->heap_region_iterate(&g1_note_end);
}
@@ -1991,16 +1966,16 @@
G1RemSet* _g1rs;
BitMap* _region_bm;
BitMap* _card_bm;
+ HeapRegionClaimer _hrclaimer;
+
public:
- G1ParScrubRemSetTask(G1CollectedHeap* g1h,
- BitMap* region_bm, BitMap* card_bm) :
- AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()),
- _region_bm(region_bm), _card_bm(card_bm) { }
+ G1ParScrubRemSetTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, uint n_workers) :
+ AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), _region_bm(region_bm), _card_bm(card_bm), _hrclaimer(n_workers) {
+ }
void work(uint worker_id) {
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1rs->scrub_par(_region_bm, _card_bm, worker_id,
- HeapRegion::ScrubRemSetClaimValue);
+ _g1rs->scrub_par(_region_bm, _card_bm, worker_id, &_hrclaimer);
} else {
_g1rs->scrub(_region_bm, _card_bm);
}
@@ -2043,9 +2018,6 @@
G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- assert(g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
-
g1h->set_par_threads();
n_workers = g1h->n_par_threads();
assert(g1h->n_par_threads() == n_workers,
@@ -2053,9 +2025,6 @@
g1h->workers()->run_task(&g1_par_count_task);
// Done with the parallel phase so reset to 0.
g1h->set_par_threads(0);
-
- assert(g1h->check_heap_region_claim_values(HeapRegion::FinalCountClaimValue),
- "sanity check");
} else {
n_workers = 1;
g1_par_count_task.work(0);
@@ -2080,9 +2049,6 @@
g1h->workers()->run_task(&g1_par_verify_task);
// Done with the parallel phase so reset to 0.
g1h->set_par_threads(0);
-
- assert(g1h->check_heap_region_claim_values(HeapRegion::VerifyCountClaimValue),
- "sanity check");
} else {
g1_par_verify_task.work(0);
}
@@ -2108,14 +2074,11 @@
g1h->reset_gc_time_stamp();
// Note end of marking in all heap regions.
- G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list);
+ G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list, n_workers);
if (G1CollectedHeap::use_parallel_gc_threads()) {
g1h->set_par_threads((int)n_workers);
g1h->workers()->run_task(&g1_par_note_end_task);
g1h->set_par_threads(0);
-
- assert(g1h->check_heap_region_claim_values(HeapRegion::NoteEndClaimValue),
- "sanity check");
} else {
g1_par_note_end_task.work(0);
}
@@ -2132,15 +2095,11 @@
// regions.
if (G1ScrubRemSets) {
double rs_scrub_start = os::elapsedTime();
- G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm);
+ G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers);
if (G1CollectedHeap::use_parallel_gc_threads()) {
g1h->set_par_threads((int)n_workers);
g1h->workers()->run_task(&g1_par_scrub_rs_task);
g1h->set_par_threads(0);
-
- assert(g1h->check_heap_region_claim_values(
- HeapRegion::ScrubRemSetClaimValue),
- "sanity check");
} else {
g1_par_scrub_rs_task.work(0);
}
@@ -3288,6 +3247,7 @@
BitMap* _cm_card_bm;
uint _max_worker_id;
int _active_workers;
+ HeapRegionClaimer _hrclaimer;
public:
G1AggregateCountDataTask(G1CollectedHeap* g1h,
@@ -3295,18 +3255,18 @@
BitMap* cm_card_bm,
uint max_worker_id,
int n_workers) :
- AbstractGangTask("Count Aggregation"),
- _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm),
- _max_worker_id(max_worker_id),
- _active_workers(n_workers) { }
+ AbstractGangTask("Count Aggregation"),
+ _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm),
+ _max_worker_id(max_worker_id),
+ _active_workers(n_workers),
+ _hrclaimer(_active_workers) {
+ }
void work(uint worker_id) {
AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate_chunked(&cl, worker_id,
- _active_workers,
- HeapRegion::AggregateCountClaimValue);
+ _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
} else {
_g1h->heap_region_iterate(&cl);
}
@@ -3323,15 +3283,9 @@
_max_worker_id, n_workers);
if (G1CollectedHeap::use_parallel_gc_threads()) {
- assert(_g1h->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
_g1h->set_par_threads(n_workers);
_g1h->workers()->run_task(&g1_par_agg_task);
_g1h->set_par_threads(0);
-
- assert(_g1h->check_heap_region_claim_values(HeapRegion::AggregateCountClaimValue),
- "sanity check");
- _g1h->reset_heap_region_claim_values();
} else {
g1_par_agg_task.work(0);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -90,8 +90,8 @@
// Notes on implementation of parallelism in different tasks.
//
-// G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism.
-// The number of GC workers is passed to heap_region_par_iterate_chunked().
+// G1ParVerifyTask uses heap_region_par_iterate() for parallelism.
+// The number of GC workers is passed to heap_region_par_iterate().
// It does use run_task() which sets _n_workers in the task.
// G1ParTask executes g1_process_roots() ->
// SharedHeap::process_roots() which calls eventually to
@@ -1215,17 +1215,15 @@
class ParRebuildRSTask: public AbstractGangTask {
G1CollectedHeap* _g1;
+ HeapRegionClaimer _hrclaimer;
+
public:
- ParRebuildRSTask(G1CollectedHeap* g1)
- : AbstractGangTask("ParRebuildRSTask"),
- _g1(g1)
- { }
+ ParRebuildRSTask(G1CollectedHeap* g1) :
+ AbstractGangTask("ParRebuildRSTask"), _g1(g1), _hrclaimer(g1->workers()->active_workers()) {}
void work(uint worker_id) {
RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id);
- _g1->heap_region_par_iterate_chunked(&rebuild_rs, worker_id,
- _g1->workers()->active_workers(),
- HeapRegion::RebuildRSClaimValue);
+ _g1->heap_region_par_iterate(&rebuild_rs, worker_id, &_hrclaimer);
}
};
@@ -1455,8 +1453,6 @@
set_par_threads(n_workers);
ParRebuildRSTask rebuild_rs_task(this);
- assert(check_heap_region_claim_values(
- HeapRegion::InitialClaimValue), "sanity check");
assert(UseDynamicNumberOfGCThreads ||
workers()->active_workers() == workers()->total_workers(),
"Unless dynamic should use total workers");
@@ -1466,9 +1462,6 @@
set_par_threads(workers()->active_workers());
workers()->run_task(&rebuild_rs_task);
set_par_threads(0);
- assert(check_heap_region_claim_values(
- HeapRegion::RebuildRSClaimValue), "sanity check");
- reset_heap_region_claim_values();
} else {
RebuildRSOutOfRegionClosure rebuild_rs(this);
heap_region_iterate(&rebuild_rs);
@@ -2343,6 +2336,7 @@
case GCCause::_gc_locker: return GCLockerInvokesConcurrent;
case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent;
case GCCause::_g1_humongous_allocation: return true;
+ case GCCause::_update_allocation_context_stats_inc: return true;
default: return false;
}
}
@@ -2633,110 +2627,11 @@
}
void
-G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
- uint worker_id,
- uint num_workers,
- jint claim_value) const {
- _hrm.par_iterate(cl, worker_id, num_workers, claim_value);
-}
-
-class ResetClaimValuesClosure: public HeapRegionClosure {
-public:
- bool doHeapRegion(HeapRegion* r) {
- r->set_claim_value(HeapRegion::InitialClaimValue);
- return false;
- }
-};
-
-void G1CollectedHeap::reset_heap_region_claim_values() {
- ResetClaimValuesClosure blk;
- heap_region_iterate(&blk);
-}
-
-void G1CollectedHeap::reset_cset_heap_region_claim_values() {
- ResetClaimValuesClosure blk;
- collection_set_iterate(&blk);
-}
-
-#ifdef ASSERT
-// This checks whether all regions in the heap have the correct claim
-// value. I also piggy-backed on this a check to ensure that the
-// humongous_start_region() information on "continues humongous"
-// regions is correct.
-
-class CheckClaimValuesClosure : public HeapRegionClosure {
-private:
- jint _claim_value;
- uint _failures;
- HeapRegion* _sh_region;
-
-public:
- CheckClaimValuesClosure(jint claim_value) :
- _claim_value(claim_value), _failures(0), _sh_region(NULL) { }
- bool doHeapRegion(HeapRegion* r) {
- if (r->claim_value() != _claim_value) {
- gclog_or_tty->print_cr("Region " HR_FORMAT ", "
- "claim value = %d, should be %d",
- HR_FORMAT_PARAMS(r),
- r->claim_value(), _claim_value);
- ++_failures;
- }
- if (!r->is_humongous()) {
- _sh_region = NULL;
- } else if (r->is_starts_humongous()) {
- _sh_region = r;
- } else if (r->is_continues_humongous()) {
- if (r->humongous_start_region() != _sh_region) {
- gclog_or_tty->print_cr("Region " HR_FORMAT ", "
- "HS = "PTR_FORMAT", should be "PTR_FORMAT,
- HR_FORMAT_PARAMS(r),
- r->humongous_start_region(),
- _sh_region);
- ++_failures;
- }
- }
- return false;
- }
- uint failures() { return _failures; }
-};
-
-bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) {
- CheckClaimValuesClosure cl(claim_value);
- heap_region_iterate(&cl);
- return cl.failures() == 0;
-}
-
-class CheckClaimValuesInCSetHRClosure: public HeapRegionClosure {
-private:
- jint _claim_value;
- uint _failures;
-
-public:
- CheckClaimValuesInCSetHRClosure(jint claim_value) :
- _claim_value(claim_value), _failures(0) { }
-
- uint failures() { return _failures; }
-
- bool doHeapRegion(HeapRegion* hr) {
- assert(hr->in_collection_set(), "how?");
- assert(!hr->is_humongous(), "H-region in CSet");
- if (hr->claim_value() != _claim_value) {
- gclog_or_tty->print_cr("CSet Region " HR_FORMAT ", "
- "claim value = %d, should be %d",
- HR_FORMAT_PARAMS(hr),
- hr->claim_value(), _claim_value);
- _failures += 1;
- }
- return false;
- }
-};
-
-bool G1CollectedHeap::check_cset_heap_region_claim_values(jint claim_value) {
- CheckClaimValuesInCSetHRClosure cl(claim_value);
- collection_set_iterate(&cl);
- return cl.failures() == 0;
-}
-#endif // ASSERT
+G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl,
+ uint worker_id,
+ HeapRegionClaimer *hrclaimer) const {
+ _hrm.par_iterate(cl, worker_id, hrclaimer);
+}
// Clear the cached CSet starting regions and (more importantly)
// the time stamps. Called when we reset the GC time stamp.
@@ -3251,19 +3146,21 @@
class G1ParVerifyTask: public AbstractGangTask {
private:
- G1CollectedHeap* _g1h;
- VerifyOption _vo;
- bool _failures;
+ G1CollectedHeap* _g1h;
+ VerifyOption _vo;
+ bool _failures;
+ HeapRegionClaimer _hrclaimer;
public:
// _vo == UsePrevMarking -> use "prev" marking information,
// _vo == UseNextMarking -> use "next" marking information,
// _vo == UseMarkWord -> use mark word from object header.
G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) :
- AbstractGangTask("Parallel verify task"),
- _g1h(g1h),
- _vo(vo),
- _failures(false) { }
+ AbstractGangTask("Parallel verify task"),
+ _g1h(g1h),
+ _vo(vo),
+ _failures(false),
+ _hrclaimer(g1h->workers()->active_workers()) {}
bool failures() {
return _failures;
@@ -3272,9 +3169,7 @@
void work(uint worker_id) {
HandleMark hm;
VerifyRegionClosure blk(true, _vo);
- _g1h->heap_region_par_iterate_chunked(&blk, worker_id,
- _g1h->workers()->active_workers(),
- HeapRegion::ParVerifyClaimValue);
+ _g1h->heap_region_par_iterate(&blk, worker_id, &_hrclaimer);
if (blk.failures()) {
_failures = true;
}
@@ -3316,8 +3211,6 @@
if (!silent) { gclog_or_tty->print("HeapRegions "); }
if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
- assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
G1ParVerifyTask task(this, vo);
assert(UseDynamicNumberOfGCThreads ||
@@ -3331,15 +3224,6 @@
failures = true;
}
- // Checks that the expected amount of parallel work was done.
- // The implication is that n_workers is > 0.
- assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue),
- "sanity check");
-
- reset_heap_region_claim_values();
-
- assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
} else {
VerifyRegionClosure blk(false, vo);
heap_region_iterate(&blk);
@@ -3926,8 +3810,6 @@
}
assert(check_young_list_well_formed(), "young list should be well formed");
- assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
// Don't dynamically change the number of GC threads this early. A value of
// 0 is used to indicate serial work. When parallel work is done,
@@ -4288,26 +4170,12 @@
}
void G1CollectedHeap::remove_self_forwarding_pointers() {
- assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
-
double remove_self_forwards_start = os::elapsedTime();
+ set_par_threads();
G1ParRemoveSelfForwardPtrsTask rsfp_task(this);
-
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- set_par_threads();
- workers()->run_task(&rsfp_task);
- set_par_threads(0);
- } else {
- rsfp_task.work(0);
- }
-
- assert(check_cset_heap_region_claim_values(HeapRegion::ParEvacFailureClaimValue), "sanity");
-
- // Reset the claim values in the regions in the collection set.
- reset_cset_heap_region_claim_values();
-
- assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
+ workers()->run_task(&rsfp_task);
+ set_par_threads(0);
// Now restore saved marks, if any.
assert(_objs_with_preserved_marks.size() ==
@@ -5948,11 +5816,6 @@
purge_code_root_memory();
- if (g1_policy()->during_initial_mark_pause()) {
- // Reset the claim values set during marking the strong code roots
- reset_heap_region_claim_values();
- }
-
finalize_for_evac_failure();
if (evacuation_failed()) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -211,6 +211,7 @@
friend class G1FreeHumongousRegionClosure;
// Other related classes.
friend class G1MarkSweep;
+ friend class HeapRegionClaimer;
private:
// The one and only G1CollectedHeap, so static functions can find it.
@@ -1377,38 +1378,15 @@
inline HeapWord* bottom_addr_for_region(uint index) const;
- // Divide the heap region sequence into "chunks" of some size (the number
- // of regions divided by the number of parallel threads times some
- // overpartition factor, currently 4). Assumes that this will be called
- // in parallel by ParallelGCThreads worker threads with distinct worker
- // ids in the range [0..max(ParallelGCThreads-1, 1)], that all parallel
- // calls will use the same "claim_value", and that that claim value is
- // different from the claim_value of any heap region before the start of
- // the iteration. Applies "blk->doHeapRegion" to each of the regions, by
- // attempting to claim the first region in each chunk, and, if
- // successful, applying the closure to each region in the chunk (and
- // setting the claim value of the second and subsequent regions of the
- // chunk.) For now requires that "doHeapRegion" always returns "false",
- // i.e., that a closure never attempt to abort a traversal.
- void heap_region_par_iterate_chunked(HeapRegionClosure* cl,
- uint worker_id,
- uint num_workers,
- jint claim_value) const;
-
- // It resets all the region claim values to the default.
- void reset_heap_region_claim_values();
-
- // Resets the claim values of regions in the current
- // collection set to the default.
- void reset_cset_heap_region_claim_values();
-
-#ifdef ASSERT
- bool check_heap_region_claim_values(jint claim_value);
-
- // Same as the routine above but only checks regions in the
- // current collection set.
- bool check_cset_heap_region_claim_values(jint claim_value);
-#endif // ASSERT
+ // Iterate over the heap regions in parallel. Assumes that this will be called
+ // in parallel by ParallelGCThreads worker threads with distinct worker ids
+ // in the range [0..max(ParallelGCThreads-1, 1)]. Applies "blk->doHeapRegion"
+ // to each of the regions, by attempting to claim the region using the
+ // HeapRegionClaimer and, if successful, applying the closure to the claimed
+ // region.
+ void heap_region_par_iterate(HeapRegionClosure* cl,
+ uint worker_id,
+ HeapRegionClaimer* hrclaimer) const;
// Clear the cached cset start regions and (more importantly)
// the time stamps. Called when we reset the GC time stamp.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1598,19 +1598,17 @@
CollectionSetChooser* _hrSorted;
uint _chunk_size;
G1CollectedHeap* _g1;
+ HeapRegionClaimer _hrclaimer;
+
public:
- ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size) :
- AbstractGangTask("ParKnownGarbageTask"),
- _hrSorted(hrSorted), _chunk_size(chunk_size),
- _g1(G1CollectedHeap::heap()) { }
+ ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size, uint n_workers) :
+ AbstractGangTask("ParKnownGarbageTask"),
+ _hrSorted(hrSorted), _chunk_size(chunk_size),
+ _g1(G1CollectedHeap::heap()), _hrclaimer(n_workers) {}
void work(uint worker_id) {
ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
-
- // Back to zero for the claim value.
- _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, worker_id,
- _g1->workers()->active_workers(),
- HeapRegion::InitialClaimValue);
+ _g1->heap_region_par_iterate(&parKnownGarbageCl, worker_id, &_hrclaimer);
}
};
@@ -1641,12 +1639,8 @@
}
_collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
WorkUnit);
- ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser,
- (int) WorkUnit);
+ ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
_g1->workers()->run_task(&parKnownGarbageTask);
-
- assert(_g1->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
- "sanity check");
} else {
KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
_g1->heap_region_iterate(&knownGarbagecl);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -177,16 +177,18 @@
G1CollectedHeap* _g1h;
ConcurrentMark* _cm;
uint _worker_id;
+ HeapRegionClaimer* _hrclaimer;
DirtyCardQueue _dcq;
UpdateRSetDeferred _update_rset_cl;
public:
RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
- uint worker_id) :
- _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
- _worker_id(worker_id), _cm(_g1h->concurrent_mark()) {
- }
+ uint worker_id,
+ HeapRegionClaimer* hrclaimer) :
+ _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
+ _worker_id(worker_id), _cm(_g1h->concurrent_mark()), _hrclaimer(hrclaimer) {
+ }
bool doHeapRegion(HeapRegion *hr) {
bool during_initial_mark = _g1h->g1_policy()->during_initial_mark_pause();
@@ -195,7 +197,7 @@
assert(!hr->is_humongous(), "sanity");
assert(hr->in_collection_set(), "bad CS");
- if (hr->claimHeapRegion(HeapRegion::ParEvacFailureClaimValue)) {
+ if (_hrclaimer->claim_region(hr->hrm_index())) {
if (hr->evacuation_failed()) {
RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl,
during_initial_mark,
@@ -233,14 +235,15 @@
class G1ParRemoveSelfForwardPtrsTask: public AbstractGangTask {
protected:
G1CollectedHeap* _g1h;
+ HeapRegionClaimer _hrclaimer;
public:
G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h) :
- AbstractGangTask("G1 Remove Self-forwarding Pointers"),
- _g1h(g1h) { }
+ AbstractGangTask("G1 Remove Self-forwarding Pointers"), _g1h(g1h),
+ _hrclaimer(g1h->workers()->active_workers()) {}
void work(uint worker_id) {
- RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id);
+ RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id, &_hrclaimer);
HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
_g1h->collection_set_iterate_from(hr, &rsfp_cl);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -425,13 +425,9 @@
_g1->heap_region_iterate(&scrub_cl);
}
-void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm,
- uint worker_num, int claim_val) {
+void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
ScrubRSClosure scrub_cl(region_bm, card_bm);
- _g1->heap_region_par_iterate_chunked(&scrub_cl,
- worker_num,
- n_workers(),
- claim_val);
+ _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
}
G1TriggerClosure::G1TriggerClosure() :
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -128,10 +128,10 @@
void scrub(BitMap* region_bm, BitMap* card_bm);
// Like the above, but assumes is called in parallel: "worker_num" is the
- // parallel thread id of the current thread, and "claim_val" is the
- // value that should be used to claim heap regions.
+ // parallel thread id of the current thread, and "hrclaimer" is the shared
+ // HeapRegionClaimer that should be used to claim heap regions.
void scrub_par(BitMap* region_bm, BitMap* card_bm,
- uint worker_num, int claim_val);
+ uint worker_num, HeapRegionClaimer* hrclaimer);
// Refine the card corresponding to "card_ptr".
// If check_for_refs_into_cset is true, a true result is returned
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -217,7 +217,6 @@
} else {
hrrs->clear();
}
- _claimed = InitialClaimValue;
}
zero_marked_bytes();
@@ -294,17 +293,6 @@
_humongous_start_region = NULL;
}
-bool HeapRegion::claimHeapRegion(jint claimValue) {
- jint current = _claimed;
- if (current != claimValue) {
- jint res = Atomic::cmpxchg(claimValue, &_claimed, current);
- if (res == current) {
- return true;
- }
- }
- return false;
-}
-
HeapRegion::HeapRegion(uint hrm_index,
G1BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr) :
@@ -314,7 +302,7 @@
_humongous_start_region(NULL),
_in_collection_set(false),
_next_in_special_set(NULL),
- _claimed(InitialClaimValue), _evacuation_failed(false),
+ _evacuation_failed(false),
_prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0),
_next_young_region(NULL),
_next_dirty_cards_region(NULL), _next(NULL), _prev(NULL),
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -254,9 +254,6 @@
HeapRegionSetBase* _containing_set;
#endif // ASSERT
- // For parallel heapRegion traversal.
- jint _claimed;
-
// We use concurrent marking to determine the amount of live data
// in each heap region.
size_t _prev_marked_bytes; // Bytes known to be live via last completed marking.
@@ -336,19 +333,6 @@
// up once during initialization time.
static void setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size);
- enum ClaimValues {
- InitialClaimValue = 0,
- FinalCountClaimValue = 1,
- NoteEndClaimValue = 2,
- ScrubRemSetClaimValue = 3,
- ParVerifyClaimValue = 4,
- RebuildRSClaimValue = 5,
- ParEvacFailureClaimValue = 6,
- AggregateCountClaimValue = 7,
- VerifyCountClaimValue = 8,
- ParMarkRootClaimValue = 9
- };
-
// All allocated blocks are occupied by objects in a HeapRegion
bool block_is_obj(const HeapWord* p) const;
@@ -691,12 +675,6 @@
return (HeapWord *) obj >= next_top_at_mark_start();
}
- // For parallel heapRegion traversal.
- bool claimHeapRegion(int claimValue);
- jint claim_value() { return _claimed; }
- // Use this carefully: only when you're sure no one is claiming...
- void set_claim_value(int claimValue) { _claimed = claimValue; }
-
// Returns the "evacuation_failed" property of the region.
bool evacuation_failed() { return _evacuation_failed; }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -260,20 +260,17 @@
return num_regions;
}
-uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
- return num_regions * worker_i / num_workers;
-}
-
-void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
- const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
+void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const {
+ const uint start_index = hrclaimer->start_region_for_worker(worker_id);
// Every worker will actually look at all regions, skipping over regions that
// are currently not committed.
// This also (potentially) iterates over regions newly allocated during GC. This
// is no problem except for some extra work.
- for (uint count = 0; count < _allocated_heapregions_length; count++) {
- const uint index = (start_index + count) % _allocated_heapregions_length;
- assert(0 <= index && index < _allocated_heapregions_length, "sanity");
+ const uint n_regions = hrclaimer->n_regions();
+ for (uint count = 0; count < n_regions; count++) {
+ const uint index = (start_index + count) % n_regions;
+ assert(0 <= index && index < n_regions, "sanity");
// Skip over unavailable regions
if (!is_available(index)) {
continue;
@@ -282,11 +279,11 @@
// We'll ignore "continues humongous" regions (we'll process them
// when we come across their corresponding "start humongous"
// region) and regions already claimed.
- if (r->claim_value() == claim_value || r->is_continues_humongous()) {
+ if (hrclaimer->is_region_claimed(index) || r->is_continues_humongous()) {
continue;
}
// OK, try to claim it
- if (!r->claimHeapRegion(claim_value)) {
+ if (!hrclaimer->claim_region(index)) {
continue;
}
// Success!
@@ -306,13 +303,11 @@
assert(chr->humongous_start_region() == r,
err_msg("Must work on humongous continuation of the original start region "
PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
- assert(chr->claim_value() != claim_value,
+ assert(!hrclaimer->is_region_claimed(ch_index),
"Must not have been claimed yet because claiming of humongous continuation first claims the start region");
- bool claim_result = chr->claimHeapRegion(claim_value);
- // We should always be able to claim it; no one else should
- // be trying to claim this region.
- guarantee(claim_result, "We should always be able to claim the is_continues_humongous part of the humongous object");
+ // There's no need to actually claim the continues humongous region, but we can do it in an assert as an extra precaution.
+ assert(hrclaimer->claim_region(ch_index), "We should always be able to claim the continuesHumongous part of the humongous object");
bool res2 = blk->doHeapRegion(chr);
if (res2) {
@@ -445,3 +440,31 @@
}
#endif // PRODUCT
+HeapRegionClaimer::HeapRegionClaimer(uint n_workers) :
+ _n_workers(n_workers), _n_regions(G1CollectedHeap::heap()->_hrm._allocated_heapregions_length), _claims(NULL) {
+ assert(n_workers > 0, "Need at least one worker.");
+ _claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC);
+ memset(_claims, Unclaimed, sizeof(*_claims) * _n_regions);
+}
+
+HeapRegionClaimer::~HeapRegionClaimer() {
+ if (_claims != NULL) {
+ FREE_C_HEAP_ARRAY(uint, _claims, mtGC);
+ }
+}
+
+uint HeapRegionClaimer::start_region_for_worker(uint worker_id) const {
+ assert(worker_id < _n_workers, "Invalid worker_id.");
+ return _n_regions * worker_id / _n_workers;
+}
+
+bool HeapRegionClaimer::is_region_claimed(uint region_index) const {
+ assert(region_index < _n_regions, "Invalid index.");
+ return _claims[region_index] == Claimed;
+}
+
+bool HeapRegionClaimer::claim_region(uint region_index) {
+ assert(region_index < _n_regions, "Invalid index.");
+ uint old_val = Atomic::cmpxchg(Claimed, &_claims[region_index], Unclaimed);
+ return old_val == Unclaimed;
+}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -31,6 +31,7 @@
class HeapRegion;
class HeapRegionClosure;
+class HeapRegionClaimer;
class FreeRegionList;
class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
@@ -66,6 +67,7 @@
class HeapRegionManager: public CHeapObj<mtGC> {
friend class VMStructs;
+ friend class HeapRegionClaimer;
G1HeapRegionTable _regions;
@@ -99,9 +101,6 @@
// Notify other data structures about change in the heap layout.
void update_committed_space(HeapWord* old_end, HeapWord* new_end);
- // Calculate the starting region for each worker during parallel iteration so
- // that they do not all start from the same region.
- uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
// Find a contiguous set of empty or uncommitted regions of length num and return
// the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
@@ -223,7 +222,7 @@
// terminating the iteration early if doHeapRegion() returns true.
void iterate(HeapRegionClosure* blk) const;
- void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const;
+ void par_iterate(HeapRegionClosure* blk, uint worker_id, HeapRegionClaimer* hrclaimer) const;
// Uncommit up to num_regions_to_remove regions that are completely free.
// Return the actual number of uncommitted regions.
@@ -235,5 +234,33 @@
void verify_optional() PRODUCT_RETURN;
};
+// The HeapRegionClaimer is used during parallel iteration over heap regions,
+// allowing workers to claim heap regions, gaining exclusive rights to these regions.
+class HeapRegionClaimer : public StackObj {
+ uint _n_workers;
+ uint _n_regions;
+ uint* _claims;
+
+ static const uint Unclaimed = 0;
+ static const uint Claimed = 1;
+
+ public:
+ HeapRegionClaimer(uint n_workers);
+ ~HeapRegionClaimer();
+
+ inline uint n_regions() const {
+ return _n_regions;
+ }
+
+ // Calculate the starting region for given worker so
+ // that they do not all start from the same region.
+ uint start_region_for_worker(uint worker_id) const;
+
+ // Check if region has been claimed with this HRClaimer.
+ bool is_region_claimed(uint region_index) const;
+
+ // Claim the given region, returns true if successfully claimed.
+ bool claim_region(uint region_index);
+};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -95,8 +95,9 @@
assert(!_should_initiate_conc_mark ||
((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
(_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
- _gc_cause == GCCause::_g1_humongous_allocation),
- "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle");
+ _gc_cause == GCCause::_g1_humongous_allocation ||
+ _gc_cause == GCCause::_update_allocation_context_stats_inc),
+ "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
if (_word_size > 0) {
// An allocation has been requested. So, try to do that first.
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -54,7 +54,8 @@
case _wb_young_gc:
return "WhiteBox Initiated Young GC";
- case _update_allocation_context_stats:
+ case _update_allocation_context_stats_inc:
+ case _update_allocation_context_stats_full:
return "Update Allocation Context Stats";
case _no_gc:
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -47,7 +47,8 @@
_heap_inspection,
_heap_dump,
_wb_young_gc,
- _update_allocation_context_stats,
+ _update_allocation_context_stats_inc,
+ _update_allocation_context_stats_full,
/* implementation independent, but reserved for GC use */
_no_gc,
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -246,6 +246,12 @@
// Ignore overpasses so statics can be found during resolution
Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
+ if (klass->oop_is_array()) {
+ // Only consider klass and super klass for arrays
+ result = methodHandle(THREAD, result_oop);
+ return;
+ }
+
// JDK 8, JVMS 5.4.3.4: Interface method resolution should
// ignore static and non-public methods of java.lang.Object,
// like clone, finalize, registerNatives.
@@ -290,6 +296,11 @@
result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
}
+ if (klass->oop_is_array()) {
+ // Only consider klass and super klass for arrays
+ return;
+ }
+
if (result.is_null()) {
Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
if (default_methods != NULL) {
@@ -545,7 +556,7 @@
// 2. lookup method in resolved klass and its super klasses
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
- if (resolved_method.is_null()) { // not found in the class hierarchy
+ if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
@@ -558,16 +569,16 @@
CLEAR_PENDING_EXCEPTION;
}
}
+ }
- if (resolved_method.is_null()) {
- // 4. method lookup failed
- ResourceMark rm(THREAD);
- THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(resolved_klass(),
- method_name,
- method_signature),
- nested_exception);
- }
+ if (resolved_method.is_null()) {
+ // 4. method lookup failed
+ ResourceMark rm(THREAD);
+ THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
+ Method::name_and_sig_as_C_string(resolved_klass(),
+ method_name,
+ method_signature),
+ nested_exception);
}
// 5. access checks, access checking may be turned off when calling from within the VM.
@@ -633,17 +644,18 @@
// JDK8: also look for static methods
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
- if (resolved_method.is_null()) {
+ if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
// lookup method in all the super-interfaces
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
- if (resolved_method.is_null()) {
- // no method found
- ResourceMark rm(THREAD);
- THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(resolved_klass(),
- method_name,
- method_signature));
- }
+ }
+
+ if (resolved_method.is_null()) {
+ // no method found
+ ResourceMark rm(THREAD);
+ THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
+ Method::name_and_sig_as_C_string(resolved_klass(),
+ method_name,
+ method_signature));
}
if (check_access) {
@@ -775,7 +787,7 @@
}
// Resolve instance field
- KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
+ KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd));
// check if field exists; i.e., if a klass containing the field def has been selected
if (sel_klass.is_null()) {
ResourceMark rm(THREAD);
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -331,6 +331,14 @@
return false;
}
+ size_t len = lseek(fd, 0, SEEK_END);
+ struct FileMapInfo::FileMapHeader::space_info* si =
+ &_header->_space[MetaspaceShared::mc];
+ if (si->_file_offset >= len || len - si->_file_offset < si->_used) {
+ fail_continue("The shared archive file has been truncated.");
+ return false;
+ }
+
_file_offset += (long)n;
return true;
}
@@ -431,6 +439,7 @@
si->_capacity = capacity;
si->_read_only = read_only;
si->_allow_exec = allow_exec;
+ si->_crc = ClassLoader::crc32(0, base, (jint)size);
write_bytes_aligned(base, (int)size);
}
@@ -455,14 +464,15 @@
// Align file position to an allocation unit boundary.
void FileMapInfo::align_file_position() {
- long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
+ size_t new_file_offset = align_size_up(_file_offset,
+ os::vm_allocation_granularity());
if (new_file_offset != _file_offset) {
_file_offset = new_file_offset;
if (_file_open) {
// Seek one byte back from the target and write a byte to insure
// that the written file is the correct length.
_file_offset -= 1;
- if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
+ if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) {
fail_stop("Unable to seek.");
}
char zero = 0;
@@ -569,6 +579,19 @@
return base;
}
+bool FileMapInfo::verify_region_checksum(int i) {
+ if (!VerifySharedSpaces) {
+ return true;
+ }
+ const char* buf = _header->_space[i]._base;
+ size_t sz = _header->_space[i]._used;
+ int crc = ClassLoader::crc32(0, buf, (jint)sz);
+ if (crc != _header->_space[i]._crc) {
+ fail_continue("Checksum verification failed.");
+ return false;
+ }
+ return true;
+}
// Unmap a memory region in the address space.
@@ -629,7 +652,21 @@
return true;
}
+int FileMapInfo::FileMapHeader::compute_crc() {
+ char* header = data();
+ // start computing from the field after _crc
+ char* buf = (char*)&_crc + sizeof(int);
+ size_t sz = data_size() - (buf - header);
+ int crc = ClassLoader::crc32(0, buf, (jint)sz);
+ return crc;
+}
+
bool FileMapInfo::FileMapHeader::validate() {
+ if (VerifySharedSpaces && compute_crc() != _crc) {
+ fail_continue("Header checksum verification failed.");
+ return false;
+ }
+
if (_version != current_version()) {
FileMapInfo::fail_continue("The shared archive file is the wrong version.");
return false;
--- a/hotspot/src/share/vm/memory/filemap.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -61,7 +61,7 @@
bool _file_open;
int _fd;
- long _file_offset;
+ size_t _file_offset;
private:
static SharedClassPathEntry* _classpath_entry_table;
@@ -87,12 +87,14 @@
}
int _magic; // identify file type.
+ int _crc; // header crc checksum.
int _version; // (from enum, above.)
size_t _alignment; // how shared archive should be aligned
int _obj_alignment; // value of ObjectAlignmentInBytes
struct space_info {
- int _file_offset; // sizeof(this) rounded to vm page size
+ int _crc; // crc checksum of the current space
+ size_t _file_offset; // sizeof(this) rounded to vm page size
char* _base; // copy-on-write base address
size_t _capacity; // for validity checking
size_t _used; // for setting space top on read
@@ -135,6 +137,7 @@
virtual bool validate();
virtual void populate(FileMapInfo* info, size_t alignment);
+ int compute_crc();
};
FileMapHeader * _header;
@@ -153,6 +156,8 @@
~FileMapInfo();
static int current_version() { return _current_version; }
+ int compute_header_crc() { return _header->compute_crc(); }
+ void set_header_crc(int crc) { _header->_crc = crc; }
void populate_header(size_t alignment);
bool validate_header();
void invalidate();
@@ -181,6 +186,7 @@
void write_bytes_aligned(const void* buffer, int count);
char* map_region(int i);
void unmap_region(int i);
+ bool verify_region_checksum(int i);
void close();
bool is_open() { return _file_open; }
ReservedSpace reserve_shared_memory();
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -608,6 +608,7 @@
// Pass 2 - write data.
mapinfo->open_for_write();
+ mapinfo->set_header_crc(mapinfo->compute_header_crc());
mapinfo->write_header();
mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
@@ -937,9 +938,13 @@
// Map each shared region
if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
+ mapinfo->verify_region_checksum(ro) &&
(_rw_base = mapinfo->map_region(rw)) != NULL &&
+ mapinfo->verify_region_checksum(rw) &&
(_md_base = mapinfo->map_region(md)) != NULL &&
+ mapinfo->verify_region_checksum(md) &&
(_mc_base = mapinfo->map_region(mc)) != NULL &&
+ mapinfo->verify_region_checksum(mc) &&
(image_alignment == (size_t)max_alignment()) &&
mapinfo->validate_classpath_entry_table()) {
// Success (no need to do anything)
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -64,6 +64,13 @@
return NULL;
}
+// find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined
+Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
+ // There are no fields in an array klass but look to the super class (Object)
+ assert(super(), "super klass must be present");
+ return super()->find_field(name, sig, fd);
+}
+
Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
// There are no methods in an array klass but the super class (Object) has some
assert(super(), "super klass must be present");
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -28,6 +28,7 @@
#include "memory/universe.hpp"
#include "oops/klass.hpp"
+class fieldDescriptor;
class klassVtable;
// ArrayKlass is the abstract baseclass for all array classes
@@ -77,6 +78,9 @@
virtual oop multi_allocate(int rank, jint* sizes, TRAPS);
objArrayOop allocate_arrayArray(int n, int length, TRAPS);
+ // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined
+ Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
+
// Lookup operations
Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
--- a/hotspot/src/share/vm/oops/klass.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -130,6 +130,15 @@
return is_subclass_of(k);
}
+Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
+#ifdef ASSERT
+ tty->print_cr("Error: find_field called on a klass oop."
+ " Likely error: reflection method does not correctly"
+ " wrap return value in a mirror object.");
+#endif
+ ShouldNotReachHere();
+ return NULL;
+}
Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
#ifdef ASSERT
--- a/hotspot/src/share/vm/oops/klass.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -62,6 +62,7 @@
class klassVtable;
class ParCompactionManager;
class KlassSizeStats;
+class fieldDescriptor;
class Klass : public Metadata {
friend class VMStructs;
@@ -411,6 +412,7 @@
virtual void initialize(TRAPS);
// lookup operation for MethodLookupCache
friend class MethodLookupCache;
+ virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
public:
Method* lookup_method(Symbol* name, Symbol* signature) const {
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -1153,12 +1153,18 @@
assert(s == start(), "");
}
+/**
+ * Return the 'StartNode'. We must not have a pending failure, since the ideal graph
+ * can be in an inconsistent state, i.e., we can get segmentation faults when traversing
+ * the ideal graph.
+ */
StartNode* Compile::start() const {
- assert(!failing(), "");
+ assert (!failing(), err_msg_res("Must not have pending failure. Reason is: %s", failure_reason()));
for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) {
Node* start = root()->fast_out(i);
- if( start->is_Start() )
+ if (start->is_Start()) {
return start->as_Start();
+ }
}
fatal("Did not find Start node!");
return NULL;
--- a/hotspot/src/share/vm/opto/compile.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -707,12 +707,15 @@
void sort_expensive_nodes();
// Compilation environment.
- Arena* comp_arena() { return &_comp_arena; }
- ciEnv* env() const { return _env; }
- CompileLog* log() const { return _log; }
- bool failing() const { return _env->failing() || _failure_reason != NULL; }
- const char* failure_reason() { return _failure_reason; }
- bool failure_reason_is(const char* r) { return (r==_failure_reason) || (r!=NULL && _failure_reason!=NULL && strcmp(r, _failure_reason)==0); }
+ Arena* comp_arena() { return &_comp_arena; }
+ ciEnv* env() const { return _env; }
+ CompileLog* log() const { return _log; }
+ bool failing() const { return _env->failing() || _failure_reason != NULL; }
+ const char* failure_reason() const { return (_env->failing()) ? _env->failure_reason() : _failure_reason; }
+
+ bool failure_reason_is(const char* r) const {
+ return (r == _failure_reason) || (r != NULL && _failure_reason != NULL && strcmp(r, _failure_reason) == 0);
+ }
void record_failure(const char* reason);
void record_method_not_compilable(const char* reason, bool all_tiers = false) {
--- a/hotspot/src/share/vm/opto/doCall.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -802,10 +802,16 @@
// each arm of the Phi. If I know something clever about the exceptions
// I'm loading the class from, I can replace the LoadKlass with the
// klass constant for the exception oop.
- if( ex_node->is_Phi() ) {
- ex_klass_node = new PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
- for( uint i = 1; i < ex_node->req(); i++ ) {
- Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
+ if (ex_node->is_Phi()) {
+ ex_klass_node = new PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT);
+ for (uint i = 1; i < ex_node->req(); i++) {
+ Node* ex_in = ex_node->in(i);
+ if (ex_in == top() || ex_in == NULL) {
+ // This path was not taken.
+ ex_klass_node->init_req(i, top());
+ continue;
+ }
+ Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
ex_klass_node->init_req( i, k );
}
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -805,6 +805,7 @@
return (jclass) JNIHandles::make_local(env, k->java_mirror());
JVM_END
+// Not used; JVM_FindClassFromCaller replaces this.
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
jboolean init, jobject loader,
jboolean throwError))
@@ -831,6 +832,42 @@
return result;
JVM_END
+// Find a class with this name in this loader, using the caller's protection domain.
+JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
+ jboolean init, jobject loader,
+ jclass caller))
+ JVMWrapper2("JVM_FindClassFromCaller %s throws ClassNotFoundException", name);
+ // Java libraries should ensure that name is never null...
+ if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
+ // It's impossible to create this class; the name cannot fit
+ // into the constant pool.
+ THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
+ }
+
+ TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+
+ oop loader_oop = JNIHandles::resolve(loader);
+ oop from_class = JNIHandles::resolve(caller);
+ oop protection_domain = NULL;
+ // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get
+ // NPE. Put it in another way, the bootstrap class loader has all permission and
+ // thus no checkPackageAccess equivalence in the VM class loader.
+ // The caller is also passed as NULL by the java code if there is no security
+ // manager to avoid the performance cost of getting the calling class.
+ if (from_class != NULL && loader_oop != NULL) {
+ protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain();
+ }
+
+ Handle h_loader(THREAD, loader_oop);
+ Handle h_prot(THREAD, protection_domain);
+ jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
+ h_prot, false, THREAD);
+
+ if (TraceClassResolution && result != NULL) {
+ trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
+ }
+ return result;
+JVM_END
JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
jboolean init, jclass from))
@@ -1073,17 +1110,6 @@
JVM_END
-JVM_ENTRY(jobject, JVM_GetClassLoader(JNIEnv *env, jclass cls))
- JVMWrapper("JVM_GetClassLoader");
- if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
- return NULL;
- }
- Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- oop loader = k->class_loader();
- return JNIHandles::make_local(env, loader);
-JVM_END
-
-
JVM_QUICK_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls))
JVMWrapper("JVM_IsInterface");
oop mirror = JNIHandles::resolve_non_null(cls);
@@ -3932,10 +3958,15 @@
// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
-jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
+jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
+ Handle loader, Handle protection_domain,
+ jboolean throwError, TRAPS) {
// Security Note:
// The Java level wrapper will perform the necessary security check allowing
- // us to pass the NULL as the initiating class loader.
+ // us to pass the NULL as the initiating class loader. The VM is responsible for
+ // the checkPackageAccess relative to the initiating class loader via the
+ // protection_domain. The protection_domain is passed as NULL by the java code
+ // if there is no security manager in 3-arg Class.forName().
Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
KlassHandle klass_handle(THREAD, klass);
--- a/hotspot/src/share/vm/prims/jvm.h Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 20:04:26 2017 +0200
@@ -420,6 +420,19 @@
JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
/*
+ * Find a class from a given class loader. Throws ClassNotFoundException.
+ * name: name of class
+ * init: whether initialization is done
+ * loader: class loader to look up the class. This may not be the same as the caller's
+ * class loader.
+ * caller: initiating class. The initiating class may be null when a security
+ * manager is not installed.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
+ jobject loader, jclass caller);
+
+/*
* Find a class from a given class.
*/
JNIEXPORT jclass JNICALL
@@ -462,9 +475,6 @@
JNIEXPORT jobjectArray JNICALL
JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
-JNIEXPORT jobject JNICALL
-JVM_GetClassLoader(JNIEnv *env, jclass cls);
-
JNIEXPORT jboolean JNICALL
JVM_IsInterface(JNIEnv *env, jclass cls);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -3836,6 +3836,11 @@
return JNI_ENOMEM;
}
+ // Set up VerifySharedSpaces
+ if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
+ VerifySharedSpaces = true;
+ }
+
// Delay warning until here so that we've had a chance to process
// the -XX:-PrintWarnings flag
if (needs_hotspotrc_warning) {
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -1177,11 +1177,11 @@
"When true prevents OS-level spurious, or premature, wakeups " \
"from Object.wait (Ignored for Windows)") \
\
- product(intx, NativeMonitorTimeout, -1, "(Unstable)") \
- \
- product(intx, NativeMonitorFlags, 0, "(Unstable)") \
- \
- product(intx, NativeMonitorSpinLimit, 20, "(Unstable)") \
+ experimental(intx, NativeMonitorTimeout, -1, "(Unstable)") \
+ \
+ experimental(intx, NativeMonitorFlags, 0, "(Unstable)") \
+ \
+ experimental(intx, NativeMonitorSpinLimit, 20, "(Unstable)") \
\
develop(bool, UsePthreads, false, \
"Use pthread-based instead of libthread-based synchronization " \
@@ -3790,6 +3790,10 @@
product(bool, UseSharedSpaces, true, \
"Use shared spaces for metadata") \
\
+ product(bool, VerifySharedSpaces, false, \
+ "Verify shared spaces (false for default archive, true for " \
+ "archive specified by -XX:SharedArchiveFile)") \
+ \
product(bool, RequireSharedSpaces, false, \
"Require shared spaces for metadata") \
\
--- a/hotspot/src/share/vm/runtime/perfMemory.hpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/runtime/perfMemory.hpp Wed Jul 05 20:04:26 2017 +0200
@@ -155,9 +155,6 @@
}
}
- // filename of backing store or NULL if none.
- static char* backing_store_filename();
-
// returns the complete file path of hsperfdata.
// the caller is expected to free the allocated memory.
static char* get_perfdata_file_path();
--- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -507,7 +507,8 @@
if (access.is_protected()) {
if (!protected_restriction) {
// See if current_class (or outermost host class) is a subclass of field_class
- if (host_class->is_subclass_of(field_class)) {
+ // An interface may not access protected members of j.l.Object
+ if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) {
if (access.is_static() || // static fields are ok, see 6622385
current_class == resolved_class ||
field_class == resolved_class ||
--- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp Wed Jul 05 20:04:26 2017 +0200
@@ -540,17 +540,25 @@
// If there are no current activations of this method on the
// stack we can safely convert it to a zombie method
if (nm->can_not_entrant_be_converted()) {
- if (PrintMethodFlushing && Verbose) {
- tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
- }
// Clear ICStubs to prevent back patching stubs of zombie or unloaded
// nmethods during the next safepoint (see ICStub::finalize).
- MutexLocker cl(CompiledIC_lock);
- nm->clear_ic_stubs();
- // Code cache state change is tracked in make_zombie()
- nm->make_zombie();
- _zombified_count++;
- SWEEP(nm);
+ {
+ MutexLocker cl(CompiledIC_lock);
+ nm->clear_ic_stubs();
+ }
+ // Acquiring the CompiledIC_lock may block for a safepoint and set the
+ // nmethod to zombie (see 'CodeCache::make_marked_nmethods_zombies').
+ // Check if nmethod is still non-entrant at this point.
+ if (nm->is_not_entrant()) {
+ if (PrintMethodFlushing && Verbose) {
+ tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
+ }
+ // Code cache state change is tracked in make_zombie()
+ nm->make_zombie();
+ _zombified_count++;
+ SWEEP(nm);
+ }
+ assert(nm->is_zombie(), "nmethod must be zombie");
} else {
// Still alive, clean up its inline caches
MutexLocker cl(CompiledIC_lock);
--- a/hotspot/test/TEST.groups Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/test/TEST.groups Wed Jul 05 20:04:26 2017 +0200
@@ -447,7 +447,7 @@
compiler/codegen/ \
compiler/cpuflags/RestoreMXCSR.java \
compiler/EscapeAnalysis/ \
- compiler/exceptions/TestRecursiveReplacedException.java \
+ compiler/exceptions/ \
compiler/floatingpoint/ModNaN.java \
compiler/gcbarriers/G1CrashTest.java \
compiler/inlining/ \
--- a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Thu Oct 16 14:14:57 2014 -0700
+++ b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Wed Jul 05 20:04:26 2017 +0200
@@ -38,22 +38,26 @@
private static void verifySegmentedCodeCache(ProcessBuilder pb, boolean enabled) throws Exception {
OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldHaveExitValue(0);
if (enabled) {
try {
// Non-nmethod code heap should be always available with the segmented code cache
out.shouldContain(NON_METHOD);
} catch (RuntimeException e) {
- // TieredCompilation is disabled in a client VM
- out.shouldContain("TieredCompilation is disabled in this release.");
+ // Check if TieredCompilation is disabled (in a client VM)
+ if(!out.getOutput().contains("TieredCompilation is disabled in this release.")) {
+ // Code cache is not segmented
+ throw new RuntimeException("No code cache segmentation.");
+ }
}
} else {
out.shouldNotContain(NON_METHOD);
}
- out.shouldHaveExitValue(0);
}
private static void verifyCodeHeapNotExists(ProcessBuilder pb, String... heapNames) throws Exception {
OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldHaveExitValue(0);
for (String name : heapNames) {
out.shouldNotContain(name);
}
@@ -86,6 +90,10 @@
"-XX:ReservedCodeCacheSize=240m",
"-XX:+PrintCodeCache", "-version");
verifySegmentedCodeCache(pb, true);
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+TieredCompilation",
+ "-XX:ReservedCodeCacheSize=400m",
+ "-XX:+PrintCodeCache", "-version");
+ verifySegmentedCodeCache(pb, true);
// Always enabled if SegmentedCodeCache is set
pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache",
@@ -100,12 +108,13 @@
"-Xint",
"-XX:+PrintCodeCache", "-version");
verifyCodeHeapNotExists(pb, PROFILED, NON_PROFILED);
+
+ // If we stop compilation at CompLevel_none or CompLevel_simple we
+ // don't need a profiled code heap.
pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache",
"-XX:TieredStopAtLevel=0",
"-XX:+PrintCodeCache", "-version");
- verifyCodeHeapNotExists(pb, PROFILED, NON_PROFILED);
-
- // If we stop compilation at CompLevel_simple
+ verifyCodeHeapNotExists(pb, PROFILED);
pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache",
"-XX:TieredStopAtLevel=1",
"-XX:+PrintCodeCache", "-version");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/exceptions/CatchInlineExceptions.java Wed Jul 05 20:04:26 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8059299
+ * @summary assert(adr_type != NULL) failed: expecting TypeKlassPtr
+ * @run main/othervm -Xbatch CatchInlineExceptions
+ */
+
+class Exception1 extends Exception {};
+class Exception2 extends Exception {};
+
+public class CatchInlineExceptions {
+ private static int counter0;
+ private static int counter1;
+ private static int counter2;
+ private static int counter;
+
+ static void foo(int i) throws Exception {
+ if ((i & 1023) == 2) {
+ counter0++;
+ throw new Exception2();
+ }
+ }
+
+ static void test(int i) throws Exception {
+ try {
+ foo(i);
+ }
+ catch (Exception e) {
+ if (e instanceof Exception1) {
+ counter1++;
+ } else if (e instanceof Exception2) {
+ counter2++;
+ }
+ counter++;
+ throw e;
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ for (int i = 0; i < 15000; i++) {
+ try {
+ test(i);
+ } catch (Exception e) {
+ // expected
+ }
+ }
+ if (counter1 != 0) {
+ throw new RuntimeException("Failed: counter1(" + counter1 + ") != 0");
+ }
+ if (counter2 != counter) {
+ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter0(" + counter0 + ")");
+ }
+ if (counter2 != counter) {
+ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter(" + counter + ")");
+ }
+ System.out.println("TEST PASSED");
+ }
+}
--- a/make/MakeHelpers.gmk Thu Oct 16 14:14:57 2014 -0700
+++ b/make/MakeHelpers.gmk Wed Jul 05 20:04:26 2017 +0200
@@ -324,9 +324,10 @@
+($(CD) $$(dir $$(firstword $$(wildcard $$(addsuffix /$$(strip $3)/$$(strip $4)-$$(strip $1).gmk, \
$(MAKE_DIR_LIST))))) \
&& $(MAKE) $(MAKE_ARGS) \
- -f $$(strip $4)-$$(strip $1).gmk \
- $$(addprefix -I, $$(wildcard $(MAKE_DIR_LIST) \
- $$(addsuffix /$$(strip $3), $(MAKE_DIR_LIST)))))
+ -f $$(strip $4)-$$(strip $1).gmk \
+ $$(addprefix -I, $$(wildcard $(MAKE_DIR_LIST) \
+ $$(addsuffix /$$(strip $3), $(MAKE_DIR_LIST)))) \
+ MODULE=$$(strip $1))
endef
################################################################################
--- a/modules.xml Thu Oct 16 14:14:57 2014 -0700
+++ b/modules.xml Wed Jul 05 20:04:26 2017 +0200
@@ -1491,16 +1491,6 @@
</export>
</module>
<module>
- <name>jdk.compact3</name>
- <depend re-exports="true">java.compact3</depend>
- <depend re-exports="true">java.smartcardio</depend>
- <depend re-exports="true">jdk.httpserver</depend>
- <depend re-exports="true">jdk.naming.dns</depend>
- <depend re-exports="true">jdk.naming.rmi</depend>
- <depend re-exports="true">jdk.sctp</depend>
- <depend re-exports="true">jdk.security.auth</depend>
- </module>
- <module>
<name>jdk.compiler</name>
<depend>java.base</depend>
<depend re-exports="true">java.compiler</depend>
@@ -1735,7 +1725,6 @@
<depend>java.base</depend>
<depend>java.desktop</depend>
<depend>java.se</depend>
- <depend>jdk.compact3</depend>
</module>
<module>
<name>jdk.scripting.nashorn</name>