This commit is contained in:
Daniel D. Daugherty 2008-03-13 14:17:48 -07:00
commit 0745d10694
26 changed files with 444 additions and 100 deletions

View File

@ -518,10 +518,10 @@ static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
}
static ps_prochandle_ops core_ops = {
release: core_release,
p_pread: core_read_data,
p_pwrite: core_write_data,
get_lwp_regs: core_get_lwp_regs
.release= core_release,
.p_pread= core_read_data,
.p_pwrite= core_write_data,
.get_lwp_regs= core_get_lwp_regs
};
// read regs and create thread from NT_PRSTATUS entries from core file

View File

@ -291,10 +291,10 @@ static void process_cleanup(struct ps_prochandle* ph) {
}
static ps_prochandle_ops process_ops = {
release: process_cleanup,
p_pread: process_read_data,
p_pwrite: process_write_data,
get_lwp_regs: process_get_lwp_regs
.release= process_cleanup,
.p_pread= process_read_data,
.p_pwrite= process_write_data,
.get_lwp_regs= process_get_lwp_regs
};
// attach to the process. One and only one exposed stuff

View File

@ -80,6 +80,11 @@ ifneq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
MFLAGS += " LP64=1 "
endif
# pass USE_SUNCC further, through MFLAGS
ifdef USE_SUNCC
MFLAGS += " USE_SUNCC=1 "
endif
# The following renders pathnames in generated Makefiles valid on
# machines other than the machine containing the build tree.
#

View File

@ -35,6 +35,8 @@ CFLAGS += -DVM_LITTLE_ENDIAN
CFLAGS += -D_LP64=1
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
ifndef USE_SUNCC
CFLAGS += -fno-omit-frame-pointer
endif
OPT_CFLAGS/compactingPermGenGen.o = -O1

View File

@ -63,7 +63,11 @@ QUIETLY$(MAKE_VERBOSE) = @
# For now, until the compiler is less wobbly:
TESTFLAGS = -Xbatch -showversion
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
ifeq ($(VARIANT),tiered)

View 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

View 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

View 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

View File

@ -1304,7 +1304,7 @@ void Assembler::movl(Address dst, Register src) {
emit_operand(src, dst);
}
void Assembler::mov64(Register dst, int64_t imm64) {
void Assembler::mov64(Register dst, intptr_t imm64) {
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
emit_byte(0xB8 | encode);
@ -1331,7 +1331,7 @@ void Assembler::movq(Register dst, Address 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");
InstructionMark im(this);
prefixq(dst);

View File

@ -232,7 +232,7 @@ LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
// where <ver> is the protocol version (1), <cmd> is the command
// name ("load", "datadump", ...), and <arg> is an argument
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);
char buf[max_len];

View File

@ -60,7 +60,18 @@ inline u4 Bytes::swap_u4(u4 x) {
#ifdef AMD64
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);
#endif
}
#else
// Helper function for swap_u8

View File

@ -62,8 +62,14 @@
#endif // AMD64
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);
return (address) esp;
#endif
}
char* os::non_memory_address_word() {
@ -139,7 +145,12 @@ frame os::get_sender_for_C_frame(frame* fr) {
}
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);
#endif
return (intptr_t*) *ebp; // we want what it points to.
}
@ -560,7 +571,9 @@ bool os::Linux::supports_variable_stack_size() { return true; }
#else
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;})
#endif
// Test if pthread library can support variable thread stack size. 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
// detect stack-heap collisions. But otherwise it's harmless.
//
#ifdef __GNUC__
return (GET_GS() != 0);
#else
return false;
#endif
}
}
#endif // AMD64

View File

@ -155,8 +155,8 @@ bool Dictionary::do_unloading(BoolObjectClosure* is_alive) {
for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
// check the previous versions array for GC'ed weak refs
PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
jweak cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
jobject cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
if (cp_ref == NULL) {
delete pv_node;
ik->previous_versions()->remove_at(i);

View File

@ -3067,6 +3067,7 @@ oopMap.hpp vmreg.hpp
oopMapCache.cpp allocation.inline.hpp
oopMapCache.cpp handles.inline.hpp
oopMapCache.cpp jvmtiRedefineClassesTrace.hpp
oopMapCache.cpp oop.inline.hpp
oopMapCache.cpp oopMapCache.hpp
oopMapCache.cpp resourceArea.hpp

View File

@ -532,6 +532,10 @@ void OopMapCache::flush_obsolete_entries() {
if (!_array[i].is_empty() && _array[i].method()->is_old()) {
// Cache entry is occupied by an old redefined method and we don't want
// 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();
}
}
@ -577,6 +581,15 @@ void OopMapCache::lookup(methodHandle method,
// Entry is not in hashtable.
// 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
for(i = 0; i < _probe_depth; i++) {
entry = entry_at(probe + i);
@ -584,12 +597,6 @@ void OopMapCache::lookup(methodHandle method,
entry->fill(method, bci);
entry_for->resource_copy(entry);
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;
}
}
@ -623,13 +630,6 @@ void OopMapCache::lookup(methodHandle method,
}
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;
}

View File

@ -26,9 +26,27 @@
#include "incls/_compactingPermGenGen.cpp.incl"
// 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.
// An ObjectClosure 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. 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 {
public:
@ -274,9 +292,27 @@ CompactingPermGenGen::CompactingPermGenGen(ReservedSpace rs,
// objects in the space will page in more objects than we need.
// Instead, use the system dictionary as strong roots into the read
// 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() {
if (spec()->enable_shared_spaces()) {
if (JvmtiExport::has_redefined_a_class()) {
// RedefineClasses() requires a brute force approach
AdjustSharedObjectClosure blk;
rw_space()->object_iterate(&blk);
} else {
RecursiveAdjustSharedObjectClosure blk;
Universe::oops_do(&blk);
StringTable::oops_do(&blk);
@ -285,6 +321,7 @@ void CompactingPermGenGen::pre_adjust_pointers() {
SystemDictionary::placeholders_do(&tpc);
}
}
}
#ifdef ASSERT

View File

@ -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.
// Allocate a new array of methods.
jmethodID* to_dealloc_jmeths = NULL;
jmethodID* new_jmeths = NULL;
if (length <= idnum) {
// 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.
jmethodID to_dealloc_id = NULL;
jmethodID new_id = NULL;
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
@ -997,14 +995,27 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan
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);
id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths);
}
}
return id;
}
// 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();
jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum,
jmethodID new_id, jmethodID* new_jmeths) {
// 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
@ -1024,14 +1035,12 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan
} 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;
}
@ -2187,12 +2196,20 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
ikh->external_name(), _previous_versions->length(), emcp_method_count));
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;
objArrayOop old_methods = ikh->methods();
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,
("add: all methods are obsolete; flushing any EMCP weak refs"));
} 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);
@ -2230,7 +2248,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh,
// check the previous versions array for a GC'ed weak refs
pv_node = _previous_versions->at(i);
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) {
delete pv_node;
_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
pv_node = _previous_versions->at(j);
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) {
delete pv_node;
_previous_versions->remove_at(j);
@ -2401,8 +2419,8 @@ bool instanceKlass::has_previous_version() const {
// been GC'ed
PreviousVersionNode * pv_node = _previous_versions->at(i);
jweak cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
jobject cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
if (cp_ref == NULL) {
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
// the instanceKlass.
PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
GrowableArray<jweak>* prev_EMCP_methods) {
PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
_prev_constant_pool = prev_constant_pool;
_prev_cp_is_weak = prev_cp_is_weak;
_prev_EMCP_methods = prev_EMCP_methods;
}
@ -2473,7 +2492,11 @@ PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
// Destroy a PreviousVersionNode
PreviousVersionNode::~PreviousVersionNode() {
if (_prev_constant_pool != NULL) {
if (_prev_cp_is_weak) {
JNIHandles::destroy_weak_global(_prev_constant_pool);
} else {
JNIHandles::destroy_global(_prev_constant_pool);
}
}
if (_prev_EMCP_methods != NULL) {
@ -2493,8 +2516,8 @@ PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) {
_prev_constant_pool_handle = constantPoolHandle(); // NULL handle
_prev_EMCP_method_handles = NULL;
jweak cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
jobject cp_ref = pv_node->prev_constant_pool();
assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
if (cp_ref == NULL) {
return; // robustness
}

View File

@ -432,6 +432,8 @@ class instanceKlass: public Klass {
_enclosing_method_method_index = method_index; }
// 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);
jmethodID jmethod_id_or_null(methodOop method);
@ -838,11 +840,20 @@ class BreakpointInfo;
// A collection point for interesting information about the previous
// version(s) of an instanceKlass. This class uses weak references to
// 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.
class PreviousVersionNode : public CHeapObj {
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
// EMCP methods, then _prev_EMCP_methods will be NULL. If all the
// EMCP methods have been collected, then _prev_EMCP_methods can
@ -850,10 +861,10 @@ class PreviousVersionNode : public CHeapObj {
GrowableArray<jweak>* _prev_EMCP_methods;
public:
PreviousVersionNode(jweak prev_constant_pool,
PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
GrowableArray<jweak>* prev_EMCP_methods);
~PreviousVersionNode();
jweak prev_constant_pool() const {
jobject prev_constant_pool() const {
return _prev_constant_pool;
}
GrowableArray<jweak>* prev_EMCP_methods() const {

View File

@ -37,3 +37,32 @@ void markOopDesc::print_on(outputStream* st) const {
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;
}

View File

@ -357,4 +357,7 @@ class markOopDesc: public oopDesc {
// 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(); }
// see the definition in markOop.cpp for the gory details
bool should_not_be_cached() const;
};

View File

@ -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,
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

View File

@ -524,6 +524,8 @@ class methodOopDesc : public oopDesc {
void set_is_old() { _access_flags.set_is_old(); }
bool is_obsolete() const { return access_flags().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:
bool is_prefixed_native() const { return access_flags().is_prefixed_native(); }

View File

@ -64,7 +64,7 @@
// 0x01000000 | 16777216 - impl details: nmethod evolution info
// 0x02000000 | 33554432 - impl details: annotation updates
// 0x04000000 | 67108864 - impl details: StackMapTable updates
// 0x08000000 | 134217728 - unused
// 0x08000000 | 134217728 - impl details: OopMapCache updates
// 0x10000000 | 268435456 - unused
// 0x20000000 | 536870912 - unused
// 0x40000000 | 1073741824 - unused

View File

@ -1548,10 +1548,11 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle
}
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");
}
methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
methodHandle method(THREAD, m);
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)));
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");
}
methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot)));
methodHandle method(THREAD, m);
assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
// Make sure klass gets initialize

View File

@ -1317,10 +1317,6 @@ JavaThread::~JavaThread() {
ThreadSafepointState::destroy(this);
if (_thread_profiler != NULL) delete _thread_profiler;
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
}
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
Threads::remove(this);
}

View File

@ -37,23 +37,45 @@
# include <stdlib.h>
# include <wchar.h>
# include <stdarg.h>
#ifdef SOLARIS
# include <ieeefp.h>
#endif
# 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 <fcntl.h>
# include <dlfcn.h>
# include <pthread.h>
#ifdef SOLARIS
# include <thread.h>
#endif
# include <limits.h>
# include <errno.h>
#ifdef SOLARIS
# include <sys/trap.h>
# include <sys/regset.h>
# include <sys/procset.h>
# include <ucontext.h>
# include <setjmp.h>
#endif
# ifdef SOLARIS_MUTATOR_LIBTHREAD
# include <sys/procfs.h>
# 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
// 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.
//
// 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
#undef NULL
#define NULL 0L
@ -76,13 +103,25 @@
#define NULL 0
#endif
#endif
#endif
// NULL vs NULL_WORD:
// 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
// pointer is stored as integer value.
// pointer is stored as integer value. On some platforms, sizeof(intptr_t) >
// 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
typedef unsigned short uint16_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
// prior definition of intptr_t, and add "&& !defined(XXX)" above.
#endif
#endif
// 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 max_jlong = CONST64(0x7fffffffffffffff);
#ifdef SOLARIS
//----------------------------------------------------------------------------------------------------
// ANSI C++ fixes
// 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)(cond_t *cv);
};
#endif
//----------------------------------------------------------------------------------------------------
// Debugging
@ -173,7 +213,7 @@ extern "C" void breakpoint();
#define BREAKPOINT ::breakpoint()
// checking for nanness
#ifdef SOLARIS
#ifdef SPARC
inline int g_isnan(float f) { return isnanf(f); }
#else
@ -182,6 +222,12 @@ inline int g_isnan(float f) { return isnand(f); }
#endif
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
@ -195,9 +241,11 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
// 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);
#define vsnprintf local_vsnprintf
#endif
// Portability macros
#define PRAGMA_INTERFACE