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
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) {
map_info* map;
if ((map = allocate_init_map(ph->core->classes_jsa_fd,
offset, vaddr, memsz)) == NULL) {
return NULL;
return;
}
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
# it off explicitly.
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
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
endif
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))
# XXXDARWIN: for _dyld_bind_fully_image_containing_address

View File

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

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=22
HS_BUILD_NUMBER=23
JDK_MAJOR_VER=1
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
# it off explicitly.
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
ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
endif
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases
CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))

View File

@ -118,8 +118,8 @@ endif
# Compiler warnings are treated as errors
WARNINGS_ARE_ERRORS = -Werror
# Enable these warnings. See 'info gcc' about details on these options
ADDITIONAL_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ADDITIONAL_WARNINGS)
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
# Special cases
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,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "NEED TO FIX");
// 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,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup
// in InterpreterGenerator::generate_fixed_frame.
// 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 computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
*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 {
assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
// 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,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "FIX ME");
// 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
// given unextended SP. The unextended SP might also be the saved SP
// 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) {
frame fr;

View File

@ -170,7 +170,7 @@
return (intptr_t*) addr_at(offset);
}
#if ASSERT
#ifdef ASSERT
// 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_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {

View File

@ -1585,7 +1585,8 @@ int AbstractInterpreter::layout_activation(Method* method,
int callee_locals,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry.
// 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,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
// Note: This calculation must exactly parallel the frame setup
// in AbstractInterpreterGenerator::generate_method_entry.
// 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,
frame* caller,
frame* interpreter_frame,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
assert(popframe_extra_args == 0, "what to do?");
assert(!is_top_frame || (!callee_locals && !callee_param_count),
"top frame should have no caller");

View File

@ -57,6 +57,7 @@
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
@ -2275,13 +2276,25 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
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;
}
bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special()
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() {

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,6 +40,9 @@
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \
\
product(bool, LoadExecStackDllInVMThread, true, \
"Load DLLs with executable-stack attribute in the VM Thread") \
\
product(bool, UseSHM, false, \
"Use SYSV shared memory for large pages")

View File

@ -44,6 +44,7 @@
#include "runtime/extendedPC.hpp"
#include "runtime/globals.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
@ -57,10 +58,12 @@
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/elfFile.hpp"
#include "utilities/growableArray.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
// 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 * 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) {
// Successful loading
return result;
@ -1952,6 +2039,38 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
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,
* 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);
}
// 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;
}
bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special()
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() {

View File

@ -94,6 +94,9 @@ class Linux {
static void print_libversion_info(outputStream* st);
public:
static bool _stack_is_executable;
static void *dll_load_inner(const char *name);
static void init_thread_fpu_state();
static int get_fpu_control_word();
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) {
addrs[0] = p;
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_count++;
}
@ -3420,13 +3420,25 @@ char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
if ((retAddr != NULL) && UseNUMAInterleaving) {
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;
}
bool os::release_memory_special(char* base, size_t bytes) {
// detaching the SHM segment will also delete it, see reserve_memory_special()
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() {

View File

@ -60,6 +60,7 @@
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
@ -2836,7 +2837,7 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
PAGE_READWRITE);
// If reservation failed, 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);
// 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) {
// Some memory was committed so release it.
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);
}
#ifdef ASSERT
@ -2909,10 +2915,19 @@ static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags,
#endif
return NULL;
}
bytes_remaining -= bytes_to_rq;
next_alloc_addr += bytes_to_rq;
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
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
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
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;
}
}
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);
}

View File

@ -516,7 +516,7 @@ JVM_handle_bsd_signal(int sig,
// here if the underlying file has been truncated.
// Do not crash the VM in such a case.
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()) {
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.
thread->disable_stack_red_zone();
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 {
// Accessing stack address below sp may cause SEGV if current
// 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.
thread->disable_stack_red_zone();
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 {
// Accessing stack address below sp may cause SEGV if current
// 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
void visit(LIR_Op* op);
#if ASSERT
#ifdef ASSERT
// check that an operation has no operands
bool no_operands(LIR_Op* op);
#endif

View File

@ -2540,7 +2540,7 @@ void ciTypeFlow::build_loop_tree(Block* blk) {
} else if (innermost->head() == blk) {
// If loop header, complete the tree pointers
if (blk->loop() != innermost) {
#if ASSERT
#ifdef ASSERT
assert(blk->loop()->head() == innermost->head(), "same head");
Loop* dl;
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"
class FieldAllocationCount;
class FieldLayoutInfo;
// Parser for for .class files
@ -47,6 +48,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
u2 _major_version;
u2 _minor_version;
Symbol* _class_name;
ClassLoaderData* _loader_data;
KlassHandle _host_klass;
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:
bool _synthetic_flag;
int _sde_length;
char* _sde_buffer;
Symbol* _sourcefile;
Symbol* _generic_signature;
char* _sde_buffer;
int _sde_length;
Array<u2>* _inner_classes;
// Metadata created before the instance klass is created. Must be deallocated
// 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* _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_sourcefile(Symbol* x) { _sourcefile = 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_inner_classes(Array<u2>* x) { _inner_classes = x; }
void set_class_annotations(AnnotationArray* x) { _annotations = x; }
void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; }
void init_parsed_class_attributes() {
void init_parsed_class_attributes(ClassLoaderData* loader_data) {
_loader_data = loader_data;
_synthetic_flag = false;
_sourcefile = NULL;
_generic_signature = NULL;
_sde_buffer = NULL;
_sde_length = 0;
_annotations = _type_annotations = NULL;
// initialize the other flags too:
_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
_max_bootstrap_specifier_index = -1;
clear_class_metadata();
_klass = NULL;
}
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 {
public:
@ -124,11 +152,27 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void set_contended(bool contended) { set_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 {
ClassLoaderData* _loader_data;
AnnotationArray* _field_annotations;
AnnotationArray* _field_type_annotations;
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);
~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 {
public:
MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
@ -152,38 +196,30 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void set_stream(ClassFileStream* st) { _stream = st; }
// Constant pool parsing
void parse_constant_pool_entries(ClassLoaderData* loader_data,
constantPoolHandle cp, int length, TRAPS);
void parse_constant_pool_entries(int length, TRAPS);
constantPoolHandle parse_constant_pool(ClassLoaderData* loader_data, TRAPS);
constantPoolHandle parse_constant_pool(TRAPS);
// Interface parsing
Array<Klass*>* parse_interfaces(constantPoolHandle cp,
int length,
ClassLoaderData* loader_data,
Array<Klass*>* parse_interfaces(int length,
Handle protection_domain,
Symbol* class_name,
bool* has_default_methods,
TRAPS);
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
instanceKlassHandle parse_super_class(int super_class_index, TRAPS);
// Field parsing
void parse_field_attributes(ClassLoaderData* loader_data,
constantPoolHandle cp, u2 attributes_count,
void parse_field_attributes(u2 attributes_count,
bool is_static, u2 signature_index,
u2* constantvalue_index_addr,
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
AnnotationArray** field_annotations,
AnnotationArray** field_type_annotations,
FieldAnnotationCollector* parsed_annotations,
TRAPS);
Array<u2>* parse_fields(ClassLoaderData* loader_data,
Symbol* class_name,
constantPoolHandle cp, bool is_interface,
Array<u2>* parse_fields(Symbol* class_name,
bool is_interface,
FieldAllocationCount *fac,
Array<AnnotationArray*>** fields_annotations,
Array<AnnotationArray*>** fields_type_annotations,
u2* java_fields_count_ptr, TRAPS);
void print_field_layout(Symbol* name,
@ -195,65 +231,52 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int static_fields_end);
// Method parsing
methodHandle parse_method(ClassLoaderData* loader_data,
constantPoolHandle cp,
bool is_interface,
methodHandle parse_method(bool is_interface,
AccessFlags* promoted_flags,
TRAPS);
Array<Method*>* parse_methods(ClassLoaderData* loader_data,
constantPoolHandle cp,
bool is_interface,
Array<Method*>* parse_methods(bool is_interface,
AccessFlags* promoted_flags,
bool* has_final_method,
bool* has_default_method,
TRAPS);
Array<int>* sort_methods(ClassLoaderData* loader_data,
Array<Method*>* methods,
TRAPS);
u2* parse_exception_table(ClassLoaderData* loader_data,
u4 code_length, u4 exception_table_length,
constantPoolHandle cp, TRAPS);
intArray* sort_methods(Array<Method*>* methods);
u2* parse_exception_table(u4 code_length, u4 exception_table_length,
TRAPS);
void parse_linenumber_table(
u4 code_attribute_length, u4 code_length,
CompressedLineNumberWriteStream** write_stream, TRAPS);
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);
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,
u1* u1_array, u2* u2_array, constantPoolHandle cp, TRAPS);
Array<u1>* parse_stackmap_table(ClassLoaderData* loader_data, u4 code_attribute_length, TRAPS);
u1* u1_array, u2* u2_array, TRAPS);
u1* parse_stackmap_table(u4 code_attribute_length, TRAPS);
// Classfile attribute parsing
void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS);
void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
int length, TRAPS);
u2 parse_classfile_inner_classes_attribute(ClassLoaderData* loader_data,
u1* inner_classes_attribute_start,
void parse_classfile_sourcefile_attribute(TRAPS);
void parse_classfile_source_debug_extension_attribute(int length, TRAPS);
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
constantPoolHandle cp,
TRAPS);
void parse_classfile_attributes(ClassLoaderData* loader_data,
constantPoolHandle cp,
ClassAnnotationCollector* parsed_annotations,
void parse_classfile_attributes(ClassAnnotationCollector* parsed_annotations,
TRAPS);
void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS);
void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS);
void parse_classfile_bootstrap_methods_attribute(ClassLoaderData* loader_data, constantPoolHandle cp, u4 attribute_length, TRAPS);
void parse_classfile_synthetic_attribute(TRAPS);
void parse_classfile_signature_attribute(TRAPS);
void parse_classfile_bootstrap_methods_attribute(u4 attribute_length, TRAPS);
// Annotations handling
AnnotationArray* assemble_annotations(ClassLoaderData* loader_data,
u1* runtime_visible_annotations,
AnnotationArray* assemble_annotations(u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
u1* runtime_invisible_annotations,
int runtime_invisible_annotations_length, TRAPS);
int skip_annotation(u1* buffer, int limit, int index);
int skip_annotation_value(u1* buffer, int limit, int index);
void parse_annotations(ClassLoaderData* loader_data,
u1* buffer, int limit, constantPoolHandle cp,
void parse_annotations(u1* buffer, int limit,
/* Results (currently, only one result is supported): */
AnnotationCollector* result,
TRAPS);
@ -267,8 +290,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int* nonstatic_oop_offsets,
unsigned int* nonstatic_oop_counts);
void set_precomputed_flags(instanceKlassHandle k);
Array<Klass*>* compute_transitive_interfaces(ClassLoaderData* loader_data,
instanceKlassHandle super,
Array<Klass*>* compute_transitive_interfaces(instanceKlassHandle super,
Array<Klass*>* local_ifs, TRAPS);
// Format checker methods
@ -318,7 +340,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
bool is_supported_version(u2 major, u2 minor);
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_class_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
// constant pool construction, but in later versions they can.
// %%% Let's phase out the old is_klass_reference.
bool is_klass_reference(constantPoolHandle cp, int index) {
return (EnableInvokeDynamic
? cp->tag_at(index).is_klass_or_reference()
: cp->tag_at(index).is_klass_reference());
bool valid_klass_reference_at(int index) {
return _cp->is_within_bounds(index) &&
(EnableInvokeDynamic
? _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,
@ -373,8 +402,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
u2** localvariable_type_table_start,
TRAPS);
void copy_method_annotations(ClassLoaderData* loader_data,
ConstMethod* cm,
void copy_method_annotations(ConstMethod* cm,
u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
u1* runtime_invisible_annotations,
@ -391,9 +419,15 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int annotation_default_length,
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:
// Constructor
ClassFileParser(ClassFileStream* st) { set_stream(st); }
~ClassFileParser();
// 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

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.
*
* 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;
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
assert(!DumpSharedSpaces, "never allocate to C heap");
sym = new (len, THREAD) Symbol(name, len, 1);
assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
} else {
if (DumpSharedSpaces) {
sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, -1);
} else {
// Allocate to global arena
sym = new (len, arena(), THREAD) Symbol(name, len, -1);
}
}
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).
// These directives can be removed once the MS VS.NET 2005
// compiler stack overflow is fixed.
#if _MSC_VER >=1400 && !defined(_WIN64)
#if defined(_MSC_VER) && _MSC_VER >=1400 && !defined(_WIN64)
#pragma optimize("", off)
#pragma warning(disable: 4748)
#endif
@ -276,7 +276,7 @@ void test_compressed_stream(int trace) {
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 optimize("", on)
#endif

View File

@ -505,7 +505,7 @@ void CompileTask::log_task(xmlStream* log) {
ResourceMark rm(thread);
// <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) {
log->print(" compile_kind='osr'"); // same as nmethod::compile_kind
} // else compile_kind='c2c'

View File

@ -2063,11 +2063,6 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
// required.
_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);
// For a mark-sweep, compute_new_size() will be called
@ -3400,10 +3395,10 @@ CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
if (PrintCMSStatistics != 0) {
_collector->resetYields();
}
if (PrintGCDetails && PrintGCTimeStamps) {
if (PrintGCDetails) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp();
gclog_or_tty->print_cr(": [%s-concurrent-%s-start]",
gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
_collector->cmsGen()->short_name(), _phase);
}
_collector->resetTimer();

View File

@ -1310,11 +1310,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
_markStack.expand();
}
#if VERIFY_OBJS_PROCESSED
_scan_obj_cl.objs_processed = 0;
ThreadLocalObjQueue::objs_enqueued = 0;
#endif
// Statistics
double now = os::elapsedTime();
_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");
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
@ -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
// granularity).
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
if (new_finger >= _region_limit) {
giveup_current_region();

View File

@ -97,7 +97,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
HeapWord* limit = NULL) const;
// conversion utilities
// XXX Fix these so that offsets are size_t's...
HeapWord* offsetToHeapWord(size_t offset) const {
return _bmStartWord + (offset << _shifter);
}
@ -105,8 +104,13 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
return pointer_delta(addr, _bmStartWord) >> _shifter;
}
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

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.
*
* 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);
while (start_offset < end_offset) {
HeapWord* obj_addr = offsetToHeapWord(start_offset);
oop obj = (oop) obj_addr;
if (!cl->do_bit(start_offset)) {
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);
start_offset = _bm.get_next_one_offset(next_offset, end_offset);
}

View File

@ -409,7 +409,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate(
// heap remains parsable.
const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true;
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;
}
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())
&& page_expected.size != 0) {
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 callee_params,
int callee_locals,
bool is_top_frame) {
bool is_top_frame,
bool is_bottom_frame) {
return layout_activation(method,
temps,
popframe_args,
@ -196,7 +197,8 @@ class AbstractInterpreter: AllStatic {
callee_locals,
(frame*)NULL,
(frame*)NULL,
is_top_frame);
is_top_frame,
is_bottom_frame);
}
static int layout_activation(Method* method,
@ -208,7 +210,8 @@ class AbstractInterpreter: AllStatic {
int callee_locals,
frame* caller,
frame* interpreter_frame,
bool is_top_frame);
bool is_top_frame,
bool is_bottom_frame);
// Runtime support
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();
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
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
_pool->initialize_resolved_references(loader_data, _resolved_references_map,
_resolved_reference_limit,
CHECK);
No_Safepoint_Verifier nsv;
cache->initialize(_cp_cache_map, _invokedynamic_references_map);
_pool->set_cache(cache);
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 softrefs_clear = all_soft_refs_clear();
assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true;
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; }
struct FileMapHeader* header() { return &_header; }
static void set_current_info(FileMapInfo* info) { _current_info = info; }
static FileMapInfo* current_info() { return _current_info; }
static void set_current_info(FileMapInfo* 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);
// File manipulation.
bool initialize();
bool initialize() NOT_CDS_RETURN_(false);
bool open_for_read();
void open_for_write();
void write_header();
@ -141,7 +148,7 @@ public:
void fail_continue(const char *msg, ...);
// 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

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.
*
* 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.
*
* 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_lock_chunk = 3;
size_t const allocation_from_dictionary_limit = 64 * K;
const size_t metadata_deallocate = 0xf5f5f5f5;
MetaWord* last_allocated = 0;
@ -2440,7 +2439,8 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
free_chunks_capacity_bytes / K,
used_and_free / 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

View File

@ -885,6 +885,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// the actual alignment depends on its size.
Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, 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);
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_code_size(byte_code_size);
set_constMethod_size(size);
set_inlined_tables_length(sizes);
set_inlined_tables_length(sizes); // sets _flags
set_method_type(method_type);
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*
void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {

View File

@ -280,6 +280,7 @@ public:
// stackmap table data
Array<u1>* stackmap_data() const { return _stackmap_data; }
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; }
void init_fingerprint() {

View File

@ -44,6 +44,8 @@
void ConstantPoolCacheEntry::initialize_entry(int index) {
assert(0 < index && index < 0x10000, "sanity check");
_indices = index;
_f1 = NULL;
_f2 = _flags = 0;
assert(constant_pool_index() == index, "");
}
@ -533,13 +535,17 @@ void ConstantPoolCacheEntry::verify(outputStream* st) const {
// 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);
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");
for (int i = 0; i < length(); i++) {
ConstantPoolCacheEntry* e = entry_at(i);

View File

@ -377,14 +377,21 @@ class ConstantPoolCache: public MetaspaceObj {
debug_only(friend class ClassVerifier;)
// 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++) {
assert(entry_at(i)->is_f1_null(), "Failed to clear?");
}
}
// Initialization
void initialize(const intArray& inverse_index_map, const intArray& invokedynamic_references_map);
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; }
int length() const { return _length; }
@ -405,9 +412,6 @@ class ConstantPoolCache: public MetaspaceObj {
friend class ConstantPoolCacheEntry;
public:
// Initialization
void initialize(intArray& inverse_index_map, intArray& invokedynamic_references_map);
// Accessors
void set_constant_pool(ConstantPool* pool) { _constant_pool = 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;
Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
InstanceKlass* InstanceKlass::allocate_instance_klass(
ClassLoaderData* loader_data,
int vtable_len,
int itable_len,
int static_field_size,
@ -207,10 +208,35 @@ Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data,
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);
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,
int itable_len,
int static_field_size,
@ -220,72 +246,116 @@ InstanceKlass::InstanceKlass(int vtable_len,
bool is_anonymous) {
No_Safepoint_Verifier no_safepoint; // until k becomes parsable
int size = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
access_flags.is_interface(), is_anonymous);
int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
access_flags.is_interface(), is_anonymous);
// The sizes of these these three variables are used for determining the
// size of the instanceKlassOop. It is critical that these are set to the right
// sizes before the first GC, i.e., when we allocate the mirror.
this->set_vtable_length(vtable_len);
this->set_itable_length(itable_len);
this->set_static_field_size(static_field_size);
this->set_nonstatic_oop_map_size(nonstatic_oop_map_size);
this->set_access_flags(access_flags);
this->set_is_anonymous(is_anonymous);
assert(this->size() == size, "wrong size for object");
set_vtable_length(vtable_len);
set_itable_length(itable_len);
set_static_field_size(static_field_size);
set_nonstatic_oop_map_size(nonstatic_oop_map_size);
set_access_flags(access_flags);
_misc_flags = 0; // initialize to zero
set_is_anonymous(is_anonymous);
assert(size() == iksize, "wrong size for object");
this->set_array_klasses(NULL);
this->set_methods(NULL);
this->set_method_ordering(NULL);
this->set_local_interfaces(NULL);
this->set_transitive_interfaces(NULL);
this->init_implementor();
this->set_fields(NULL, 0);
this->set_constants(NULL);
this->set_class_loader_data(NULL);
this->set_protection_domain(NULL);
this->set_signers(NULL);
this->set_source_file_name(NULL);
this->set_source_debug_extension(NULL, 0);
this->set_array_name(NULL);
this->set_inner_classes(NULL);
this->set_static_oop_field_count(0);
this->set_nonstatic_field_size(0);
this->set_is_marked_dependent(false);
this->set_init_state(InstanceKlass::allocated);
this->set_init_thread(NULL);
this->set_init_lock(NULL);
this->set_reference_type(rt);
this->set_oop_map_cache(NULL);
this->set_jni_ids(NULL);
this->set_osr_nmethods_head(NULL);
this->set_breakpoints(NULL);
this->init_previous_versions();
this->set_generic_signature(NULL);
this->release_set_methods_jmethod_ids(NULL);
this->release_set_methods_cached_itable_indices(NULL);
this->set_annotations(NULL);
this->set_jvmti_cached_class_field_map(NULL);
this->set_initial_method_idnum(0);
set_array_klasses(NULL);
set_methods(NULL);
set_method_ordering(NULL);
set_local_interfaces(NULL);
set_transitive_interfaces(NULL);
init_implementor();
set_fields(NULL, 0);
set_constants(NULL);
set_class_loader_data(NULL);
set_protection_domain(NULL);
set_signers(NULL);
set_source_file_name(NULL);
set_source_debug_extension(NULL, 0);
set_array_name(NULL);
set_inner_classes(NULL);
set_static_oop_field_count(0);
set_nonstatic_field_size(0);
set_is_marked_dependent(false);
set_init_state(InstanceKlass::allocated);
set_init_thread(NULL);
set_init_lock(NULL);
set_reference_type(rt);
set_oop_map_cache(NULL);
set_jni_ids(NULL);
set_osr_nmethods_head(NULL);
set_breakpoints(NULL);
init_previous_versions();
set_generic_signature(NULL);
release_set_methods_jmethod_ids(NULL);
release_set_methods_cached_itable_indices(NULL);
set_annotations(NULL);
set_jvmti_cached_class_field_map(NULL);
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
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;
}
// Set temporary value until parseClassFile updates it with the real instance
// 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
// InstanceKlass points to.
void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// 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.
loader_data->remove_class(this);
@ -300,17 +370,7 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// reference counting symbol names.
release_C_heap_structures();
Array<Method*>* ms = 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());
}
deallocate_methods(loader_data, methods());
set_methods(NULL);
if (method_ordering() != Universe::the_empty_int_array()) {
@ -327,24 +387,8 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
}
set_secondary_supers(NULL);
// 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() == NULL) ? NULL :
InstanceKlass::cast(super())->transitive_interfaces();
if (ti != sti) {
MetadataFactory::free_array<Klass*>(loader_data, ti);
}
}
deallocate_interfaces(loader_data, super(), local_interfaces(), transitive_interfaces());
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);
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
// 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");
MetadataFactory::free_metadata(loader_data, constants());
set_constants(NULL);
if (constants() != NULL) {
assert (!constants()->on_stack(), "shouldn't be called if anything is onstack");
MetadataFactory::free_metadata(loader_data, constants());
set_constants(NULL);
}
if (inner_classes() != Universe::the_empty_short_array()) {
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"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"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) {
st->print(BULLET"source file: ");
source_file_name()->print_value_on(st);

View File

@ -147,7 +147,8 @@ class InstanceKlass: public Klass {
AccessFlags access_flags,
bool is_anonymous);
public:
static Klass* allocate_instance_klass(ClassLoaderData* loader_data,
static InstanceKlass* allocate_instance_klass(
ClassLoaderData* loader_data,
int vtable_len,
int itable_len,
int static_field_size,
@ -266,9 +267,10 @@ class InstanceKlass: public Klass {
u1 _init_state; // state of class
u1 _reference_type; // reference type
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
NOT_PRODUCT(int _verify_count;) // to avoid redundant verifies
// Method array.
Array<Method*>* _methods;
// Interface (Klass*s) this class declares locally to implement.
@ -356,16 +358,19 @@ class InstanceKlass: public Klass {
// method ordering
Array<int>* method_ordering() const { return _method_ordering; }
void set_method_ordering(Array<int>* m) { _method_ordering = m; }
void copy_method_ordering(intArray* m, TRAPS);
// interfaces
Array<Klass*>* local_interfaces() const { return _local_interfaces; }
void set_local_interfaces(Array<Klass*>* a) {
guarantee(_local_interfaces == NULL || a == NULL, "Just checking");
_local_interfaces = a; }
Array<Klass*>* transitive_interfaces() const { return _transitive_interfaces; }
void set_transitive_interfaces(Array<Klass*>* a) {
guarantee(_transitive_interfaces == NULL || a == NULL, "Just checking");
_transitive_interfaces = a; }
_transitive_interfaces = a;
}
private:
friend class fieldDescriptor;
@ -381,10 +386,9 @@ class InstanceKlass: public Klass {
int java_fields_count() const { return (int)_java_fields_count; }
Array<u2>* fields() const { return _fields; }
void set_fields(Array<u2>* f, u2 java_fields_count) {
guarantee(_fields == NULL || f == NULL, "Just checking");
_fields = f;
_fields = f;
_java_fields_count = java_fields_count;
}
@ -588,7 +592,7 @@ class InstanceKlass: public Klass {
// symbol unloading support (refcount already added)
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
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);
// 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);
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
// 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* k = this;
{ // Preinitialize supertype information.
// A later call to initialize_supers() may update these settings:
set_super(NULL);
for (juint i = 0; i < Klass::primary_super_limit(); i++) {
_primary_supers[i] = NULL;
}
set_secondary_supers(NULL);
_primary_supers[0] = k;
set_super_check_offset(in_bytes(primary_supers_offset()));
// Preinitialize supertype information.
// A later call to initialize_supers() may update these settings:
set_super(NULL);
for (juint i = 0; i < Klass::primary_super_limit(); i++) {
_primary_supers[i] = NULL;
}
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_modifier_flags(0);

View File

@ -79,7 +79,6 @@
// [last_biased_lock_bulk_revocation_time] (64 bits)
// [prototype_header]
// [biased_lock_revocation_count]
// [verify_count ] - not in product
// [alloc_count ]
// [_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
jint _biased_lock_revocation_count;
#ifndef PRODUCT
int _verify_count; // to avoid redundant verifies
#endif
juint _alloc_count; // allocation profiling support
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);
}
Method::Method(ConstMethod* xconst,
AccessFlags access_flags, int size) {
Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
No_Safepoint_Verifier no_safepoint;
set_constMethod(xconst);
set_access_flags(access_flags);
set_method_size(size);
set_name_index(0);
set_signature_index(0);
#ifdef CC_INTERP
set_result_index(T_VOID);
#endif
set_constants(NULL);
set_max_stack(0);
set_max_locals(0);
set_intrinsic_id(vmIntrinsics::_none);
set_jfr_towrite(false);
set_force_inline(false);
set_hidden(false);
set_dont_inline(false);
set_method_data(NULL);
set_interpreter_throwout_count(0);
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.
_method = method();
if (TieredCompilation) {
_invocation_counter.init();
_backedge_counter.init();
_invocation_counter_start = 0;
_backedge_counter_start = 0;
_num_loops = 0;
_num_blocks = 0;
_highest_comp_level = 0;
_highest_osr_comp_level = 0;
_would_profile = true;
}
_invocation_counter.init();
_backedge_counter.init();
_invocation_counter_start = 0;
_backedge_counter_start = 0;
_num_loops = 0;
_num_blocks = 0;
_highest_comp_level = 0;
_highest_osr_comp_level = 0;
_would_profile = true;
set_creation_mileage(mileage_of(method()));
// Initialize flags and trap history.
_nof_decompiles = 0;
_nof_overflow_recompiles = 0;
_nof_overflow_traps = 0;
_eflags = 0;
_arg_local = 0;
_arg_stack = 0;
_arg_returned = 0;
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
Copy::zero_to_words((HeapWord*) &_trap_hist,
sizeof(_trap_hist) / sizeof(HeapWord));
@ -677,6 +679,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
// corresponding data cells.
int data_size = 0;
int empty_bc_count = 0; // number of bytecodes lacking data
_data[0] = 0; // apparently not set below.
BytecodeStream stream(method);
Bytecodes::Code c;
while ((c = stream.next()) >= 0) {
@ -710,6 +713,7 @@ MethodData::MethodData(methodHandle method, int size, TRAPS) {
post_initialize(&stream);
set_size(object_size);
}
// Get a measure of how much mileage the method has on it.

View File

@ -187,31 +187,6 @@ public:
#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--------------------------------------------
// InterFerence Graph
// An undirected graph implementation. Created with a fixed number of

View File

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

View File

@ -33,11 +33,35 @@
#include "opto/regmask.hpp"
class Block;
class LRG_List;
class PhaseCFG;
class VectorSet;
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--------------------------------------
// Compute live-in/live-out
class PhaseLive : public Phase {

View File

@ -890,7 +890,7 @@ void JvmtiSuspendControl::print() {
tty->print("Suspended Threads: [");
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);
#else
const char *name = "";

View File

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

View File

@ -1381,6 +1381,40 @@ bool Arguments::should_auto_select_low_pause_collector() {
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() {
if (os::is_server_class_machine()) {
@ -1410,30 +1444,7 @@ void Arguments::set_ergonomics_flags() {
#ifndef ZERO
#ifdef _LP64
// Check that UseCompressedOops can be set with the max heap size allocated
// 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);
}
}
set_use_compressed_oops();
// UseCompressedOops must be on for UseCompressedKlassPointers to be on.
if (!UseCompressedOops) {
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
bool Arguments::check_stack_pages()
{
@ -2273,10 +2291,12 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
}
#if !INCLUDE_JVMTI
if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
warning("profiling and debugging agents are not supported in this VM");
} else
jio_fprintf(defaultStream::error_stream(),
"Profiling and debugging agents are not supported in this VM\n");
return JNI_ERR;
}
#endif // !INCLUDE_JVMTI
add_init_library(name, options);
add_init_library(name, options);
}
// -agentlib and -agentpath
} 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 ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
warning("profiling and debugging agents are not supported in this VM");
} else
jio_fprintf(defaultStream::error_stream(),
"Profiling and debugging agents are not supported in this VM\n");
return JNI_ERR;
}
#endif // !INCLUDE_JVMTI
add_init_agent(name, options, is_absolute_path);
}
// -javaagent
} else if (match_option(option, "-javaagent:", &tail)) {
#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
if(tail != NULL) {
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
_has_profile = true;
#else // INCLUDE_FPROF
// do we have to exit?
warning("Flat profiling is not supported in this VM.");
jio_fprintf(defaultStream::error_stream(),
"Flat profiling is not supported in this VM.\n");
return JNI_ERR;
#endif // INCLUDE_FPROF
// -Xaprof
} else if (match_option(option, "-Xaprof", &tail)) {
@ -2478,8 +2502,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
#if INCLUDE_MANAGEMENT
FLAG_SET_CMDLINE(bool, ManagementServer, true);
#else
vm_exit_during_initialization(
"-Dcom.sun.management is not supported in this VM.", NULL);
jio_fprintf(defaultStream::output_stream(),
"-Dcom.sun.management is not supported in this VM.\n");
return JNI_ERR;
#endif
}
// -Xint
@ -2492,16 +2517,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xcomp", &tail)) {
// for testing the compiler; turn off all flags that inhibit compilation
set_mode_flags(_comp);
// -Xshare:dump
} 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);
set_mode_flags(_int); // Prevent compilation, which creates objects
#endif
// -Xshare:on
} else if (match_option(option, "-Xshare:on", &tail)) {
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)) {
FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
// -Xverify
} else if (match_option(option, "-Xverify", &tail)) {
if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
@ -2828,8 +2846,9 @@ SOLARIS_ONLY(
FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true);
#if !INCLUDE_MANAGEMENT
} else if (match_option(option, "-XX:+ManagementServer", &tail)) {
vm_exit_during_initialization(
"ManagementServer is not supported in this VM.", NULL);
jio_fprintf(defaultStream::error_stream(),
"ManagementServer is not supported in this VM.\n");
return JNI_ERR;
#endif // INCLUDE_MANAGEMENT
} else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
// Skip -XX:Flags= since that case has already been handled
@ -3135,7 +3154,9 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
#if INCLUDE_NMT
MemTracker::init_tracking_options(tail);
#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
}
@ -3254,6 +3275,16 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
force_serial_gc();
#endif // INCLUDE_ALL_GCS
#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();
#endif // INCLUDE_CDS
@ -3292,6 +3323,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
set_g1_gc_flags();
}
check_deprecated_gcs();
check_deprecated_gc_flags();
#else // INCLUDE_ALL_GCS
assert(verify_serial_gc_flags(), "SerialGC unset");
#endif // INCLUDE_ALL_GCS

View File

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

View File

@ -425,6 +425,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
callee_parameters,
callee_locals,
index == 0,
index == array->frames() - 1,
popframe_extra_args);
// This pc doesn't have to be perfect just good enough to identify the frame
// 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.
*
* 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 disable_stack_red_zone();
inline bool stack_guard_zone_unused();
inline bool stack_yellow_zone_disabled();
inline bool stack_yellow_zone_enabled();
@ -1759,6 +1760,10 @@ inline CompilerThread* JavaThread::as_CompilerThread() {
return (CompilerThread*)this;
}
inline bool JavaThread::stack_guard_zone_unused() {
return _stack_guard_state == stack_guard_unused;
}
inline bool JavaThread::stack_yellow_zone_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,
frame* caller,
bool is_top_frame,
bool is_bottom_frame,
int exec_mode) {
JavaThread* thread = (JavaThread*) Thread::current();
@ -275,7 +276,8 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
callee_locals,
caller,
iframe(),
is_top_frame);
is_top_frame,
is_bottom_frame);
// Update the pc in the frame object and overwrite the temporary pc
// 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_locals,
bool is_top_frame,
bool is_bottom_frame,
int popframe_extra_stack_expression_els) const {
assert(method()->max_locals() == locals()->size(), "just checking");
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,
callee_parameters,
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
// 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--) {
vframeArrayElement* elem = element(index); // caller
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,
callee_parameters,
callee_locals,
&caller_frame,
caller_frame,
index == 0,
index == frames() - 1,
exec_mode);
if (index == frames() - 1) {
Deoptimization::unwind_callee_save_values(elem->iframe(), this);
}
caller_frame = *elem->iframe();
caller_frame = elem->iframe();
caller_actual_parameters = callee_parameters;
}
deallocate_monitor_chunks();

View File

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

View File

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

View File

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

View File

@ -197,4 +197,28 @@ ElfStringTable* ElfFile::get_string_table(int index) {
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

View File

@ -43,6 +43,7 @@ typedef Elf64_Addr Elf_Addr;
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Sym Elf_Sym;
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
@ -59,6 +60,7 @@ typedef Elf32_Addr Elf_Addr;
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Sym Elf_Sym;
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
@ -123,6 +125,14 @@ protected:
ElfFile* next() const { return m_next; }
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:
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;
}
}