This commit is contained in:
Alejandro Murillo 2013-03-15 11:18:39 -07:00
commit 593a00095a
74 changed files with 2562 additions and 1455 deletions

View File

@ -132,12 +132,12 @@ static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
} }
// Part of the class sharing workaround // Part of the class sharing workaround
static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset, static void add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
uintptr_t vaddr, size_t memsz) { uintptr_t vaddr, size_t memsz) {
map_info* map; map_info* map;
if ((map = allocate_init_map(ph->core->classes_jsa_fd, if ((map = allocate_init_map(ph->core->classes_jsa_fd,
offset, vaddr, memsz)) == NULL) { offset, vaddr, memsz)) == NULL) {
return NULL; return;
} }
map->next = ph->core->class_share_maps; map->next = ph->core->class_share_maps;

View File

@ -168,12 +168,12 @@ endif
# conversions which might affect the values. To avoid that, we need to turn # conversions which might affect the values. To avoid that, we need to turn
# it off explicitly. # it off explicitly.
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0" ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
else else
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
endif endif
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS) CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases # Special cases
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
# XXXDARWIN: for _dyld_bind_fully_image_containing_address # XXXDARWIN: for _dyld_bind_fully_image_containing_address

View File

@ -69,7 +69,7 @@ ifeq ($(INCLUDE_CDS), false)
CXXFLAGS += -DINCLUDE_CDS=0 CXXFLAGS += -DINCLUDE_CDS=0
CFLAGS += -DINCLUDE_CDS=0 CFLAGS += -DINCLUDE_CDS=0
Src_Files_EXCLUDE += metaspaceShared.cpp Src_Files_EXCLUDE += filemap.cpp metaspaceShared.cpp
endif endif
ifeq ($(INCLUDE_ALL_GCS), false) ifeq ($(INCLUDE_ALL_GCS), false)

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=22 HS_BUILD_NUMBER=23
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8

View File

@ -131,12 +131,12 @@ WARNINGS_ARE_ERRORS = -Werror
# conversions which might affect the values. To avoid that, we need to turn # conversions which might affect the values. To avoid that, we need to turn
# it off explicitly. # it off explicitly.
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0" ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
else else
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
endif endif
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS) CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases # Special cases
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))

View File

@ -118,8 +118,8 @@ endif
# Compiler warnings are treated as errors # Compiler warnings are treated as errors
WARNINGS_ARE_ERRORS = -Werror WARNINGS_ARE_ERRORS = -Werror
# Enable these warnings. See 'info gcc' about details on these options # Enable these warnings. See 'info gcc' about details on these options
ADDITIONAL_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ADDITIONAL_WARNINGS) CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases # Special cases
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))

View File

@ -2194,7 +2194,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals_size, int callee_locals_size,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "NEED TO FIX"); assert(popframe_extra_args == 0, "NEED TO FIX");
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()

View File

@ -1581,7 +1581,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_local_count, int callee_local_count,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup // Note: This calculation must exactly parallel the frame setup
// in InterpreterGenerator::generate_fixed_frame. // in InterpreterGenerator::generate_fixed_frame.
// If f!=NULL, set up the following variables: // If f!=NULL, set up the following variables:
@ -1664,6 +1665,15 @@ int AbstractInterpreter::layout_activation(Method* method,
int delta = local_words - parm_words; int delta = local_words - parm_words;
int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0; int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
*interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS; *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
if (!is_bottom_frame) {
// Llast_SP is set below for the current frame to SP (with the
// extra space for the callee's locals). Here we adjust
// Llast_SP for the caller's frame, removing the extra space
// for the current method's locals.
*caller->register_addr(Llast_SP) = *interpreter_frame->register_addr(I5_savedSP);
} else {
assert(*caller->register_addr(Llast_SP) >= *interpreter_frame->register_addr(I5_savedSP), "strange Llast_SP");
}
} else { } else {
assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases"); assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
// Don't have Lesp available; lay out locals block in the caller // Don't have Lesp available; lay out locals block in the caller

View File

@ -2361,7 +2361,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "FIX ME"); assert(popframe_extra_args == 0, "FIX ME");
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state() // NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()

View File

@ -356,7 +356,7 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
// Verifies the calculated original PC of a deoptimization PC for the // Verifies the calculated original PC of a deoptimization PC for the
// given unextended SP. The unextended SP might also be the saved SP // given unextended SP. The unextended SP might also be the saved SP
// for MethodHandle call sites. // for MethodHandle call sites.
#if ASSERT #ifdef ASSERT
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
frame fr; frame fr;

View File

@ -170,7 +170,7 @@
return (intptr_t*) addr_at(offset); return (intptr_t*) addr_at(offset);
} }
#if ASSERT #ifdef ASSERT
// Used in frame::sender_for_{interpreter,compiled}_frame // Used in frame::sender_for_{interpreter,compiled}_frame
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false); static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) { static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {

View File

@ -1585,7 +1585,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup // Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry. // in AbstractInterpreterGenerator::generate_method_entry.
// If interpreter_frame!=NULL, set up the method, locals, and monitors. // If interpreter_frame!=NULL, set up the method, locals, and monitors.

View File

@ -1599,7 +1599,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup // Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry. // in AbstractInterpreterGenerator::generate_method_entry.
// If interpreter_frame!=NULL, set up the method, locals, and monitors. // If interpreter_frame!=NULL, set up the method, locals, and monitors.

View File

@ -919,7 +919,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "what to do?"); assert(popframe_extra_args == 0, "what to do?");
assert(!is_top_frame || (!callee_locals && !callee_param_count), assert(!is_top_frame || (!callee_locals && !callee_param_count),
"top frame should have no caller"); "top frame should have no caller");

View File

@ -57,6 +57,7 @@
#include "runtime/threadCritical.hpp" #include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
#include "services/attachListener.hpp" #include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp" #include "services/runtimeService.hpp"
#include "utilities/decoder.hpp" #include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
@ -2275,13 +2276,25 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
return NULL; return NULL;
} }
// The memory is committed
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc);
MemTracker::record_virtual_memory_commit((address)addr, bytes, pc);
return addr; return addr;
} }
bool os::release_memory_special(char* base, size_t bytes) { bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special() // detaching the SHM segment will also delete it, see reserve_memory_special()
int rslt = shmdt(base); int rslt = shmdt(base);
return rslt == 0; if (rslt == 0) {
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
MemTracker::record_virtual_memory_release((address)base, bytes);
return true;
} else {
return false;
}
} }
size_t os::large_page_size() { size_t os::large_page_size() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,6 +40,9 @@
product(bool, UseHugeTLBFS, false, \ product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \ "Use MAP_HUGETLB for large pages") \
\ \
product(bool, LoadExecStackDllInVMThread, true, \
"Load DLLs with executable-stack attribute in the VM Thread") \
\
product(bool, UseSHM, false, \ product(bool, UseSHM, false, \
"Use SYSV shared memory for large pages") "Use SYSV shared memory for large pages")

View File

@ -44,6 +44,7 @@
#include "runtime/extendedPC.hpp" #include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
#include "runtime/interfaceSupport.hpp" #include "runtime/interfaceSupport.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "runtime/javaCalls.hpp" #include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
@ -57,10 +58,12 @@
#include "runtime/threadCritical.hpp" #include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
#include "services/attachListener.hpp" #include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp" #include "services/runtimeService.hpp"
#include "utilities/decoder.hpp" #include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
#include "utilities/events.hpp" #include "utilities/events.hpp"
#include "utilities/elfFile.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
#include "utilities/vmError.hpp" #include "utilities/vmError.hpp"
@ -1796,9 +1799,93 @@ bool os::dll_address_to_library_name(address addr, char* buf,
// in case of error it checks if .dll/.so was built for the // in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on // same architecture as Hotspot is running on
// Remember the stack's state. The Linux dynamic linker will change
// the stack to 'executable' at most once, so we must safepoint only once.
bool os::Linux::_stack_is_executable = false;
// VM operation that loads a library. This is necessary if stack protection
// of the Java stacks can be lost during loading the library. If we
// do not stop the Java threads, they can stack overflow before the stacks
// are protected again.
class VM_LinuxDllLoad: public VM_Operation {
private:
const char *_filename;
void *_lib;
public:
VM_LinuxDllLoad(const char *fn) :
_filename(fn), _lib(NULL) {}
VMOp_Type type() const { return VMOp_LinuxDllLoad; }
void doit() {
_lib = os::Linux::dll_load_inner(_filename);
os::Linux::_stack_is_executable = true;
}
void* loaded_library() { return _lib; }
};
void * os::dll_load(const char *filename, char *ebuf, int ebuflen) void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
{ {
void * result= ::dlopen(filename, RTLD_LAZY); void * result = NULL;
bool load_attempted = false;
// Check whether the library to load might change execution rights
// of the stack. If they are changed, the protection of the stack
// guard pages will be lost. We need a safepoint to fix this.
//
// See Linux man page execstack(8) for more info.
if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
ElfFile ef(filename);
if (!ef.specifies_noexecstack()) {
if (!is_init_completed()) {
os::Linux::_stack_is_executable = true;
// This is OK - No Java threads have been created yet, and hence no
// stack guard pages to fix.
//
// This should happen only when you are building JDK7 using a very
// old version of JDK6 (e.g., with JPRT) and running test_gamma.
//
// Dynamic loader will make all stacks executable after
// this function returns, and will not do that again.
assert(Threads::first() == NULL, "no Java threads should exist yet.");
} else {
warning("You have loaded library %s which might have disabled stack guard. "
"The VM will try to fix the stack guard now.\n"
"It's highly recommended that you fix the library with "
"'execstack -c <libfile>', or link it with '-z noexecstack'.",
filename);
assert(Thread::current()->is_Java_thread(), "must be Java thread");
JavaThread *jt = JavaThread::current();
if (jt->thread_state() != _thread_in_native) {
// This happens when a compiler thread tries to load a hsdis-<arch>.so file
// that requires ExecStack. Cannot enter safe point. Let's give up.
warning("Unable to fix stack guard. Giving up.");
} else {
if (!LoadExecStackDllInVMThread) {
// This is for the case where the DLL has an static
// constructor function that executes JNI code. We cannot
// load such DLLs in the VMThread.
result = ::dlopen(filename, RTLD_LAZY);
}
ThreadInVMfromNative tiv(jt);
debug_only(VMNativeEntryWrapper vew;)
VM_LinuxDllLoad op(filename);
VMThread::execute(&op);
if (LoadExecStackDllInVMThread) {
result = op.loaded_library();
}
load_attempted = true;
}
}
}
}
if (!load_attempted) {
result = ::dlopen(filename, RTLD_LAZY);
}
if (result != NULL) { if (result != NULL) {
// Successful loading // Successful loading
return result; return result;
@ -1952,6 +2039,38 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
return NULL; return NULL;
} }
void * os::Linux::dll_load_inner(const char *filename) {
void * result = NULL;
if (LoadExecStackDllInVMThread) {
result = ::dlopen(filename, RTLD_LAZY);
}
// Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
// library that requires an executable stack, or which does not have this
// stack attribute set, dlopen changes the stack attribute to executable. The
// read protection of the guard pages gets lost.
//
// Need to check _stack_is_executable again as multiple VM_LinuxDllLoad
// may have been queued at the same time.
if (!_stack_is_executable) {
JavaThread *jt = Threads::first();
while (jt) {
if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized
jt->stack_yellow_zone_enabled()) { // No pending stack overflow exceptions
if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
warning("Attempt to reguard stack yellow zone failed.");
}
}
jt = jt->next();
}
}
return result;
}
/* /*
* glibc-2.0 libdl is not MT safe. If you are building with any glibc, * glibc-2.0 libdl is not MT safe. If you are building with any glibc,
* chances are you might want to run the generated bits against glibc-2.0 * chances are you might want to run the generated bits against glibc-2.0
@ -3094,13 +3213,24 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
numa_make_global(addr, bytes); numa_make_global(addr, bytes);
} }
// The memory is committed
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc);
MemTracker::record_virtual_memory_commit((address)addr, bytes, pc);
return addr; return addr;
} }
bool os::release_memory_special(char* base, size_t bytes) { bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special() // detaching the SHM segment will also delete it, see reserve_memory_special()
int rslt = shmdt(base); int rslt = shmdt(base);
return rslt == 0; if (rslt == 0) {
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
MemTracker::record_virtual_memory_release((address)base, bytes);
return true;
} else {
return false;
}
} }
size_t os::large_page_size() { size_t os::large_page_size() {

View File

@ -94,6 +94,9 @@ class Linux {
static void print_libversion_info(outputStream* st); static void print_libversion_info(outputStream* st);
public: public:
static bool _stack_is_executable;
static void *dll_load_inner(const char *name);
static void init_thread_fpu_state(); static void init_thread_fpu_state();
static int get_fpu_control_word(); static int get_fpu_control_word();
static void set_fpu_control_word(int fpu_control); static void set_fpu_control_word(int fpu_control);

View File

@ -2945,7 +2945,7 @@ char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info
while (p < (uint64_t)end) { while (p < (uint64_t)end) {
addrs[0] = p; addrs[0] = p;
size_t addrs_count = 1; size_t addrs_count = 1;
while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] < (uint64_t)end) { while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] + page_size < (uint64_t)end) {
addrs[addrs_count] = addrs[addrs_count - 1] + page_size; addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
addrs_count++; addrs_count++;
} }
@ -3420,13 +3420,25 @@ char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
if ((retAddr != NULL) && UseNUMAInterleaving) { if ((retAddr != NULL) && UseNUMAInterleaving) {
numa_make_global(retAddr, size); numa_make_global(retAddr, size);
} }
// The memory is committed
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve((address)retAddr, size, pc);
MemTracker::record_virtual_memory_commit((address)retAddr, size, pc);
return retAddr; return retAddr;
} }
bool os::release_memory_special(char* base, size_t bytes) { bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special() // detaching the SHM segment will also delete it, see reserve_memory_special()
int rslt = shmdt(base); int rslt = shmdt(base);
return rslt == 0; if (rslt == 0) {
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
MemTracker::record_virtual_memory_release((address)base, bytes);
return true;
} else {
return false;
}
} }
size_t os::large_page_size() { size_t os::large_page_size() {

View File

@ -60,6 +60,7 @@
#include "runtime/threadCritical.hpp" #include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
#include "services/attachListener.hpp" #include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp" #include "services/runtimeService.hpp"
#include "utilities/decoder.hpp" #include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
@ -2836,7 +2837,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
PAGE_READWRITE); PAGE_READWRITE);
// If reservation failed, return NULL // If reservation failed, return NULL
if (p_buf == NULL) return NULL; if (p_buf == NULL) return NULL;
MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
os::release_memory(p_buf, bytes + chunk_size); os::release_memory(p_buf, bytes + chunk_size);
// we still need to round up to a page boundary (in case we are using large pages) // we still need to round up to a page boundary (in case we are using large pages)
@ -2898,6 +2899,11 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
if (next_alloc_addr > p_buf) { if (next_alloc_addr > p_buf) {
// Some memory was committed so release it. // Some memory was committed so release it.
size_t bytes_to_release = bytes - bytes_remaining; size_t bytes_to_release = bytes - bytes_remaining;
// NMT has yet to record any individual blocks, so it
// need to create a dummy 'reserve' record to match
// the release.
MemTracker::record_virtual_memory_reserve((address)p_buf,
bytes_to_release, CALLER_PC);
os::release_memory(p_buf, bytes_to_release); os::release_memory(p_buf, bytes_to_release);
} }
#ifdef ASSERT #ifdef ASSERT
@ -2909,10 +2915,19 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
#endif #endif
return NULL; return NULL;
} }
bytes_remaining -= bytes_to_rq; bytes_remaining -= bytes_to_rq;
next_alloc_addr += bytes_to_rq; next_alloc_addr += bytes_to_rq;
count++; count++;
} }
// Although the memory is allocated individually, it is returned as one.
// NMT records it as one block.
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc);
if ((flags & MEM_COMMIT) != 0) {
MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc);
}
// made it this far, success // made it this far, success
return p_buf; return p_buf;
} }
@ -3099,11 +3114,20 @@ char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
// normal policy just allocate it all at once // normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
if (res != NULL) {
address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve((address)res, bytes, pc);
MemTracker::record_virtual_memory_commit((address)res, bytes, pc);
}
return res; return res;
} }
} }
bool os::release_memory_special(char* base, size_t bytes) { bool os::release_memory_special(char* base, size_t bytes) {
assert(base != NULL, "Sanity check");
// Memory allocated via reserve_memory_special() is committed
MemTracker::record_virtual_memory_uncommit((address)base, bytes);
return release_memory(base, bytes); return release_memory(base, bytes);
} }

View File

@ -516,7 +516,7 @@ JVM_handle_bsd_signal(int sig,
// here if the underlying file has been truncated. // here if the underlying file has been truncated.
// Do not crash the VM in such a case. // Do not crash the VM in such a case.
CodeBlob* cb = CodeCache::find_blob_unsafe(pc); CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
if (nm != NULL && nm->has_unsafe_access()) { if (nm != NULL && nm->has_unsafe_access()) {
stub = StubRoutines::handler_for_unsafe_access(); stub = StubRoutines::handler_for_unsafe_access();
} }

View File

@ -410,6 +410,11 @@ inline static bool checkOverflow(sigcontext* uc,
// to handle_unexpected_exception way down below. // to handle_unexpected_exception way down below.
thread->disable_stack_red_zone(); thread->disable_stack_red_zone();
tty->print_raw_cr("An irrecoverable stack overflow has occurred."); tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
// This is a likely cause, but hard to verify. Let's just print
// it as a hint.
tty->print_raw_cr("Please check if any of your loaded .so files has "
"enabled executable stack (see man page execstack(8))");
} else { } else {
// Accessing stack address below sp may cause SEGV if current // Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when // thread has MAP_GROWSDOWN stack. This should only happen when

View File

@ -305,6 +305,11 @@ JVM_handle_linux_signal(int sig,
// to handle_unexpected_exception way down below. // to handle_unexpected_exception way down below.
thread->disable_stack_red_zone(); thread->disable_stack_red_zone();
tty->print_raw_cr("An irrecoverable stack overflow has occurred."); tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
// This is a likely cause, but hard to verify. Let's just print
// it as a hint.
tty->print_raw_cr("Please check if any of your loaded .so files has "
"enabled executable stack (see man page execstack(8))");
} else { } else {
// Accessing stack address below sp may cause SEGV if current // Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when // thread has MAP_GROWSDOWN stack. This should only happen when

View File

@ -2375,7 +2375,7 @@ class LIR_OpVisitState: public StackObj {
// collects all register operands of the instruction // collects all register operands of the instruction
void visit(LIR_Op* op); void visit(LIR_Op* op);
#if ASSERT #ifdef ASSERT
// check that an operation has no operands // check that an operation has no operands
bool no_operands(LIR_Op* op); bool no_operands(LIR_Op* op);
#endif #endif

View File

@ -2540,7 +2540,7 @@ void ciTypeFlow::build_loop_tree(Block* blk) {
} else if (innermost->head() == blk) { } else if (innermost->head() == blk) {
// If loop header, complete the tree pointers // If loop header, complete the tree pointers
if (blk->loop() != innermost) { if (blk->loop() != innermost) {
#if ASSERT #ifdef ASSERT
assert(blk->loop()->head() == innermost->head(), "same head"); assert(blk->loop()->head() == innermost->head(), "same head");
Loop* dl; Loop* dl;
for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent()); for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent());

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@
#include "classfile/symbolTable.hpp" #include "classfile/symbolTable.hpp"
class FieldAllocationCount; class FieldAllocationCount;
class FieldLayoutInfo;
// Parser for for .class files // Parser for for .class files
@ -47,6 +48,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
u2 _major_version; u2 _major_version;
u2 _minor_version; u2 _minor_version;
Symbol* _class_name; Symbol* _class_name;
ClassLoaderData* _loader_data;
KlassHandle _host_klass; KlassHandle _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries GrowableArray<Handle>* _cp_patches; // overrides for CP entries
@ -58,33 +60,59 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// class attributes parsed before the instance klass is created: // class attributes parsed before the instance klass is created:
bool _synthetic_flag; bool _synthetic_flag;
int _sde_length;
char* _sde_buffer;
Symbol* _sourcefile; Symbol* _sourcefile;
Symbol* _generic_signature; Symbol* _generic_signature;
char* _sde_buffer;
int _sde_length; // Metadata created before the instance klass is created. Must be deallocated
Array<u2>* _inner_classes; // if not transferred to the InstanceKlass upon successful class loading
// in which case these pointers have been set to NULL.
instanceKlassHandle _super_klass;
ConstantPool* _cp;
Array<u2>* _fields;
Array<Method*>* _methods;
Array<u2>* _inner_classes;
Array<Klass*>* _local_interfaces;
Array<Klass*>* _transitive_interfaces;
AnnotationArray* _annotations; AnnotationArray* _annotations;
AnnotationArray* _type_annotations; AnnotationArray* _type_annotations;
Array<AnnotationArray*>* _fields_annotations;
Array<AnnotationArray*>* _fields_type_annotations;
InstanceKlass* _klass; // InstanceKlass once created.
void set_class_synthetic_flag(bool x) { _synthetic_flag = x; } void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
void set_class_sourcefile(Symbol* x) { _sourcefile = x; } void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
void set_class_generic_signature(Symbol* x) { _generic_signature = x; } void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; } void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
void set_class_inner_classes(Array<u2>* x) { _inner_classes = x; }
void set_class_annotations(AnnotationArray* x) { _annotations = x; } void init_parsed_class_attributes(ClassLoaderData* loader_data) {
void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; } _loader_data = loader_data;
void init_parsed_class_attributes() {
_synthetic_flag = false; _synthetic_flag = false;
_sourcefile = NULL; _sourcefile = NULL;
_generic_signature = NULL; _generic_signature = NULL;
_sde_buffer = NULL; _sde_buffer = NULL;
_sde_length = 0; _sde_length = 0;
_annotations = _type_annotations = NULL;
// initialize the other flags too: // initialize the other flags too:
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false; _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
_max_bootstrap_specifier_index = -1; _max_bootstrap_specifier_index = -1;
clear_class_metadata();
_klass = NULL;
} }
void apply_parsed_class_attributes(instanceKlassHandle k); // update k void apply_parsed_class_attributes(instanceKlassHandle k); // update k
void apply_parsed_class_metadata(instanceKlassHandle k, int fields_count, TRAPS);
void clear_class_metadata() {
// metadata created before the instance klass is created. Must be
// deallocated if classfile parsing returns an error.
_cp = NULL;
_fields = NULL;
_methods = NULL;
_inner_classes = NULL;
_local_interfaces = NULL;
_transitive_interfaces = NULL;
_annotations = _type_annotations = NULL;
_fields_annotations = _fields_type_annotations = NULL;
}
class AnnotationCollector { class AnnotationCollector {
public: public:
@ -124,11 +152,27 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void set_contended(bool contended) { set_annotation(_sun_misc_Contended); } void set_contended(bool contended) { set_annotation(_sun_misc_Contended); }
bool is_contended() { return has_annotation(_sun_misc_Contended); } bool is_contended() { return has_annotation(_sun_misc_Contended); }
}; };
// This class also doubles as a holder for metadata cleanup.
class FieldAnnotationCollector: public AnnotationCollector { class FieldAnnotationCollector: public AnnotationCollector {
ClassLoaderData* _loader_data;
AnnotationArray* _field_annotations;
AnnotationArray* _field_type_annotations;
public: public:
FieldAnnotationCollector() : AnnotationCollector(_in_field) { } FieldAnnotationCollector(ClassLoaderData* loader_data) :
AnnotationCollector(_in_field),
_loader_data(loader_data),
_field_annotations(NULL),
_field_type_annotations(NULL) {}
void apply_to(FieldInfo* f); void apply_to(FieldInfo* f);
~FieldAnnotationCollector();
AnnotationArray* field_annotations() { return _field_annotations; }
AnnotationArray* field_type_annotations() { return _field_type_annotations; }
void set_field_annotations(AnnotationArray* a) { _field_annotations = a; }
void set_field_type_annotations(AnnotationArray* a) { _field_type_annotations = a; }
}; };
class MethodAnnotationCollector: public AnnotationCollector { class MethodAnnotationCollector: public AnnotationCollector {
public: public:
MethodAnnotationCollector() : AnnotationCollector(_in_method) { } MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
@ -152,38 +196,30 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void set_stream(ClassFileStream* st) { _stream = st; } void set_stream(ClassFileStream* st) { _stream = st; }
// Constant pool parsing // Constant pool parsing
void parse_constant_pool_entries(ClassLoaderData* loader_data, void parse_constant_pool_entries(int length, TRAPS);
constantPoolHandle cp, int length, TRAPS);
constantPoolHandle parse_constant_pool(ClassLoaderData* loader_data, TRAPS); constantPoolHandle parse_constant_pool(TRAPS);
// Interface parsing // Interface parsing
Array<Klass*>* parse_interfaces(constantPoolHandle cp, Array<Klass*>* parse_interfaces(int length,
int length,
ClassLoaderData* loader_data,
Handle protection_domain, Handle protection_domain,
Symbol* class_name, Symbol* class_name,
bool* has_default_methods, bool* has_default_methods,
TRAPS); TRAPS);
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS); void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
instanceKlassHandle parse_super_class(int super_class_index, TRAPS);
// Field parsing // Field parsing
void parse_field_attributes(ClassLoaderData* loader_data, void parse_field_attributes(u2 attributes_count,
constantPoolHandle cp, u2 attributes_count,
bool is_static, u2 signature_index, bool is_static, u2 signature_index,
u2* constantvalue_index_addr, u2* constantvalue_index_addr,
bool* is_synthetic_addr, bool* is_synthetic_addr,
u2* generic_signature_index_addr, u2* generic_signature_index_addr,
AnnotationArray** field_annotations,
AnnotationArray** field_type_annotations,
FieldAnnotationCollector* parsed_annotations, FieldAnnotationCollector* parsed_annotations,
TRAPS); TRAPS);
Array<u2>* parse_fields(ClassLoaderData* loader_data, Array<u2>* parse_fields(Symbol* class_name,
Symbol* class_name, bool is_interface,
constantPoolHandle cp, bool is_interface,
FieldAllocationCount *fac, FieldAllocationCount *fac,
Array<AnnotationArray*>** fields_annotations,
Array<AnnotationArray*>** fields_type_annotations,
u2* java_fields_count_ptr, TRAPS); u2* java_fields_count_ptr, TRAPS);
void print_field_layout(Symbol* name, void print_field_layout(Symbol* name,
@ -195,65 +231,52 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int static_fields_end); int static_fields_end);
// Method parsing // Method parsing
methodHandle parse_method(ClassLoaderData* loader_data, methodHandle parse_method(bool is_interface,
constantPoolHandle cp,
bool is_interface,
AccessFlags* promoted_flags, AccessFlags* promoted_flags,
TRAPS); TRAPS);
Array<Method*>* parse_methods(ClassLoaderData* loader_data, Array<Method*>* parse_methods(bool is_interface,
constantPoolHandle cp,
bool is_interface,
AccessFlags* promoted_flags, AccessFlags* promoted_flags,
bool* has_final_method, bool* has_final_method,
bool* has_default_method, bool* has_default_method,
TRAPS); TRAPS);
Array<int>* sort_methods(ClassLoaderData* loader_data, intArray* sort_methods(Array<Method*>* methods);
Array<Method*>* methods,
TRAPS); u2* parse_exception_table(u4 code_length, u4 exception_table_length,
u2* parse_exception_table(ClassLoaderData* loader_data, TRAPS);
u4 code_length, u4 exception_table_length,
constantPoolHandle cp, TRAPS);
void parse_linenumber_table( void parse_linenumber_table(
u4 code_attribute_length, u4 code_length, u4 code_attribute_length, u4 code_length,
CompressedLineNumberWriteStream** write_stream, TRAPS); CompressedLineNumberWriteStream** write_stream, TRAPS);
u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length, u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length,
constantPoolHandle cp, u2* localvariable_table_length, u2* localvariable_table_length,
bool isLVTT, TRAPS); bool isLVTT, TRAPS);
u2* parse_checked_exceptions(u2* checked_exceptions_length, u4 method_attribute_length, u2* parse_checked_exceptions(u2* checked_exceptions_length, u4 method_attribute_length,
constantPoolHandle cp, TRAPS); TRAPS);
void parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index, void parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index,
u1* u1_array, u2* u2_array, constantPoolHandle cp, TRAPS); u1* u1_array, u2* u2_array, TRAPS);
Array<u1>* parse_stackmap_table(ClassLoaderData* loader_data, u4 code_attribute_length, TRAPS); u1* parse_stackmap_table(u4 code_attribute_length, TRAPS);
// Classfile attribute parsing // Classfile attribute parsing
void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS); void parse_classfile_sourcefile_attribute(TRAPS);
void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, void parse_classfile_source_debug_extension_attribute(int length, TRAPS);
int length, TRAPS); u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
u2 parse_classfile_inner_classes_attribute(ClassLoaderData* loader_data,
u1* inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute, bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index, u2 enclosing_method_class_index,
u2 enclosing_method_method_index, u2 enclosing_method_method_index,
constantPoolHandle cp,
TRAPS); TRAPS);
void parse_classfile_attributes(ClassLoaderData* loader_data, void parse_classfile_attributes(ClassAnnotationCollector* parsed_annotations,
constantPoolHandle cp,
ClassAnnotationCollector* parsed_annotations,
TRAPS); TRAPS);
void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS); void parse_classfile_synthetic_attribute(TRAPS);
void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS); void parse_classfile_signature_attribute(TRAPS);
void parse_classfile_bootstrap_methods_attribute(ClassLoaderData* loader_data, constantPoolHandle cp, u4 attribute_length, TRAPS); void parse_classfile_bootstrap_methods_attribute(u4 attribute_length, TRAPS);
// Annotations handling // Annotations handling
AnnotationArray* assemble_annotations(ClassLoaderData* loader_data, AnnotationArray* assemble_annotations(u1* runtime_visible_annotations,
u1* runtime_visible_annotations,
int runtime_visible_annotations_length, int runtime_visible_annotations_length,
u1* runtime_invisible_annotations, u1* runtime_invisible_annotations,
int runtime_invisible_annotations_length, TRAPS); int runtime_invisible_annotations_length, TRAPS);
int skip_annotation(u1* buffer, int limit, int index); int skip_annotation(u1* buffer, int limit, int index);
int skip_annotation_value(u1* buffer, int limit, int index); int skip_annotation_value(u1* buffer, int limit, int index);
void parse_annotations(ClassLoaderData* loader_data, void parse_annotations(u1* buffer, int limit,
u1* buffer, int limit, constantPoolHandle cp,
/* Results (currently, only one result is supported): */ /* Results (currently, only one result is supported): */
AnnotationCollector* result, AnnotationCollector* result,
TRAPS); TRAPS);
@ -267,8 +290,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int* nonstatic_oop_offsets, int* nonstatic_oop_offsets,
unsigned int* nonstatic_oop_counts); unsigned int* nonstatic_oop_counts);
void set_precomputed_flags(instanceKlassHandle k); void set_precomputed_flags(instanceKlassHandle k);
Array<Klass*>* compute_transitive_interfaces(ClassLoaderData* loader_data, Array<Klass*>* compute_transitive_interfaces(instanceKlassHandle super,
instanceKlassHandle super,
Array<Klass*>* local_ifs, TRAPS); Array<Klass*>* local_ifs, TRAPS);
// Format checker methods // Format checker methods
@ -318,7 +340,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
bool is_supported_version(u2 major, u2 minor); bool is_supported_version(u2 major, u2 minor);
bool has_illegal_visibility(jint flags); bool has_illegal_visibility(jint flags);
void verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS); void verify_constantvalue(int constantvalue_index, int signature_index, TRAPS);
void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS); void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS);
void verify_legal_class_name(Symbol* name, TRAPS); void verify_legal_class_name(Symbol* name, TRAPS);
void verify_legal_field_name(Symbol* name, TRAPS); void verify_legal_field_name(Symbol* name, TRAPS);
@ -359,10 +381,17 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// In older versions of the VM, Klass*s cannot sneak into early phases of // In older versions of the VM, Klass*s cannot sneak into early phases of
// constant pool construction, but in later versions they can. // constant pool construction, but in later versions they can.
// %%% Let's phase out the old is_klass_reference. // %%% Let's phase out the old is_klass_reference.
bool is_klass_reference(constantPoolHandle cp, int index) { bool valid_klass_reference_at(int index) {
return (EnableInvokeDynamic return _cp->is_within_bounds(index) &&
? cp->tag_at(index).is_klass_or_reference() (EnableInvokeDynamic
: cp->tag_at(index).is_klass_reference()); ? _cp->tag_at(index).is_klass_or_reference()
: _cp->tag_at(index).is_klass_reference());
}
// Checks that the cpool index is in range and is a utf8
bool valid_symbol_at(int cpool_index) {
return (_cp->is_within_bounds(cpool_index) &&
_cp->tag_at(cpool_index).is_utf8());
} }
void copy_localvariable_table(ConstMethod* cm, int lvt_cnt, void copy_localvariable_table(ConstMethod* cm, int lvt_cnt,
@ -373,8 +402,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
u2** localvariable_type_table_start, u2** localvariable_type_table_start,
TRAPS); TRAPS);
void copy_method_annotations(ClassLoaderData* loader_data, void copy_method_annotations(ConstMethod* cm,
ConstMethod* cm,
u1* runtime_visible_annotations, u1* runtime_visible_annotations,
int runtime_visible_annotations_length, int runtime_visible_annotations_length,
u1* runtime_invisible_annotations, u1* runtime_invisible_annotations,
@ -391,9 +419,15 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int annotation_default_length, int annotation_default_length,
TRAPS); TRAPS);
// lays out fields in class and returns the total oopmap count
void layout_fields(Handle class_loader, FieldAllocationCount* fac,
ClassAnnotationCollector* parsed_annotations,
FieldLayoutInfo* info, TRAPS);
public: public:
// Constructor // Constructor
ClassFileParser(ClassFileStream* st) { set_stream(st); } ClassFileParser(ClassFileStream* st) { set_stream(st); }
~ClassFileParser();
// Parse .class file and return new Klass*. The Klass* is not hooked up // Parse .class file and return new Klass*. The Klass* is not hooked up
// to the system dictionary or any other structures, so a .class file can // to the system dictionary or any other structures, so a .class file can

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,18 +49,17 @@ Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS
Symbol* sym; Symbol* sym;
if (c_heap) { if (DumpSharedSpaces) {
// Allocate all symbols to CLD shared metaspace
sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
} else if (c_heap) {
// refcount starts as 1 // refcount starts as 1
assert(!DumpSharedSpaces, "never allocate to C heap");
sym = new (len, THREAD) Symbol(name, len, 1); sym = new (len, THREAD) Symbol(name, len, 1);
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
} else { } else {
if (DumpSharedSpaces) { // Allocate to global arena
sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
} else {
sym = new (len, arena(), THREAD) Symbol(name, len, -1); sym = new (len, arena(), THREAD) Symbol(name, len, -1);
} }
}
return sym; return sym;
} }

View File

@ -195,7 +195,7 @@ void CompressedWriteStream::write_int_mb(jint value) {
// for this block (a matching directive turns it back on later). // for this block (a matching directive turns it back on later).
// These directives can be removed once the MS VS.NET 2005 // These directives can be removed once the MS VS.NET 2005
// compiler stack overflow is fixed. // compiler stack overflow is fixed.
#if _MSC_VER >=1400 && !defined(_WIN64) #if defined(_MSC_VER) && _MSC_VER >=1400 && !defined(_WIN64)
#pragma optimize("", off) #pragma optimize("", off)
#pragma warning(disable: 4748) #pragma warning(disable: 4748)
#endif #endif
@ -276,7 +276,7 @@ void test_compressed_stream(int trace) {
guarantee(fails == 0, "test failures"); guarantee(fails == 0, "test failures");
} }
#if _MSC_VER >=1400 && !defined(_WIN64) #if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64)
#pragma warning(default: 4748) #pragma warning(default: 4748)
#pragma optimize("", on) #pragma optimize("", on)
#endif #endif

View File

@ -505,7 +505,7 @@ void CompileTask::log_task(xmlStream* log) {
ResourceMark rm(thread); ResourceMark rm(thread);
// <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'> // <task id='9' method='M' osr_bci='X' level='1' blocking='1' stamp='1.234'>
if (_compile_id != 0) log->print(" compile_id='%d'", _compile_id); log->print(" compile_id='%d'", _compile_id);
if (_osr_bci != CompileBroker::standard_entry_bci) { if (_osr_bci != CompileBroker::standard_entry_bci) {
log->print(" compile_kind='osr'"); // same as nmethod::compile_kind log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
} // else compile_kind='c2c' } // else compile_kind='c2c'

View File

@ -2063,11 +2063,6 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
// required. // required.
_collectorState = FinalMarking; _collectorState = FinalMarking;
} }
if (PrintGCDetails &&
(_collectorState > Idling ||
!GCCause::is_user_requested_gc(GenCollectedHeap::heap()->gc_cause()))) {
gclog_or_tty->print(" (concurrent mode failure)");
}
collect_in_foreground(clear_all_soft_refs); collect_in_foreground(clear_all_soft_refs);
// For a mark-sweep, compute_new_size() will be called // For a mark-sweep, compute_new_size() will be called
@ -3400,10 +3395,10 @@ CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
if (PrintCMSStatistics != 0) { if (PrintCMSStatistics != 0) {
_collector->resetYields(); _collector->resetYields();
} }
if (PrintGCDetails && PrintGCTimeStamps) { if (PrintGCDetails) {
gclog_or_tty->date_stamp(PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(); gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print_cr(": [%s-concurrent-%s-start]", gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
_collector->cmsGen()->short_name(), _phase); _collector->cmsGen()->short_name(), _phase);
} }
_collector->resetTimer(); _collector->resetTimer();

View File

@ -1310,11 +1310,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
_markStack.expand(); _markStack.expand();
} }
#if VERIFY_OBJS_PROCESSED
_scan_obj_cl.objs_processed = 0;
ThreadLocalObjQueue::objs_enqueued = 0;
#endif
// Statistics // Statistics
double now = os::elapsedTime(); double now = os::elapsedTime();
_remark_mark_times.add((mark_work_end - start) * 1000.0); _remark_mark_times.add((mark_work_end - start) * 1000.0);
@ -2555,17 +2550,6 @@ void ConcurrentMark::checkpointRootsFinalWork() {
guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant"); guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
print_stats(); print_stats();
#if VERIFY_OBJS_PROCESSED
if (_scan_obj_cl.objs_processed != ThreadLocalObjQueue::objs_enqueued) {
gclog_or_tty->print_cr("Processed = %d, enqueued = %d.",
_scan_obj_cl.objs_processed,
ThreadLocalObjQueue::objs_enqueued);
guarantee(_scan_obj_cl.objs_processed ==
ThreadLocalObjQueue::objs_enqueued,
"Different number of objs processed and enqueued.");
}
#endif
} }
#ifndef PRODUCT #ifndef PRODUCT
@ -4111,7 +4095,7 @@ void CMTask::do_marking_step(double time_target_ms,
// bitmap knows by how much we need to move it as it knows its // bitmap knows by how much we need to move it as it knows its
// granularity). // granularity).
assert(_finger < _region_limit, "invariant"); assert(_finger < _region_limit, "invariant");
HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger); HeapWord* new_finger = _nextMarkBitMap->nextObject(_finger);
// Check if bitmap iteration was aborted while scanning the last object // Check if bitmap iteration was aborted while scanning the last object
if (new_finger >= _region_limit) { if (new_finger >= _region_limit) {
giveup_current_region(); giveup_current_region();

View File

@ -97,7 +97,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
HeapWord* limit = NULL) const; HeapWord* limit = NULL) const;
// conversion utilities // conversion utilities
// XXX Fix these so that offsets are size_t's...
HeapWord* offsetToHeapWord(size_t offset) const { HeapWord* offsetToHeapWord(size_t offset) const {
return _bmStartWord + (offset << _shifter); return _bmStartWord + (offset << _shifter);
} }
@ -105,8 +104,13 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
return pointer_delta(addr, _bmStartWord) >> _shifter; return pointer_delta(addr, _bmStartWord) >> _shifter;
} }
int heapWordDiffToOffsetDiff(size_t diff) const; int heapWordDiffToOffsetDiff(size_t diff) const;
HeapWord* nextWord(HeapWord* addr) {
return offsetToHeapWord(heapWordToOffset(addr) + 1); // The argument addr should be the start address of a valid object
HeapWord* nextObject(HeapWord* addr) {
oop obj = (oop) addr;
HeapWord* res = addr + obj->size();
assert(offsetToHeapWord(heapWordToOffset(res)) == res, "sanity");
return res;
} }
// debugging // debugging

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -252,12 +252,10 @@ inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
start_offset = _bm.get_next_one_offset(start_offset, end_offset); start_offset = _bm.get_next_one_offset(start_offset, end_offset);
while (start_offset < end_offset) { while (start_offset < end_offset) {
HeapWord* obj_addr = offsetToHeapWord(start_offset);
oop obj = (oop) obj_addr;
if (!cl->do_bit(start_offset)) { if (!cl->do_bit(start_offset)) {
return false; return false;
} }
HeapWord* next_addr = MIN2(obj_addr + obj->size(), end_addr); HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
BitMap::idx_t next_offset = heapWordToOffset(next_addr); BitMap::idx_t next_offset = heapWordToOffset(next_addr);
start_offset = _bm.get_next_one_offset(next_offset, end_offset); start_offset = _bm.get_next_one_offset(next_offset, end_offset);
} }

View File

@ -409,7 +409,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate(
// heap remains parsable. // heap remains parsable.
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded(); const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
const bool softrefs_clear = collector_policy()->all_soft_refs_clear(); const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
if (limit_exceeded && softrefs_clear) { if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true; *gc_overhead_limit_was_exceeded = true;
size_policy()->set_gc_overhead_limit_exceeded(false); size_policy()->set_gc_overhead_limit_exceeded(false);

View File

@ -948,6 +948,8 @@ void MutableNUMASpace::LGRPSpace::scan_pages(size_t page_size, size_t page_count
break; break;
} }
if (e != scan_end) { if (e != scan_end) {
assert(e < scan_end, err_msg("e: " PTR_FORMAT " scan_end: " PTR_FORMAT, e, scan_end));
if ((page_expected.size != page_size || page_expected.lgrp_id != lgrp_id()) if ((page_expected.size != page_size || page_expected.lgrp_id != lgrp_id())
&& page_expected.size != 0) { && page_expected.size != 0) {
os::free_memory(s, pointer_delta(e, s, sizeof(char)), page_size); os::free_memory(s, pointer_delta(e, s, sizeof(char)), page_size);

View File

@ -186,7 +186,8 @@ class AbstractInterpreter: AllStatic {
int caller_actual_parameters, int caller_actual_parameters,
int callee_params, int callee_params,
int callee_locals, int callee_locals,
bool is_top_frame) { bool is_top_frame,
bool is_bottom_frame) {
return layout_activation(method, return layout_activation(method,
temps, temps,
popframe_args, popframe_args,
@ -196,7 +197,8 @@ class AbstractInterpreter: AllStatic {
callee_locals, callee_locals,
(frame*)NULL, (frame*)NULL,
(frame*)NULL, (frame*)NULL,
is_top_frame); is_top_frame,
is_bottom_frame);
} }
static int layout_activation(Method* method, static int layout_activation(Method* method,
@ -208,7 +210,8 @@ class AbstractInterpreter: AllStatic {
int callee_locals, int callee_locals,
frame* caller, frame* caller,
frame* interpreter_frame, frame* interpreter_frame,
bool is_top_frame); bool is_top_frame,
bool is_bottom_frame);
// Runtime support // Runtime support
static bool is_not_reached( methodHandle method, int bci); static bool is_not_reached( methodHandle method, int bci);

View File

@ -84,15 +84,13 @@ void Rewriter::make_constant_pool_cache(TRAPS) {
const int length = _cp_cache_map.length(); const int length = _cp_cache_map.length();
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data(); ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
ConstantPoolCache* cache = ConstantPoolCache* cache =
ConstantPoolCache::allocate(loader_data, length, CHECK); ConstantPoolCache::allocate(loader_data, length, _cp_cache_map,
_invokedynamic_references_map, CHECK);
// initialize object cache in constant pool // initialize object cache in constant pool
_pool->initialize_resolved_references(loader_data, _resolved_references_map, _pool->initialize_resolved_references(loader_data, _resolved_references_map,
_resolved_reference_limit, _resolved_reference_limit,
CHECK); CHECK);
No_Safepoint_Verifier nsv;
cache->initialize(_cp_cache_map, _invokedynamic_references_map);
_pool->set_cache(cache); _pool->set_cache(cache);
cache->set_constant_pool(_pool()); cache->set_constant_pool(_pool());
} }

View File

@ -620,7 +620,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded(); const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
const bool softrefs_clear = all_soft_refs_clear(); const bool softrefs_clear = all_soft_refs_clear();
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
if (limit_exceeded && softrefs_clear) { if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true; *gc_overhead_limit_was_exceeded = true;
size_policy()->set_gc_overhead_limit_exceeded(false); size_policy()->set_gc_overhead_limit_exceeded(false);

View File

@ -112,12 +112,19 @@ public:
char* region_base(int i) { return _header._space[i]._base; } char* region_base(int i) { return _header._space[i]._base; }
struct FileMapHeader* header() { return &_header; } struct FileMapHeader* header() { return &_header; }
static void set_current_info(FileMapInfo* info) { _current_info = info; } static void set_current_info(FileMapInfo* info) {
static FileMapInfo* current_info() { return _current_info; } CDS_ONLY(_current_info = info;)
}
static FileMapInfo* current_info() {
CDS_ONLY(return _current_info;)
NOT_CDS(return NULL;)
}
static void assert_mark(bool check); static void assert_mark(bool check);
// File manipulation. // File manipulation.
bool initialize(); bool initialize() NOT_CDS_RETURN_(false);
bool open_for_read(); bool open_for_read();
void open_for_write(); void open_for_write();
void write_header(); void write_header();
@ -141,7 +148,7 @@ public:
void fail_continue(const char *msg, ...); void fail_continue(const char *msg, ...);
// Return true if given address is in the mapped shared space. // Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p); bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
}; };
#endif // SHARE_VM_MEMORY_FILEMAP_HPP #endif // SHARE_VM_MEMORY_FILEMAP_HPP

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -52,7 +52,6 @@ const bool metaspace_slow_verify = false;
const uint metadata_deallocate_a_lot_block = 10; const uint metadata_deallocate_a_lot_block = 10;
const uint metadata_deallocate_a_lock_chunk = 3; const uint metadata_deallocate_a_lock_chunk = 3;
size_t const allocation_from_dictionary_limit = 64 * K; size_t const allocation_from_dictionary_limit = 64 * K;
const size_t metadata_deallocate = 0xf5f5f5f5;
MetaWord* last_allocated = 0; MetaWord* last_allocated = 0;
@ -2440,7 +2439,8 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
free_chunks_capacity_bytes / K, free_chunks_capacity_bytes / K,
used_and_free / K, used_and_free / K,
capacity_bytes / K); capacity_bytes / K);
assert(used_and_free == capacity_bytes, "Accounting is wrong"); // Accounting can only be correct if we got the values during a safepoint
assert(!SafepointSynchronize::is_at_safepoint() || used_and_free == capacity_bytes, "Accounting is wrong");
} }
// Print total fragmentation for class and data metaspaces separately // Print total fragmentation for class and data metaspaces separately

View File

@ -885,6 +885,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// the actual alignment depends on its size. // the actual alignment depends on its size.
Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment)); Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment); size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops");
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr); ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);

View File

@ -55,11 +55,24 @@ ConstMethod::ConstMethod(int byte_code_size,
set_stackmap_data(NULL); set_stackmap_data(NULL);
set_code_size(byte_code_size); set_code_size(byte_code_size);
set_constMethod_size(size); set_constMethod_size(size);
set_inlined_tables_length(sizes); set_inlined_tables_length(sizes); // sets _flags
set_method_type(method_type); set_method_type(method_type);
assert(this->size() == size, "wrong size for object"); assert(this->size() == size, "wrong size for object");
set_name_index(0);
set_signature_index(0);
set_constants(NULL);
set_max_stack(0);
set_max_locals(0);
set_method_idnum(0);
set_size_of_parameters(0);
} }
// Accessor that copies to metadata.
void ConstMethod::copy_stackmap_data(ClassLoaderData* loader_data,
u1* sd, int length, TRAPS) {
_stackmap_data = MetadataFactory::new_array<u1>(loader_data, length, CHECK);
memcpy((void*)_stackmap_data->adr_at(0), (void*)sd, length);
}
// Deallocate metadata fields associated with ConstMethod* // Deallocate metadata fields associated with ConstMethod*
void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) { void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {

View File

@ -280,6 +280,7 @@ public:
// stackmap table data // stackmap table data
Array<u1>* stackmap_data() const { return _stackmap_data; } Array<u1>* stackmap_data() const { return _stackmap_data; }
void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; } void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
bool has_stackmap_table() const { return _stackmap_data != NULL; } bool has_stackmap_table() const { return _stackmap_data != NULL; }
void init_fingerprint() { void init_fingerprint() {

View File

@ -44,6 +44,8 @@
void ConstantPoolCacheEntry::initialize_entry(int index) { void ConstantPoolCacheEntry::initialize_entry(int index) {
assert(0 < index && index < 0x10000, "sanity check"); assert(0 < index && index < 0x10000, "sanity check");
_indices = index; _indices = index;
_f1 = NULL;
_f2 = _flags = 0;
assert(constant_pool_index() == index, ""); assert(constant_pool_index() == index, "");
} }
@ -533,13 +535,17 @@ void ConstantPoolCacheEntry::verify(outputStream* st) const {
// Implementation of ConstantPoolCache // Implementation of ConstantPoolCache
ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data, int length, TRAPS) { ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
int length,
const intStack& index_map,
const intStack& invokedynamic_map, TRAPS) {
int size = ConstantPoolCache::size(length); int size = ConstantPoolCache::size(length);
return new (loader_data, size, false, THREAD) ConstantPoolCache(length); return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
} }
void ConstantPoolCache::initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map) { void ConstantPoolCache::initialize(const intArray& inverse_index_map,
const intArray& invokedynamic_references_map) {
assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache"); assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
for (int i = 0; i < length(); i++) { for (int i = 0; i < length(); i++) {
ConstantPoolCacheEntry* e = entry_at(i); ConstantPoolCacheEntry* e = entry_at(i);

View File

@ -377,14 +377,21 @@ class ConstantPoolCache: public MetaspaceObj {
debug_only(friend class ClassVerifier;) debug_only(friend class ClassVerifier;)
// Constructor // Constructor
ConstantPoolCache(int length) : _length(length), _constant_pool(NULL) { ConstantPoolCache(int length, const intStack& inverse_index_map,
const intStack& invokedynamic_references_map) :
_length(length), _constant_pool(NULL) {
initialize(inverse_index_map, invokedynamic_references_map);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
assert(entry_at(i)->is_f1_null(), "Failed to clear?"); assert(entry_at(i)->is_f1_null(), "Failed to clear?");
} }
} }
// Initialization
void initialize(const intArray& inverse_index_map, const intArray& invokedynamic_references_map);
public: public:
static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length, TRAPS); static ConstantPoolCache* allocate(ClassLoaderData* loader_data, int length,
const intStack& inverse_index_map,
const intStack& invokedynamic_references_map, TRAPS);
bool is_constantPoolCache() const { return true; } bool is_constantPoolCache() const { return true; }
int length() const { return _length; } int length() const { return _length; }
@ -405,9 +412,6 @@ class ConstantPoolCache: public MetaspaceObj {
friend class ConstantPoolCacheEntry; friend class ConstantPoolCacheEntry;
public: public:
// Initialization
void initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map);
// Accessors // Accessors
void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; } void set_constant_pool(ConstantPool* pool) { _constant_pool = pool; }
ConstantPool* constant_pool() const { return _constant_pool; } ConstantPool* constant_pool() const { return _constant_pool; }

View File

@ -165,7 +165,8 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
volatile int InstanceKlass::_total_instanceKlass_count = 0; volatile int InstanceKlass::_total_instanceKlass_count = 0;
Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data, InstanceKlass* InstanceKlass::allocate_instance_klass(
ClassLoaderData* loader_data,
int vtable_len, int vtable_len,
int itable_len, int itable_len,
int static_field_size, int static_field_size,
@ -207,10 +208,35 @@ Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
access_flags, is_anonymous); access_flags, is_anonymous);
} }
// Check for pending exception before adding to the loader data and incrementing
// class count. Can get OOM here.
if (HAS_PENDING_EXCEPTION) {
return NULL;
}
// Add all classes to our internal class loader list here,
// including classes in the bootstrap (NULL) class loader.
loader_data->add_class(ik);
Atomic::inc(&_total_instanceKlass_count); Atomic::inc(&_total_instanceKlass_count);
return ik; return ik;
} }
// copy method ordering from resource area to Metaspace
void InstanceKlass::copy_method_ordering(intArray* m, TRAPS) {
if (m != NULL) {
// allocate a new array and copy contents (memcpy?)
_method_ordering = MetadataFactory::new_array<int>(class_loader_data(), m->length(), CHECK);
for (int i = 0; i < m->length(); i++) {
_method_ordering->at_put(i, m->at(i));
}
} else {
_method_ordering = Universe::the_empty_int_array();
}
}
InstanceKlass::InstanceKlass(int vtable_len, InstanceKlass::InstanceKlass(int vtable_len,
int itable_len, int itable_len,
int static_field_size, int static_field_size,
@ -220,72 +246,116 @@ InstanceKlass::InstanceKlass(int vtable_len,
bool is_anonymous) { bool is_anonymous) {
No_Safepoint_Verifier no_safepoint; // until k becomes parsable No_Safepoint_Verifier no_safepoint; // until k becomes parsable
int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size, int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
access_flags.is_interface(), is_anonymous); access_flags.is_interface(), is_anonymous);
// The sizes of these these three variables are used for determining the set_vtable_length(vtable_len);
// size of the instanceKlassOop. It is critical that these are set to the right set_itable_length(itable_len);
// sizes before the first GC, i.e., when we allocate the mirror. set_static_field_size(static_field_size);
this->set_vtable_length(vtable_len); set_nonstatic_oop_map_size(nonstatic_oop_map_size);
this->set_itable_length(itable_len); set_access_flags(access_flags);
this->set_static_field_size(static_field_size); _misc_flags = 0; // initialize to zero
this->set_nonstatic_oop_map_size(nonstatic_oop_map_size); set_is_anonymous(is_anonymous);
this->set_access_flags(access_flags); assert(size() == iksize, "wrong size for object");
this->set_is_anonymous(is_anonymous);
assert(this->size() == size, "wrong size for object");
this->set_array_klasses(NULL); set_array_klasses(NULL);
this->set_methods(NULL); set_methods(NULL);
this->set_method_ordering(NULL); set_method_ordering(NULL);
this->set_local_interfaces(NULL); set_local_interfaces(NULL);
this->set_transitive_interfaces(NULL); set_transitive_interfaces(NULL);
this->init_implementor(); init_implementor();
this->set_fields(NULL, 0); set_fields(NULL, 0);
this->set_constants(NULL); set_constants(NULL);
this->set_class_loader_data(NULL); set_class_loader_data(NULL);
this->set_protection_domain(NULL); set_protection_domain(NULL);
this->set_signers(NULL); set_signers(NULL);
this->set_source_file_name(NULL); set_source_file_name(NULL);
this->set_source_debug_extension(NULL, 0); set_source_debug_extension(NULL, 0);
this->set_array_name(NULL); set_array_name(NULL);
this->set_inner_classes(NULL); set_inner_classes(NULL);
this->set_static_oop_field_count(0); set_static_oop_field_count(0);
this->set_nonstatic_field_size(0); set_nonstatic_field_size(0);
this->set_is_marked_dependent(false); set_is_marked_dependent(false);
this->set_init_state(InstanceKlass::allocated); set_init_state(InstanceKlass::allocated);
this->set_init_thread(NULL); set_init_thread(NULL);
this->set_init_lock(NULL); set_init_lock(NULL);
this->set_reference_type(rt); set_reference_type(rt);
this->set_oop_map_cache(NULL); set_oop_map_cache(NULL);
this->set_jni_ids(NULL); set_jni_ids(NULL);
this->set_osr_nmethods_head(NULL); set_osr_nmethods_head(NULL);
this->set_breakpoints(NULL); set_breakpoints(NULL);
this->init_previous_versions(); init_previous_versions();
this->set_generic_signature(NULL); set_generic_signature(NULL);
this->release_set_methods_jmethod_ids(NULL); release_set_methods_jmethod_ids(NULL);
this->release_set_methods_cached_itable_indices(NULL); release_set_methods_cached_itable_indices(NULL);
this->set_annotations(NULL); set_annotations(NULL);
this->set_jvmti_cached_class_field_map(NULL); set_jvmti_cached_class_field_map(NULL);
this->set_initial_method_idnum(0); set_initial_method_idnum(0);
_dependencies = NULL;
set_jvmti_cached_class_field_map(NULL);
set_cached_class_file(NULL, 0);
set_initial_method_idnum(0);
set_minor_version(0);
set_major_version(0);
NOT_PRODUCT(_verify_count = 0;)
// initialize the non-header words to zero // initialize the non-header words to zero
intptr_t* p = (intptr_t*)this; intptr_t* p = (intptr_t*)this;
for (int index = InstanceKlass::header_size(); index < size; index++) { for (int index = InstanceKlass::header_size(); index < iksize; index++) {
p[index] = NULL_WORD; p[index] = NULL_WORD;
} }
// Set temporary value until parseClassFile updates it with the real instance // Set temporary value until parseClassFile updates it with the real instance
// size. // size.
this->set_layout_helper(Klass::instance_layout_helper(0, true)); set_layout_helper(Klass::instance_layout_helper(0, true));
} }
void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data,
Array<Method*>* methods) {
if (methods != NULL && methods != Universe::the_empty_method_array()) {
for (int i = 0; i < methods->length(); i++) {
Method* method = methods->at(i);
if (method == NULL) continue; // maybe null if error processing
// Only want to delete methods that are not executing for RedefineClasses.
// The previous version will point to them so they're not totally dangling
assert (!method->on_stack(), "shouldn't be called with methods on stack");
MetadataFactory::free_metadata(loader_data, method);
}
MetadataFactory::free_array<Method*>(loader_data, methods);
}
}
void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data,
Klass* super_klass,
Array<Klass*>* local_interfaces,
Array<Klass*>* transitive_interfaces) {
// Only deallocate transitive interfaces if not empty, same as super class
// or same as local interfaces. See code in parseClassFile.
Array<Klass*>* ti = transitive_interfaces;
if (ti != Universe::the_empty_klass_array() && ti != local_interfaces) {
// check that the interfaces don't come from super class
Array<Klass*>* sti = (super_klass == NULL) ? NULL :
InstanceKlass::cast(super_klass)->transitive_interfaces();
if (ti != sti) {
MetadataFactory::free_array<Klass*>(loader_data, ti);
}
}
// local interfaces can be empty
if (local_interfaces != Universe::the_empty_klass_array()) {
MetadataFactory::free_array<Klass*>(loader_data, local_interfaces);
}
}
// This function deallocates the metadata and C heap pointers that the // This function deallocates the metadata and C heap pointers that the
// InstanceKlass points to. // InstanceKlass points to.
void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// Orphan the mirror first, CMS thinks it's still live. // Orphan the mirror first, CMS thinks it's still live.
java_lang_Class::set_klass(java_mirror(), NULL); if (java_mirror() != NULL) {
java_lang_Class::set_klass(java_mirror(), NULL);
}
// Need to take this class off the class loader data list. // Need to take this class off the class loader data list.
loader_data->remove_class(this); loader_data->remove_class(this);
@ -300,17 +370,7 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// reference counting symbol names. // reference counting symbol names.
release_C_heap_structures(); release_C_heap_structures();
Array<Method*>* ms = methods(); deallocate_methods(loader_data, methods());
if (ms != Universe::the_empty_method_array()) {
for (int i = 0; i <= methods()->length() -1 ; i++) {
Method* method = methods()->at(i);
// Only want to delete methods that are not executing for RedefineClasses.
// The previous version will point to them so they're not totally dangling
assert (!method->on_stack(), "shouldn't be called with methods on stack");
MetadataFactory::free_metadata(loader_data, method);
}
MetadataFactory::free_array<Method*>(loader_data, methods());
}
set_methods(NULL); set_methods(NULL);
if (method_ordering() != Universe::the_empty_int_array()) { if (method_ordering() != Universe::the_empty_int_array()) {
@ -327,24 +387,8 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
} }
set_secondary_supers(NULL); set_secondary_supers(NULL);
// Only deallocate transitive interfaces if not empty, same as super class deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces());
// or same as local interfaces. See code in parseClassFile.
Array<Klass*>* ti = transitive_interfaces();
if (ti != Universe::the_empty_klass_array() && ti != local_interfaces()) {
// check that the interfaces don't come from super class
Array<Klass*>* sti = (super() == NULL) ? NULL :
InstanceKlass::cast(super())->transitive_interfaces();
if (ti != sti) {
MetadataFactory::free_array<Klass*>(loader_data, ti);
}
}
set_transitive_interfaces(NULL); set_transitive_interfaces(NULL);
// local interfaces can be empty
Array<Klass*>* li = local_interfaces();
if (li != Universe::the_empty_klass_array()) {
MetadataFactory::free_array<Klass*>(loader_data, li);
}
set_local_interfaces(NULL); set_local_interfaces(NULL);
MetadataFactory::free_array<jushort>(loader_data, fields()); MetadataFactory::free_array<jushort>(loader_data, fields());
@ -352,9 +396,11 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// If a method from a redefined class is using this constant pool, don't // If a method from a redefined class is using this constant pool, don't
// delete it, yet. The new class's previous version will point to this. // delete it, yet. The new class's previous version will point to this.
assert (!constants()->on_stack(), "shouldn't be called if anything is onstack"); if (constants() != NULL) {
MetadataFactory::free_metadata(loader_data, constants()); assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
set_constants(NULL); MetadataFactory::free_metadata(loader_data, constants());
set_constants(NULL);
}
if (inner_classes() != Universe::the_empty_short_array()) { if (inner_classes() != Universe::the_empty_short_array()) {
MetadataFactory::free_array<jushort>(loader_data, inner_classes()); MetadataFactory::free_array<jushort>(loader_data, inner_classes());
@ -2785,7 +2831,7 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr(); st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr(); st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
st->print(BULLET"init_lock: "); ((oop)init_lock())->print_value_on(st); st->cr(); st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr();
if (source_file_name() != NULL) { if (source_file_name() != NULL) {
st->print(BULLET"source file: "); st->print(BULLET"source file: ");
source_file_name()->print_value_on(st); source_file_name()->print_value_on(st);

View File

@ -147,7 +147,8 @@ class InstanceKlass: public Klass {
AccessFlags access_flags, AccessFlags access_flags,
bool is_anonymous); bool is_anonymous);
public: public:
static Klass* allocate_instance_klass(ClassLoaderData* loader_data, static InstanceKlass* allocate_instance_klass(
ClassLoaderData* loader_data,
int vtable_len, int vtable_len,
int itable_len, int itable_len,
int static_field_size, int static_field_size,
@ -266,9 +267,10 @@ class InstanceKlass: public Klass {
u1 _init_state; // state of class u1 _init_state; // state of class
u1 _reference_type; // reference type u1 _reference_type; // reference type
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
NOT_PRODUCT(int _verify_count;) // to avoid redundant verifies
// Method array. // Method array.
Array<Method*>* _methods; Array<Method*>* _methods;
// Interface (Klass*s) this class declares locally to implement. // Interface (Klass*s) this class declares locally to implement.
@ -356,16 +358,19 @@ class InstanceKlass: public Klass {
// method ordering // method ordering
Array<int>* method_ordering() const { return _method_ordering; } Array<int>* method_ordering() const { return _method_ordering; }
void set_method_ordering(Array<int>* m) { _method_ordering = m; } void set_method_ordering(Array<int>* m) { _method_ordering = m; }
void copy_method_ordering(intArray* m, TRAPS);
// interfaces // interfaces
Array<Klass*>* local_interfaces() const { return _local_interfaces; } Array<Klass*>* local_interfaces() const { return _local_interfaces; }
void set_local_interfaces(Array<Klass*>* a) { void set_local_interfaces(Array<Klass*>* a) {
guarantee(_local_interfaces == NULL || a == NULL, "Just checking"); guarantee(_local_interfaces == NULL || a == NULL, "Just checking");
_local_interfaces = a; } _local_interfaces = a; }
Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; } Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; }
void set_transitive_interfaces(Array<Klass*>* a) { void set_transitive_interfaces(Array<Klass*>* a) {
guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking"); guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking");
_transitive_interfaces = a; } _transitive_interfaces = a;
}
private: private:
friend class fieldDescriptor; friend class fieldDescriptor;
@ -381,10 +386,9 @@ class InstanceKlass: public Klass {
int java_fields_count() const { return (int)_java_fields_count; } int java_fields_count() const { return (int)_java_fields_count; }
Array<u2>* fields() const { return _fields; } Array<u2>* fields() const { return _fields; }
void set_fields(Array<u2>* f, u2 java_fields_count) { void set_fields(Array<u2>* f, u2 java_fields_count) {
guarantee(_fields == NULL || f == NULL, "Just checking"); guarantee(_fields == NULL || f == NULL, "Just checking");
_fields = f; _fields = f;
_java_fields_count = java_fields_count; _java_fields_count = java_fields_count;
} }
@ -588,7 +592,7 @@ class InstanceKlass: public Klass {
// symbol unloading support (refcount already added) // symbol unloading support (refcount already added)
Symbol* array_name() { return _array_name; } Symbol* array_name() { return _array_name; }
void set_array_name(Symbol* name) { assert(_array_name == NULL, "name already created"); _array_name = name; } void set_array_name(Symbol* name) { assert(_array_name == NULL || name == NULL, "name already created"); _array_name = name; }
// nonstatic oop-map blocks // nonstatic oop-map blocks
static int nonstatic_oop_map_size(unsigned int oop_map_count) { static int nonstatic_oop_map_size(unsigned int oop_map_count) {
@ -914,8 +918,15 @@ class InstanceKlass: public Klass {
void clean_method_data(BoolObjectClosure* is_alive); void clean_method_data(BoolObjectClosure* is_alive);
// Explicit metaspace deallocation of fields // Explicit metaspace deallocation of fields
// For RedefineClasses, we need to deallocate instanceKlasses // For RedefineClasses and class file parsing errors, we need to deallocate
// instanceKlasses and the metadata they point to.
void deallocate_contents(ClassLoaderData* loader_data); void deallocate_contents(ClassLoaderData* loader_data);
static void deallocate_methods(ClassLoaderData* loader_data,
Array<Method*>* methods);
void static deallocate_interfaces(ClassLoaderData* loader_data,
Klass* super_klass,
Array<Klass*>* local_interfaces,
Array<Klass*>* transitive_interfaces);
// The constant pool is on stack if any of the methods are executing or // The constant pool is on stack if any of the methods are executing or
// referenced by handles. // referenced by handles.

View File

@ -146,16 +146,16 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
Klass::Klass() { Klass::Klass() {
Klass* k = this; Klass* k = this;
{ // Preinitialize supertype information. // Preinitialize supertype information.
// A later call to initialize_supers() may update these settings: // A later call to initialize_supers() may update these settings:
set_super(NULL); set_super(NULL);
for (juint i = 0; i < Klass::primary_super_limit(); i++) { for (juint i = 0; i < Klass::primary_super_limit(); i++) {
_primary_supers[i] = NULL; _primary_supers[i] = NULL;
}
set_secondary_supers(NULL);
_primary_supers[0] = k;
set_super_check_offset(in_bytes(primary_supers_offset()));
} }
set_secondary_supers(NULL);
set_secondary_super_cache(NULL);
_primary_supers[0] = k;
set_super_check_offset(in_bytes(primary_supers_offset()));
set_java_mirror(NULL); set_java_mirror(NULL);
set_modifier_flags(0); set_modifier_flags(0);

View File

@ -79,7 +79,6 @@
// [last_biased_lock_bulk_revocation_time] (64 bits) // [last_biased_lock_bulk_revocation_time] (64 bits)
// [prototype_header] // [prototype_header]
// [biased_lock_revocation_count] // [biased_lock_revocation_count]
// [verify_count ] - not in product
// [alloc_count ] // [alloc_count ]
// [_modified_oops] // [_modified_oops]
// [_accumulated_modified_oops] // [_accumulated_modified_oops]
@ -172,10 +171,6 @@ class Klass : public Metadata {
markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type
jint _biased_lock_revocation_count; jint _biased_lock_revocation_count;
#ifndef PRODUCT
int _verify_count; // to avoid redundant verifies
#endif
juint _alloc_count; // allocation profiling support juint _alloc_count; // allocation profiling support
TRACE_DEFINE_KLASS_TRACE_ID; TRACE_DEFINE_KLASS_TRACE_ID;

View File

@ -77,22 +77,19 @@ Method* Method::allocate(ClassLoaderData* loader_data,
return new (loader_data, size, false, THREAD) Method(cm, access_flags, size); return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
} }
Method::Method(ConstMethod* xconst, Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
AccessFlags access_flags, int size) {
No_Safepoint_Verifier no_safepoint; No_Safepoint_Verifier no_safepoint;
set_constMethod(xconst); set_constMethod(xconst);
set_access_flags(access_flags); set_access_flags(access_flags);
set_method_size(size); set_method_size(size);
set_name_index(0);
set_signature_index(0);
#ifdef CC_INTERP #ifdef CC_INTERP
set_result_index(T_VOID); set_result_index(T_VOID);
#endif #endif
set_constants(NULL);
set_max_stack(0);
set_max_locals(0);
set_intrinsic_id(vmIntrinsics::_none); set_intrinsic_id(vmIntrinsics::_none);
set_jfr_towrite(false); set_jfr_towrite(false);
set_force_inline(false);
set_hidden(false);
set_dont_inline(false);
set_method_data(NULL); set_method_data(NULL);
set_interpreter_throwout_count(0); set_interpreter_throwout_count(0);
set_vtable_index(Method::garbage_vtable_index); set_vtable_index(Method::garbage_vtable_index);

View File

@ -652,23 +652,25 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
// Set the method back-pointer. // Set the method back-pointer.
_method = method(); _method = method();
if (TieredCompilation) { _invocation_counter.init();
_invocation_counter.init(); _backedge_counter.init();
_backedge_counter.init(); _invocation_counter_start = 0;
_invocation_counter_start = 0; _backedge_counter_start = 0;
_backedge_counter_start = 0; _num_loops = 0;
_num_loops = 0; _num_blocks = 0;
_num_blocks = 0; _highest_comp_level = 0;
_highest_comp_level = 0; _highest_osr_comp_level = 0;
_highest_osr_comp_level = 0; _would_profile = true;
_would_profile = true;
}
set_creation_mileage(mileage_of(method())); set_creation_mileage(mileage_of(method()));
// Initialize flags and trap history. // Initialize flags and trap history.
_nof_decompiles = 0; _nof_decompiles = 0;
_nof_overflow_recompiles = 0; _nof_overflow_recompiles = 0;
_nof_overflow_traps = 0; _nof_overflow_traps = 0;
_eflags = 0;
_arg_local = 0;
_arg_stack = 0;
_arg_returned = 0;
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align"); assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
Copy::zero_to_words((HeapWord*) &_trap_hist, Copy::zero_to_words((HeapWord*) &_trap_hist,
sizeof(_trap_hist) / sizeof(HeapWord)); sizeof(_trap_hist) / sizeof(HeapWord));
@ -677,6 +679,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
// corresponding data cells. // corresponding data cells.
int data_size = 0; int data_size = 0;
int empty_bc_count = 0; // number of bytecodes lacking data int empty_bc_count = 0; // number of bytecodes lacking data
_data[0] = 0; // apparently not set below.
BytecodeStream stream(method); BytecodeStream stream(method);
Bytecodes::Code c; Bytecodes::Code c;
while ((c = stream.next()) >= 0) { while ((c = stream.next()) >= 0) {
@ -710,6 +713,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
post_initialize(&stream); post_initialize(&stream);
set_size(object_size); set_size(object_size);
} }
// Get a measure of how much mileage the method has on it. // Get a measure of how much mileage the method has on it.

View File

@ -187,31 +187,6 @@ public:
#endif #endif
}; };
//------------------------------LRG_List---------------------------------------
// Map Node indices to Live RanGe indices.
// Array lookup in the optimized case.
class LRG_List : public ResourceObj {
friend class VMStructs;
uint _cnt, _max;
uint* _lidxs;
ReallocMark _nesting; // assertion check for reallocations
public:
LRG_List( uint max );
uint lookup( uint nidx ) const {
return _lidxs[nidx];
}
uint operator[] (uint nidx) const { return lookup(nidx); }
void map( uint nidx, uint lidx ) {
assert( nidx < _cnt, "oob" );
_lidxs[nidx] = lidx;
}
void extend( uint nidx, uint lidx );
uint Size() const { return _cnt; }
};
//------------------------------IFG-------------------------------------------- //------------------------------IFG--------------------------------------------
// InterFerence Graph // InterFerence Graph
// An undirected graph implementation. Created with a fixed number of // An undirected graph implementation. Created with a fixed number of

View File

@ -892,7 +892,7 @@ Compile::Compile( ciEnv* ci_env,
: Phase(Compiler), : Phase(Compiler),
_env(ci_env), _env(ci_env),
_log(ci_env->log()), _log(ci_env->log()),
_compile_id(-1), _compile_id(0),
_save_argument_registers(save_arg_registers), _save_argument_registers(save_arg_registers),
_method(NULL), _method(NULL),
_stub_name(stub_name), _stub_name(stub_name),

View File

@ -33,11 +33,35 @@
#include "opto/regmask.hpp" #include "opto/regmask.hpp"
class Block; class Block;
class LRG_List;
class PhaseCFG; class PhaseCFG;
class VectorSet; class VectorSet;
class IndexSet; class IndexSet;
//------------------------------LRG_List---------------------------------------
// Map Node indices to Live RanGe indices.
// Array lookup in the optimized case.
class LRG_List : public ResourceObj {
friend class VMStructs;
uint _cnt, _max;
uint* _lidxs;
ReallocMark _nesting; // assertion check for reallocations
public:
LRG_List( uint max );
uint lookup( uint nidx ) const {
return _lidxs[nidx];
}
uint operator[] (uint nidx) const { return lookup(nidx); }
void map( uint nidx, uint lidx ) {
assert( nidx < _cnt, "oob" );
_lidxs[nidx] = lidx;
}
void extend( uint nidx, uint lidx );
uint Size() const { return _cnt; }
};
//------------------------------PhaseLive-------------------------------------- //------------------------------PhaseLive--------------------------------------
// Compute live-in/live-out // Compute live-in/live-out
class PhaseLive : public Phase { class PhaseLive : public Phase {

View File

@ -890,7 +890,7 @@ void JvmtiSuspendControl::print() {
tty->print("Suspended Threads: ["); tty->print("Suspended Threads: [");
for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
#if JVMTI_TRACE #ifdef JVMTI_TRACE
const char *name = JvmtiTrace::safe_get_thread_name(thread); const char *name = JvmtiTrace::safe_get_thread_name(thread);
#else #else
const char *name = ""; const char *name = "";

View File

@ -43,10 +43,10 @@
// Support tracing except in product build on the client compiler // Support tracing except in product build on the client compiler
#ifndef PRODUCT #ifndef PRODUCT
#define JVMTI_TRACE 1 #define JVMTI_TRACE
#else #else
#ifdef COMPILER2 #ifdef COMPILER2
#define JVMTI_TRACE 1 #define JVMTI_TRACE
#endif #endif
#endif #endif

View File

@ -1381,6 +1381,40 @@ bool Arguments::should_auto_select_low_pause_collector() {
return false; return false;
} }
void Arguments::set_use_compressed_oops() {
#ifndef ZERO
#ifdef _LP64
// MaxHeapSize is not set up properly at this point, but
// the only value that can override MaxHeapSize if we are
// to use UseCompressedOops is InitialHeapSize.
size_t max_heap_size = MAX2(MaxHeapSize, InitialHeapSize);
if (max_heap_size <= max_heap_for_compressed_oops()) {
#if !defined(COMPILER1) || defined(TIERED)
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
#endif
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
// Cannot allocate guard pages for implicit checks in indexed addressing
// mode, when large pages are specified on windows.
// This flag could be switched ON if narrow oop base address is set to 0,
// see code in Universe::initialize_heap().
Universe::set_narrow_oop_use_implicit_null_checks(false);
}
#endif // _WIN64
} else {
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
warning("Max heap size too large for Compressed Oops");
FLAG_SET_DEFAULT(UseCompressedOops, false);
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
}
}
#endif // _LP64
#endif // ZERO
}
void Arguments::set_ergonomics_flags() { void Arguments::set_ergonomics_flags() {
if (os::is_server_class_machine()) { if (os::is_server_class_machine()) {
@ -1410,30 +1444,7 @@ void Arguments::set_ergonomics_flags() {
#ifndef ZERO #ifndef ZERO
#ifdef _LP64 #ifdef _LP64
// Check that UseCompressedOops can be set with the max heap size allocated set_use_compressed_oops();
// by ergonomics.
if (MaxHeapSize <= max_heap_for_compressed_oops()) {
#if !defined(COMPILER1) || defined(TIERED)
if (FLAG_IS_DEFAULT(UseCompressedOops)) {
FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
#endif
#ifdef _WIN64
if (UseLargePages && UseCompressedOops) {
// Cannot allocate guard pages for implicit checks in indexed addressing
// mode, when large pages are specified on windows.
// This flag could be switched ON if narrow oop base address is set to 0,
// see code in Universe::initialize_heap().
Universe::set_narrow_oop_use_implicit_null_checks(false);
}
#endif // _WIN64
} else {
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
warning("Max heap size too large for Compressed Oops");
FLAG_SET_DEFAULT(UseCompressedOops, false);
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
}
}
// UseCompressedOops must be on for UseCompressedKlassPointers to be on. // UseCompressedOops must be on for UseCompressedKlassPointers to be on.
if (!UseCompressedOops) { if (!UseCompressedOops) {
if (UseCompressedKlassPointers) { if (UseCompressedKlassPointers) {
@ -1813,6 +1824,13 @@ void Arguments::check_deprecated_gcs() {
} }
} }
void Arguments::check_deprecated_gc_flags() {
if (FLAG_IS_CMDLINE(MaxGCMinorPauseMillis)) {
warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
"and will likely be removed in future release");
}
}
// Check stack pages settings // Check stack pages settings
bool Arguments::check_stack_pages() bool Arguments::check_stack_pages()
{ {
@ -2273,10 +2291,12 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} }
#if !INCLUDE_JVMTI #if !INCLUDE_JVMTI
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
warning("profiling and debugging agents are not supported in this VM"); jio_fprintf(defaultStream::error_stream(),
} else "Profiling and debugging agents are not supported in this VM\n");
return JNI_ERR;
}
#endif // !INCLUDE_JVMTI #endif // !INCLUDE_JVMTI
add_init_library(name, options); add_init_library(name, options);
} }
// -agentlib and -agentpath // -agentlib and -agentpath
} else if (match_option(option, "-agentlib:", &tail) || } else if (match_option(option, "-agentlib:", &tail) ||
@ -2293,16 +2313,19 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} }
#if !INCLUDE_JVMTI #if !INCLUDE_JVMTI
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
warning("profiling and debugging agents are not supported in this VM"); jio_fprintf(defaultStream::error_stream(),
} else "Profiling and debugging agents are not supported in this VM\n");
return JNI_ERR;
}
#endif // !INCLUDE_JVMTI #endif // !INCLUDE_JVMTI
add_init_agent(name, options, is_absolute_path); add_init_agent(name, options, is_absolute_path);
} }
// -javaagent // -javaagent
} else if (match_option(option, "-javaagent:", &tail)) { } else if (match_option(option, "-javaagent:", &tail)) {
#if !INCLUDE_JVMTI #if !INCLUDE_JVMTI
warning("Instrumentation agents are not supported in this VM"); jio_fprintf(defaultStream::error_stream(),
"Instrumentation agents are not supported in this VM\n");
return JNI_ERR;
#else #else
if(tail != NULL) { if(tail != NULL) {
char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail); char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
@ -2443,8 +2466,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
#if INCLUDE_FPROF #if INCLUDE_FPROF
_has_profile = true; _has_profile = true;
#else // INCLUDE_FPROF #else // INCLUDE_FPROF
// do we have to exit? jio_fprintf(defaultStream::error_stream(),
warning("Flat profiling is not supported in this VM."); "Flat profiling is not supported in this VM.\n");
return JNI_ERR;
#endif // INCLUDE_FPROF #endif // INCLUDE_FPROF
// -Xaprof // -Xaprof
} else if (match_option(option, "-Xaprof", &tail)) { } else if (match_option(option, "-Xaprof", &tail)) {
@ -2478,8 +2502,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
#if INCLUDE_MANAGEMENT #if INCLUDE_MANAGEMENT
FLAG_SET_CMDLINE(bool, ManagementServer, true); FLAG_SET_CMDLINE(bool, ManagementServer, true);
#else #else
vm_exit_during_initialization( jio_fprintf(defaultStream::output_stream(),
"-Dcom.sun.management is not supported in this VM.", NULL); "-Dcom.sun.management is not supported in this VM.\n");
return JNI_ERR;
#endif #endif
} }
// -Xint // -Xint
@ -2492,16 +2517,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xcomp", &tail)) { } else if (match_option(option, "-Xcomp", &tail)) {
// for testing the compiler; turn off all flags that inhibit compilation // for testing the compiler; turn off all flags that inhibit compilation
set_mode_flags(_comp); set_mode_flags(_comp);
// -Xshare:dump // -Xshare:dump
} else if (match_option(option, "-Xshare:dump", &tail)) { } else if (match_option(option, "-Xshare:dump", &tail)) {
#if !INCLUDE_CDS
vm_exit_during_initialization(
"Dumping a shared archive is not supported in this VM.", NULL);
#else
FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true); FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
set_mode_flags(_int); // Prevent compilation, which creates objects set_mode_flags(_int); // Prevent compilation, which creates objects
#endif
// -Xshare:on // -Xshare:on
} else if (match_option(option, "-Xshare:on", &tail)) { } else if (match_option(option, "-Xshare:on", &tail)) {
FLAG_SET_CMDLINE(bool, UseSharedSpaces, true); FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
@ -2514,7 +2533,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xshare:off", &tail)) { } else if (match_option(option, "-Xshare:off", &tail)) {
FLAG_SET_CMDLINE(bool, UseSharedSpaces, false); FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
// -Xverify // -Xverify
} else if (match_option(option, "-Xverify", &tail)) { } else if (match_option(option, "-Xverify", &tail)) {
if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) { if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
@ -2828,8 +2846,9 @@ SOLARIS_ONLY(
FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true); FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
#if !INCLUDE_MANAGEMENT #if !INCLUDE_MANAGEMENT
} else if (match_option(option, "-XX:+ManagementServer", &tail)) { } else if (match_option(option, "-XX:+ManagementServer", &tail)) {
vm_exit_during_initialization( jio_fprintf(defaultStream::error_stream(),
"ManagementServer is not supported in this VM.", NULL); "ManagementServer is not supported in this VM.\n");
return JNI_ERR;
#endif // INCLUDE_MANAGEMENT #endif // INCLUDE_MANAGEMENT
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
// Skip -XX:Flags= since that case has already been handled // Skip -XX:Flags= since that case has already been handled
@ -3135,7 +3154,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
#if INCLUDE_NMT #if INCLUDE_NMT
MemTracker::init_tracking_options(tail); MemTracker::init_tracking_options(tail);
#else #else
warning("Native Memory Tracking is not supported in this VM"); jio_fprintf(defaultStream::error_stream(),
"Native Memory Tracking is not supported in this VM\n");
return JNI_ERR;
#endif #endif
} }
@ -3254,6 +3275,16 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
force_serial_gc(); force_serial_gc();
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
#if !INCLUDE_CDS #if !INCLUDE_CDS
if (DumpSharedSpaces || RequireSharedSpaces) {
jio_fprintf(defaultStream::error_stream(),
"Shared spaces are not supported in this VM\n");
return JNI_ERR;
}
if ((UseSharedSpaces && FLAG_IS_CMDLINE(UseSharedSpaces)) || PrintSharedSpaces) {
warning("Shared spaces are not supported in this VM");
FLAG_SET_DEFAULT(UseSharedSpaces, false);
FLAG_SET_DEFAULT(PrintSharedSpaces, false);
}
no_shared_spaces(); no_shared_spaces();
#endif // INCLUDE_CDS #endif // INCLUDE_CDS
@ -3292,6 +3323,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
set_g1_gc_flags(); set_g1_gc_flags();
} }
check_deprecated_gcs(); check_deprecated_gcs();
check_deprecated_gc_flags();
#else // INCLUDE_ALL_GCS #else // INCLUDE_ALL_GCS
assert(verify_serial_gc_flags(), "SerialGC unset"); assert(verify_serial_gc_flags(), "SerialGC unset");
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS

View File

@ -309,6 +309,7 @@ class Arguments : AllStatic {
// Garbage-First (UseG1GC) // Garbage-First (UseG1GC)
static void set_g1_gc_flags(); static void set_g1_gc_flags();
// GC ergonomics // GC ergonomics
static void set_use_compressed_oops();
static void set_ergonomics_flags(); static void set_ergonomics_flags();
static void set_shared_spaces_flags(); static void set_shared_spaces_flags();
// Setup heap size // Setup heap size
@ -414,6 +415,7 @@ class Arguments : AllStatic {
// Check for consistency in the selection of the garbage collector. // Check for consistency in the selection of the garbage collector.
static bool check_gc_consistency(); static bool check_gc_consistency();
static void check_deprecated_gcs(); static void check_deprecated_gcs();
static void check_deprecated_gc_flags();
// Check consistecy or otherwise of VM argument settings // Check consistecy or otherwise of VM argument settings
static bool check_vm_args_consistency(); static bool check_vm_args_consistency();
// Check stack pages settings // Check stack pages settings

View File

@ -425,6 +425,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
callee_parameters, callee_parameters,
callee_locals, callee_locals,
index == 0, index == 0,
index == array->frames() - 1,
popframe_extra_args); popframe_extra_args);
// This pc doesn't have to be perfect just good enough to identify the frame // This pc doesn't have to be perfect just good enough to identify the frame
// as interpreted so the skeleton frame will be walkable // as interpreted so the skeleton frame will be walkable

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1289,6 +1289,7 @@ class JavaThread: public Thread {
void enable_stack_red_zone(); void enable_stack_red_zone();
void disable_stack_red_zone(); void disable_stack_red_zone();
inline bool stack_guard_zone_unused();
inline bool stack_yellow_zone_disabled(); inline bool stack_yellow_zone_disabled();
inline bool stack_yellow_zone_enabled(); inline bool stack_yellow_zone_enabled();
@ -1759,6 +1760,10 @@ inline CompilerThread* JavaThread::as_CompilerThread() {
return (CompilerThread*)this; return (CompilerThread*)this;
} }
inline bool JavaThread::stack_guard_zone_unused() {
return _stack_guard_state == stack_guard_unused;
}
inline bool JavaThread::stack_yellow_zone_disabled() { inline bool JavaThread::stack_yellow_zone_disabled() {
return _stack_guard_state == stack_guard_yellow_disabled; return _stack_guard_state == stack_guard_yellow_disabled;
} }

View File

@ -160,6 +160,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
bool is_top_frame, bool is_top_frame,
bool is_bottom_frame,
int exec_mode) { int exec_mode) {
JavaThread* thread = (JavaThread*) Thread::current(); JavaThread* thread = (JavaThread*) Thread::current();
@ -275,7 +276,8 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
callee_locals, callee_locals,
caller, caller,
iframe(), iframe(),
is_top_frame); is_top_frame,
is_bottom_frame);
// Update the pc in the frame object and overwrite the temporary pc // Update the pc in the frame object and overwrite the temporary pc
// we placed in the skeletal frame now that we finally know the // we placed in the skeletal frame now that we finally know the
@ -420,6 +422,7 @@ int vframeArrayElement::on_stack_size(int caller_actual_parameters,
int callee_parameters, int callee_parameters,
int callee_locals, int callee_locals,
bool is_top_frame, bool is_top_frame,
bool is_bottom_frame,
int popframe_extra_stack_expression_els) const { int popframe_extra_stack_expression_els) const {
assert(method()->max_locals() == locals()->size(), "just checking"); assert(method()->max_locals() == locals()->size(), "just checking");
int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors(); int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors();
@ -431,7 +434,8 @@ int vframeArrayElement::on_stack_size(int caller_actual_parameters,
caller_actual_parameters, caller_actual_parameters,
callee_parameters, callee_parameters,
callee_locals, callee_locals,
is_top_frame); is_top_frame,
is_bottom_frame);
} }
@ -522,7 +526,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller
// Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee // Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee
// Unpack the frames from the oldest (frames() -1) to the youngest (0) // Unpack the frames from the oldest (frames() -1) to the youngest (0)
frame caller_frame = me; frame* caller_frame = &me;
for (index = frames() - 1; index >= 0 ; index--) { for (index = frames() - 1; index >= 0 ; index--) {
vframeArrayElement* elem = element(index); // caller vframeArrayElement* elem = element(index); // caller
int callee_parameters, callee_locals; int callee_parameters, callee_locals;
@ -542,13 +546,14 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller
elem->unpack_on_stack(caller_actual_parameters, elem->unpack_on_stack(caller_actual_parameters,
callee_parameters, callee_parameters,
callee_locals, callee_locals,
&caller_frame, caller_frame,
index == 0, index == 0,
index == frames() - 1,
exec_mode); exec_mode);
if (index == frames() - 1) { if (index == frames() - 1) {
Deoptimization::unwind_callee_save_values(elem->iframe(), this); Deoptimization::unwind_callee_save_values(elem->iframe(), this);
} }
caller_frame = *elem->iframe(); caller_frame = elem->iframe();
caller_actual_parameters = callee_parameters; caller_actual_parameters = callee_parameters;
} }
deallocate_monitor_chunks(); deallocate_monitor_chunks();

View File

@ -88,6 +88,7 @@ class vframeArrayElement : public _ValueObj {
int on_stack_size(int caller_actual_parameters, int on_stack_size(int caller_actual_parameters,
int callee_parameters, int callee_parameters,
int callee_locals, int callee_locals,
bool is_bottom_frame,
bool is_top_frame, bool is_top_frame,
int popframe_extra_stack_expression_els) const; int popframe_extra_stack_expression_els) const;
@ -97,6 +98,7 @@ class vframeArrayElement : public _ValueObj {
int callee_locals, int callee_locals,
frame* caller, frame* caller,
bool is_top_frame, bool is_top_frame,
bool is_bottom_frame,
int exec_mode); int exec_mode);
#ifndef PRODUCT #ifndef PRODUCT

View File

@ -336,7 +336,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _access_flags, AccessFlags) \
nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _subklass, Klass*) \
nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _next_sibling, Klass*) \
nonproduct_nonstatic_field(Klass, _verify_count, int) \
nonstatic_field(Klass, _alloc_count, juint) \ nonstatic_field(Klass, _alloc_count, juint) \
nonstatic_field(MethodData, _size, int) \ nonstatic_field(MethodData, _size, int) \
nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _method, Method*) \

View File

@ -94,6 +94,7 @@
template(ReportJavaOutOfMemory) \ template(ReportJavaOutOfMemory) \
template(JFRCheckpoint) \ template(JFRCheckpoint) \
template(Exit) \ template(Exit) \
template(LinuxDllLoad) \
class VM_Operation: public CHeapObj<mtInternal> { class VM_Operation: public CHeapObj<mtInternal> {
public: public:

View File

@ -197,4 +197,28 @@ ElfStringTable* ElfFile::get_string_table(int index) {
return NULL; return NULL;
} }
#ifdef LINUX
bool ElfFile::specifies_noexecstack() {
Elf_Phdr phdr;
if (!m_file) return true;
if (!fseek(m_file, m_elfHdr.e_phoff, SEEK_SET)) {
for (int index = 0; index < m_elfHdr.e_phnum; index ++) {
if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, m_file) != 1) {
m_status = NullDecoder::file_invalid;
return false;
}
if (phdr.p_type == PT_GNU_STACK) {
if (phdr.p_flags == (PF_R | PF_W)) {
return true;
} else {
return false;
}
}
}
}
return false;
}
#endif
#endif // _WINDOWS #endif // _WINDOWS

View File

@ -43,6 +43,7 @@ typedef Elf64_Addr Elf_Addr;
typedef Elf64_Ehdr Elf_Ehdr; typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr; typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Sym Elf_Sym; typedef Elf64_Sym Elf_Sym;
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__) #if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
@ -59,6 +60,7 @@ typedef Elf32_Addr Elf_Addr;
typedef Elf32_Ehdr Elf_Ehdr; typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr; typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Sym Elf_Sym; typedef Elf32_Sym Elf_Sym;
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__) #if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
@ -123,6 +125,14 @@ protected:
ElfFile* next() const { return m_next; } ElfFile* next() const { return m_next; }
void set_next(ElfFile* file) { m_next = file; } void set_next(ElfFile* file) { m_next = file; }
public:
// Returns true if the elf file is marked NOT to require an executable stack,
// or if the file could not be opened.
// Returns false if the elf file requires an executable stack, the stack flag
// is not set at all, or if the file can not be read.
// On systems other than linux it always returns false.
bool specifies_noexecstack() NOT_LINUX({ return false; });
protected: protected:
ElfFile* m_next; ElfFile* m_next;

View File

@ -0,0 +1,255 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8009761
* @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
* @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761
*
*/
public class Test8009761 {
static class UnloadedClass {
volatile int i;
}
static Object m1(boolean deopt) {
// When running interpreted, on sparc, the caller's stack is
// extended for the locals and the caller's frame is restored
// on return.
long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
l508, l509, l510, l511;
long ll0, ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, ll9, ll10, ll11, ll12,
ll13, ll14, ll15, ll16, ll17, ll18, ll19, ll20, ll21, ll22, ll23, ll24,
ll25, ll26, ll27, ll28, ll29, ll30, ll31, ll32, ll33, ll34, ll35, ll36,
ll37, ll38, ll39, ll40, ll41, ll42, ll43, ll44, ll45, ll46, ll47, ll48,
ll49, ll50, ll51, ll52, ll53, ll54, ll55, ll56, ll57, ll58, ll59, ll60,
ll61, ll62, ll63, ll64, ll65, ll66, ll67, ll68, ll69, ll70, ll71, ll72,
ll73, ll74, ll75, ll76, ll77, ll78, ll79, ll80, ll81, ll82, ll83, ll84,
ll85, ll86, ll87, ll88, ll89, ll90, ll91, ll92, ll93, ll94, ll95, ll96,
ll97, ll98, ll99, ll100, ll101, ll102, ll103, ll104, ll105, ll106, ll107,
ll108, ll109, ll110, ll111, ll112, ll113, ll114, ll115, ll116, ll117,
ll118, ll119, ll120, ll121, ll122, ll123, ll124, ll125, ll126, ll127,
ll128, ll129, ll130, ll131, ll132, ll133, ll134, ll135, ll136, ll137,
ll138, ll139, ll140, ll141, ll142, ll143, ll144, ll145, ll146, ll147,
ll148, ll149, ll150, ll151, ll152, ll153, ll154, ll155, ll156, ll157,
ll158, ll159, ll160, ll161, ll162, ll163, ll164, ll165, ll166, ll167,
ll168, ll169, ll170, ll171, ll172, ll173, ll174, ll175, ll176, ll177,
ll178, ll179, ll180, ll181, ll182, ll183, ll184, ll185, ll186, ll187,
ll188, ll189, ll190, ll191, ll192, ll193, ll194, ll195, ll196, ll197,
ll198, ll199, ll200, ll201, ll202, ll203, ll204, ll205, ll206, ll207,
ll208, ll209, ll210, ll211, ll212, ll213, ll214, ll215, ll216, ll217,
ll218, ll219, ll220, ll221, ll222, ll223, ll224, ll225, ll226, ll227,
ll228, ll229, ll230, ll231, ll232, ll233, ll234, ll235, ll236, ll237,
ll238, ll239, ll240, ll241, ll242, ll243, ll244, ll245, ll246, ll247,
ll248, ll249, ll250, ll251, ll252, ll253, ll254, ll255, ll256, ll257,
ll258, ll259, ll260, ll261, ll262, ll263, ll264, ll265, ll266, ll267,
ll268, ll269, ll270, ll271, ll272, ll273, ll274, ll275, ll276, ll277,
ll278, ll279, ll280, ll281, ll282, ll283, ll284, ll285, ll286, ll287,
ll288, ll289, ll290, ll291, ll292, ll293, ll294, ll295, ll296, ll297,
ll298, ll299, ll300, ll301, ll302, ll303, ll304, ll305, ll306, ll307,
ll308, ll309, ll310, ll311, ll312, ll313, ll314, ll315, ll316, ll317,
ll318, ll319, ll320, ll321, ll322, ll323, ll324, ll325, ll326, ll327,
ll328, ll329, ll330, ll331, ll332, ll333, ll334, ll335, ll336, ll337,
ll338, ll339, ll340, ll341, ll342, ll343, ll344, ll345, ll346, ll347,
ll348, ll349, ll350, ll351, ll352, ll353, ll354, ll355, ll356, ll357,
ll358, ll359, ll360, ll361, ll362, ll363, ll364, ll365, ll366, ll367,
ll368, ll369, ll370, ll371, ll372, ll373, ll374, ll375, ll376, ll377,
ll378, ll379, ll380, ll381, ll382, ll383, ll384, ll385, ll386, ll387,
ll388, ll389, ll390, ll391, ll392, ll393, ll394, ll395, ll396, ll397,
ll398, ll399, ll400, ll401, ll402, ll403, ll404, ll405, ll406, ll407,
ll408, ll409, ll410, ll411, ll412, ll413, ll414, ll415, ll416, ll417,
ll418, ll419, ll420, ll421, ll422, ll423, ll424, ll425, ll426, ll427,
ll428, ll429, ll430, ll431, ll432, ll433, ll434, ll435, ll436, ll437,
ll438, ll439, ll440, ll441, ll442, ll443, ll444, ll445, ll446, ll447,
ll448, ll449, ll450, ll451, ll452, ll453, ll454, ll455, ll456, ll457,
ll458, ll459, ll460, ll461, ll462, ll463, ll464, ll465, ll466, ll467,
ll468, ll469, ll470, ll471, ll472, ll473, ll474, ll475, ll476, ll477,
ll478, ll479, ll480, ll481, ll482, ll483, ll484, ll485, ll486, ll487,
ll488, ll489, ll490, ll491, ll492, ll493, ll494, ll495, ll496, ll497,
ll498, ll499, ll500, ll501, ll502, ll503, ll504, ll505, ll506, ll507,
ll508, ll509, ll510, ll511;
if (deopt) {
UnloadedClass res = new UnloadedClass(); // sufficient to force deopt with c2 but not c1
res.i = 0; // forces deopt with c1
return res;
}
return null;
}
static int count = 0;
static void m2() {
// Will be called recursively until a stack overflow
// exception. Makes sure it has a lot of locals so that it's
// not called a sufficient number of times to trigger
// compilation.
long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12,
l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24,
l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36,
l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48,
l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60,
l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72,
l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84,
l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96,
l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107,
l108, l109, l110, l111, l112, l113, l114, l115, l116, l117,
l118, l119, l120, l121, l122, l123, l124, l125, l126, l127,
l128, l129, l130, l131, l132, l133, l134, l135, l136, l137,
l138, l139, l140, l141, l142, l143, l144, l145, l146, l147,
l148, l149, l150, l151, l152, l153, l154, l155, l156, l157,
l158, l159, l160, l161, l162, l163, l164, l165, l166, l167,
l168, l169, l170, l171, l172, l173, l174, l175, l176, l177,
l178, l179, l180, l181, l182, l183, l184, l185, l186, l187,
l188, l189, l190, l191, l192, l193, l194, l195, l196, l197,
l198, l199, l200, l201, l202, l203, l204, l205, l206, l207,
l208, l209, l210, l211, l212, l213, l214, l215, l216, l217,
l218, l219, l220, l221, l222, l223, l224, l225, l226, l227,
l228, l229, l230, l231, l232, l233, l234, l235, l236, l237,
l238, l239, l240, l241, l242, l243, l244, l245, l246, l247,
l248, l249, l250, l251, l252, l253, l254, l255, l256, l257,
l258, l259, l260, l261, l262, l263, l264, l265, l266, l267,
l268, l269, l270, l271, l272, l273, l274, l275, l276, l277,
l278, l279, l280, l281, l282, l283, l284, l285, l286, l287,
l288, l289, l290, l291, l292, l293, l294, l295, l296, l297,
l298, l299, l300, l301, l302, l303, l304, l305, l306, l307,
l308, l309, l310, l311, l312, l313, l314, l315, l316, l317,
l318, l319, l320, l321, l322, l323, l324, l325, l326, l327,
l328, l329, l330, l331, l332, l333, l334, l335, l336, l337,
l338, l339, l340, l341, l342, l343, l344, l345, l346, l347,
l348, l349, l350, l351, l352, l353, l354, l355, l356, l357,
l358, l359, l360, l361, l362, l363, l364, l365, l366, l367,
l368, l369, l370, l371, l372, l373, l374, l375, l376, l377,
l378, l379, l380, l381, l382, l383, l384, l385, l386, l387,
l388, l389, l390, l391, l392, l393, l394, l395, l396, l397,
l398, l399, l400, l401, l402, l403, l404, l405, l406, l407,
l408, l409, l410, l411, l412, l413, l414, l415, l416, l417,
l418, l419, l420, l421, l422, l423, l424, l425, l426, l427,
l428, l429, l430, l431, l432, l433, l434, l435, l436, l437,
l438, l439, l440, l441, l442, l443, l444, l445, l446, l447,
l448, l449, l450, l451, l452, l453, l454, l455, l456, l457,
l458, l459, l460, l461, l462, l463, l464, l465, l466, l467,
l468, l469, l470, l471, l472, l473, l474, l475, l476, l477,
l478, l479, l480, l481, l482, l483, l484, l485, l486, l487,
l488, l489, l490, l491, l492, l493, l494, l495, l496, l497,
l498, l499, l500, l501, l502, l503, l504, l505, l506, l507,
l508, l509, l510, l511;
count++;
m2();
}
static Object m3(boolean overflow_stack, boolean deopt) {
if (overflow_stack) {
m2();
return null;
}
Object o = m1(deopt);
if (deopt) {
m2();
}
return o;
}
static public void main(String[] args) {
int c1;
// Call m2 from m3 recursively until stack overflow. Count the number of recursive calls.
try {
m3(true, false);
} catch(StackOverflowError soe) {
}
c1 = count;
// Force the compilation of m3() that will inline m1()
for (int i = 0; i < 20000; i++) {
m3(false, false);
}
count = 0;
// Force deoptimization of m3() in m1(), then return from m1()
// to m3(), call recursively m2(). If deoptimization correctly
// built the interpreter stack for m3()/m1() then we should be
// able to call m2() recursively as many times as before.
try {
m3(false, true);
} catch(StackOverflowError soe) {
}
if (c1 != count) {
System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count);
System.exit(97);
} else {
System.out.println("PASSED");
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 SAP AG. 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.
*/
class Test {
static boolean loadLib(String libName){
try {
System.loadLibrary(libName);
System.out.println("Loaded library "+ libName + ".");
return true;
} catch (SecurityException e) {
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
} catch (UnsatisfiedLinkError e) {
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
}
return false;
}
public static int counter = 1;
static int Runner() {
counter = counter * -1;
int i = counter;
if(counter < 2) counter += Runner();
return i;
}
public static int run() {
try{
Runner();
} catch (StackOverflowError e) {
System.out.println("Caught stack overflow error.");
return 0;
} catch (OutOfMemoryError e) {
return 0;
}
return 2;
}
public static void main(String argv[]) {
loadLib(argv[0]);
System.exit(run());
}
}

View File

@ -0,0 +1,98 @@
#!/bin/sh
#
# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011 SAP AG. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
##
## @test Test7107135.sh
## @bug 7107135
## @summary Stack guard pages lost after loading library with executable stack.
## @run shell Test7107135.sh
##
if [ "${TESTSRC}" = "" ]
then TESTSRC=.
fi
if [ "${TESTJAVA}" = "" ]
then
PARENT=`dirname \`which java\``
TESTJAVA=`dirname ${PARENT}`
echo "TESTJAVA not set, selecting " ${TESTJAVA}
echo "If this is incorrect, try setting the variable manually."
fi
BIT_FLAG=""
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Linux)
NULL=/dev/null
PS=":"
FS="/"
;;
*)
NULL=NUL
PS=";"
FS="\\"
echo "Test passed; only valid for Linux"
exit 0;
;;
esac
ARCH=`uname -m`
THIS_DIR=`pwd`
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
${TESTJAVA}${FS}bin${FS}javac *.java
gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
ld -shared -z execstack -o libtest-rwx.so test.o
ld -shared -z noexecstack -o libtest-rw.so test.o
LD_LIBRARY_PATH=${THIS_DIR}
echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
# This should not fail.
echo Check testprogram. Expected to pass:
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
echo
echo Test changing of stack protection:
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx
if [ "$?" == "0" ]
then
echo
echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
fi
exit $?

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 SAP AG. 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.
*/
class TestMT {
static boolean loadLib(String libName) {
try {
System.loadLibrary(libName);
System.out.println("Loaded library "+ libName + ".");
return true;
} catch (SecurityException e) {
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
} catch (UnsatisfiedLinkError e) {
System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n");
}
return false;
}
public static int counter = 1;
static int Runner() {
counter = counter * -1;
int i = counter;
if (counter < 2) counter += Runner();
return i;
}
public static int run(String msg) {
try {
Runner();
} catch (StackOverflowError e) {
System.out.println(msg + " caught stack overflow error.");
return 0;
} catch (OutOfMemoryError e) {
return 0;
}
return 2;
}
public static void main(String argv[]) {
try {
for (int i = 0; i < 20; i++) {
Thread t = new DoStackOverflow("SpawnedThread " + i);
t.start();
}
run("Main thread");
loadLib("test-rwx");
run("Main thread");
} catch (Exception e) {
System.out.println(e);
}
}
static class DoStackOverflow extends Thread {
public DoStackOverflow(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 10; ++i) {
TestMT.run(getName());
yield();
}
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 SAP AG. 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.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "jni.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_Test_someMethod(JNIEnv *env, jobject mainObject) {
return 3;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 2013, 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.
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.Class;
import java.lang.String;
import java.lang.System;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import sun.misc.Unsafe;
import sun.misc.Contended;
/*
* @test
* @bug 8003985
* @summary Support Contended Annotation - JEP 142
*
* @run main/othervm -XX:-RestrictContended Test8003985
*/
public class Test8003985 {
private static final Unsafe U;
private static int ADDRESS_SIZE;
private static int HEADER_SIZE;
static {
// steal Unsafe
try {
Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
U = (Unsafe) unsafe.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
// When running with CompressedOops on 64-bit platform, the address size
// reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
// Try to guess the reference field size with this naive trick.
try {
long off1 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj1"));
long off2 = U.objectFieldOffset(CompressedOopsClass.class.getField("obj2"));
ADDRESS_SIZE = (int) Math.abs(off2 - off1);
HEADER_SIZE = (int) Math.min(off1, off2);
} catch (NoSuchFieldException e) {
ADDRESS_SIZE = -1;
}
}
static class CompressedOopsClass {
public Object obj1;
public Object obj2;
}
public static boolean arePaddedPairwise(Class klass, String field1, String field2) throws Exception {
Field f1 = klass.getDeclaredField(field1);
Field f2 = klass.getDeclaredField(field2);
if (isStatic(f1) != isStatic(f2)) {
return true; // these guys are in naturally disjoint locations
}
int diff = offset(f1) - offset(f2);
if (diff < 0) {
// f1 is first
return (offset(f2) - (offset(f1) + getSize(f1))) > 64;
} else {
// f2 is first
return (offset(f1) - (offset(f2) + getSize(f2))) > 64;
}
}
public static boolean isPadded(Class klass, String field1) throws Exception {
Field f1 = klass.getDeclaredField(field1);
if (isStatic(f1)) {
return offset(f1) > 128 + 64;
}
return offset(f1) > 64;
}
public static boolean sameLayout(Class klass1, Class klass2) throws Exception {
for (Field f1 : klass1.getDeclaredFields()) {
Field f2 = klass2.getDeclaredField(f1.getName());
if (offset(f1) != offset(f2)) {
return false;
}
}
for (Field f2 : klass1.getDeclaredFields()) {
Field f1 = klass2.getDeclaredField(f2.getName());
if (offset(f1) != offset(f2)) {
return false;
}
}
return true;
}
public static boolean isStatic(Field field) {
return Modifier.isStatic(field.getModifiers());
}
public static int offset(Field field) {
if (isStatic(field)) {
return (int) U.staticFieldOffset(field);
} else {
return (int) U.objectFieldOffset(field);
}
}
public static int getSize(Field field) {
Class type = field.getType();
if (type == byte.class) { return 1; }
if (type == boolean.class) { return 1; }
if (type == short.class) { return 2; }
if (type == char.class) { return 2; }
if (type == int.class) { return 4; }
if (type == float.class) { return 4; }
if (type == long.class) { return 8; }
if (type == double.class) { return 8; }
return ADDRESS_SIZE;
}
public static void main(String[] args) throws Exception {
boolean endResult = true;
// --------------- INSTANCE FIELDS ---------------------
if (arePaddedPairwise(Test1.class, "int1", "int2") ||
isPadded(Test1.class, "int1") ||
isPadded(Test1.class, "int2")) {
System.err.println("Test1 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test2.class, "int1", "int2") ||
!isPadded(Test2.class, "int1") ||
isPadded(Test2.class, "int2")) {
System.err.println("Test2 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test3.class, "int1", "int2") ||
!isPadded(Test3.class, "int1") ||
!isPadded(Test3.class, "int2")) {
System.err.println("Test3 failed");
endResult &= false;
}
if (arePaddedPairwise(Test4.class, "int1", "int2") ||
!isPadded(Test4.class, "int1") ||
!isPadded(Test4.class, "int2")) {
System.err.println("Test4 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test5.class, "int1", "int2") ||
!isPadded(Test5.class, "int1") ||
!isPadded(Test5.class, "int2")) {
System.err.println("Test5 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test6.class, "int1", "int2") ||
!isPadded(Test6.class, "int1") ||
!isPadded(Test6.class, "int2")) {
System.err.println("Test6 failed");
endResult &= false;
}
if (arePaddedPairwise(Test7.class, "int1", "int2") ||
!isPadded(Test7.class, "int1") ||
!isPadded(Test7.class, "int2")) {
System.err.println("Test7 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test8.class, "int1", "int2") ||
!isPadded(Test8.class, "int1") ||
!isPadded(Test8.class, "int2")) {
System.err.println("Test8 failed");
endResult &= false;
}
if (!arePaddedPairwise(Test9.class, "int1", "int2") ||
!isPadded(Test9.class, "int1") ||
!isPadded(Test9.class, "int2")) {
System.err.println("Test9 failed");
endResult &= false;
}
if (!sameLayout(Test4.class, Test7.class)) {
System.err.println("Test4 and Test7 have different layouts");
endResult &= false;
}
if (!sameLayout(Test5.class, Test6.class)) {
System.err.println("Test5 and Test6 have different layouts");
endResult &= false;
}
if (!sameLayout(Test8.class, Test9.class)) {
System.err.println("Test8 and Test9 have different layouts");
endResult &= false;
}
System.out.println(endResult ? "Test PASSES" : "Test FAILS");
if (!endResult) {
throw new Error("Test failed");
}
}
// ----------------------------------- INSTANCE FIELDS -----------------------------------------
// naturally packed
public static class Test1 {
private int int1;
private int int2;
}
// int1 is padded
public static class Test2 {
@Contended private int int1;
private int int2;
}
// both fields are padded
public static class Test3 {
@Contended private int int1;
@Contended private int int2;
}
// fields are padded in the singular group
public static class Test4 {
@Contended("sameGroup") private int int1;
@Contended("sameGroup") private int int2;
}
// fields are padded in disjoint groups
public static class Test5 {
@Contended("diffGroup1") private int int1;
@Contended("diffGroup2") private int int2;
}
// fields are padded in disjoint groups
public static class Test6 {
@Contended private int int1;
@Contended("diffGroup2") private int int2;
}
// fields are padded in the singular group
@Contended
public static class Test7 {
private int int1;
private int int2;
}
// all fields are padded as the group, and one field is padded specifically
@Contended
public static class Test8 {
@Contended private int int1;
private int int2;
}
// all fields are padded as the group, and one field is padded specifically
@Contended
public static class Test9 {
@Contended("group") private int int1;
private int int2;
}
}