This commit is contained in:
Serguei Spitsyn 2017-05-03 02:32:02 +00:00
commit 0c74ceb12d
67 changed files with 655 additions and 583 deletions

View File

@ -560,6 +560,7 @@ fc7e94cb748507366b839e859f865f724467446a jdk-10+0
a9fdfd55835ef9dccb7f317b07249bd66653b874 jdk-9+154
f3b3d77a1751897413aae43ac340a130b6fa2ae1 jdk-9+155
43139c588ea48b6504e52b6c3dec530b17b1fdb4 jdk-9+156
1ea217626ba0995dd03127f8322ba3687926a085 jdk-10+1
b2d0a906afd73dcf27f572217eb1be0f196ec16c jdk-9+157
4e78f30935229f13ce7c43089621cf7169f5abac jdk-9+158
9211c2e89c1cd11ec2d5752b0f97131a7d7525c7 jdk-9+159
@ -570,3 +571,4 @@ b01c519b715ef6f785d0631adee0a6537cf6c12e jdk-9+162
0af429be8bbaeaaf0cb838e9af28c953dda6a9c8 jdk-9+164
c92c6416ca03b1464d5ed99cf6201e52b5ba0a70 jdk-9+165
560d7aa083a24b6a56443feb8de0f40435d33aa9 jdk-9+166
48809c513ed5ebb4d4dbf2f454afcce2780db6db jdk-10+2

View File

@ -968,10 +968,11 @@ class StubGenerator: public StubCodeGenerator {
// than prefetch distance.
__ set(prefetch_count, O4);
__ cmp_and_brx_short(count, O4, Assembler::less, Assembler::pt, L_block_copy);
__ sub(count, prefetch_count, count);
__ sub(count, O4, count);
(this->*copy_loop_func)(from, to, count, count_dec, L_block_copy_prefetch, true, true);
__ add(count, prefetch_count, count); // restore count
__ set(prefetch_count, O4);
__ add(count, O4, count);
} // prefetch_count > 0
@ -992,11 +993,12 @@ class StubGenerator: public StubCodeGenerator {
// than prefetch distance.
__ set(prefetch_count, O4);
__ cmp_and_brx_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_copy);
__ sub(count, prefetch_count, count);
__ sub(count, O4, count);
Label L_copy_prefetch;
(this->*copy_loop_func)(from, to, count, count_dec, L_copy_prefetch, true, false);
__ add(count, prefetch_count, count); // restore count
__ set(prefetch_count, O4);
__ add(count, O4, count);
} // prefetch_count > 0

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2017, 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.
*
*/
package sun.jvm.hotspot.memory;
public class AltHashing {
public static long murmur3_32(long seed, byte[] data) {
long h1 = seed;
int len = data.length;
int count = len;
int offset = 0;
// body
while (count >= 4) {
long k1 = (data[offset] & 0x0FF)
| (data[offset + 1] & 0x0FF) << 8
| (data[offset + 2] & 0x0FF) << 16
| data[offset + 3] << 24;
count -= 4;
offset += 4;
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 = Integer.rotateLeft((int)h1, 13);
h1 = h1 * 5 + 0xe6546b64;
h1 &= 0xFFFFFFFFL;
}
//tail
if (count > 0) {
long k1 = 0;
switch (count) {
case 3:
k1 ^= (data[offset + 2] & 0xff) << 16;
// fall through
case 2:
k1 ^= (data[offset + 1] & 0xff) << 8;
// fall through
case 1:
k1 ^= (data[offset] & 0xff);
// fall through
default:
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 &= 0xFFFFFFFFL;
}
}
// finalization
h1 ^= len;
// finalization mix force all bits of a hash block to avalanche
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 16;
return h1 & 0xFFFFFFFFL;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -45,11 +45,14 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
sharedTableField = type.getAddressField("_shared_table");
type = db.lookupType("RehashableSymbolHashtable");
seedField = type.getCIntegerField("_seed");
}
// Fields
private static AddressField theTableField;
private static AddressField sharedTableField;
private static CIntegerField seedField;
private CompactHashTable sharedTable;
@ -62,6 +65,17 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
return table;
}
public static long getSeed() {
return (long) seedField.getValue();
}
public static boolean useAlternateHashcode() {
if (getSeed() != 0) {
return true;
}
return false;
}
public SymbolTable(Address addr) {
super(addr);
}
@ -86,11 +100,17 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
// shared table does not use alternate hashing algorithm,
// it always uses the same original hash code.
Symbol s = sharedTable.probe(name, hashValue);
if (s != null) {
return s;
}
if (useAlternateHashcode()) {
hashValue = AltHashing.murmur3_32(getSeed(), name);
}
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) {
Symbol sym = Symbol.create(e.literalValue());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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,23 +42,18 @@ inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
// Adding a lock prefix to an instruction on MP machine
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
inline jint Atomic::add (jint add_value, volatile jint* dest) {
jint addend = add_value;
int mp = os::is_MP();
__asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)"
__asm__ volatile ( "lock xaddl %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
inline void Atomic::inc (volatile jint* dest) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
: "r" (dest), "r" (mp) : "cc", "memory");
__asm__ volatile ( "lock addl $1,(%0)" :
: "r" (dest) : "cc", "memory");
}
inline void Atomic::inc_ptr(volatile void* dest) {
@ -66,9 +61,8 @@ inline void Atomic::inc_ptr(volatile void* dest) {
}
inline void Atomic::dec (volatile jint* dest) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
: "r" (dest), "r" (mp) : "cc", "memory");
__asm__ volatile ( "lock subl $1,(%0)" :
: "r" (dest) : "cc", "memory");
}
inline void Atomic::dec_ptr(volatile void* dest) {
@ -89,19 +83,17 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
__asm__ volatile ( "lock cmpxchgb %1,(%3)"
: "=a" (exchange_value)
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "q" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
__asm__ volatile ( "lock cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
@ -112,10 +104,9 @@ inline void Atomic::store (jlong store_value, volatile jlong* dest) { *
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
intptr_t addend = add_value;
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
__asm__ __volatile__ ( "lock xaddq %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
@ -125,18 +116,16 @@ inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
}
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)"
__asm__ __volatile__ ( "lock addq $1,(%0)"
:
: "r" (dest), "r" (mp)
: "r" (dest)
: "cc", "memory");
}
inline void Atomic::dec_ptr(volatile intptr_t* dest) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)"
__asm__ __volatile__ ( "lock subq $1,(%0)"
:
: "r" (dest), "r" (mp)
: "r" (dest)
: "cc", "memory");
}
@ -149,10 +138,9 @@ inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* des
}
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
__asm__ __volatile__ ( "lock cmpxchgq %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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,23 +42,18 @@ inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
// Adding a lock prefix to an instruction on MP machine
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
inline jint Atomic::add (jint add_value, volatile jint* dest) {
jint addend = add_value;
int mp = os::is_MP();
__asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)"
__asm__ volatile ( "lock xaddl %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
inline void Atomic::inc (volatile jint* dest) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" :
: "r" (dest), "r" (mp) : "cc", "memory");
__asm__ volatile ( "lock addl $1,(%0)" :
: "r" (dest) : "cc", "memory");
}
inline void Atomic::inc_ptr(volatile void* dest) {
@ -66,9 +61,8 @@ inline void Atomic::inc_ptr(volatile void* dest) {
}
inline void Atomic::dec (volatile jint* dest) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" :
: "r" (dest), "r" (mp) : "cc", "memory");
__asm__ volatile ( "lock subl $1,(%0)" :
: "r" (dest) : "cc", "memory");
}
inline void Atomic::dec_ptr(volatile void* dest) {
@ -89,19 +83,17 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
__asm__ volatile ("lock cmpxchgb %1,(%3)"
: "=a" (exchange_value)
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "q" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
__asm__ volatile ("lock cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
@ -112,10 +104,9 @@ inline void Atomic::store (jlong store_value, volatile jlong* dest) { *
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
intptr_t addend = add_value;
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
__asm__ __volatile__ ("lock xaddq %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
@ -125,18 +116,16 @@ inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
}
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)"
__asm__ __volatile__ ("lock addq $1,(%0)"
:
: "r" (dest), "r" (mp)
: "r" (dest)
: "cc", "memory");
}
inline void Atomic::dec_ptr(volatile intptr_t* dest) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)"
__asm__ __volatile__ ("lock subq $1,(%0)"
:
: "r" (dest), "r" (mp)
: "r" (dest)
: "cc", "memory");
}
@ -149,10 +138,9 @@ inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* des
}
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
__asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
@ -192,12 +180,12 @@ inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* des
extern "C" {
// defined in linux_x86.s
jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool);
jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong);
void _Atomic_move_long(volatile jlong* src, volatile jlong* dst);
}
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) {
return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP());
return _Atomic_cmpxchg_long(exchange_value, dest, compare_value);
}
inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) {

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2004, 2017, 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
@ -614,8 +614,7 @@ mmx_acs_CopyLeft:
# Support for jlong Atomic::cmpxchg(jlong exchange_value,
# volatile jlong* dest,
# jlong compare_value,
# bool is_MP)
# jlong compare_value)
#
.p2align 4,,15
.type _Atomic_cmpxchg_long,@function
@ -628,10 +627,7 @@ _Atomic_cmpxchg_long:
movl 24(%esp), %eax # 24(%esp) : compare_value (low)
movl 28(%esp), %edx # 28(%esp) : compare_value (high)
movl 20(%esp), %edi # 20(%esp) : dest
cmpl $0, 32(%esp) # 32(%esp) : is_MP
je 1f
lock
1: cmpxchg8b (%edi)
lock cmpxchg8b (%edi)
popl %edi
popl %ebx
ret

View File

@ -404,7 +404,7 @@ int VM_Version::platform_features(int features) {
// is available to us as well
Sysinfo cpu_info(SI_CPUBRAND);
bool use_solaris_12_api = cpu_info.valid();
const char* impl;
const char* impl = "unknown";
int impl_m = 0;
if (use_solaris_12_api) {
impl = cpu_info.value();
@ -431,7 +431,7 @@ int VM_Version::platform_features(int features) {
kstat_close(kc);
}
}
assert(impl_m != 0, "Unknown CPU implementation %s", impl);
assert(impl_m != 0, "Unrecognized CPU implementation: %s", impl);
features |= impl_m;
bool is_sun4v = (features & sun4v_m) != 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -52,31 +52,19 @@ inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest);
// For Sun Studio - implementation is in solaris_x86_[32/64].il.
// For gcc - implementation is just below.
// The lock prefix can be omitted for certain instructions on uniprocessors; to
// facilitate this, os::is_MP() is passed as an additional argument. 64-bit
// processors are assumed to be multi-threaded and/or multi-core, so the extra
// argument is unnecessary.
#ifndef _LP64
#define IS_MP_DECL() , int is_mp
#define IS_MP_ARG() , (int) os::is_MP()
#else
#define IS_MP_DECL()
#define IS_MP_ARG()
#endif // _LP64
extern "C" {
jint _Atomic_add(jint add_value, volatile jint* dest IS_MP_DECL());
jint _Atomic_add(jint add_value, volatile jint* dest);
jint _Atomic_xchg(jint exchange_value, volatile jint* dest);
jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest,
jbyte compare_value IS_MP_DECL());
jbyte compare_value);
jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest,
jint compare_value IS_MP_DECL());
jint compare_value);
jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest,
jlong compare_value IS_MP_DECL());
jlong compare_value);
}
inline jint Atomic::add (jint add_value, volatile jint* dest) {
return _Atomic_add(add_value, dest IS_MP_ARG());
return _Atomic_add(add_value, dest);
}
inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
@ -85,15 +73,15 @@ inline jint Atomic::xchg (jint exchange_value, volatile jint*
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) {
return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG());
return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value);
}
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) {
return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG());
return _Atomic_cmpxchg(exchange_value, dest, compare_value);
}
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) {
return _Atomic_cmpxchg_long(exchange_value, dest, compare_value IS_MP_ARG());
return _Atomic_cmpxchg_long(exchange_value, dest, compare_value);
}
@ -174,25 +162,23 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) {
#endif // AMD64
#ifdef _GNU_SOURCE
// Add a lock prefix to an instruction on an MP machine
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
extern "C" {
inline jint _Atomic_add(jint add_value, volatile jint* dest, int mp) {
inline jint _Atomic_add(jint add_value, volatile jint* dest) {
jint addend = add_value;
__asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)"
__asm__ volatile ("lock xaddl %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
#ifdef AMD64
inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp) {
inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest) {
intptr_t addend = add_value;
__asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
__asm__ __volatile__ ("lock xaddq %0,(%2)"
: "=r" (addend)
: "0" (addend), "r" (dest), "r" (mp)
: "0" (addend), "r" (dest)
: "cc", "memory");
return addend + add_value;
}
@ -215,35 +201,35 @@ extern "C" {
return exchange_value;
}
inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp) {
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
__asm__ volatile ("lock cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, int mp) {
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)"
inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
__asm__ volatile ("lock cmpxchgb %1,(%3)"
: "=a" (exchange_value)
: "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "q" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}
// This is the interface to the atomic instruction in solaris_i486.s.
jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp);
jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value);
inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) {
inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
#ifdef AMD64
__asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
__asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
#else
return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP());
return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value);
#if 0
// The code below does not work presumably because of the bug in gcc
@ -255,23 +241,19 @@ extern "C" {
volatile jlong_accessor evl, cvl, rv;
evl.long_value = exchange_value;
cvl.long_value = compare_value;
int mp = os::is_MP();
__asm__ volatile ("cmp $0, %%esi\n\t"
"je 1f \n\t"
"lock\n\t"
"1: cmpxchg8b (%%edi)\n\t"
__asm__ volatile (
"lock cmpxchg8b (%%edi)\n\t"
: "=a"(cvl.words[0]), "=d"(cvl.words[1])
: "a"(cvl.words[0]), "d"(cvl.words[1]),
"b"(evl.words[0]), "c"(evl.words[1]),
"D"(dest), "S"(mp)
"D"(dest)
: "cc", "memory");
return cvl.long_value;
#endif // if 0
#endif // AMD64
}
}
#undef LOCK_IF_MP
#endif // _GNU_SOURCE

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2003, 2017, 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
@ -55,18 +55,12 @@
.end
// Support for jint Atomic::add(jint inc, volatile jint* dest)
// An additional bool (os::is_MP()) is passed as the last argument.
.inline _Atomic_add,3
movl 0(%esp), %eax // inc
movl 4(%esp), %edx // dest
movl %eax, %ecx
cmpl $0, 8(%esp) // MP test
jne 1f
xaddl %eax, (%edx)
jmp 2f
1: lock
xaddl %eax, (%edx)
2: addl %ecx, %eax
lock xaddl %eax, (%edx)
addl %ecx, %eax
.end
// Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
@ -79,41 +73,26 @@
// Support for jbyte Atomic::cmpxchg(jbyte exchange_value,
// volatile jbyte *dest,
// jbyte compare_value)
// An additional bool (os::is_MP()) is passed as the last argument.
.inline _Atomic_cmpxchg_byte,4
movb 8(%esp), %al // compare_value
movb 0(%esp), %cl // exchange_value
movl 4(%esp), %edx // dest
cmp $0, 12(%esp) // MP test
jne 1f
cmpxchgb %cl, (%edx)
jmp 2f
1: lock
cmpxchgb %cl, (%edx)
2:
lock cmpxchgb %cl, (%edx)
.end
// Support for jint Atomic::cmpxchg(jint exchange_value,
// volatile jint *dest,
// jint compare_value)
// An additional bool (os::is_MP()) is passed as the last argument.
.inline _Atomic_cmpxchg,4
movl 8(%esp), %eax // compare_value
movl 0(%esp), %ecx // exchange_value
movl 4(%esp), %edx // dest
cmp $0, 12(%esp) // MP test
jne 1f
cmpxchgl %ecx, (%edx)
jmp 2f
1: lock
cmpxchgl %ecx, (%edx)
2:
lock cmpxchgl %ecx, (%edx)
.end
// Support for jlong Atomic::cmpxchg(jlong exchange_value,
// volatile jlong* dest,
// jlong compare_value)
// An additional bool (os::is_MP()) is passed as the last argument.
.inline _Atomic_cmpxchg_long,6
pushl %ebx
pushl %edi
@ -122,13 +101,8 @@
movl 16(%esp), %edi // dest
movl 8(%esp), %ebx // exchange_value (low)
movl 12(%esp), %ecx // exchange_high (high)
cmp $0, 28(%esp) // MP test
jne 1f
cmpxchg8b (%edi)
jmp 2f
1: lock
cmpxchg8b (%edi)
2: popl %edi
lock cmpxchg8b (%edi)
popl %edi
popl %ebx
.end

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2004, 2017, 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
@ -643,8 +643,7 @@ mmx_acs_CopyLeft:
/ Support for jlong Atomic::cmpxchg(jlong exchange_value,
/ volatile jlong* dest,
/ jlong compare_value,
/ bool is_MP)
/ jlong compare_value)
/ Used only for Solaris/gcc builds
.align 16
_Atomic_cmpxchg_long_gcc:
@ -656,10 +655,7 @@ _Atomic_cmpxchg_long_gcc:
movl 24(%esp), %eax / 24(%esp) : compare_value (low)
movl 28(%esp), %edx / 28(%esp) : compare_value (high)
movl 20(%esp), %edi / 20(%esp) : dest
cmpl $0, 32(%esp) / 32(%esp) : is_MP
je 1f
lock
1: cmpxchg8b (%edi)
lock cmpxchg8b (%edi)
popl %edi
popl %ebx
ret

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -57,15 +57,6 @@ inline void Atomic::store (jint store_value, volatile jint* dest) { *
inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
// Adding a lock prefix to an instruction on MP machine
// VC++ doesn't like the lock prefix to be on a single line
// so we can't insert a label after the lock prefix.
// By emitting a lock prefix, we can define a label after it.
#define LOCK_IF_MP(mp) __asm cmp mp, 0 \
__asm je L0 \
__asm _emit 0xF0 \
__asm L0:
#ifdef AMD64
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
@ -144,13 +135,11 @@ inline jlong Atomic::load(volatile jlong* src) { return *src; }
#else // !AMD64
inline jint Atomic::add (jint add_value, volatile jint* dest) {
int mp = os::is_MP();
__asm {
mov edx, dest;
mov eax, add_value;
mov ecx, eax;
LOCK_IF_MP(mp)
xadd dword ptr [edx], eax;
lock xadd dword ptr [edx], eax;
add eax, ecx;
}
}
@ -165,11 +154,9 @@ inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
inline void Atomic::inc (volatile jint* dest) {
// alternative for InterlockedIncrement
int mp = os::is_MP();
__asm {
mov edx, dest;
LOCK_IF_MP(mp)
add dword ptr [edx], 1;
lock add dword ptr [edx], 1;
}
}
@ -183,11 +170,9 @@ inline void Atomic::inc_ptr(volatile void* dest) {
inline void Atomic::dec (volatile jint* dest) {
// alternative for InterlockedDecrement
int mp = os::is_MP();
__asm {
mov edx, dest;
LOCK_IF_MP(mp)
sub dword ptr [edx], 1;
lock sub dword ptr [edx], 1;
}
}
@ -219,30 +204,25 @@ inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* des
#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) {
// alternative for InterlockedCompareExchange
int mp = os::is_MP();
__asm {
mov edx, dest
mov cl, exchange_value
mov al, compare_value
LOCK_IF_MP(mp)
cmpxchg byte ptr [edx], cl
lock cmpxchg byte ptr [edx], cl
}
}
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) {
// alternative for InterlockedCompareExchange
int mp = os::is_MP();
__asm {
mov edx, dest
mov ecx, exchange_value
mov eax, compare_value
LOCK_IF_MP(mp)
cmpxchg dword ptr [edx], ecx
lock cmpxchg dword ptr [edx], ecx
}
}
inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) {
int mp = os::is_MP();
jint ex_lo = (jint)exchange_value;
jint ex_hi = *( ((jint*)&exchange_value) + 1 );
jint cmp_lo = (jint)compare_value;
@ -255,8 +235,7 @@ inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong*
mov edi, dest
mov ebx, ex_lo
mov ecx, ex_hi
LOCK_IF_MP(mp)
cmpxchg8b qword ptr [edi]
lock cmpxchg8b qword ptr [edi]
pop edi
pop ebx
}

View File

@ -102,6 +102,7 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Depen
// ModuleEntryTable or PackageEntryTable created for it. The defining package
// and module for an anonymous class will be found in its host class.
if (!is_anonymous) {
_packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
if (h_class_loader.is_null()) {
// Create unnamed module for boot loader
_unnamed_module = ModuleEntry::create_boot_unnamed_module(this);
@ -297,8 +298,8 @@ void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
if (_modules != NULL) {
for (int i = 0; i < _modules->table_size(); i++) {
for (ModuleEntry* entry = _modules->bucket(i);
entry != NULL;
entry = entry->next()) {
entry != NULL;
entry = entry->next()) {
f(entry);
}
}
@ -306,13 +307,12 @@ void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
}
void ClassLoaderData::packages_do(void f(PackageEntry*)) {
// Lock-free access requires load_ptr_acquire
PackageEntryTable* packages = load_ptr_acquire(&_packages);
if (packages != NULL) {
for (int i = 0; i < packages->table_size(); i++) {
for (PackageEntry* entry = packages->bucket(i);
entry != NULL;
entry = entry->next()) {
assert_locked_or_safepoint(Module_lock);
if (_packages != NULL) {
for (int i = 0; i < _packages->table_size(); i++) {
for (PackageEntry* entry = _packages->bucket(i);
entry != NULL;
entry = entry->next()) {
f(entry);
}
}
@ -494,22 +494,6 @@ void ClassLoaderData::unload() {
free_deallocate_list();
}
PackageEntryTable* ClassLoaderData::packages() {
// Lazily create the package entry table at first request.
// Lock-free access requires load_ptr_acquire.
PackageEntryTable* packages = load_ptr_acquire(&_packages);
if (packages == NULL) {
MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag);
// Check if _packages got allocated while we were waiting for this lock.
if ((packages = _packages) == NULL) {
packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
// Ensure _packages is stable, since it is examined without a lock
OrderAccess::release_store_ptr(&_packages, packages);
}
}
return packages;
}
ModuleEntryTable* ClassLoaderData::modules() {
// Lazily create the module entry table at first request.
// Lock-free access requires load_ptr_acquire.
@ -1096,7 +1080,7 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure,
// occur after each class loader's aliveness is determined.
data = _head;
while (data != NULL) {
if (data->packages_defined()) {
if (data->packages() != NULL) {
data->packages()->purge_all_package_exports();
}
if (data->modules_defined()) {

View File

@ -347,8 +347,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
bool contains_klass(Klass* k);
void record_dependency(const Klass* to, TRAPS);
void init_dependencies(TRAPS);
PackageEntryTable* packages();
bool packages_defined() { return (_packages != NULL); }
PackageEntryTable* packages() { return _packages; }
ModuleEntry* unnamed_module() { return _unnamed_module; }
ModuleEntryTable* modules();
bool modules_defined() { return (_modules != NULL); }

View File

@ -174,8 +174,6 @@ PackageEntryTable::PackageEntryTable(int table_size)
}
PackageEntryTable::~PackageEntryTable() {
assert_locked_or_safepoint(Module_lock);
// Walk through all buckets and all entries in each bucket,
// freeing each entry.
for (int i = 0; i < table_size(); ++i) {
@ -271,6 +269,7 @@ PackageEntry* PackageEntryTable::lookup_only(Symbol* name) {
// Called when a define module for java.base is being processed.
// Verify the packages loaded thus far are in java.base's package list.
void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) {
assert_lock_strong(Module_lock);
for (int i = 0; i < table_size(); i++) {
for (PackageEntry* entry = bucket(i);
entry != NULL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -218,11 +218,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int
HandleMark hm;
Klass* klass = receiver->klass();
InstanceKlass* ik = InstanceKlass::cast(klass);
klassVtable* vt = ik->vtable();
klassVtable vt = ik->vtable();
ik->print();
fatal("bad compiled vtable dispatch: receiver " INTPTR_FORMAT ", "
"index %d (vtable length %d)",
p2i(receiver), index, vt->length());
p2i(receiver), index, vt.length());
}
#endif // PRODUCT

View File

@ -923,8 +923,6 @@ public:
double end_vtime_sec = os::elapsedVTime();
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
_cm->clear_has_overflown();
_cm->do_yield_check();
jlong sleep_time_ms;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -224,12 +224,12 @@ void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {
mark_and_push_closure.set_ref_processor(_ref_processor);
}
MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
AdjustPointerClosure MarkSweep::adjust_pointer_closure;
template <typename T>
void MarkSweep::AdjustPointerClosure::do_oop_nv(T* p) { adjust_pointer(p); }
void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { do_oop_nv(p); }
void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
void AdjustPointerClosure::do_oop_nv(T* p) { MarkSweep::adjust_pointer(p); }
void AdjustPointerClosure::do_oop(oop* p) { do_oop_nv(p); }
void AdjustPointerClosure::do_oop(narrowOop* p) { do_oop_nv(p); }
void MarkSweep::adjust_marks() {
assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
@ -280,79 +280,5 @@ void marksweep_init() {
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
}
int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
int size = size_helper();
oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
return size;
}
int InstanceMirrorKlass::oop_ms_adjust_pointers(oop obj) {
int size = oop_size(obj);
InstanceKlass::oop_ms_adjust_pointers(obj);
oop_oop_iterate_statics<true>(obj, &MarkSweep::adjust_pointer_closure);
return size;
}
int InstanceClassLoaderKlass::oop_ms_adjust_pointers(oop obj) {
return InstanceKlass::oop_ms_adjust_pointers(obj);
}
#ifdef ASSERT
template <class T> static void trace_reference_gc(const char *s, oop obj,
T* referent_addr,
T* next_addr,
T* discovered_addr) {
log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
}
#endif
template <class T> void static adjust_object_specialized(oop obj) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
MarkSweep::adjust_pointer(referent_addr);
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
MarkSweep::adjust_pointer(next_addr);
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
MarkSweep::adjust_pointer(discovered_addr);
debug_only(trace_reference_gc("InstanceRefKlass::oop_ms_adjust_pointers", obj,
referent_addr, next_addr, discovered_addr);)
}
int InstanceRefKlass::oop_ms_adjust_pointers(oop obj) {
int size = size_helper();
InstanceKlass::oop_ms_adjust_pointers(obj);
if (UseCompressedOops) {
adjust_object_specialized<narrowOop>(obj);
} else {
adjust_object_specialized<oop>(obj);
}
return size;
}
int ObjArrayKlass::oop_ms_adjust_pointers(oop obj) {
assert(obj->is_objArray(), "obj must be obj array");
objArrayOop a = objArrayOop(obj);
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = a->object_size();
oop_oop_iterate_elements<true>(a, &MarkSweep::adjust_pointer_closure);
return size;
}
int TypeArrayKlass::oop_ms_adjust_pointers(oop obj) {
assert(obj->is_typeArray(), "must be a type array");
typeArrayOop t = typeArrayOop(obj);
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::TypeArrayKlass never moves.
return t->object_size();
}
// Generate MS specialized oop_oop_iterate functions.
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(ALL_KLASS_OOP_OOP_ITERATE_DEFN)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -50,6 +50,7 @@ class STWGCTimer;
// declared at end
class PreservedMark;
class MarkAndPushClosure;
class AdjustPointerClosure;
class MarkSweep : AllStatic {
//
@ -66,16 +67,6 @@ class MarkSweep : AllStatic {
virtual void do_void();
};
class AdjustPointerClosure: public OopsInGenClosure {
public:
template <typename T> void do_oop_nv(T* p);
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
// This closure provides its own oop verification code.
debug_only(virtual bool should_verify_oops() { return false; })
};
// Used for java/lang/ref handling
class IsAliveClosure: public BoolObjectClosure {
public:
@ -201,6 +192,17 @@ public:
}
};
class AdjustPointerClosure: public OopsInGenClosure {
public:
template <typename T> void do_oop_nv(T* p);
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
// This closure provides its own oop verification code.
debug_only(virtual bool should_verify_oops() { return false; })
};
class PreservedMark VALUE_OBJ_CLASS_SPEC {
private:
oop _obj;

View File

@ -42,7 +42,7 @@ inline bool MarkSweep::is_archive_object(oop object) {
}
inline int MarkSweep::adjust_pointers(oop obj) {
return obj->ms_adjust_pointers();
return obj->oop_iterate_size(&MarkSweep::adjust_pointer_closure);
}
template <class T> inline void MarkSweep::adjust_pointer(T* p) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -44,6 +44,7 @@ class FastScanClosure;
class FilteringClosure;
// MarkSweep
class MarkAndPushClosure;
class AdjustPointerClosure;
// ParNew
class ParScanWithBarrierClosure;
class ParScanWithoutBarrierClosure;
@ -90,7 +91,8 @@ class NoHeaderExtendedOopClosure;
SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_MS(f) \
f(MarkAndPushClosure,_nv)
f(MarkAndPushClosure,_nv) \
f(AdjustPointerClosure,_nv)
#if INCLUDE_ALL_GCS
#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f) \

View File

@ -86,14 +86,15 @@ class UnlockFlagSaver {
// State accessors
void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
last_frame(thread).interpreter_frame_set_bcp(bcp);
LastFrameAccessor last_frame(thread);
last_frame.set_bcp(bcp);
if (ProfileInterpreter) {
// ProfileTraps uses MDOs independently of ProfileInterpreter.
// That is why we must check both ProfileInterpreter and mdo != NULL.
MethodData* mdo = last_frame(thread).interpreter_frame_method()->method_data();
MethodData* mdo = last_frame.method()->method_data();
if (mdo != NULL) {
NEEDS_CLEANUP;
last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci()));
last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci()));
}
}
}
@ -104,8 +105,9 @@ void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
// access constant pool
ConstantPool* pool = method(thread)->constants();
int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc);
LastFrameAccessor last_frame(thread);
ConstantPool* pool = last_frame.method()->constants();
int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
constantTag tag = pool->tag_at(index);
assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
@ -118,13 +120,14 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::C
assert(bytecode == Bytecodes::_fast_aldc ||
bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
ResourceMark rm(thread);
methodHandle m (thread, method(thread));
Bytecode_loadconstant ldc(m, bci(thread));
LastFrameAccessor last_frame(thread);
methodHandle m (thread, last_frame.method());
Bytecode_loadconstant ldc(m, last_frame.bci());
oop result = ldc.resolve_constant(CHECK);
#ifdef ASSERT
{
// The bytecode wrappers aren't GC-safe so construct a new one
Bytecode_loadconstant ldc2(m, bci(thread));
Bytecode_loadconstant ldc2(m, last_frame.bci());
oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
assert(result == coop, "expected result for assembly code");
}
@ -181,10 +184,11 @@ IRT_END
IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
// We may want to pass in more arguments - could make this slightly faster
ConstantPool* constants = method(thread)->constants();
int i = get_index_u2(thread, Bytecodes::_multianewarray);
Klass* klass = constants->klass_at(i, CHECK);
int nof_dims = number_of_dimensions(thread);
LastFrameAccessor last_frame(thread);
ConstantPool* constants = last_frame.method()->constants();
int i = last_frame.get_index_u2(Bytecodes::_multianewarray);
Klass* klass = constants->klass_at(i, CHECK);
int nof_dims = last_frame.number_of_dimensions();
assert(klass->is_klass(), "not a class");
assert(nof_dims >= 1, "multianewarray rank must be nonzero");
@ -216,8 +220,9 @@ IRT_END
// Quicken instance-of and check-cast bytecodes
IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
// Force resolving; quicken the bytecode
int which = get_index_u2(thread, Bytecodes::_checkcast);
ConstantPool* cpool = method(thread)->constants();
LastFrameAccessor last_frame(thread);
int which = last_frame.get_index_u2(Bytecodes::_checkcast);
ConstantPool* cpool = last_frame.method()->constants();
// We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
// program we might have seen an unquick'd bytecode in the interpreter but have another
// thread quicken the bytecode before we get here.
@ -256,8 +261,9 @@ void InterpreterRuntime::note_trap_inner(JavaThread* thread, int reason,
// If necessary, create an MDO to hold the information, and record it.
void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
assert(ProfileTraps, "call me only if profiling");
methodHandle trap_method(thread, method(thread));
int trap_bci = trap_method->bci_from(bcp(thread));
LastFrameAccessor last_frame(thread);
methodHandle trap_method(thread, last_frame.method());
int trap_bci = trap_method->bci_from(last_frame.bcp());
note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
}
@ -390,12 +396,13 @@ IRT_END
// invoke w/o arguments (i.e., as if one were inside the call).
IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception))
LastFrameAccessor last_frame(thread);
Handle h_exception(thread, exception);
methodHandle h_method (thread, method(thread));
methodHandle h_method (thread, last_frame.method());
constantPoolHandle h_constants(thread, h_method->constants());
bool should_repeat;
int handler_bci;
int current_bci = bci(thread);
int current_bci = last_frame.bci();
if (thread->frames_to_pop_failed_realloc() > 0) {
// Allocation of scalar replaced object used in this frame
@ -493,7 +500,7 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
// notify JVMTI of an exception throw; JVMTI will detect if this is a first
// time throw or a stack unwinding throw and accordingly notify the debugger
if (JvmtiExport::can_post_on_exceptions()) {
JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception());
JvmtiExport::post_exception_throw(thread, h_method(), last_frame.bcp(), h_exception());
}
#ifdef CC_INTERP
@ -556,20 +563,21 @@ void InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code byt
Thread* THREAD = thread;
// resolve field
fieldDescriptor info;
constantPoolHandle pool(thread, method(thread)->constants());
methodHandle m(thread, method(thread));
LastFrameAccessor last_frame(thread);
constantPoolHandle pool(thread, last_frame.method()->constants());
methodHandle m(thread, last_frame.method());
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield ||
bytecode == Bytecodes::_putstatic);
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
m, bytecode, CHECK);
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
if (cp_cache_entry->is_resolved(bytecode)) return;
// compute auxiliary field attributes
@ -718,15 +726,15 @@ IRT_END
void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
Thread* THREAD = thread;
LastFrameAccessor last_frame(thread);
// extract receiver from the outgoing argument list if necessary
Handle receiver(thread, NULL);
if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
ResourceMark rm(thread);
methodHandle m (thread, method(thread));
Bytecode_invoke call(m, bci(thread));
methodHandle m (thread, last_frame.method());
Bytecode_invoke call(m, last_frame.bci());
Symbol* signature = call.signature();
receiver = Handle(thread,
thread->last_frame().interpreter_callee_receiver(signature));
receiver = Handle(thread, last_frame.callee_receiver(signature));
assert(Universe::heap()->is_in_reserved_or_null(receiver()),
"sanity check");
assert(receiver.is_null() ||
@ -736,12 +744,12 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
// resolve method
CallInfo info;
constantPoolHandle pool(thread, method(thread)->constants());
constantPoolHandle pool(thread, last_frame.method()->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, receiver, pool,
get_index_u2_cpcache(thread, bytecode), bytecode,
last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
int retry_count = 0;
@ -753,14 +761,14 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
"Could not resolve to latest version of redefined method");
// method is redefined in the middle of resolve so re-try.
LinkResolver::resolve_invoke(info, receiver, pool,
get_index_u2_cpcache(thread, bytecode), bytecode,
last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
}
}
} // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
if (cp_cache_entry->is_resolved(bytecode)) return;
#ifdef ASSERT
@ -815,33 +823,35 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
Thread* THREAD = thread;
const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
LastFrameAccessor last_frame(thread);
// resolve method
CallInfo info;
constantPoolHandle pool(thread, method(thread)->constants());
constantPoolHandle pool(thread, last_frame.method()->constants());
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
get_index_u2_cpcache(thread, bytecode), bytecode,
last_frame.get_index_u2_cpcache(bytecode), bytecode,
CHECK);
} // end JvmtiHideSingleStepping
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
cp_cache_entry->set_method_handle(pool, info);
}
// First time execution: Resolve symbols, create a permanent CallSite object.
void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
Thread* THREAD = thread;
LastFrameAccessor last_frame(thread);
const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
//TO DO: consider passing BCI to Java.
// int caller_bci = method(thread)->bci_from(bcp(thread));
// int caller_bci = last_frame.method()->bci_from(last_frame.bcp());
// resolve method
CallInfo info;
constantPoolHandle pool(thread, method(thread)->constants());
int index = get_index_u4(thread, bytecode);
constantPoolHandle pool(thread, last_frame.method()->constants());
int index = last_frame.get_index_u4(bytecode);
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_invoke(info, Handle(), pool,
@ -895,9 +905,9 @@ nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, addr
// nm could have been unloaded so look it up again. It's unsafe
// to examine nm directly since it might have been freed and used
// for something else.
frame fr = thread->last_frame();
Method* method = fr.interpreter_frame_method();
int bci = method->bci_from(fr.interpreter_frame_bcp());
LastFrameAccessor last_frame(thread);
Method* method = last_frame.method();
int bci = method->bci_from(last_frame.bcp());
nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
}
#ifndef PRODUCT
@ -917,11 +927,11 @@ IRT_ENTRY(nmethod*,
// flag, in case this method triggers classloading which will call into Java.
UnlockFlagSaver fs(thread);
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must come from interpreter");
methodHandle method(thread, fr.interpreter_frame_method());
LastFrameAccessor last_frame(thread);
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
methodHandle method(thread, last_frame.method());
const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
const int bci = branch_bcp != NULL ? method->bci_from(last_frame.bcp()) : InvocationEntryBci;
assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
@ -937,9 +947,9 @@ IRT_ENTRY(nmethod*,
if (UseBiasedLocking) {
ResourceMark rm;
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end();
kptr < fr.interpreter_frame_monitor_begin();
kptr = fr.next_monitor_in_interpreter_frame(kptr) ) {
for( BasicObjectLock *kptr = last_frame.monitor_end();
kptr < last_frame.monitor_begin();
kptr = last_frame.next_monitor(kptr) ) {
if( kptr->obj() != NULL ) {
objects_to_revoke->append(Handle(THREAD, kptr->obj()));
}
@ -964,9 +974,9 @@ IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread))
UnlockFlagSaver fs(thread);
assert(ProfileInterpreter, "must be profiling interpreter");
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must come from interpreter");
methodHandle method(thread, fr.interpreter_frame_method());
LastFrameAccessor last_frame(thread);
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
methodHandle method(thread, last_frame.method());
Method::build_interpreter_method_data(method, THREAD);
if (HAS_PENDING_EXCEPTION) {
assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
@ -1011,9 +1021,9 @@ IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int r
assert(ProfileInterpreter, "must be profiling interpreter");
ResourceMark rm(thread);
HandleMark hm(thread);
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "must come from interpreter");
MethodData* h_mdo = fr.interpreter_frame_method()->method_data();
LastFrameAccessor last_frame(thread);
assert(last_frame.is_interpreted_frame(), "must come from interpreter");
MethodData* h_mdo = last_frame.method()->method_data();
// Grab a lock to ensure atomic access to setting the return bci and
// the displacement. This can block and GC, invalidating all naked oops.
@ -1021,10 +1031,10 @@ IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int r
// ProfileData is essentially a wrapper around a derived oop, so we
// need to take the lock before making any ProfileData structures.
ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp()));
ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(last_frame.mdp()));
RetData* rdata = data->as_RetData();
address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
fr.interpreter_frame_set_mdp(new_mdp);
last_frame.set_mdp(new_mdp);
IRT_END
IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
@ -1049,7 +1059,8 @@ IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread))
// We are called during regular safepoints and when the VM is
// single stepping. If any thread is marked for single stepping,
// then we may have JVMTI work to do.
JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread));
LastFrameAccessor last_frame(thread);
JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
}
IRT_END
@ -1072,7 +1083,8 @@ ConstantPoolCacheEntry *cp_entry))
}
InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static);
JvmtiExport::post_field_access(thread, method(thread), bcp(thread), cp_entry_f1, h_obj, fid);
LastFrameAccessor last_frame(thread);
JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
@ -1127,17 +1139,20 @@ IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
h_obj = Handle(thread, obj);
}
JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), ik, h_obj,
LastFrameAccessor last_frame(thread);
JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj,
fid, sig_type, &fvalue);
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread))
JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
LastFrameAccessor last_frame(thread);
JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame());
IRT_END
IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread))
JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
LastFrameAccessor last_frame(thread);
JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame());
IRT_END
IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc))
@ -1362,10 +1377,10 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa
ResetNoHandleMark rnm; // In a LEAF entry.
HandleMark hm;
ResourceMark rm;
frame fr = thread->last_frame();
assert(fr.is_interpreted_frame(), "");
jint bci = fr.interpreter_frame_bci();
methodHandle mh(thread, fr.interpreter_frame_method());
LastFrameAccessor last_frame(thread);
assert(last_frame.is_interpreted_frame(), "");
jint bci = last_frame.bci();
methodHandle mh(thread, last_frame.method());
Bytecode_invoke invoke(mh, bci);
ArgumentSizeComputer asc(invoke.signature());
int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
@ -1411,10 +1426,10 @@ IRT_END
// The generated code still uses call_VM because that will set up the frame pointer for
// bcp and method.
IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
const frame f = thread->last_frame();
assert(f.is_interpreted_frame(), "must be an interpreted frame");
methodHandle mh(thread, f.interpreter_frame_method());
BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
LastFrameAccessor last_frame(thread);
assert(last_frame.is_interpreted_frame(), "must be an interpreted frame");
methodHandle mh(thread, last_frame.method());
BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2);
return preserve_this_value;
IRT_END
#endif // !PRODUCT

View File

@ -42,29 +42,54 @@ class InterpreterRuntime: AllStatic {
friend class PrintingClosure; // for method and bcp
private:
// Helper functions to access current interpreter state
static frame last_frame(JavaThread *thread) { return thread->last_frame(); }
static Method* method(JavaThread *thread) { return last_frame(thread).interpreter_frame_method(); }
static address bcp(JavaThread *thread) { return last_frame(thread).interpreter_frame_bcp(); }
static int bci(JavaThread *thread) { return last_frame(thread).interpreter_frame_bci(); }
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
static Bytecodes::Code code(JavaThread *thread) {
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
return Bytecodes::code_at(method(thread), bcp(thread));
}
static Bytecode bytecode(JavaThread *thread) { return Bytecode(method(thread), bcp(thread)); }
static int get_index_u1(JavaThread *thread, Bytecodes::Code bc)
{ return bytecode(thread).get_index_u1(bc); }
static int get_index_u2(JavaThread *thread, Bytecodes::Code bc)
{ return bytecode(thread).get_index_u2(bc); }
static int get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
{ return bytecode(thread).get_index_u2_cpcache(bc); }
static int get_index_u4(JavaThread *thread, Bytecodes::Code bc)
{ return bytecode(thread).get_index_u4(bc); }
static int number_of_dimensions(JavaThread *thread) { return bcp(thread)[3]; }
// Helper class to access current interpreter state
class LastFrameAccessor : public StackObj {
frame _last_frame;
public:
LastFrameAccessor(JavaThread* thread) {
assert(thread == Thread::current(), "sanity");
_last_frame = thread->last_frame();
}
bool is_interpreted_frame() const { return _last_frame.is_interpreted_frame(); }
Method* method() const { return _last_frame.interpreter_frame_method(); }
address bcp() const { return _last_frame.interpreter_frame_bcp(); }
int bci() const { return _last_frame.interpreter_frame_bci(); }
address mdp() const { return _last_frame.interpreter_frame_mdp(); }
static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); }
static ConstantPoolCacheEntry* cache_entry(JavaThread *thread) { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
void set_bcp(address bcp) { _last_frame.interpreter_frame_set_bcp(bcp); }
void set_mdp(address dp) { _last_frame.interpreter_frame_set_mdp(dp); }
// pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
Bytecodes::Code code() const { return Bytecodes::code_at(method(), bcp()); }
Bytecode bytecode() const { return Bytecode(method(), bcp()); }
int get_index_u1(Bytecodes::Code bc) const { return bytecode().get_index_u1(bc); }
int get_index_u2(Bytecodes::Code bc) const { return bytecode().get_index_u2(bc); }
int get_index_u2_cpcache(Bytecodes::Code bc) const
{ return bytecode().get_index_u2_cpcache(bc); }
int get_index_u4(Bytecodes::Code bc) const { return bytecode().get_index_u4(bc); }
int number_of_dimensions() const { return bcp()[3]; }
ConstantPoolCacheEntry* cache_entry_at(int i) const
{ return method()->constants()->cache()->entry_at(i); }
ConstantPoolCacheEntry* cache_entry() const { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
oop callee_receiver(Symbol* signature) {
return _last_frame.interpreter_callee_receiver(signature);
}
BasicObjectLock* monitor_begin() const {
return _last_frame.interpreter_frame_monitor_end();
}
BasicObjectLock* monitor_end() const {
return _last_frame.interpreter_frame_monitor_begin();
}
BasicObjectLock* next_monitor(BasicObjectLock* current) const {
return _last_frame.next_monitor_in_interpreter_frame(current);
}
frame& get_frame() { return _last_frame; }
};
static void set_bcp_and_mdp(address bcp, JavaThread*thread);
static void note_trap_inner(JavaThread* thread, int reason,
methodHandle trap_method, int trap_bci, TRAPS);
static void note_trap(JavaThread *thread, int reason, TRAPS);
@ -139,7 +164,7 @@ class InterpreterRuntime: AllStatic {
static void _breakpoint(JavaThread* thread, Method* method, address bcp);
static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
static void set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(bcp(thread)) == Bytecodes::_breakpoint; }
static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; }
// Safepoints
static void at_safepoint(JavaThread* thread);

View File

@ -150,8 +150,6 @@ CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
kind = CallInfo::vtable_call;
} else if (!resolved_klass->is_interface()) {
// A default or miranda method. Compute the vtable index.
ResourceMark rm;
klassVtable* vt = resolved_klass->vtable();
index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
resolved_method);
assert(index >= 0 , "we should have valid vtable index at this point");
@ -163,7 +161,7 @@ CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
#ifdef ASSERT
// Ensure that this is really the case.
Klass* object_klass = SystemDictionary::Object_klass();
Method * object_resolved_method = object_klass->vtable()->method_at(index);
Method * object_resolved_method = object_klass->vtable().method_at(index);
assert(object_resolved_method->name() == resolved_method->name(),
"Object and interface method names should match at vtable index %d, %s != %s",
index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string());
@ -400,9 +398,8 @@ int LinkResolver::vtable_index_of_interface_method(Klass* klass,
}
if (vtable_index == Method::invalid_vtable_index) {
// get vtable_index for miranda methods
ResourceMark rm;
klassVtable *vt = ik->vtable();
vtable_index = vt->index_of_miranda(name, signature);
klassVtable vt = ik->vtable();
vtable_index = vt.index_of_miranda(name, signature);
}
return vtable_index;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -65,6 +65,16 @@ class ExtendedOopClosure : public OopClosure {
public:
ReferenceProcessor* ref_processor() const { return _ref_processor; }
// Iteration of InstanceRefKlasses differ depending on the closure,
// the below enum describes the different alternatives.
enum ReferenceIterationMode {
DO_DISCOVERY, // Apply closure and discover references
DO_FIELDS // Apply closure to all fields
};
// The default iteration mode is to do discovery.
virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; }
// If the do_metadata functions return "true",
// we invoke the following when running oop_iterate():
//

View File

@ -526,8 +526,7 @@ void Universe::run_finalizers_on_exit() {
// In case those ever change we use handles for oops
void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) {
// init vtable of k and all subclasses
klassVtable* vt = ko->vtable();
if (vt) vt->initialize_vtable(false, CHECK);
ko->vtable().initialize_vtable(false, CHECK);
if (ko->is_instance_klass()) {
for (Klass* sk = ko->subklass();
sk != NULL;
@ -539,7 +538,7 @@ void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) {
void initialize_itable_for_klass(Klass* k, TRAPS) {
InstanceKlass::cast(k)->itable()->initialize_itable(false, CHECK);
InstanceKlass::cast(k)->itable().initialize_itable(false, CHECK);
}

View File

@ -99,7 +99,7 @@ ArrayKlass::ArrayKlass(Symbol* name) :
void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module_entry, TRAPS) {
ResourceMark rm(THREAD);
k->initialize_supers(super_klass, CHECK);
k->vtable()->initialize_vtable(false, CHECK);
k->vtable().initialize_vtable(false, CHECK);
// During bootstrapping, before java.base is defined, the module_entry may not be present yet.
// These classes will be put on a fixup list and their module fields will be patched once

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, 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
@ -48,8 +48,6 @@ public:
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -373,8 +373,8 @@ bool InstanceKlass::should_be_initialized() const {
return !is_initialized();
}
klassItable* InstanceKlass::itable() const {
return new klassItable(const_cast<InstanceKlass*>(this));
klassItable InstanceKlass::itable() const {
return klassItable(const_cast<InstanceKlass*>(this));
}
void InstanceKlass::eager_initialize(Thread *thread) {
@ -621,15 +621,14 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
if (!(is_shared() &&
loader_data->is_the_null_class_loader_data())) {
ResourceMark rm(THREAD);
vtable()->initialize_vtable(true, CHECK_false);
itable()->initialize_itable(true, CHECK_false);
vtable().initialize_vtable(true, CHECK_false);
itable().initialize_itable(true, CHECK_false);
}
#ifdef ASSERT
else {
ResourceMark rm(THREAD);
vtable()->verify(tty, true);
vtable().verify(tty, true);
// In case itable verification is ever added.
// itable()->verify(tty, true);
// itable().verify(tty, true);
}
#endif
set_init_state(linked);
@ -807,8 +806,8 @@ void InstanceKlass::initialize_impl(TRAPS) {
// Step 9
if (!HAS_PENDING_EXCEPTION) {
set_initialization_state_and_notify(fully_initialized, CHECK);
{ ResourceMark rm(THREAD);
debug_only(vtable()->verify(tty, true);)
{
debug_only(vtable().verify(tty, true);)
}
}
else {
@ -2041,8 +2040,8 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
// vtables in the shared system dictionary, only the main one.
// It also redefines the itable too so fix that too.
ResourceMark rm(THREAD);
vtable()->initialize_vtable(false, CHECK);
itable()->initialize_itable(false, CHECK);
vtable().initialize_vtable(false, CHECK);
itable().initialize_itable(false, CHECK);
}
// restore constant pool resolved references
@ -3212,10 +3211,9 @@ void InstanceKlass::verify_on(outputStream* st) {
// Verify vtables
if (is_linked()) {
ResourceMark rm;
// $$$ This used to be done only for m/s collections. Doing it
// always seemed a valid generalization. (DLD -- 6/00)
vtable()->verify(st);
vtable().verify(st);
}
// Verify first subklass

View File

@ -1127,7 +1127,7 @@ public:
}
// Java itable
klassItable* itable() const; // return new klassItable wrapper
klassItable itable() const; // return klassItable wrapper
Method* method_at_itable(Klass* holder, int index, TRAPS);
#if INCLUDE_JVMTI
@ -1163,8 +1163,6 @@ public:
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -89,8 +89,6 @@ class InstanceMirrorKlass: public InstanceKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -58,8 +58,6 @@ class InstanceRefKlass: public InstanceKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);
@ -107,6 +105,30 @@ private:
template <bool nv, class OopClosureType>
inline void oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure);
// Building blocks for specialized handling.
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_referent(oop obj, OopClosureType* closure, Contains& contains);
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_next(oop obj, OopClosureType* closure, Contains& contains);
template <bool nv, typename T, class OopClosureType, class Contains>
static void do_discovered(oop obj, OopClosureType* closure, Contains& contains);
template <typename T, class OopClosureType>
static bool try_discover(oop obj, ReferenceType type, OopClosureType* closure);
// Do discovery while handling InstanceRefKlasses. Reference discovery
// is only done if the closure provides a ReferenceProcessor.
template <bool nv, typename T, class OopClosureType, class Contains>
static void oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains);
// Apply the closure to all fields. No reference discovery is done.
template <bool nv, typename T, class OopClosureType, class Contains>
static void oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains);
template <typename T>
static void trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) NOT_DEBUG_RETURN;
public:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -36,39 +36,99 @@
#include "utilities/macros.hpp"
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
if (closure->apply_to_weak_ref_discovered_field()) {
Devirtualizer<nv>::do_oop(closure, disc_addr);
}
void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
ReferenceProcessor* rp = closure->ref_processor();
if (!oopDesc::is_null(heap_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!referent->is_gc_marked() && (rp != NULL) &&
rp->discover_reference(obj, reference_type())) {
return;
} else if (contains(referent_addr)) {
// treat referent as normal oop
Devirtualizer<nv>::do_oop(closure, referent_addr);
}
if (contains(referent_addr)) {
Devirtualizer<nv>::do_oop(closure, referent_addr);
}
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
T next_oop = oopDesc::load_heap_oop(next_addr);
// Treat discovered as normal oop, if ref is not "active" (next non-NULL)
if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {
// i.e. ref is not "active"
log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(disc_addr));
Devirtualizer<nv>::do_oop(closure, disc_addr);
}
// treat next as normal oop
if (contains(next_addr)) {
Devirtualizer<nv>::do_oop(closure, next_addr);
}
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
if (contains(discovered_addr)) {
Devirtualizer<nv>::do_oop(closure, discovered_addr);
}
}
template <typename T, class OopClosureType>
bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
ReferenceProcessor* rp = closure->ref_processor();
if (rp != NULL) {
T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
if (!oopDesc::is_null(referent_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
if (!referent->is_gc_marked()) {
// Only try to discover if not yet marked.
return rp->discover_reference(obj, type);
}
}
}
return false;
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {
log_develop_trace(gc, ref)("Process reference with discovery " PTR_FORMAT, p2i(obj));
// Special case for some closures.
if (closure->apply_to_weak_ref_discovered_field()) {
do_discovered<nv, T>(obj, closure, contains);
}
// Try to discover reference and return if it succeeds.
if (try_discover<T>(obj, type, closure)) {
return;
}
// Treat referent as normal oop.
do_referent<nv, T>(obj, closure, contains);
// Treat discovered as normal oop, if ref is not "active" (next non-NULL).
T next_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
if (!oopDesc::is_null(next_oop)) {
do_discovered<nv, T>(obj, closure, contains);
}
// Treat next as normal oop.
do_next<nv, T>(obj, closure, contains);
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
do_referent<nv, T>(obj, closure, contains);
do_discovered<nv, T>(obj, closure, contains);
do_next<nv, T>(obj, closure, contains);
trace_reference_gc("InstanceRefKlass::oop_oop_iterate_fields()",
obj,
(T*)java_lang_ref_Reference::referent_addr(obj),
(T*)java_lang_ref_Reference::next_addr(obj),
(T*)java_lang_ref_Reference::discovered_addr(obj));
}
template <bool nv, typename T, class OopClosureType, class Contains>
void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) {
switch (closure->reference_iteration_mode()) {
case ExtendedOopClosure::DO_DISCOVERY:
oop_oop_iterate_discovery<nv, T>(obj, reference_type(), closure, contains);
break;
case ExtendedOopClosure::DO_FIELDS:
oop_oop_iterate_fields<nv, T>(obj, closure, contains);
break;
default:
ShouldNotReachHere();
}
}
class AlwaysContains {
public:
template <typename T> bool operator()(T* p) const { return true; }
@ -125,6 +185,19 @@ void InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure,
oop_oop_iterate_ref_processing_bounded<nv>(obj, closure, mr);
}
#ifdef ASSERT
template <typename T>
void InstanceRefKlass::trace_reference_gc(const char *s, oop obj, T* referent_addr, T* next_addr, T* discovered_addr) {
log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
}
#endif
// Macro to define InstanceRefKlass::oop_oop_iterate for virtual/nonvirtual for
// all closures. Macros calling macros above for each oop size.
#define ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \

View File

@ -497,10 +497,12 @@ void Klass::remove_unshareable_info() {
// Null out class_loader_data because we don't share that yet.
set_class_loader_data(NULL);
set_is_shared();
}
void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
assert(is_klass(), "ensure C++ vtable is restored");
assert(is_shared(), "must be set");
TRACE_RESTORE_ID(this);
// If an exception happened during CDS restore, some of these fields may already be
@ -696,8 +698,8 @@ void Klass::oop_verify_on(oop obj, outputStream* st) {
guarantee(obj->klass()->is_klass(), "klass field is not a klass");
}
klassVtable* Klass::vtable() const {
return new klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
klassVtable Klass::vtable() const {
return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
}
vtableEntry* Klass::start_of_vtable() const {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -399,7 +399,7 @@ protected:
#endif
// vtables
klassVtable* vtable() const;
klassVtable vtable() const;
int vtable_length() const { return _vtable_len; }
// subclass check
@ -563,6 +563,8 @@ protected:
void set_has_vanilla_constructor() { _access_flags.set_has_vanilla_constructor(); }
bool has_miranda_methods () const { return access_flags().has_miranda_methods(); }
void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); }
bool is_shared() const { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)()
void set_is_shared() { _access_flags.set_is_shared_class(); }
bool is_cloneable() const;
void set_is_cloneable();
@ -607,8 +609,6 @@ protected:
// GC specific object visitors
//
// Mark Sweep
virtual int oop_ms_adjust_pointers(oop obj) = 0;
#if INCLUDE_ALL_GCS
// Parallel Scavenge
virtual void oop_ps_push_contents( oop obj, PSPromotionManager* pm) = 0;

View File

@ -136,22 +136,22 @@ int klassVtable::initialize_from_super(Klass* super) {
// methods from super class for shared class, as that was already done
// during archiving time. However, if Jvmti has redefined a class,
// copy super class's vtable in case the super class has changed.
return super->vtable()->length();
return super->vtable().length();
} else {
// copy methods from superKlass
klassVtable* superVtable = super->vtable();
assert(superVtable->length() <= _length, "vtable too short");
klassVtable superVtable = super->vtable();
assert(superVtable.length() <= _length, "vtable too short");
#ifdef ASSERT
superVtable->verify(tty, true);
superVtable.verify(tty, true);
#endif
superVtable->copy_vtable_to(table());
superVtable.copy_vtable_to(table());
if (log_develop_is_enabled(Trace, vtables)) {
ResourceMark rm;
log_develop_trace(vtables)("copy vtable from %s to %s size %d",
super->internal_name(), klass()->internal_name(),
_length);
}
return superVtable->length();
return superVtable.length();
}
}
@ -290,9 +290,9 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
InstanceKlass* superk = initialsuper;
while (superk != NULL && superk->super() != NULL) {
InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super());
klassVtable* ssVtable = supersuperklass->vtable();
if (vtable_index < ssVtable->length()) {
Method* super_method = ssVtable->method_at(vtable_index);
klassVtable ssVtable = supersuperklass->vtable();
if (vtable_index < ssVtable.length()) {
Method* super_method = ssVtable.method_at(vtable_index);
#ifndef PRODUCT
Symbol* name= target_method()->name();
Symbol* signature = target_method()->signature();
@ -445,8 +445,8 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
if (is_preinitialized_vtable()) {
// If this is a shared class, the vtable is already in the final state (fully
// initialized). Need to look at the super's vtable.
klassVtable* superVtable = super->vtable();
super_method = superVtable->method_at(i);
klassVtable superVtable = super->vtable();
super_method = superVtable.method_at(i);
} else {
super_method = method_at(i);
}
@ -1014,15 +1014,16 @@ bool klassVtable::is_initialized() {
void itableMethodEntry::initialize(Method* m) {
if (m == NULL) return;
#ifdef ASSERT
if (MetaspaceShared::is_in_shared_space((void*)&_method) &&
!MetaspaceShared::remapped_readwrite()) {
// At runtime initialize_itable is rerun as part of link_class_impl()
// for a shared class loaded by the non-boot loader.
// The dumptime itable method entry should be the same as the runtime entry.
assert(_method == m, "sanity");
} else {
_method = m;
}
#endif
_method = m;
}
klassItable::klassItable(InstanceKlass* klass) {
@ -1249,17 +1250,6 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
}
}
// Update entry for specific Method*
void klassItable::initialize_with_method(Method* m) {
itableMethodEntry* ime = method_entry(0);
for(int i = 0; i < _size_method_table; i++) {
if (ime->method() == m) {
ime->initialize(m);
}
ime++;
}
}
#if INCLUDE_JVMTI
// search the itable for uses of either obsolete or EMCP methods
void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
@ -1488,9 +1478,9 @@ void klassVtable::verify(outputStream* st, bool forced) {
Klass* super = _klass->super();
if (super != NULL) {
InstanceKlass* sk = InstanceKlass::cast(super);
klassVtable* vt = sk->vtable();
for (int i = 0; i < vt->length(); i++) {
verify_against(st, vt, i);
klassVtable vt = sk->vtable();
for (int i = 0; i < vt.length(); i++) {
verify_against(st, &vt, i);
}
}
}
@ -1557,8 +1547,7 @@ class VtableStats : AllStatic {
static void do_class(Klass* k) {
Klass* kl = k;
klassVtable* vt = kl->vtable();
if (vt == NULL) return;
klassVtable vt = kl->vtable();
no_klasses++;
if (kl->is_instance_klass()) {
no_instance_klasses++;
@ -1566,9 +1555,9 @@ class VtableStats : AllStatic {
}
if (kl->is_array_klass()) {
no_array_klasses++;
sum_of_array_vtable_len += vt->length();
sum_of_array_vtable_len += vt.length();
}
sum_of_vtable_len += vt->length();
sum_of_vtable_len += vt.length();
}
static void compute() {

View File

@ -41,7 +41,7 @@
class vtableEntry;
class klassVtable : public ResourceObj {
class klassVtable VALUE_OBJ_CLASS_SPEC {
Klass* _klass; // my klass
int _tableOffset; // offset of start of vtable data within klass
int _length; // length of vtable (number of entries)
@ -288,7 +288,7 @@ class itableMethodEntry VALUE_OBJ_CLASS_SPEC {
// -- vtable for interface 2 ---
// ...
//
class klassItable : public ResourceObj {
class klassItable VALUE_OBJ_CLASS_SPEC {
private:
InstanceKlass* _klass; // my klass
int _table_offset; // offset of start of itable data within klass (in words)
@ -310,9 +310,6 @@ class klassItable : public ResourceObj {
// Initialization
void initialize_itable(bool checkconstraints, TRAPS);
// Updates
void initialize_with_method(Method* m);
#if INCLUDE_JVMTI
// RedefineClasses() API support:
// if any entry of this itable points to any of old_methods,

View File

@ -1191,7 +1191,6 @@ bool Method::is_overridden_in(Klass* k) const {
}
assert(ik->is_subclass_of(method_holder()), "should be subklass");
assert(ik->vtable() != NULL, "vtable should exist");
if (!has_vtable_index()) {
return false;
} else {

View File

@ -112,8 +112,6 @@ class ObjArrayKlass : public ArrayKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -325,10 +325,6 @@ class oopDesc {
// Garbage Collection support
// Mark Sweep
// Adjust all pointers in this object to point at it's forwarded location and
// return the size of this oop. This is used by the MarkSweep collector.
inline int ms_adjust_pointers();
#if INCLUDE_ALL_GCS
// Parallel Compact
inline void pc_follow_contents(ParCompactionManager* cm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -664,13 +664,6 @@ void oopDesc::incr_age() {
}
}
int oopDesc::ms_adjust_pointers() {
debug_only(int check_size = size());
int s = klass()->oop_ms_adjust_pointers(this);
assert(s == check_size, "should be the same");
return s;
}
#if INCLUDE_ALL_GCS
void oopDesc::pc_follow_contents(ParCompactionManager* cm) {
klass()->oop_pc_follow_contents(this, cm);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -74,8 +74,6 @@ class TypeArrayKlass : public ArrayKlass {
// GC specific object visitors
//
// Mark Sweep
int oop_ms_adjust_pointers(oop obj);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
void oop_ps_push_contents( oop obj, PSPromotionManager* pm);

View File

@ -3272,7 +3272,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// If the class being redefined is java.lang.Object, we need to fix all
// array class vtables also
if (k->is_array_klass() && _the_class == SystemDictionary::Object_klass()) {
k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
k->vtable().adjust_method_entries(the_class, &trace_name_printed);
} else if (k->is_instance_klass()) {
HandleMark hm(_thread);
@ -3315,7 +3315,7 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
// ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
ik->vtable().adjust_method_entries(the_class, &trace_name_printed);
ik->adjust_default_methods(the_class, &trace_name_printed);
}
@ -3329,10 +3329,8 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) {
if (ik->itable_length() > 0 && (_the_class->is_interface()
|| _the_class == SystemDictionary::internal_Unsafe_klass()
|| ik->is_subclass_of(_the_class))) {
// ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
ik->itable().adjust_method_entries(the_class, &trace_name_printed);
}
// The constant pools in other classes (other_cp) can refer to
@ -3957,8 +3955,8 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// compare_and_normalize_class_versions has already checked:
// - classloaders unchanged, signatures unchanged
// - all instanceKlasses for redefined classes reused & contents updated
the_class->vtable()->initialize_vtable(false, THREAD);
the_class->itable()->initialize_itable(false, THREAD);
the_class->vtable().initialize_vtable(false, THREAD);
the_class->itable().initialize_itable(false, THREAD);
assert(!HAS_PENDING_EXCEPTION || (THREAD->pending_exception()->is_a(SystemDictionary::ThreadDeath_klass())), "redefine exception");
}
@ -4093,12 +4091,12 @@ void VM_RedefineClasses::CheckClass::do_klass(Klass* k) {
// a vtable should never contain old or obsolete methods
ResourceMark rm(_thread);
if (k->vtable_length() > 0 &&
!k->vtable()->check_no_old_or_obsolete_entries()) {
!k->vtable().check_no_old_or_obsolete_entries()) {
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
log_trace(redefine, class, obsolete, metadata)
("klassVtable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
k->signature_name());
k->vtable()->dump_vtable();
k->vtable().dump_vtable();
}
no_old_methods = false;
}
@ -4109,12 +4107,12 @@ void VM_RedefineClasses::CheckClass::do_klass(Klass* k) {
// an itable should never contain old or obsolete methods
if (ik->itable_length() > 0 &&
!ik->itable()->check_no_old_or_obsolete_entries()) {
!ik->itable().check_no_old_or_obsolete_entries()) {
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
log_trace(redefine, class, obsolete, metadata)
("klassItable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
ik->signature_name());
ik->itable()->dump_itable();
ik->itable().dump_itable();
}
no_old_methods = false;
}

View File

@ -218,7 +218,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool int
m_klass_non_interface = SystemDictionary::Object_klass();
#ifdef ASSERT
{ ResourceMark rm;
Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
Method* m2 = m_klass_non_interface->vtable().method_at(vmindex);
assert(m->name() == m2->name() && m->signature() == m2->signature(),
"at %d, %s != %s", vmindex,
m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string());

View File

@ -289,10 +289,10 @@ Flag::Error OptoLoopAlignmentConstraintFunc(intx value, bool verbose) {
}
Flag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
if (value != 0) {
if (value >= 4032) {
CommandLineError::print(verbose,
"ArraycopyDstPrefetchDistance (" UINTX_FORMAT ") must be 0\n",
value);
"ArraycopyDstPrefetchDistance (" UINTX_FORMAT ") must be"
"between 0 and 4031\n", value);
return Flag::VIOLATES_CONSTRAINT;
}
@ -300,10 +300,10 @@ Flag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose
}
Flag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose) {
if (value != 0) {
if (value >= 4032) {
CommandLineError::print(verbose,
"ArraycopySrcPrefetchDistance (" UINTX_FORMAT ") must be 0\n",
value);
"ArraycopySrcPrefetchDistance (" UINTX_FORMAT ") must be"
"between 0 and 4031\n", value);
return Flag::VIOLATES_CONSTRAINT;
}

View File

@ -865,16 +865,15 @@ static Flag flagTable[] = {
Flag* Flag::flags = flagTable;
size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag));
inline bool str_equal(const char* s, const char* q, size_t len) {
// s is null terminated, q is not!
if (strlen(s) != (unsigned int) len) return false;
return strncmp(s, q, len) == 0;
inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) {
if (s_len != q_len) return false;
return memcmp(s, q, q_len) == 0;
}
// Search the flag table for a named flag
Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
if (str_equal(current->_name, name, length)) {
if (str_equal(current->_name, current->get_name_length(), name, length)) {
// Found a matching entry.
// Don't report notproduct and develop flags in product builds.
if (current->is_constant_in_binary()) {
@ -895,6 +894,14 @@ Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool r
return NULL;
}
// Get or compute the flag name length
size_t Flag::get_name_length() {
if (_name_len == 0) {
_name_len = strlen(_name);
}
return _name_len;
}
// Compute string similarity based on Dice's coefficient
static float str_similar(const char* str1, const char* str2, size_t len2) {
int len1 = (int) strlen(str1);

View File

@ -186,6 +186,7 @@ struct Flag {
void* _addr;
NOT_PRODUCT(const char* _doc;)
Flags _flags;
size_t _name_len;
// points to all Flags static array
static Flag* flags;
@ -247,6 +248,8 @@ struct Flag {
Flags get_origin();
void set_origin(Flags origin);
size_t get_name_length();
bool is_default();
bool is_ergonomic();
bool is_command_line();

View File

@ -199,6 +199,7 @@ typedef Hashtable<InstanceKlass*, mtClass> KlassHashtable;
typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
typedef RehashableHashtable<Symbol*, mtSymbol> RehashableSymbolHashtable;
//--------------------------------------------------------------------------------
// VM_STRUCTS
@ -584,6 +585,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
static_field(SymbolTable, _the_table, SymbolTable*) \
static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
static_field(RehashableSymbolHashtable, _seed, juint) \
\
/***************/ \
/* StringTable */ \
@ -1602,6 +1604,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
declare_toplevel_type(BasicHashtable<mtInternal>) \
declare_type(IntptrHashtable, BasicHashtable<mtInternal>) \
declare_toplevel_type(BasicHashtable<mtSymbol>) \
declare_type(RehashableSymbolHashtable, BasicHashtable<mtSymbol>) \
declare_type(SymbolTable, SymbolHashtable) \
declare_type(StringTable, StringHashtable) \
declare_type(LoaderConstraintTable, KlassHashtable) \

View File

@ -64,6 +64,7 @@ enum {
JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method
JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code
JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method
JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared
// Klass* and Method* flags
JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000,
@ -146,6 +147,8 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; }
bool has_final_method () const { return (_flags & JVM_ACC_HAS_FINAL_METHOD ) != 0; }
bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; }
bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; }
// Klass* and Method* flags
bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; }
void set_has_localvariable_table() { atomic_set_bits(JVM_ACC_HAS_LOCAL_VARIABLE_TABLE); }
@ -216,6 +219,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC {
void set_has_final_method() { atomic_set_bits(JVM_ACC_HAS_FINAL_METHOD); }
void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); }
void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); }
void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); }
public:
// field flags

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -490,7 +490,7 @@ extern "C" void blob(CodeBlob* cb) {
extern "C" void dump_vtable(address p) {
Command c("dump_vtable");
Klass* k = (Klass*)p;
k->vtable()->print();
k->vtable().print();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -294,6 +294,7 @@ protected:
};
template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
friend class VMStructs;
protected:
enum {

View File

@ -113,6 +113,7 @@ compiler/aot/DeoptimizationTest.java 8175791 windows-all
gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
gc/survivorAlignment/TestPromotionToSurvivor.java 8129886 generic-all
gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
#############################################################################
@ -121,7 +122,6 @@ gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
# This test is disabled since it will stress NMT and timeout during normal testing
runtime/NMT/MallocStressTest.java 8166548 generic-all
runtime/SharedArchiveFile/BootAppendTests.java 8150683 generic-all
runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
#############################################################################

View File

@ -27,6 +27,7 @@
* attempting to use CDS archive. JVM should exit gracefully
* when sharing mode is ON, and continue w/o sharing if sharing
* mode is AUTO.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -24,6 +24,7 @@
/**
* @test
* @summary Testing -Xbootclasspath/a support for CDS
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@ -73,7 +74,7 @@ public class BootAppendTests {
logTestCase("1");
testBootAppendModuleClass();
log("TESTCASE: 2");
logTestCase("2");
testBootAppendDuplicateModuleClass();
logTestCase("3");
@ -123,11 +124,11 @@ public class BootAppendTests {
for (String mode : modes) {
CDSOptions opts = (new CDSOptions())
.setXShareMode(mode).setUseVersion(false)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar, "-showversion")
.addSuffix(APP_CLASS, BOOT_APPEND_MODULE_CLASS_NAME);
CDSTestUtils.runWithArchive(opts)
.shouldContain("java.lang.ClassNotFoundException: javax.sound.sampled.MyClass");
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "java.lang.ClassNotFoundException: javax.sound.sampled.MyClass");
}
}
@ -144,11 +145,13 @@ public class BootAppendTests {
for (String mode : modes) {
CDSOptions opts = (new CDSOptions())
.setXShareMode(mode).setUseVersion(false)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
.addSuffix(APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
.addPrefix("--add-modules", "java.corba", "-showversion",
"-Xbootclasspath/a:" + bootAppendJar, "-cp", appJar)
.addSuffix("-Xlog:class+load=info",
APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
CDSTestUtils.runWithArchive(opts)
.shouldContain("[class,load] org.omg.CORBA.Context source: jrt:/java.corba");
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "[class,load] org.omg.CORBA.Context source: jrt:/java.corba");
}
}
@ -164,17 +167,17 @@ public class BootAppendTests {
for (String mode : modes) {
CDSOptions opts = (new CDSOptions())
.setXShareMode(mode).setUseVersion(false)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar,
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
"--limit-modules=java.base", "-cp", appJar)
.addSuffix("-Xlog:class+load=info",
APP_CLASS, BOOT_APPEND_MODULE_CLASS_NAME);
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts)
.shouldContain("[class,load] javax.sound.sampled.MyClass");
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "[class,load] javax.sound.sampled.MyClass");
// When CDS is enabled, the shared class should be loaded from the archive.
if (mode.equals("on")) {
out.shouldContain("[class,load] javax.sound.sampled.MyClass source: shared objects file");
CDSTestUtils.checkExec(out, opts, "[class,load] javax.sound.sampled.MyClass source: shared objects file");
}
}
}
@ -193,14 +196,16 @@ public class BootAppendTests {
for (String mode : modes) {
CDSOptions opts = (new CDSOptions())
.setXShareMode(mode).setUseVersion(false)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar,
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
"--limit-modules=java.base", "-cp", appJar)
.addSuffix("-Xlog:class+load=info",
APP_CLASS, BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
CDSTestUtils.runWithArchive(opts)
.shouldContain("[class,load] org.omg.CORBA.Context")
.shouldMatch(".*\\[class,load\\] org.omg.CORBA.Context source:.*bootAppend.jar");
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "[class,load] org.omg.CORBA.Context");
if (!CDSTestUtils.isUnableToMap(out)) {
out.shouldMatch(".*\\[class,load\\] org.omg.CORBA.Context source:.*bootAppend.jar");
}
}
}
@ -215,18 +220,18 @@ public class BootAppendTests {
for (String mode : modes) {
CDSOptions opts = (new CDSOptions())
.setXShareMode(mode).setUseVersion(false)
.addPrefix("-Xbootclasspath/a:" + bootAppendJar,
.addPrefix("-Xbootclasspath/a:" + bootAppendJar, "-showversion",
"--limit-modules=java.base", "-cp", appJar)
.addSuffix("-Xlog:class+load=info",
APP_CLASS, BOOT_APPEND_CLASS_NAME);
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts)
.shouldContain("[class,load] nonjdk.myPackage.MyClass");
OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
CDSTestUtils.checkExec(out, opts, "[class,load] nonjdk.myPackage.MyClass");
// If CDS is enabled, the nonjdk.myPackage.MyClass should be loaded
// from the shared archive.
if (mode.equals("on")) {
out.shouldContain(
CDSTestUtils.checkExec(out, opts,
"[class,load] nonjdk.myPackage.MyClass source: shared objects file");
}
}

View File

@ -25,6 +25,7 @@
* @test CdsDifferentCompactStrings
* @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings
* setting between archive creation time and load time.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -28,6 +28,7 @@
* This is a negative test; using object alignment for loading that
* is different from object alignment for creating a CDS file
* should fail when loading.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @bug 8025642
* @modules java.base/jdk.internal.misc

View File

@ -25,6 +25,7 @@
* @test CdsSameObjectAlignment
* @summary Testing CDS (class data sharing) using varying object alignment.
* Using same object alignment for each dump/load pair
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -24,6 +24,7 @@
/*
* @test DefaultUseWithClient
* @summary Test default behavior of sharing with -client
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -26,6 +26,7 @@
* @bug 8168790 8169870
* @summary Test CDS dumping using specific space size without crashing.
* The space size used in the test might not be suitable on windows.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @requires (os.family != "windows")
* @library /test/lib
* @modules java.base/jdk.internal.misc

View File

@ -23,6 +23,7 @@
/* @test LimitSharedSizes
* @summary Test handling of limits on shared space size
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib /runtime/CommandLine/OptionsValidation/common
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -25,6 +25,7 @@
* @test
* @bug 8066670
* @summary Testing -XX:+PrintSharedArchiveAndExit option
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -24,6 +24,7 @@
/*
* @test SASymbolTableTest
* @summary Walk symbol table using SA, with and without CDS.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* jdk.hotspot.agent/sun.jvm.hotspot.oops

View File

@ -25,6 +25,7 @@
* @test
* @bug 8014138
* @summary Testing new -XX:SharedArchiveFile=<file-name> option
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@ -40,14 +41,14 @@ import jdk.test.lib.process.OutputAnalyzer;
// methods to form command line to create/use shared archive.
public class SharedArchiveFile {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
"-Xshare:dump");
OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile");
CDSTestUtils.checkDump(out);
pb = ProcessTools.createJavaProcessBuilder(
pb = ProcessTools.createJavaProcessBuilder(true,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=./SharedArchiveFile.jsa",
"-Xshare:on", "-version");

View File

@ -25,6 +25,7 @@
* @test SharedBaseAddress
* @summary Test variety of values for SharedBaseAddress, making sure
* VM handles normal values as well as edge values w/o a crash.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -25,6 +25,7 @@
* @test
* @bug 8059510
* @summary Test SharedSymbolTableBucketSize option
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -24,6 +24,7 @@
/*
* @test SpaceUtilizationCheck
* @summary Check if the space utilization for shared spaces is adequate
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management

View File

@ -26,6 +26,7 @@
* @bug 8169711
* @summary Test interpreter method entries for intrinsics with CDS (class data sharing)
* and different settings of the intrinsic flag during dump/use of the archive.
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management