Merge
This commit is contained in:
commit
0745d10694
@ -518,10 +518,10 @@ static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ps_prochandle_ops core_ops = {
|
static ps_prochandle_ops core_ops = {
|
||||||
release: core_release,
|
.release= core_release,
|
||||||
p_pread: core_read_data,
|
.p_pread= core_read_data,
|
||||||
p_pwrite: core_write_data,
|
.p_pwrite= core_write_data,
|
||||||
get_lwp_regs: core_get_lwp_regs
|
.get_lwp_regs= core_get_lwp_regs
|
||||||
};
|
};
|
||||||
|
|
||||||
// read regs and create thread from NT_PRSTATUS entries from core file
|
// read regs and create thread from NT_PRSTATUS entries from core file
|
||||||
|
@ -291,10 +291,10 @@ static void process_cleanup(struct ps_prochandle* ph) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ps_prochandle_ops process_ops = {
|
static ps_prochandle_ops process_ops = {
|
||||||
release: process_cleanup,
|
.release= process_cleanup,
|
||||||
p_pread: process_read_data,
|
.p_pread= process_read_data,
|
||||||
p_pwrite: process_write_data,
|
.p_pwrite= process_write_data,
|
||||||
get_lwp_regs: process_get_lwp_regs
|
.get_lwp_regs= process_get_lwp_regs
|
||||||
};
|
};
|
||||||
|
|
||||||
// attach to the process. One and only one exposed stuff
|
// attach to the process. One and only one exposed stuff
|
||||||
|
@ -80,6 +80,11 @@ ifneq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
|
|||||||
MFLAGS += " LP64=1 "
|
MFLAGS += " LP64=1 "
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# pass USE_SUNCC further, through MFLAGS
|
||||||
|
ifdef USE_SUNCC
|
||||||
|
MFLAGS += " USE_SUNCC=1 "
|
||||||
|
endif
|
||||||
|
|
||||||
# The following renders pathnames in generated Makefiles valid on
|
# The following renders pathnames in generated Makefiles valid on
|
||||||
# machines other than the machine containing the build tree.
|
# machines other than the machine containing the build tree.
|
||||||
#
|
#
|
||||||
|
@ -35,6 +35,8 @@ CFLAGS += -DVM_LITTLE_ENDIAN
|
|||||||
CFLAGS += -D_LP64=1
|
CFLAGS += -D_LP64=1
|
||||||
|
|
||||||
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
|
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
|
||||||
CFLAGS += -fno-omit-frame-pointer
|
ifndef USE_SUNCC
|
||||||
|
CFLAGS += -fno-omit-frame-pointer
|
||||||
|
endif
|
||||||
|
|
||||||
OPT_CFLAGS/compactingPermGenGen.o = -O1
|
OPT_CFLAGS/compactingPermGenGen.o = -O1
|
||||||
|
@ -63,7 +63,11 @@ QUIETLY$(MAKE_VERBOSE) = @
|
|||||||
# For now, until the compiler is less wobbly:
|
# For now, until the compiler is less wobbly:
|
||||||
TESTFLAGS = -Xbatch -showversion
|
TESTFLAGS = -Xbatch -showversion
|
||||||
|
|
||||||
PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
|
ifdef USE_SUNCC
|
||||||
|
PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
|
||||||
|
else
|
||||||
|
PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH)
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef FORCE_TIERED
|
ifdef FORCE_TIERED
|
||||||
ifeq ($(VARIANT),tiered)
|
ifeq ($(VARIANT),tiered)
|
||||||
|
93
hotspot/build/linux/makefiles/sparcWorks.make
Normal file
93
hotspot/build/linux/makefiles/sparcWorks.make
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#
|
||||||
|
# Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
# have any questions.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
# CC, CPP & AS
|
||||||
|
|
||||||
|
CPP = CC
|
||||||
|
CC = cc
|
||||||
|
AS = $(CC) -c
|
||||||
|
|
||||||
|
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
|
||||||
|
ARCHFLAG/i486 = -m32
|
||||||
|
ARCHFLAG/amd64 = -m64
|
||||||
|
|
||||||
|
CFLAGS += $(ARCHFLAG)
|
||||||
|
AOUT_FLAGS += $(ARCHFLAG)
|
||||||
|
LFLAGS += $(ARCHFLAG)
|
||||||
|
ASFLAGS += $(ARCHFLAG)
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
# Compiler flags
|
||||||
|
|
||||||
|
# position-independent code
|
||||||
|
PICFLAG = -KPIC
|
||||||
|
|
||||||
|
CFLAGS += $(PICFLAG)
|
||||||
|
# no more exceptions
|
||||||
|
CFLAGS += -features=no%except
|
||||||
|
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
|
||||||
|
CFLAGS += -features=no%split_init
|
||||||
|
# allow zero sized arrays
|
||||||
|
CFLAGS += -features=zla
|
||||||
|
|
||||||
|
# Use C++ Interpreter
|
||||||
|
ifdef CC_INTERP
|
||||||
|
CFLAGS += -DCC_INTERP
|
||||||
|
endif
|
||||||
|
|
||||||
|
# We don't need libCstd.so and librwtools7.so, only libCrun.so
|
||||||
|
CFLAGS += -library=Crun
|
||||||
|
LIBS += -lCrun
|
||||||
|
|
||||||
|
CFLAGS += -mt
|
||||||
|
LFLAGS += -mt
|
||||||
|
|
||||||
|
# Compiler warnings are treated as errors
|
||||||
|
#WARNINGS_ARE_ERRORS = -errwarn=%all
|
||||||
|
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS)
|
||||||
|
# Special cases
|
||||||
|
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
|
||||||
|
|
||||||
|
# The flags to use for an Optimized build
|
||||||
|
OPT_CFLAGS+=-xO4
|
||||||
|
OPT_CFLAGS/NOOPT=-xO0
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
# Linker flags
|
||||||
|
|
||||||
|
# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
|
||||||
|
MAPFLAG = -Wl,--version-script=FILENAME
|
||||||
|
|
||||||
|
# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj
|
||||||
|
SONAMEFLAG = -h SONAME
|
||||||
|
|
||||||
|
# Build shared library
|
||||||
|
SHARED_FLAG = -G
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
# Debug flags
|
||||||
|
DEBUG_CFLAGS += -g
|
||||||
|
FASTDEBUG_CFLAGS = -g0
|
||||||
|
|
17
hotspot/build/linux/platform_amd64.suncc
Normal file
17
hotspot/build/linux/platform_amd64.suncc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
os_family = linux
|
||||||
|
|
||||||
|
arch = x86
|
||||||
|
|
||||||
|
arch_model = x86_64
|
||||||
|
|
||||||
|
os_arch = linux_x86
|
||||||
|
|
||||||
|
os_arch_model = linux_x86_64
|
||||||
|
|
||||||
|
lib_arch = amd64
|
||||||
|
|
||||||
|
compiler = sparcWorks
|
||||||
|
|
||||||
|
gnu_dis_arch = amd64
|
||||||
|
|
||||||
|
sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DAMD64
|
17
hotspot/build/linux/platform_i486.suncc
Normal file
17
hotspot/build/linux/platform_i486.suncc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
os_family = linux
|
||||||
|
|
||||||
|
arch = x86
|
||||||
|
|
||||||
|
arch_model = x86_32
|
||||||
|
|
||||||
|
os_arch = linux_x86
|
||||||
|
|
||||||
|
os_arch_model = linux_x86_32
|
||||||
|
|
||||||
|
lib_arch = i386
|
||||||
|
|
||||||
|
compiler = sparcWorks
|
||||||
|
|
||||||
|
gnu_dis_arch = i386
|
||||||
|
|
||||||
|
sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DIA32
|
@ -1304,7 +1304,7 @@ void Assembler::movl(Address dst, Register src) {
|
|||||||
emit_operand(src, dst);
|
emit_operand(src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::mov64(Register dst, int64_t imm64) {
|
void Assembler::mov64(Register dst, intptr_t imm64) {
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
int encode = prefixq_and_encode(dst->encoding());
|
int encode = prefixq_and_encode(dst->encoding());
|
||||||
emit_byte(0xB8 | encode);
|
emit_byte(0xB8 | encode);
|
||||||
@ -1331,7 +1331,7 @@ void Assembler::movq(Register dst, Address src) {
|
|||||||
emit_operand(dst, src);
|
emit_operand(dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::mov64(Address dst, int64_t imm32) {
|
void Assembler::mov64(Address dst, intptr_t imm32) {
|
||||||
assert(is_simm32(imm32), "lost bits");
|
assert(is_simm32(imm32), "lost bits");
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
prefixq(dst);
|
prefixq(dst);
|
||||||
|
@ -232,7 +232,7 @@ LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
|
|||||||
// where <ver> is the protocol version (1), <cmd> is the command
|
// where <ver> is the protocol version (1), <cmd> is the command
|
||||||
// name ("load", "datadump", ...), and <arg> is an argument
|
// name ("load", "datadump", ...), and <arg> is an argument
|
||||||
int expected_str_count = 2 + AttachOperation::arg_count_max;
|
int expected_str_count = 2 + AttachOperation::arg_count_max;
|
||||||
int max_len = (strlen(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
|
const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
|
||||||
AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
|
AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
|
||||||
|
|
||||||
char buf[max_len];
|
char buf[max_len];
|
||||||
|
@ -60,7 +60,18 @@ inline u4 Bytes::swap_u4(u4 x) {
|
|||||||
|
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
inline u8 Bytes::swap_u8(u8 x) {
|
inline u8 Bytes::swap_u8(u8 x) {
|
||||||
|
#ifdef SPARC_WORKS
|
||||||
|
// workaround for SunStudio12 CR6615391
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"bswapq %0"
|
||||||
|
:"=r" (x) // output : register 0 => x
|
||||||
|
:"0" (x) // input : x => register 0
|
||||||
|
:"0" // clobbered register
|
||||||
|
);
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
return bswap_64(x);
|
return bswap_64(x);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Helper function for swap_u8
|
// Helper function for swap_u8
|
||||||
|
@ -62,8 +62,14 @@
|
|||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
|
|
||||||
address os::current_stack_pointer() {
|
address os::current_stack_pointer() {
|
||||||
|
#ifdef SPARC_WORKS
|
||||||
|
register void *esp;
|
||||||
|
__asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
|
||||||
|
return (address) ((char*)esp + sizeof(long)*2);
|
||||||
|
#else
|
||||||
register void *esp __asm__ (SPELL_REG_SP);
|
register void *esp __asm__ (SPELL_REG_SP);
|
||||||
return (address) esp;
|
return (address) esp;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char* os::non_memory_address_word() {
|
char* os::non_memory_address_word() {
|
||||||
@ -139,7 +145,12 @@ frame os::get_sender_for_C_frame(frame* fr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
intptr_t* _get_previous_fp() {
|
intptr_t* _get_previous_fp() {
|
||||||
|
#ifdef SPARC_WORKS
|
||||||
|
register intptr_t **ebp;
|
||||||
|
__asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
|
||||||
|
#else
|
||||||
register intptr_t **ebp __asm__ (SPELL_REG_FP);
|
register intptr_t **ebp __asm__ (SPELL_REG_FP);
|
||||||
|
#endif
|
||||||
return (intptr_t*) *ebp; // we want what it points to.
|
return (intptr_t*) *ebp; // we want what it points to.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +571,9 @@ bool os::Linux::supports_variable_stack_size() { return true; }
|
|||||||
#else
|
#else
|
||||||
size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
|
size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
|
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test if pthread library can support variable thread stack size. LinuxThreads
|
// Test if pthread library can support variable thread stack size. LinuxThreads
|
||||||
// in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
|
// in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
|
||||||
@ -591,7 +604,11 @@ bool os::Linux::supports_variable_stack_size() {
|
|||||||
// return true and skip _thread_safety_check(), so we may not be able to
|
// return true and skip _thread_safety_check(), so we may not be able to
|
||||||
// detect stack-heap collisions. But otherwise it's harmless.
|
// detect stack-heap collisions. But otherwise it's harmless.
|
||||||
//
|
//
|
||||||
|
#ifdef __GNUC__
|
||||||
return (GET_GS() != 0);
|
return (GET_GS() != 0);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // AMD64
|
#endif // AMD64
|
||||||
|
@ -155,8 +155,8 @@ bool Dictionary::do_unloading(BoolObjectClosure* is_alive) {
|
|||||||
for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
|
for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
|
||||||
// check the previous versions array for GC'ed weak refs
|
// check the previous versions array for GC'ed weak refs
|
||||||
PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
|
PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
|
||||||
jweak cp_ref = pv_node->prev_constant_pool();
|
jobject cp_ref = pv_node->prev_constant_pool();
|
||||||
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
|
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
|
||||||
if (cp_ref == NULL) {
|
if (cp_ref == NULL) {
|
||||||
delete pv_node;
|
delete pv_node;
|
||||||
ik->previous_versions()->remove_at(i);
|
ik->previous_versions()->remove_at(i);
|
||||||
|
@ -3067,6 +3067,7 @@ oopMap.hpp vmreg.hpp
|
|||||||
|
|
||||||
oopMapCache.cpp allocation.inline.hpp
|
oopMapCache.cpp allocation.inline.hpp
|
||||||
oopMapCache.cpp handles.inline.hpp
|
oopMapCache.cpp handles.inline.hpp
|
||||||
|
oopMapCache.cpp jvmtiRedefineClassesTrace.hpp
|
||||||
oopMapCache.cpp oop.inline.hpp
|
oopMapCache.cpp oop.inline.hpp
|
||||||
oopMapCache.cpp oopMapCache.hpp
|
oopMapCache.cpp oopMapCache.hpp
|
||||||
oopMapCache.cpp resourceArea.hpp
|
oopMapCache.cpp resourceArea.hpp
|
||||||
|
@ -532,6 +532,10 @@ void OopMapCache::flush_obsolete_entries() {
|
|||||||
if (!_array[i].is_empty() && _array[i].method()->is_old()) {
|
if (!_array[i].is_empty() && _array[i].method()->is_old()) {
|
||||||
// Cache entry is occupied by an old redefined method and we don't want
|
// Cache entry is occupied by an old redefined method and we don't want
|
||||||
// to pin it down so flush the entry.
|
// to pin it down so flush the entry.
|
||||||
|
RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
|
||||||
|
_array[i].method()->name()->as_C_string(),
|
||||||
|
_array[i].method()->signature()->as_C_string(), i));
|
||||||
|
|
||||||
_array[i].flush();
|
_array[i].flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -577,6 +581,15 @@ void OopMapCache::lookup(methodHandle method,
|
|||||||
// Entry is not in hashtable.
|
// Entry is not in hashtable.
|
||||||
// Compute entry and return it
|
// Compute entry and return it
|
||||||
|
|
||||||
|
if (method->should_not_be_cached()) {
|
||||||
|
// It is either not safe or not a good idea to cache this methodOop
|
||||||
|
// at this time. We give the caller of lookup() a copy of the
|
||||||
|
// interesting info via parameter entry_for, but we don't add it to
|
||||||
|
// the cache. See the gory details in methodOop.cpp.
|
||||||
|
compute_one_oop_map(method, bci, entry_for);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// First search for an empty slot
|
// First search for an empty slot
|
||||||
for(i = 0; i < _probe_depth; i++) {
|
for(i = 0; i < _probe_depth; i++) {
|
||||||
entry = entry_at(probe + i);
|
entry = entry_at(probe + i);
|
||||||
@ -584,12 +597,6 @@ void OopMapCache::lookup(methodHandle method,
|
|||||||
entry->fill(method, bci);
|
entry->fill(method, bci);
|
||||||
entry_for->resource_copy(entry);
|
entry_for->resource_copy(entry);
|
||||||
assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
|
assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
|
||||||
if (method->is_old()) {
|
|
||||||
// The caller of lookup() will receive a copy of the interesting
|
|
||||||
// info via entry_for, but we don't keep an old redefined method in
|
|
||||||
// the cache to avoid pinning down the method.
|
|
||||||
entry->flush();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -623,13 +630,6 @@ void OopMapCache::lookup(methodHandle method,
|
|||||||
}
|
}
|
||||||
assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
|
assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
|
||||||
|
|
||||||
if (method->is_old()) {
|
|
||||||
// The caller of lookup() will receive a copy of the interesting
|
|
||||||
// info via entry_for, but we don't keep an old redefined method in
|
|
||||||
// the cache to avoid pinning down the method.
|
|
||||||
entry->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +26,27 @@
|
|||||||
#include "incls/_compactingPermGenGen.cpp.incl"
|
#include "incls/_compactingPermGenGen.cpp.incl"
|
||||||
|
|
||||||
|
|
||||||
// Recursively adjust all pointers in an object and all objects by
|
// An ObjectClosure helper: Recursively adjust all pointers in an object
|
||||||
// referenced it. Clear marks on objects in order to prevent visiting
|
// and all objects by referenced it. Clear marks on objects in order to
|
||||||
// any object twice.
|
// prevent visiting any object twice. This helper is used when the
|
||||||
|
// RedefineClasses() API has been called.
|
||||||
|
|
||||||
|
class AdjustSharedObjectClosure : public ObjectClosure {
|
||||||
|
public:
|
||||||
|
void do_object(oop obj) {
|
||||||
|
if (obj->is_shared_readwrite()) {
|
||||||
|
if (obj->mark()->is_marked()) {
|
||||||
|
obj->init_mark(); // Don't revisit this object.
|
||||||
|
obj->adjust_pointers(); // Adjust this object's references.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// An OopClosure helper: Recursively adjust all pointers in an object
|
||||||
|
// and all objects by referenced it. Clear marks on objects in order
|
||||||
|
// to prevent visiting any object twice.
|
||||||
|
|
||||||
class RecursiveAdjustSharedObjectClosure : public OopClosure {
|
class RecursiveAdjustSharedObjectClosure : public OopClosure {
|
||||||
public:
|
public:
|
||||||
@ -274,15 +292,34 @@ CompactingPermGenGen::CompactingPermGenGen(ReservedSpace rs,
|
|||||||
// objects in the space will page in more objects than we need.
|
// objects in the space will page in more objects than we need.
|
||||||
// Instead, use the system dictionary as strong roots into the read
|
// Instead, use the system dictionary as strong roots into the read
|
||||||
// write space.
|
// write space.
|
||||||
|
//
|
||||||
|
// If a RedefineClasses() call has been made, then we have to iterate
|
||||||
|
// over the entire shared read-write space in order to find all the
|
||||||
|
// objects that need to be forwarded. For example, it is possible for
|
||||||
|
// an nmethod to be found and marked in GC phase-1 only for the nmethod
|
||||||
|
// to be freed by the time we reach GC phase-3. The underlying method
|
||||||
|
// is still marked, but we can't (easily) find it in GC phase-3 so we
|
||||||
|
// blow up in GC phase-4. With RedefineClasses() we want replaced code
|
||||||
|
// (EMCP or obsolete) to go away (i.e., be collectible) once it is no
|
||||||
|
// longer being executed by any thread so we keep minimal attachments
|
||||||
|
// to the replaced code. However, we can't guarantee when those EMCP
|
||||||
|
// or obsolete methods will be collected so they may still be out there
|
||||||
|
// even after we've severed our minimal attachments.
|
||||||
|
|
||||||
void CompactingPermGenGen::pre_adjust_pointers() {
|
void CompactingPermGenGen::pre_adjust_pointers() {
|
||||||
if (spec()->enable_shared_spaces()) {
|
if (spec()->enable_shared_spaces()) {
|
||||||
RecursiveAdjustSharedObjectClosure blk;
|
if (JvmtiExport::has_redefined_a_class()) {
|
||||||
Universe::oops_do(&blk);
|
// RedefineClasses() requires a brute force approach
|
||||||
StringTable::oops_do(&blk);
|
AdjustSharedObjectClosure blk;
|
||||||
SystemDictionary::always_strong_classes_do(&blk);
|
rw_space()->object_iterate(&blk);
|
||||||
TraversePlaceholdersClosure tpc;
|
} else {
|
||||||
SystemDictionary::placeholders_do(&tpc);
|
RecursiveAdjustSharedObjectClosure blk;
|
||||||
|
Universe::oops_do(&blk);
|
||||||
|
StringTable::oops_do(&blk);
|
||||||
|
SystemDictionary::always_strong_classes_do(&blk);
|
||||||
|
TraversePlaceholdersClosure tpc;
|
||||||
|
SystemDictionary::placeholders_do(&tpc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,7 +972,6 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan
|
|||||||
// These allocations will have to be freed if they are unused.
|
// These allocations will have to be freed if they are unused.
|
||||||
|
|
||||||
// Allocate a new array of methods.
|
// Allocate a new array of methods.
|
||||||
jmethodID* to_dealloc_jmeths = NULL;
|
|
||||||
jmethodID* new_jmeths = NULL;
|
jmethodID* new_jmeths = NULL;
|
||||||
if (length <= idnum) {
|
if (length <= idnum) {
|
||||||
// A new array will be needed (unless some other thread beats us to it)
|
// A new array will be needed (unless some other thread beats us to it)
|
||||||
@ -983,7 +982,6 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new method ID.
|
// Allocate a new method ID.
|
||||||
jmethodID to_dealloc_id = NULL;
|
|
||||||
jmethodID new_id = NULL;
|
jmethodID new_id = NULL;
|
||||||
if (method_h->is_old() && !method_h->is_obsolete()) {
|
if (method_h->is_old() && !method_h->is_obsolete()) {
|
||||||
// The method passed in is old (but not obsolete), we need to use the current version
|
// The method passed in is old (but not obsolete), we need to use the current version
|
||||||
@ -997,40 +995,51 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan
|
|||||||
new_id = JNIHandles::make_jmethod_id(method_h);
|
new_id = JNIHandles::make_jmethod_id(method_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
|
||||||
|
// No need and unsafe to lock the JmethodIdCreation_lock at safepoint.
|
||||||
|
id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
|
||||||
|
} else {
|
||||||
MutexLocker ml(JmethodIdCreation_lock);
|
MutexLocker ml(JmethodIdCreation_lock);
|
||||||
|
id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
|
||||||
// We must not go to a safepoint while holding this lock.
|
|
||||||
debug_only(No_Safepoint_Verifier nosafepoints;)
|
|
||||||
|
|
||||||
// Retry lookup after we got the lock
|
|
||||||
jmeths = ik_h->methods_jmethod_ids_acquire();
|
|
||||||
if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
|
|
||||||
if (jmeths != NULL) {
|
|
||||||
// We have grown the array: copy the existing entries, and delete the old array
|
|
||||||
for (size_t index = 0; index < length; index++) {
|
|
||||||
new_jmeths[index+1] = jmeths[index+1];
|
|
||||||
}
|
|
||||||
to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
|
|
||||||
}
|
|
||||||
ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
|
|
||||||
} else {
|
|
||||||
id = jmeths[idnum+1];
|
|
||||||
to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
|
|
||||||
}
|
|
||||||
if (id == NULL) {
|
|
||||||
id = new_id;
|
|
||||||
jmeths[idnum+1] = id; // install the new method ID
|
|
||||||
} else {
|
|
||||||
to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
// Free up unneeded or no longer needed resources
|
|
||||||
FreeHeap(to_dealloc_jmeths);
|
jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
|
||||||
if (to_dealloc_id != NULL) {
|
jmethodID new_id, jmethodID* new_jmeths) {
|
||||||
JNIHandles::destroy_jmethod_id(to_dealloc_id);
|
// Retry lookup after we got the lock or ensured we are at safepoint
|
||||||
|
jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
|
||||||
|
jmethodID id = NULL;
|
||||||
|
jmethodID to_dealloc_id = NULL;
|
||||||
|
jmethodID* to_dealloc_jmeths = NULL;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) {
|
||||||
|
if (jmeths != NULL) {
|
||||||
|
// We have grown the array: copy the existing entries, and delete the old array
|
||||||
|
for (size_t index = 0; index < length; index++) {
|
||||||
|
new_jmeths[index+1] = jmeths[index+1];
|
||||||
|
}
|
||||||
|
to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one
|
||||||
}
|
}
|
||||||
|
ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths);
|
||||||
|
} else {
|
||||||
|
id = jmeths[idnum+1];
|
||||||
|
to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one
|
||||||
|
}
|
||||||
|
if (id == NULL) {
|
||||||
|
id = new_id;
|
||||||
|
jmeths[idnum+1] = id; // install the new method ID
|
||||||
|
} else {
|
||||||
|
to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free up unneeded or no longer needed resources
|
||||||
|
FreeHeap(to_dealloc_jmeths);
|
||||||
|
if (to_dealloc_id != NULL) {
|
||||||
|
JNIHandles::destroy_jmethod_id(to_dealloc_id);
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -2187,12 +2196,20 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
|
|||||||
RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
|
RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
|
||||||
ikh->external_name(), _previous_versions->length(), emcp_method_count));
|
ikh->external_name(), _previous_versions->length(), emcp_method_count));
|
||||||
constantPoolHandle cp_h(ikh->constants());
|
constantPoolHandle cp_h(ikh->constants());
|
||||||
jweak cp_ref = JNIHandles::make_weak_global(cp_h);
|
jobject cp_ref;
|
||||||
|
if (cp_h->is_shared()) {
|
||||||
|
// a shared ConstantPool requires a regular reference; a weak
|
||||||
|
// reference would be collectible
|
||||||
|
cp_ref = JNIHandles::make_global(cp_h);
|
||||||
|
} else {
|
||||||
|
cp_ref = JNIHandles::make_weak_global(cp_h);
|
||||||
|
}
|
||||||
PreviousVersionNode * pv_node = NULL;
|
PreviousVersionNode * pv_node = NULL;
|
||||||
objArrayOop old_methods = ikh->methods();
|
objArrayOop old_methods = ikh->methods();
|
||||||
|
|
||||||
if (emcp_method_count == 0) {
|
if (emcp_method_count == 0) {
|
||||||
pv_node = new PreviousVersionNode(cp_ref, NULL);
|
// non-shared ConstantPool gets a weak reference
|
||||||
|
pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
|
||||||
RC_TRACE(0x00000400,
|
RC_TRACE(0x00000400,
|
||||||
("add: all methods are obsolete; flushing any EMCP weak refs"));
|
("add: all methods are obsolete; flushing any EMCP weak refs"));
|
||||||
} else {
|
} else {
|
||||||
@ -2212,7 +2229,8 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pv_node = new PreviousVersionNode(cp_ref, method_refs);
|
// non-shared ConstantPool gets a weak reference
|
||||||
|
pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
_previous_versions->append(pv_node);
|
_previous_versions->append(pv_node);
|
||||||
@ -2230,7 +2248,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
|
|||||||
// check the previous versions array for a GC'ed weak refs
|
// check the previous versions array for a GC'ed weak refs
|
||||||
pv_node = _previous_versions->at(i);
|
pv_node = _previous_versions->at(i);
|
||||||
cp_ref = pv_node->prev_constant_pool();
|
cp_ref = pv_node->prev_constant_pool();
|
||||||
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
|
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
|
||||||
if (cp_ref == NULL) {
|
if (cp_ref == NULL) {
|
||||||
delete pv_node;
|
delete pv_node;
|
||||||
_previous_versions->remove_at(i);
|
_previous_versions->remove_at(i);
|
||||||
@ -2303,7 +2321,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
|
|||||||
// check the previous versions array for a GC'ed weak refs
|
// check the previous versions array for a GC'ed weak refs
|
||||||
pv_node = _previous_versions->at(j);
|
pv_node = _previous_versions->at(j);
|
||||||
cp_ref = pv_node->prev_constant_pool();
|
cp_ref = pv_node->prev_constant_pool();
|
||||||
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
|
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
|
||||||
if (cp_ref == NULL) {
|
if (cp_ref == NULL) {
|
||||||
delete pv_node;
|
delete pv_node;
|
||||||
_previous_versions->remove_at(j);
|
_previous_versions->remove_at(j);
|
||||||
@ -2401,8 +2419,8 @@ bool instanceKlass::has_previous_version() const {
|
|||||||
// been GC'ed
|
// been GC'ed
|
||||||
PreviousVersionNode * pv_node = _previous_versions->at(i);
|
PreviousVersionNode * pv_node = _previous_versions->at(i);
|
||||||
|
|
||||||
jweak cp_ref = pv_node->prev_constant_pool();
|
jobject cp_ref = pv_node->prev_constant_pool();
|
||||||
assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
|
assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
|
||||||
if (cp_ref == NULL) {
|
if (cp_ref == NULL) {
|
||||||
continue; // robustness
|
continue; // robustness
|
||||||
}
|
}
|
||||||
@ -2462,10 +2480,11 @@ void instanceKlass::set_methods_annotations_of(int idnum, typeArrayOop anno, obj
|
|||||||
|
|
||||||
// Construct a PreviousVersionNode entry for the array hung off
|
// Construct a PreviousVersionNode entry for the array hung off
|
||||||
// the instanceKlass.
|
// the instanceKlass.
|
||||||
PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
|
PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
|
||||||
GrowableArray<jweak>* prev_EMCP_methods) {
|
bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
|
||||||
|
|
||||||
_prev_constant_pool = prev_constant_pool;
|
_prev_constant_pool = prev_constant_pool;
|
||||||
|
_prev_cp_is_weak = prev_cp_is_weak;
|
||||||
_prev_EMCP_methods = prev_EMCP_methods;
|
_prev_EMCP_methods = prev_EMCP_methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2473,7 +2492,11 @@ PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
|
|||||||
// Destroy a PreviousVersionNode
|
// Destroy a PreviousVersionNode
|
||||||
PreviousVersionNode::~PreviousVersionNode() {
|
PreviousVersionNode::~PreviousVersionNode() {
|
||||||
if (_prev_constant_pool != NULL) {
|
if (_prev_constant_pool != NULL) {
|
||||||
JNIHandles::destroy_weak_global(_prev_constant_pool);
|
if (_prev_cp_is_weak) {
|
||||||
|
JNIHandles::destroy_weak_global(_prev_constant_pool);
|
||||||
|
} else {
|
||||||
|
JNIHandles::destroy_global(_prev_constant_pool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_prev_EMCP_methods != NULL) {
|
if (_prev_EMCP_methods != NULL) {
|
||||||
@ -2493,8 +2516,8 @@ PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
|
|||||||
_prev_constant_pool_handle = constantPoolHandle(); // NULL handle
|
_prev_constant_pool_handle = constantPoolHandle(); // NULL handle
|
||||||
_prev_EMCP_method_handles = NULL;
|
_prev_EMCP_method_handles = NULL;
|
||||||
|
|
||||||
jweak cp_ref = pv_node->prev_constant_pool();
|
jobject cp_ref = pv_node->prev_constant_pool();
|
||||||
assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
|
assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
|
||||||
if (cp_ref == NULL) {
|
if (cp_ref == NULL) {
|
||||||
return; // robustness
|
return; // robustness
|
||||||
}
|
}
|
||||||
|
@ -432,6 +432,8 @@ class instanceKlass: public Klass {
|
|||||||
_enclosing_method_method_index = method_index; }
|
_enclosing_method_method_index = method_index; }
|
||||||
|
|
||||||
// jmethodID support
|
// jmethodID support
|
||||||
|
static jmethodID get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
|
||||||
|
jmethodID new_id, jmethodID* new_jmeths);
|
||||||
static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h);
|
static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h);
|
||||||
jmethodID jmethod_id_or_null(methodOop method);
|
jmethodID jmethod_id_or_null(methodOop method);
|
||||||
|
|
||||||
@ -838,11 +840,20 @@ class BreakpointInfo;
|
|||||||
// A collection point for interesting information about the previous
|
// A collection point for interesting information about the previous
|
||||||
// version(s) of an instanceKlass. This class uses weak references to
|
// version(s) of an instanceKlass. This class uses weak references to
|
||||||
// the information so that the information may be collected as needed
|
// the information so that the information may be collected as needed
|
||||||
// by the system. A GrowableArray of PreviousVersionNodes is attached
|
// by the system. If the information is shared, then a regular
|
||||||
|
// reference must be used because a weak reference would be seen as
|
||||||
|
// collectible. A GrowableArray of PreviousVersionNodes is attached
|
||||||
// to the instanceKlass as needed. See PreviousVersionWalker below.
|
// to the instanceKlass as needed. See PreviousVersionWalker below.
|
||||||
class PreviousVersionNode : public CHeapObj {
|
class PreviousVersionNode : public CHeapObj {
|
||||||
private:
|
private:
|
||||||
jweak _prev_constant_pool;
|
// A shared ConstantPool is never collected so we'll always have
|
||||||
|
// a reference to it so we can update items in the cache. We'll
|
||||||
|
// have a weak reference to a non-shared ConstantPool until all
|
||||||
|
// of the methods (EMCP or obsolete) have been collected; the
|
||||||
|
// non-shared ConstantPool becomes collectible at that point.
|
||||||
|
jobject _prev_constant_pool; // regular or weak reference
|
||||||
|
bool _prev_cp_is_weak; // true if not a shared ConstantPool
|
||||||
|
|
||||||
// If the previous version of the instanceKlass doesn't have any
|
// If the previous version of the instanceKlass doesn't have any
|
||||||
// EMCP methods, then _prev_EMCP_methods will be NULL. If all the
|
// EMCP methods, then _prev_EMCP_methods will be NULL. If all the
|
||||||
// EMCP methods have been collected, then _prev_EMCP_methods can
|
// EMCP methods have been collected, then _prev_EMCP_methods can
|
||||||
@ -850,10 +861,10 @@ class PreviousVersionNode : public CHeapObj {
|
|||||||
GrowableArray<jweak>* _prev_EMCP_methods;
|
GrowableArray<jweak>* _prev_EMCP_methods;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PreviousVersionNode(jweak prev_constant_pool,
|
PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
|
||||||
GrowableArray<jweak>* prev_EMCP_methods);
|
GrowableArray<jweak>* prev_EMCP_methods);
|
||||||
~PreviousVersionNode();
|
~PreviousVersionNode();
|
||||||
jweak prev_constant_pool() const {
|
jobject prev_constant_pool() const {
|
||||||
return _prev_constant_pool;
|
return _prev_constant_pool;
|
||||||
}
|
}
|
||||||
GrowableArray<jweak>* prev_EMCP_methods() const {
|
GrowableArray<jweak>* prev_EMCP_methods() const {
|
||||||
|
@ -37,3 +37,32 @@ void markOopDesc::print_on(outputStream* st) const {
|
|||||||
st->print("age %d)", age());
|
st->print("age %d)", age());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Give advice about whether the oop that contains this markOop
|
||||||
|
// should be cached or not.
|
||||||
|
bool markOopDesc::should_not_be_cached() const {
|
||||||
|
// the cast is because decode_pointer() isn't marked const
|
||||||
|
if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) {
|
||||||
|
// If the oop containing this markOop is being forwarded, then
|
||||||
|
// we are in the middle of GC and we do not want the containing
|
||||||
|
// oop to be added to a cache. We have no way of knowing whether
|
||||||
|
// the cache has already been visited by the current GC phase so
|
||||||
|
// we don't know whether the forwarded oop will be properly
|
||||||
|
// processed in this phase. If the forwarded oop is not properly
|
||||||
|
// processed, then we'll see strange crashes or asserts during
|
||||||
|
// the next GC run because the markOop will contain an unexpected
|
||||||
|
// value.
|
||||||
|
//
|
||||||
|
// This situation has been seen when we are GC'ing a methodOop
|
||||||
|
// because we use the methodOop while we're GC'ing it. Scary
|
||||||
|
// stuff. Some of the uses the methodOop cause the methodOop to
|
||||||
|
// be added to the OopMapCache in the instanceKlass as a side
|
||||||
|
// effect. This check lets the cache maintainer know when a
|
||||||
|
// cache addition would not be safe.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// caching the containing oop should be just fine
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -357,4 +357,7 @@ class markOopDesc: public oopDesc {
|
|||||||
|
|
||||||
// Recover address of oop from encoded form used in mark
|
// Recover address of oop from encoded form used in mark
|
||||||
inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
|
inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
|
||||||
|
|
||||||
|
// see the definition in markOop.cpp for the gory details
|
||||||
|
bool should_not_be_cached() const;
|
||||||
};
|
};
|
||||||
|
@ -765,6 +765,28 @@ bool methodOopDesc::is_overridden_in(klassOop k) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// give advice about whether this methodOop should be cached or not
|
||||||
|
bool methodOopDesc::should_not_be_cached() const {
|
||||||
|
if (is_old()) {
|
||||||
|
// This method has been redefined. It is either EMCP or obsolete
|
||||||
|
// and we don't want to cache it because that would pin the method
|
||||||
|
// down and prevent it from being collectible if and when it
|
||||||
|
// finishes executing.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mark()->should_not_be_cached()) {
|
||||||
|
// It is either not safe or not a good idea to cache this
|
||||||
|
// method at this time because of the state of the embedded
|
||||||
|
// markOop. See markOop.cpp for the gory details.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// caching this method should be just fine
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
|
methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
|
||||||
u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
|
u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
|
||||||
// Code below does not work for native methods - they should never get rewritten anyway
|
// Code below does not work for native methods - they should never get rewritten anyway
|
||||||
|
@ -524,6 +524,8 @@ class methodOopDesc : public oopDesc {
|
|||||||
void set_is_old() { _access_flags.set_is_old(); }
|
void set_is_old() { _access_flags.set_is_old(); }
|
||||||
bool is_obsolete() const { return access_flags().is_obsolete(); }
|
bool is_obsolete() const { return access_flags().is_obsolete(); }
|
||||||
void set_is_obsolete() { _access_flags.set_is_obsolete(); }
|
void set_is_obsolete() { _access_flags.set_is_obsolete(); }
|
||||||
|
// see the definition in methodOop.cpp for the gory details
|
||||||
|
bool should_not_be_cached() const;
|
||||||
|
|
||||||
// JVMTI Native method prefixing support:
|
// JVMTI Native method prefixing support:
|
||||||
bool is_prefixed_native() const { return access_flags().is_prefixed_native(); }
|
bool is_prefixed_native() const { return access_flags().is_prefixed_native(); }
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
// 0x01000000 | 16777216 - impl details: nmethod evolution info
|
// 0x01000000 | 16777216 - impl details: nmethod evolution info
|
||||||
// 0x02000000 | 33554432 - impl details: annotation updates
|
// 0x02000000 | 33554432 - impl details: annotation updates
|
||||||
// 0x04000000 | 67108864 - impl details: StackMapTable updates
|
// 0x04000000 | 67108864 - impl details: StackMapTable updates
|
||||||
// 0x08000000 | 134217728 - unused
|
// 0x08000000 | 134217728 - impl details: OopMapCache updates
|
||||||
// 0x10000000 | 268435456 - unused
|
// 0x10000000 | 268435456 - unused
|
||||||
// 0x20000000 | 536870912 - unused
|
// 0x20000000 | 536870912 - unused
|
||||||
// 0x40000000 | 1073741824 - unused
|
// 0x40000000 | 1073741824 - unused
|
||||||
|
@ -1548,10 +1548,11 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle
|
|||||||
}
|
}
|
||||||
|
|
||||||
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
|
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
|
||||||
if (!klass->methods()->is_within_bounds(slot)) {
|
methodOop m = klass->method_with_idnum(slot);
|
||||||
|
if (m == NULL) {
|
||||||
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
|
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
|
||||||
}
|
}
|
||||||
methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
|
methodHandle method(THREAD, m);
|
||||||
|
|
||||||
return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
|
return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD);
|
||||||
}
|
}
|
||||||
@ -1564,10 +1565,11 @@ oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args,
|
|||||||
objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
|
objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror)));
|
||||||
|
|
||||||
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
|
instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror));
|
||||||
if (!klass->methods()->is_within_bounds(slot)) {
|
methodOop m = klass->method_with_idnum(slot);
|
||||||
|
if (m == NULL) {
|
||||||
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
|
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
|
||||||
}
|
}
|
||||||
methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
|
methodHandle method(THREAD, m);
|
||||||
assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
|
assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
|
||||||
|
|
||||||
// Make sure klass gets initialize
|
// Make sure klass gets initialize
|
||||||
|
@ -1317,10 +1317,6 @@ JavaThread::~JavaThread() {
|
|||||||
ThreadSafepointState::destroy(this);
|
ThreadSafepointState::destroy(this);
|
||||||
if (_thread_profiler != NULL) delete _thread_profiler;
|
if (_thread_profiler != NULL) delete _thread_profiler;
|
||||||
if (_thread_stat != NULL) delete _thread_stat;
|
if (_thread_stat != NULL) delete _thread_stat;
|
||||||
|
|
||||||
if (jvmti_thread_state() != NULL) {
|
|
||||||
JvmtiExport::cleanup_thread(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1571,6 +1567,10 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
|||||||
tlab().make_parsable(true); // retire TLAB
|
tlab().make_parsable(true); // retire TLAB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jvmti_thread_state() != NULL) {
|
||||||
|
JvmtiExport::cleanup_thread(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
|
||||||
Threads::remove(this);
|
Threads::remove(this);
|
||||||
}
|
}
|
||||||
|
@ -37,23 +37,45 @@
|
|||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <wchar.h>
|
# include <wchar.h>
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
|
#ifdef SOLARIS
|
||||||
# include <ieeefp.h>
|
# include <ieeefp.h>
|
||||||
|
#endif
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
|
#ifdef LINUX
|
||||||
|
#ifndef FP_PZERO
|
||||||
|
// Linux doesn't have positive/negative zero
|
||||||
|
#define FP_PZERO FP_ZERO
|
||||||
|
#endif
|
||||||
|
#ifndef fpclass
|
||||||
|
#define fpclass fpclassify
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
|
#ifdef SOLARIS
|
||||||
# include <thread.h>
|
# include <thread.h>
|
||||||
|
#endif
|
||||||
# include <limits.h>
|
# include <limits.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
#ifdef SOLARIS
|
||||||
# include <sys/trap.h>
|
# include <sys/trap.h>
|
||||||
# include <sys/regset.h>
|
# include <sys/regset.h>
|
||||||
# include <sys/procset.h>
|
# include <sys/procset.h>
|
||||||
# include <ucontext.h>
|
# include <ucontext.h>
|
||||||
# include <setjmp.h>
|
# include <setjmp.h>
|
||||||
|
#endif
|
||||||
# ifdef SOLARIS_MUTATOR_LIBTHREAD
|
# ifdef SOLARIS_MUTATOR_LIBTHREAD
|
||||||
# include <sys/procfs.h>
|
# include <sys/procfs.h>
|
||||||
# endif
|
# endif
|
||||||
|
#ifdef LINUX
|
||||||
|
# include <inttypes.h>
|
||||||
|
# include <signal.h>
|
||||||
|
# include <ucontext.h>
|
||||||
|
# include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures
|
// 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures
|
||||||
// When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in
|
// When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in
|
||||||
@ -68,6 +90,11 @@
|
|||||||
// pointer when it extracts the argument, then we have a problem.
|
// pointer when it extracts the argument, then we have a problem.
|
||||||
//
|
//
|
||||||
// Solution: For 64-bit architectures, redefine NULL as 64-bit constant 0.
|
// Solution: For 64-bit architectures, redefine NULL as 64-bit constant 0.
|
||||||
|
//
|
||||||
|
// Note: this fix doesn't work well on Linux because NULL will be overwritten
|
||||||
|
// whenever a system header file is included. Linux handles NULL correctly
|
||||||
|
// through a special type '__null'.
|
||||||
|
#ifdef SOLARIS
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
#undef NULL
|
#undef NULL
|
||||||
#define NULL 0L
|
#define NULL 0L
|
||||||
@ -76,13 +103,25 @@
|
|||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// NULL vs NULL_WORD:
|
// NULL vs NULL_WORD:
|
||||||
// On Linux NULL is defined as a special type '__null'. Assigning __null to
|
// On Linux NULL is defined as a special type '__null'. Assigning __null to
|
||||||
// integer variable will cause gcc warning. Use NULL_WORD in places where a
|
// integer variable will cause gcc warning. Use NULL_WORD in places where a
|
||||||
// pointer is stored as integer value.
|
// pointer is stored as integer value. On some platforms, sizeof(intptr_t) >
|
||||||
#define NULL_WORD NULL
|
// sizeof(void*), so here we want something which is integer type, but has the
|
||||||
|
// same size as a pointer.
|
||||||
|
#ifdef LINUX
|
||||||
|
#ifdef _LP64
|
||||||
|
#define NULL_WORD 0L
|
||||||
|
#else
|
||||||
|
#define NULL_WORD 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define NULL_WORD NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LINUX
|
||||||
// Compiler-specific primitive types
|
// Compiler-specific primitive types
|
||||||
typedef unsigned short uint16_t;
|
typedef unsigned short uint16_t;
|
||||||
#ifndef _UINT32_T
|
#ifndef _UINT32_T
|
||||||
@ -100,6 +139,7 @@ typedef unsigned int uintptr_t;
|
|||||||
// If this gets an error, figure out a symbol XXX that implies the
|
// If this gets an error, figure out a symbol XXX that implies the
|
||||||
// prior definition of intptr_t, and add "&& !defined(XXX)" above.
|
// prior definition of intptr_t, and add "&& !defined(XXX)" above.
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Additional Java basic types
|
// Additional Java basic types
|
||||||
|
|
||||||
@ -128,7 +168,7 @@ inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; }
|
|||||||
const jlong min_jlong = CONST64(0x8000000000000000);
|
const jlong min_jlong = CONST64(0x8000000000000000);
|
||||||
const jlong max_jlong = CONST64(0x7fffffffffffffff);
|
const jlong max_jlong = CONST64(0x7fffffffffffffff);
|
||||||
|
|
||||||
|
#ifdef SOLARIS
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// ANSI C++ fixes
|
// ANSI C++ fixes
|
||||||
// NOTE:In the ANSI committee's continuing attempt to make each version
|
// NOTE:In the ANSI committee's continuing attempt to make each version
|
||||||
@ -162,7 +202,7 @@ extern "C" {
|
|||||||
typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg);
|
typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg);
|
||||||
typedef int (*int_fnP_cond_tP)(cond_t *cv);
|
typedef int (*int_fnP_cond_tP)(cond_t *cv);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
// Debugging
|
// Debugging
|
||||||
@ -173,7 +213,7 @@ extern "C" void breakpoint();
|
|||||||
#define BREAKPOINT ::breakpoint()
|
#define BREAKPOINT ::breakpoint()
|
||||||
|
|
||||||
// checking for nanness
|
// checking for nanness
|
||||||
|
#ifdef SOLARIS
|
||||||
#ifdef SPARC
|
#ifdef SPARC
|
||||||
inline int g_isnan(float f) { return isnanf(f); }
|
inline int g_isnan(float f) { return isnanf(f); }
|
||||||
#else
|
#else
|
||||||
@ -182,6 +222,12 @@ inline int g_isnan(float f) { return isnand(f); }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline int g_isnan(double f) { return isnand(f); }
|
inline int g_isnan(double f) { return isnand(f); }
|
||||||
|
#elif LINUX
|
||||||
|
inline int g_isnan(float f) { return isnanf(f); }
|
||||||
|
inline int g_isnan(double f) { return isnan(f); }
|
||||||
|
#else
|
||||||
|
#error "missing platform-specific definition here"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Checking for finiteness
|
// Checking for finiteness
|
||||||
|
|
||||||
@ -195,9 +241,11 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
|
|||||||
|
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
|
// NOTE: This one leads to an infinite recursion on Linux
|
||||||
|
#ifndef LINUX
|
||||||
int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr);
|
int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr);
|
||||||
#define vsnprintf local_vsnprintf
|
#define vsnprintf local_vsnprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
// Portability macros
|
// Portability macros
|
||||||
#define PRAGMA_INTERFACE
|
#define PRAGMA_INTERFACE
|
||||||
|
Loading…
Reference in New Issue
Block a user