This commit is contained in:
Daniel D. Daugherty 2015-07-02 14:20:36 -07:00
commit 9b1474b512
190 changed files with 4710 additions and 1418 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -48,8 +48,13 @@ public class CodeCache {
Type type = db.lookupType("CodeCache");
// Get array of CodeHeaps
// Note: CodeHeap may be subclassed with optional private heap mechanisms.
Type codeHeapType = db.lookupType("CodeHeap");
VirtualBaseConstructor heapConstructor =
new VirtualBaseConstructor(db, codeHeapType, "sun.jvm.hotspot.memory", CodeHeap.class);
AddressField heapsField = type.getAddressField("_heaps");
heapArray = GrowableArray.create(heapsField.getValue(), new StaticBaseConstructor<CodeHeap>(CodeHeap.class));
heapArray = GrowableArray.create(heapsField.getValue(), heapConstructor);
scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
@ -180,31 +185,9 @@ public class CodeCache {
public void iterate(CodeCacheVisitor visitor) {
visitor.prologue(lowBound(), highBound());
CodeBlob lastBlob = null;
for (int i = 0; i < heapArray.length(); ++i) {
CodeHeap current_heap = heapArray.at(i);
Address ptr = current_heap.begin();
while (ptr != null && ptr.lessThan(current_heap.end())) {
try {
// Use findStart to get a pointer inside blob other findBlob asserts
CodeBlob blob = findBlobUnsafe(current_heap.findStart(ptr));
if (blob != null) {
visitor.visit(blob);
if (blob == lastBlob) {
throw new InternalError("saw same blob twice");
}
lastBlob = blob;
}
} catch (RuntimeException e) {
e.printStackTrace();
}
Address next = current_heap.nextBlock(ptr);
if (next != null && next.lessThan(ptr)) {
throw new InternalError("pointer moved backwards");
}
ptr = next;
}
current_heap.iterate(visitor, this);
}
visitor.epilogue();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, 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
@ -25,6 +25,7 @@
package sun.jvm.hotspot.memory;
import java.util.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
@ -90,7 +91,7 @@ public class CodeHeap extends VMObject {
return h.getAllocatedSpace();
}
public Address nextBlock(Address ptr) {
private Address nextBlock(Address ptr) {
Address base = blockBase(ptr);
if (base == null) {
return null;
@ -99,6 +100,31 @@ public class CodeHeap extends VMObject {
return base.addOffsetTo(block.getLength() * (1 << getLog2SegmentSize()));
}
public void iterate(CodeCacheVisitor visitor, CodeCache cache) {
CodeBlob lastBlob = null;
Address ptr = begin();
while (ptr != null && ptr.lessThan(end())) {
try {
// Use findStart to get a pointer inside blob other findBlob asserts
CodeBlob blob = cache.createCodeBlobWrapper(findStart(ptr));
if (blob != null) {
visitor.visit(blob);
if (blob == lastBlob) {
throw new InternalError("saw same blob twice");
}
lastBlob = blob;
}
} catch (RuntimeException e) {
e.printStackTrace();
}
Address next = nextBlock(ptr);
if (next != null && next.lessThan(ptr)) {
throw new InternalError("pointer moved backwards");
}
ptr = next;
}
}
//--------------------------------------------------------------------------------
// Internals only below this point
//

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -139,6 +139,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -139,6 +139,18 @@
_JVM_Halt
_JVM_HoldsLock
_JVM_IHashCode
_JVM_ImageAttributeOffsets
_JVM_ImageAttributeOffsetsLength
_JVM_ImageClose
_JVM_ImageFindAttributes
_JVM_ImageGetAttributes
_JVM_ImageGetAttributesCount
_JVM_ImageGetDataAddress
_JVM_ImageGetIndexAddress
_JVM_ImageGetStringBytes
_JVM_ImageOpen
_JVM_ImageRead
_JVM_ImageReadCompressed
_JVM_InitAgentProperties
_JVM_InitProperties
_JVM_InternString
@ -188,7 +200,7 @@
_JVM_Yield
_JVM_handle_bsd_signal
# miscellaneous functions
# miscellaneous functions
_jio_fprintf
_jio_printf
_jio_snprintf

View File

@ -139,6 +139,18 @@
_JVM_Halt
_JVM_HoldsLock
_JVM_IHashCode
_JVM_ImageAttributeOffsets
_JVM_ImageAttributeOffsetsLength
_JVM_ImageClose
_JVM_ImageFindAttributes
_JVM_ImageGetAttributes
_JVM_ImageGetAttributesCount
_JVM_ImageGetDataAddress
_JVM_ImageGetIndexAddress
_JVM_ImageGetStringBytes
_JVM_ImageOpen
_JVM_ImageRead
_JVM_ImageReadCompressed
_JVM_InitAgentProperties
_JVM_InitProperties
_JVM_InternString

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -118,7 +118,8 @@ SIMPLE_DIRS = \
$(PLATFORM_DIR)/generated/dependencies \
$(PLATFORM_DIR)/generated/adfiles \
$(PLATFORM_DIR)/generated/jvmtifiles \
$(PLATFORM_DIR)/generated/tracefiles
$(PLATFORM_DIR)/generated/tracefiles \
$(PLATFORM_DIR)/generated/extensions
TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2015, 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
@ -34,7 +34,7 @@ DEMANGLE = $(DEMANGLER) < $@ > .$@ && $(MV) -f .$@ $@
CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS)
CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS)
AS.S = $(AS) $(ASFLAGS)
AS.S = $(AS) $(ASFLAGS)
COMPILE.CC = $(CC_COMPILE) -c
GENASM.CC = $(CC_COMPILE) -S
@ -170,6 +170,12 @@ endif
$(QUIETLY) $(REMOVE_TARGET)
$(QUIETLY) $(AS.S) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)
# gcc applies preprocessing if the file extension is .S instead of .s
%.o: %.S
@echo $(LOG_INFO) Preprocessing and assembling $<
$(QUIETLY) $(REMOVE_TARGET)
$(QUIETLY) $(AS.S) $(DEPFLAGS) -o $@ $< $(COMPILE_DONE)
%.s: %.cpp
@echo $(LOG_INFO) Generating assembly for $<
$(QUIETLY) $(GENASM.CXX) -o $@ $<

View File

@ -54,7 +54,7 @@ endif
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
# The adfiles directory contains ad_<arch>.[ch]pp.
# The jvmtifiles directory contains jvmti*.[ch]pp
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles $(GENERATED)/extensions
VPATH += $(Src_Dirs_V:%=%:)
# set INCLUDES for C preprocessor.
@ -161,6 +161,8 @@ CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
fi)
endif
CORE_PATHS+=$(GENERATED)/extensions
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
@ -207,6 +209,8 @@ ifeq ($(Platform_arch_model), x86_64)
Src_Files_EXCLUDE += \*x86_32\*
endif
Src_Files_BASE += \*.c \*.cpp \*.s
# Alternate vm.make
# This has to be included here to allow changes to the source
# directories and excluded files before they are expanded
@ -216,13 +220,13 @@ endif
# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
define findsrc
$(notdir $(shell find $(1)/. ! -name . -prune \
-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
-a \( -name DUMMY $(addprefix -o -name ,$(Src_Files_BASE)) \) \
-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
endef
Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
Obj_Files = $(sort $(addsuffix .o,$(basename $(Src_Files))))
Obj_Files = $(sort $(addsuffix .o,$(basename $(Src_Files))) $(EXTENDED_JVM_OBJ_FILES))
JVM_OBJ_FILES = $(Obj_Files)
@ -244,10 +248,16 @@ VMDEF_PAT = ^_ZTV
VMDEF_PAT := ^gHotSpotVM|$(VMDEF_PAT)
VMDEF_PAT := ^UseSharedSpaces$$|$(VMDEF_PAT)
VMDEF_PAT := ^_ZN9Arguments17SharedArchivePathE$$|$(VMDEF_PAT)
ifneq ($(VMDEF_PAT_EXT),)
VMDEF_PAT := $(VMDEF_PAT_EXT)|$(VMDEF_PAT)
endif
vm.def: $(Res_Files) $(Obj_Files)
vm.def: $(Res_Files) $(Obj_Files) $(VM_DEF_EXT)
$(QUIETLY) $(NM) --defined-only $(Obj_Files) | sort -k3 -u | \
awk '$$3 ~ /$(VMDEF_PAT)/ { print "\t" $$3 ";" }' > $@
ifneq ($(VM_DEF_EXT),)
cat $(VM_DEF_EXT) >> $@
endif
mapfile_ext:
rm -f $@

View File

@ -141,6 +141,18 @@ SUNWprivate_1.1 {
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_ImageAttributeOffsets;
JVM_ImageAttributeOffsetsLength;
JVM_ImageClose;
JVM_ImageFindAttributes;
JVM_ImageGetAttributes;
JVM_ImageGetAttributesCount;
JVM_ImageGetDataAddress;
JVM_ImageGetIndexAddress;
JVM_ImageGetStringBytes;
JVM_ImageOpen;
JVM_ImageRead;
JVM_ImageReadCompressed;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InternString;

View File

@ -143,7 +143,7 @@ else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
endif # sparcWorks
LIBS += -lkstat
LIBS += -lkstat -lrt
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM

View File

@ -105,7 +105,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
__ flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
vtable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));
@ -184,7 +184,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
__ flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
itable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));

View File

@ -465,7 +465,7 @@ void trace_method_handle_stub(const char* adaptername,
bool has_mh = (strstr(adaptername, "/static") == NULL &&
strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH
const char* mh_reg_name = has_mh ? "R23_method_handle" : "G23";
tty->print_cr("MH %s %s="INTPTR_FORMAT " sp=" INTPTR_FORMAT,
tty->print_cr("MH %s %s=" INTPTR_FORMAT " sp=" INTPTR_FORMAT,
adaptername, mh_reg_name, p2i(mh), p2i(entry_sp));
if (Verbose) {

View File

@ -483,7 +483,7 @@ void trace_method_handle_stub(const char* adaptername,
bool has_mh = (strstr(adaptername, "/static") == NULL &&
strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH
const char* mh_reg_name = has_mh ? "G3_mh" : "G3";
tty->print_cr("MH %s %s="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT,
tty->print_cr("MH %s %s=" INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT,
adaptername, mh_reg_name,
p2i(mh), p2i(saved_sp), p2i(args));

View File

@ -110,7 +110,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
masm->flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
vtable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));
@ -205,7 +205,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
masm->flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
itable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));

View File

@ -5152,7 +5152,7 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad
{
ResourceMark rm;
stringStream ss;
ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
ss.print("DelayedValue=" INTPTR_FORMAT, delayed_value_addr[1]);
buf = code_string(ss.as_string());
}
jcc(Assembler::notZero, L);

View File

@ -484,7 +484,7 @@ void trace_method_handle_stub(const char* adaptername,
bool has_mh = (strstr(adaptername, "/static") == NULL &&
strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH
const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT,
tty->print_cr("MH %s %s=" PTR_FORMAT " sp=" PTR_FORMAT,
adaptername, mh_reg_name,
(void *)mh, entry_sp);

View File

@ -117,7 +117,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
masm->flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
vtable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));
@ -198,7 +198,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
masm->flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
itable_index, p2i(s->entry_point()),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));

View File

@ -112,7 +112,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
__ flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
vtable_index, s->entry_point(),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));
@ -205,7 +205,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
__ flush();
if (PrintMiscellaneous && (WizardMode || Verbose)) {
tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
itable_index, s->entry_point(),
(int)(s->code_end() - s->entry_point()),
(int)(s->code_end() - __ pc()));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,6 +42,7 @@
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
static unsigned int jvmsigs = 0; /* signals used by jvm */
static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
/* used to synchronize the installation of signal handlers */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@ -76,6 +77,8 @@ static void signal_unlock() {
static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
bool is_sigset) {
sa_handler_t res;
if (os_signal == NULL) {
if (!is_sigset) {
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
@ -87,7 +90,10 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
exit(0);
}
}
return (*os_signal)(sig, disp);
reentry = true;
res = (*os_signal)(sig, disp);
reentry = false;
return res;
}
static void save_signal_handler(int sig, sa_handler_t disp) {
@ -161,6 +167,10 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
bool sigused;
struct sigaction oldAct;
if (reentry) {
return call_os_sigaction(sig, act, oact);
}
signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0;

View File

@ -59,6 +59,7 @@
#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "semaphore_bsd.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
@ -1940,47 +1941,54 @@ typedef sem_t os_semaphore_t;
#define SEM_DESTROY(sem) sem_destroy(&sem)
#endif
class Semaphore : public StackObj {
public:
Semaphore();
~Semaphore();
void signal();
void wait();
bool trywait();
bool timedwait(unsigned int sec, int nsec);
private:
jlong currenttime() const;
os_semaphore_t _semaphore;
};
#ifdef __APPLE__
// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
Semaphore::Semaphore() : _semaphore(0) {
SEM_INIT(_semaphore, 0);
static const char* sem_init_strerror(kern_return_t value) {
switch (value) {
case KERN_INVALID_ARGUMENT: return "Invalid argument";
case KERN_RESOURCE_SHORTAGE: return "Resource shortage";
default: return "Unknown";
}
}
Semaphore::~Semaphore() {
OSXSemaphore::OSXSemaphore(uint value) {
kern_return_t ret = SEM_INIT(_semaphore, value);
guarantee(ret == KERN_SUCCESS, err_msg("Failed to create semaphore: %s", sem_init_strerror(ret)));
}
OSXSemaphore::~OSXSemaphore() {
SEM_DESTROY(_semaphore);
}
void Semaphore::signal() {
SEM_POST(_semaphore);
void OSXSemaphore::signal(uint count) {
for (uint i = 0; i < count; i++) {
kern_return_t ret = SEM_POST(_semaphore);
assert(ret == KERN_SUCCESS, "Failed to signal semaphore");
}
}
void Semaphore::wait() {
SEM_WAIT(_semaphore);
void OSXSemaphore::wait() {
kern_return_t ret;
while ((ret = SEM_WAIT(_semaphore)) == KERN_ABORTED) {
// Semaphore was interrupted. Retry.
}
assert(ret == KERN_SUCCESS, "Failed to wait on semaphore");
}
jlong Semaphore::currenttime() const {
jlong OSXSemaphore::currenttime() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
}
#ifdef __APPLE__
bool Semaphore::trywait() {
bool OSXSemaphore::trywait() {
return timedwait(0, 0);
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
bool OSXSemaphore::timedwait(unsigned int sec, int nsec) {
kern_return_t kr = KERN_ABORTED;
mach_timespec_t waitspec;
waitspec.tv_sec = sec;
@ -2011,33 +2019,24 @@ bool Semaphore::timedwait(unsigned int sec, int nsec) {
}
#else
// Use POSIX implementation of semaphores.
bool Semaphore::trywait() {
return sem_trywait(&_semaphore) == 0;
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
struct timespec ts;
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
while (1) {
int result = sem_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
} else if (errno == EINTR) {
continue;
} else if (errno == ETIMEDOUT) {
return false;
} else {
return false;
}
}
return ts;
}
#endif // __APPLE__
static os_semaphore_t sig_sem;
static Semaphore sr_semaphore;
#ifdef __APPLE__
static OSXSemaphore sr_semaphore;
#else
static PosixSemaphore sr_semaphore;
#endif
void os::signal_init_pd() {
// Initialize signal structures

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2015, 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.
*
*/
#ifndef OS_BSD_VM_SEMAPHORE_BSD_HPP
#define OS_BSD_VM_SEMAPHORE_BSD_HPP
#ifndef __APPLE__
// Use POSIX semaphores.
# include "semaphore_posix.hpp"
#else
// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
# include "memory/allocation.hpp"
# include <mach/semaphore.h>
class OSXSemaphore : public CHeapObj<mtInternal>{
semaphore_t _semaphore;
// Prevent copying and assignment.
OSXSemaphore(const OSXSemaphore&);
OSXSemaphore& operator=(const OSXSemaphore&);
public:
OSXSemaphore(uint value = 0);
~OSXSemaphore();
void signal(uint count = 1);
void wait();
bool trywait();
bool timedwait(unsigned int sec, int nsec);
private:
static jlong currenttime();
};
typedef OSXSemaphore SemaphoreImpl;
#endif // __APPLE__
#endif // OS_BSD_VM_SEMAPHORE_BSD_HPP

View File

@ -60,6 +60,7 @@
#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "semaphore_posix.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
@ -2315,40 +2316,7 @@ void* os::user_handler() {
return CAST_FROM_FN_PTR(void*, UserHandler);
}
class Semaphore : public StackObj {
public:
Semaphore();
~Semaphore();
void signal();
void wait();
bool trywait();
bool timedwait(unsigned int sec, int nsec);
private:
sem_t _semaphore;
};
Semaphore::Semaphore() {
sem_init(&_semaphore, 0, 0);
}
Semaphore::~Semaphore() {
sem_destroy(&_semaphore);
}
void Semaphore::signal() {
sem_post(&_semaphore);
}
void Semaphore::wait() {
sem_wait(&_semaphore);
}
bool Semaphore::trywait() {
return sem_trywait(&_semaphore) == 0;
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
struct timespec ts;
// Semaphore's are always associated with CLOCK_REALTIME
os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
@ -2365,18 +2333,7 @@ bool Semaphore::timedwait(unsigned int sec, int nsec) {
}
}
while (1) {
int result = sem_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
} else if (errno == EINTR) {
continue;
} else if (errno == ETIMEDOUT) {
return false;
} else {
return false;
}
}
return ts;
}
extern "C" {
@ -2416,7 +2373,7 @@ static volatile jint pending_signals[NSIG+1] = { 0 };
// Linux(POSIX) specific hand shaking semaphore.
static sem_t sig_sem;
static Semaphore sr_semaphore;
static PosixSemaphore sr_semaphore;
void os::signal_init_pd() {
// Initialize signal structures

View File

@ -24,6 +24,7 @@
#include "utilities/globalDefinitions.hpp"
#include "prims/jvm.h"
#include "semaphore_posix.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
@ -34,6 +35,7 @@
#include <sys/resource.h>
#include <sys/utsname.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
@ -1015,3 +1017,73 @@ void os::WatcherThreadCrashProtection::check_crash_protection(int sig,
}
}
}
#define check_with_errno(check_type, cond, msg) \
do { \
int err = errno; \
check_type(cond, err_msg("%s; error='%s' (errno=%d)", msg, strerror(err), err)); \
} while (false)
#define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg)
#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
// POSIX unamed semaphores are not supported on OS X.
#ifndef __APPLE__
PosixSemaphore::PosixSemaphore(uint value) {
int ret = sem_init(&_semaphore, 0, value);
guarantee_with_errno(ret == 0, "Failed to initialize semaphore");
}
PosixSemaphore::~PosixSemaphore() {
sem_destroy(&_semaphore);
}
void PosixSemaphore::signal(uint count) {
for (uint i = 0; i < count; i++) {
int ret = sem_post(&_semaphore);
assert_with_errno(ret == 0, "sem_post failed");
}
}
void PosixSemaphore::wait() {
int ret;
do {
ret = sem_wait(&_semaphore);
} while (ret != 0 && errno == EINTR);
assert_with_errno(ret == 0, "sem_wait failed");
}
bool PosixSemaphore::trywait() {
int ret;
do {
ret = sem_trywait(&_semaphore);
} while (ret != 0 && errno == EINTR);
assert_with_errno(ret == 0 || errno == EAGAIN, "trywait failed");
return ret == 0;
}
bool PosixSemaphore::timedwait(const struct timespec ts) {
while (true) {
int result = sem_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
} else if (errno == EINTR) {
continue;
} else if (errno == ETIMEDOUT) {
return false;
} else {
assert_with_errno(false, "timedwait failed");
return false;
}
}
}
#endif // __APPLE__

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2015, 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.
*
*/
#ifndef OS_POSIX_VM_SEMAPHORE_POSIX_HPP
#define OS_POSIX_VM_SEMAPHORE_POSIX_HPP
#include "memory/allocation.hpp"
#include <semaphore.h>
class PosixSemaphore : public CHeapObj<mtInternal> {
sem_t _semaphore;
// Prevent copying and assignment.
PosixSemaphore(const PosixSemaphore&);
PosixSemaphore& operator=(const PosixSemaphore&);
public:
PosixSemaphore(uint value = 0);
~PosixSemaphore();
void signal(uint count = 1);
void wait();
bool trywait();
bool timedwait(unsigned int sec, int nsec) {
return timedwait(create_timespec(sec, nsec));
}
private:
bool timedwait(struct timespec ts);
// OS specific implementation to create a timespec suitable for semaphores.
struct timespec create_timespec(unsigned int set, int nsec);
};
typedef PosixSemaphore SemaphoreImpl;
#endif // OS_POSIX_VM_SEMAPHORE_POSIX_HPP

View File

@ -60,6 +60,7 @@
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_version.hpp"
#include "semaphore_posix.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
@ -2263,55 +2264,11 @@ void* os::user_handler() {
return CAST_FROM_FN_PTR(void*, UserHandler);
}
class Semaphore : public StackObj {
public:
Semaphore();
~Semaphore();
void signal();
void wait();
bool trywait();
bool timedwait(unsigned int sec, int nsec);
private:
sema_t _semaphore;
};
Semaphore::Semaphore() {
sema_init(&_semaphore, 0, NULL, NULL);
}
Semaphore::~Semaphore() {
sema_destroy(&_semaphore);
}
void Semaphore::signal() {
sema_post(&_semaphore);
}
void Semaphore::wait() {
sema_wait(&_semaphore);
}
bool Semaphore::trywait() {
return sema_trywait(&_semaphore) == 0;
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
struct timespec ts;
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
while (1) {
int result = sema_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
} else if (errno == EINTR) {
continue;
} else if (errno == ETIME) {
return false;
} else {
return false;
}
}
return ts;
}
extern "C" {
@ -3711,7 +3668,7 @@ static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
osthread->set_ucontext(context);
}
static Semaphore sr_semaphore;
static PosixSemaphore sr_semaphore;
void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
// Save and restore errno to avoid confusing native code with EINTR

View File

@ -63,6 +63,7 @@
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_version.hpp"
#include "semaphore_windows.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
@ -1901,6 +1902,30 @@ int os::get_last_error() {
return (int)error;
}
WindowsSemaphore::WindowsSemaphore(uint value) {
_semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL);
guarantee(_semaphore != NULL, err_msg("CreateSemaphore failed with error code: %lu", GetLastError()));
}
WindowsSemaphore::~WindowsSemaphore() {
::CloseHandle(_semaphore);
}
void WindowsSemaphore::signal(uint count) {
if (count > 0) {
BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL);
assert(ret != 0, err_msg("ReleaseSemaphore failed with error code: %lu", GetLastError()));
}
}
void WindowsSemaphore::wait() {
DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE);
assert(ret != WAIT_FAILED, err_msg("WaitForSingleObject failed with error code: %lu", GetLastError()));
assert(ret == WAIT_OBJECT_0, err_msg("WaitForSingleObject failed with return value: %lu", ret));
}
// sun.misc.Signal
// NOTE that this is a workaround for an apparent kernel bug where if
// a signal handler for SIGBREAK is installed then that signal handler
@ -5890,7 +5915,7 @@ void TestReserveMemorySpecial_test() {
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
if (result == NULL) {
if (VerboseInternalVMTests) {
gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.",
gclog_or_tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",
large_allocation_size);
}
} else {
@ -5903,7 +5928,7 @@ void TestReserveMemorySpecial_test() {
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
if (actual_location == NULL) {
if (VerboseInternalVMTests) {
gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.",
gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
expected_location, large_allocation_size);
}
} else {
@ -5911,7 +5936,7 @@ void TestReserveMemorySpecial_test() {
os::release_memory_special(actual_location, expected_allocation_size);
// only now check, after releasing any memory to avoid any leaks.
assert(actual_location == expected_location,
err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead",
err_msg("Failed to allocate memory at requested location " PTR_FORMAT " of size " SIZE_FORMAT ", is " PTR_FORMAT " instead",
expected_location, expected_allocation_size, actual_location));
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, 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.
*
*/
#ifndef OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP
#define OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP
#include "memory/allocation.hpp"
#include <windef.h>
class WindowsSemaphore : public CHeapObj<mtInternal> {
HANDLE _semaphore;
// Prevent copying and assignment.
WindowsSemaphore(const WindowsSemaphore&);
WindowsSemaphore& operator=(const WindowsSemaphore&);
public:
WindowsSemaphore(uint value = 0);
~WindowsSemaphore();
void signal(uint count = 1);
void wait();
};
typedef WindowsSemaphore SemaphoreImpl;
#endif // OS_WINDOWS_VM_SEMAPHORE_WINDOWS_HPP

View File

@ -1093,9 +1093,11 @@ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
void CodeStrings::assign(CodeStrings& other) {
other.check_valid();
// Cannot do following because CodeStrings constructor is not alway run!
assert(is_null(), "Cannot assign onto non-empty CodeStrings");
_strings = other._strings;
#ifdef ASSERT
_defunct = false;
#endif
other.set_null_and_invalidate();
}
@ -1115,13 +1117,15 @@ void CodeStrings::copy(CodeStrings& other) {
}
}
const char* CodeStrings::_prefix = " ;; "; // default: can be changed via set_prefix
void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
check_valid();
if (_strings != NULL) {
CodeString* c = find(offset);
while (c && c->offset() == offset) {
stream->bol();
stream->print(" ;; ");
stream->print("%s", _prefix);
stream->print_cr("%s", c->string());
c = c->next_comment();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, 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
@ -249,6 +249,7 @@ private:
// Becomes true after copy-out, forbids further use.
bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
#endif
static const char* _prefix; // defaults to " ;; "
#endif
CodeString* find(intptr_t offset) const;
@ -289,11 +290,18 @@ public:
void assign(CodeStrings& other) PRODUCT_RETURN;
// COPY strings from other to this; leave other valid.
void copy(CodeStrings& other) PRODUCT_RETURN;
// FREE strings; invalidate this.
void free() PRODUCT_RETURN;
// Guarantee that _strings are used at most once; assign invalidates a buffer.
// Guarantee that _strings are used at most once; assign and free invalidate a buffer.
inline void check_valid() const {
#ifdef ASSERT
assert(!_defunct, "Use of invalid CodeStrings");
#endif
}
static void set_prefix(const char *prefix) {
#ifndef PRODUCT
_prefix = prefix;
#endif
}
};
@ -379,6 +387,7 @@ class CodeBuffer: public StackObj {
_oop_recorder = NULL;
_decode_begin = NULL;
_overflow_arena = NULL;
_code_strings = CodeStrings();
}
void initialize(address code_start, csize_t code_size) {
@ -495,6 +504,7 @@ class CodeBuffer: public StackObj {
// Properties
const char* name() const { return _name; }
void set_name(const char* name) { _name = name; }
CodeBuffer* before_expand() const { return _before_expand; }
BufferBlob* blob() const { return _blob; }
void set_blob(BufferBlob* blob);

View File

@ -161,7 +161,7 @@ void CFGPrinterOutput::print_compilation() {
print("name \"%s\"", method_name(_compilation->method(), true));
print("method \"%s\"", method_name(_compilation->method()));
print("date "INT64_FORMAT, (int64_t) os::javaTimeMillis());
print("date " INT64_FORMAT, (int64_t) os::javaTimeMillis());
print_end("compilation");
}

View File

@ -33,6 +33,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeBlob.hpp"
#include "code/codeCacheExtensions.hpp"
#include "code/compiledIC.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
@ -183,20 +184,25 @@ void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
// create code buffer for code storage
CodeBuffer code(buffer_blob);
Compilation::setup_code_buffer(&code, 0);
// create assembler for code generation
StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
// generate code for runtime stub
OopMapSet* oop_maps;
oop_maps = generate_code_for(id, sasm);
assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
"if stub has an oop map it must have a valid frame size");
int frame_size;
bool must_gc_arguments;
if (!CodeCacheExtensions::skip_compiler_support()) {
// bypass useless code generation
Compilation::setup_code_buffer(&code, 0);
// create assembler for code generation
StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
// generate code for runtime stub
oop_maps = generate_code_for(id, sasm);
assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
"if stub has an oop map it must have a valid frame size");
#ifdef ASSERT
// Make sure that stubs that need oopmaps have them
switch (id) {
// These stubs don't need to have an oopmap
// Make sure that stubs that need oopmaps have them
switch (id) {
// These stubs don't need to have an oopmap
case dtrace_object_alloc_id:
case g1_pre_barrier_slow_id:
case g1_post_barrier_slow_id:
@ -209,23 +215,32 @@ void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
#endif
break;
// All other stubs should have oopmaps
// All other stubs should have oopmaps
default:
assert(oop_maps != NULL, "must have an oopmap");
}
}
#endif
// align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
sasm->align(BytesPerWord);
// make sure all code is in code buffer
sasm->flush();
// align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
sasm->align(BytesPerWord);
// make sure all code is in code buffer
sasm->flush();
frame_size = sasm->frame_size();
must_gc_arguments = sasm->must_gc_arguments();
} else {
/* ignored values */
oop_maps = NULL;
frame_size = 0;
must_gc_arguments = false;
}
// create blob - distinguish a few special cases
CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
&code,
CodeOffsets::frame_never_safe,
sasm->frame_size(),
frame_size,
oop_maps,
sasm->must_gc_arguments());
must_gc_arguments);
// install blob
assert(blob != NULL, "blob must exist");
_blobs[id] = blob;
@ -399,7 +414,7 @@ static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, Meth
CompLevel level = (CompLevel)nm->comp_level();
int bci = InvocationEntryBci;
if (branch_bci != InvocationEntryBci) {
// Compute desination bci
// Compute destination bci
address pc = method()->code_base() + branch_bci;
Bytecodes::Code branch = Bytecodes::code_at(method(), pc);
int offset = 0;

View File

@ -68,7 +68,6 @@
#include "classfile/sharedPathsMiscInfo.hpp"
#endif
// Entry points in zip.dll for loading zip/jar file entries and image file entries
typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
@ -157,17 +156,12 @@ ClassPathEntry::ClassPathEntry() {
}
bool ClassPathEntry::is_lazy() {
return false;
}
ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
strcpy(copy, dir);
_dir = copy;
}
ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
// construct full path name
char path[JVM_MAXPATHLEN];
@ -278,90 +272,25 @@ void ClassPathZipEntry::contents_do(void f(const char* name, void* context), voi
}
}
LazyClassPathEntry::LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
_path = os::strdup_check_oom(path);
_st = *st;
_resolved_entry = NULL;
_has_error = false;
_throw_exception = throw_exception;
}
ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) :
ClassPathEntry(),
_image(image),
_module_data(NULL) {
guarantee(image != NULL, "image file is null");
LazyClassPathEntry::~LazyClassPathEntry() {
os::free((void*)_path);
}
bool LazyClassPathEntry::is_jar_file() {
size_t len = strlen(_path);
if (len < 4 || strcmp(_path + len - 4, ".jar") != 0) return false;
return ((_st.st_mode & S_IFREG) == S_IFREG);
}
ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
if (_resolved_entry != NULL) {
return (ClassPathEntry*) _resolved_entry;
}
ClassPathEntry* new_entry = NULL;
new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL);
if (!_throw_exception && new_entry == NULL) {
assert(!HAS_PENDING_EXCEPTION, "must be");
return NULL;
}
{
ThreadCritical tc;
if (_resolved_entry == NULL) {
_resolved_entry = new_entry;
return new_entry;
}
}
assert(_resolved_entry != NULL, "bug in MT-safe resolution logic");
delete new_entry;
return (ClassPathEntry*) _resolved_entry;
}
ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) {
if (_has_error) {
return NULL;
}
ClassPathEntry* cpe = resolve_entry(THREAD);
if (cpe == NULL) {
_has_error = true;
return NULL;
} else {
return cpe->open_stream(name, THREAD);
}
}
bool LazyClassPathEntry::is_lazy() {
return true;
}
u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
if (_has_error) {
return NULL;
}
ClassPathEntry* cpe = resolve_entry(THREAD);
if (cpe == NULL) {
_has_error = true;
return NULL;
} else if (cpe->is_jar_file()) {
return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
} else {
ShouldNotReachHere();
*filesize = 0;
return NULL;
}
}
ClassPathImageEntry::ClassPathImageEntry(char* name) : ClassPathEntry(), _image(new ImageFile(name)) {
bool opened = _image->open();
if (!opened) {
_image = NULL;
}
char module_data_name[JVM_MAXPATHLEN];
ImageModuleData::module_data_name(module_data_name, _image->name());
_module_data = new ImageModuleData(_image, module_data_name);
}
ClassPathImageEntry::~ClassPathImageEntry() {
if (_image) {
_image->close();
if (_module_data != NULL) {
delete _module_data;
_module_data = NULL;
}
if (_image != NULL) {
ImageFileReader::close(_image);
_image = NULL;
}
}
@ -371,15 +300,39 @@ const char* ClassPathImageEntry::name() {
}
ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
u1* buffer;
u8 size;
_image->get_resource(name, buffer, size);
ImageLocation location;
bool found = _image->find_location(name, location);
if (buffer) {
if (!found) {
const char *pslash = strrchr(name, '/');
int len = pslash - name;
// NOTE: IMAGE_MAX_PATH is used here since this path is internal to the jimage
// (effectively unlimited.) There are several JCK tests that use paths over
// 1024 characters long, the limit on Windows systems.
if (pslash && 0 < len && len < IMAGE_MAX_PATH) {
char path[IMAGE_MAX_PATH];
strncpy(path, name, len);
path[len] = '\0';
const char* moduleName = _module_data->package_to_module(path);
if (moduleName != NULL && (len + strlen(moduleName) + 2) < IMAGE_MAX_PATH) {
jio_snprintf(path, IMAGE_MAX_PATH - 1, "/%s/%s", moduleName, name);
location.clear_data();
found = _image->find_location(path, location);
}
}
}
if (found) {
u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
}
return new ClassFileStream(buffer, (int)size, (char*)name); // Resource allocated
u1* data = NEW_RESOURCE_ARRAY(u1, size);
_image->get_resource(location, data);
return new ClassFileStream(data, (int)size, _image->name()); // Resource allocated
}
return NULL;
@ -391,20 +344,14 @@ void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
tty->cr();
const ImageStrings strings = _image->get_strings();
// Retrieve each path component string.
u4 count = _image->get_location_count();
for (u4 i = 0; i < count; i++) {
u4 length = _image->table_length();
for (u4 i = 0; i < length; i++) {
u1* location_data = _image->get_location_data(i);
if (location_data) {
if (location_data != NULL) {
ImageLocation location(location_data);
const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
assert((strlen(parent) + strlen(base) + strlen(extension)) < JVM_MAXPATHLEN, "path exceeds buffer");
char path[JVM_MAXPATHLEN];
strcpy(path, parent);
strcat(path, base);
strcat(path, extension);
char path[IMAGE_MAX_PATH];
_image->location_path(location, path, IMAGE_MAX_PATH);
ClassLoader::compile_the_world_in(path, loader, CHECK);
}
}
@ -420,7 +367,7 @@ void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
}
bool ClassPathImageEntry::is_jrt() {
return string_ends_with(name(), "bootmodules.jimage");
return string_ends_with(name(), BOOT_IMAGE_NAME);
}
#endif
@ -539,11 +486,8 @@ void ClassLoader::setup_search_path(const char *class_path) {
}
ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
bool lazy, bool throw_exception, TRAPS) {
bool throw_exception, TRAPS) {
JavaThread* thread = JavaThread::current();
if (lazy) {
return new LazyClassPathEntry(path, st, throw_exception);
}
ClassPathEntry* new_entry = NULL;
if ((st->st_mode & S_IFREG) == S_IFREG) {
// Regular file, should be a zip or image file
@ -557,39 +501,39 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
return NULL;
}
}
// TODO - add proper criteria for selecting image file
ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
if (entry->is_open()) {
new_entry = entry;
ImageFileReader* image = ImageFileReader::open(canonical_path);
if (image != NULL) {
new_entry = new ClassPathImageEntry(image);
} else {
char* error_msg = NULL;
jzfile* zip;
{
// enable call to C land
ThreadToNativeFromVM ttn(thread);
HandleMark hm(thread);
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (zip != NULL && error_msg == NULL) {
new_entry = new ClassPathZipEntry(zip, path);
} else {
ResourceMark rm(thread);
char *msg;
if (error_msg == NULL) {
msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
} else {
int len = (int)(strlen(path) + strlen(error_msg) + 128);
msg = NEW_RESOURCE_ARRAY(char, len); ;
jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
char* error_msg = NULL;
jzfile* zip;
{
// enable call to C land
ThreadToNativeFromVM ttn(thread);
HandleMark hm(thread);
zip = (*ZipOpen)(canonical_path, &error_msg);
}
if (throw_exception) {
THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
if (zip != NULL && error_msg == NULL) {
new_entry = new ClassPathZipEntry(zip, path);
} else {
return NULL;
ResourceMark rm(thread);
char *msg;
if (error_msg == NULL) {
msg = NEW_RESOURCE_ARRAY(char, strlen(path) + 128); ;
jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
} else {
int len = (int)(strlen(path) + strlen(error_msg) + 128);
msg = NEW_RESOURCE_ARRAY(char, len); ;
jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
}
// Don't complain about bad jar files added via -Xbootclasspath/a:.
if (throw_exception && is_init_completed()) {
THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
} else {
return NULL;
}
}
}
}
if (TraceClassLoading || TraceClassPaths) {
tty->print_cr("[Opened %s]", path);
}
@ -666,7 +610,7 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
// File or directory found
ClassPathEntry* new_entry = NULL;
Thread* THREAD = Thread::current();
new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false));
new_entry = create_class_path_entry(path, &st, throw_exception, CHECK_(false));
if (new_entry == NULL) {
return false;
}
@ -1319,19 +1263,6 @@ bool ClassPathZipEntry::is_jrt() {
return false;
}
void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
ClassPathEntry* cpe = resolve_entry(THREAD);
if (cpe != NULL) {
cpe->compile_the_world(loader, CHECK);
}
}
bool LazyClassPathEntry::is_jrt() {
Thread* THREAD = Thread::current();
ClassPathEntry* cpe = resolve_entry(THREAD);
return (cpe != NULL) ? cpe->is_jar_file() : false;
}
void ClassLoader::compile_the_world() {
EXCEPTION_MARK;
HandleMark hm(THREAD);

View File

@ -32,9 +32,14 @@
// The VM class loader.
#include <sys/stat.h>
// Name of boot module image
#define BOOT_IMAGE_NAME "bootmodules.jimage"
// Class path entry (directory or zip file)
class ImageFileReader;
class ImageModuleData;
class ClassPathEntry: public CHeapObj<mtClass> {
private:
ClassPathEntry* _next;
@ -47,7 +52,7 @@ class ClassPathEntry: public CHeapObj<mtClass> {
}
virtual bool is_jar_file() = 0;
virtual const char* name() = 0;
virtual bool is_lazy();
virtual ImageFileReader* image() = 0;
// Constructor
ClassPathEntry();
// Attempt to locate file_name through this class path entry.
@ -63,8 +68,9 @@ class ClassPathDirEntry: public ClassPathEntry {
private:
const char* _dir; // Name of directory
public:
bool is_jar_file() { return false; }
const char* name() { return _dir; }
bool is_jar_file() { return false; }
const char* name() { return _dir; }
ImageFileReader* image() { return NULL; }
ClassPathDirEntry(const char* dir);
ClassFileStream* open_stream(const char* name, TRAPS);
// Debugging
@ -92,8 +98,9 @@ class ClassPathZipEntry: public ClassPathEntry {
jzfile* _zip; // The zip archive
const char* _zip_name; // Name of zip archive
public:
bool is_jar_file() { return true; }
const char* name() { return _zip_name; }
bool is_jar_file() { return true; }
const char* name() { return _zip_name; }
ImageFileReader* image() { return NULL; }
ClassPathZipEntry(jzfile* zip, const char* zip_name);
~ClassPathZipEntry();
u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
@ -105,39 +112,18 @@ class ClassPathZipEntry: public ClassPathEntry {
};
// For lazier loading of boot class path entries
class LazyClassPathEntry: public ClassPathEntry {
private:
const char* _path; // dir or file
struct stat _st;
bool _has_error;
bool _throw_exception;
volatile ClassPathEntry* _resolved_entry;
ClassPathEntry* resolve_entry(TRAPS);
public:
bool is_jar_file();
const char* name() { return _path; }
LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
virtual ~LazyClassPathEntry();
u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
ClassFileStream* open_stream(const char* name, TRAPS);
virtual bool is_lazy();
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
NOT_PRODUCT(bool is_jrt();)
};
// For java image files
class ImageFile;
class ClassPathImageEntry: public ClassPathEntry {
private:
ImageFile *_image;
ImageFileReader* _image;
ImageModuleData* _module_data;
public:
bool is_jar_file() { return false; }
bool is_open() { return _image != NULL; }
const char* name();
ClassPathImageEntry(char* name);
ImageFileReader* image() { return _image; }
ImageModuleData* module_data() { return _module_data; }
ClassPathImageEntry(ImageFileReader* image);
~ClassPathImageEntry();
ClassFileStream* open_stream(const char* name, TRAPS);
@ -157,7 +143,6 @@ class ClassLoader: AllStatic {
package_hash_table_size = 31 // Number of buckets
};
protected:
friend class LazyClassPathEntry;
// Performance counters
static PerfCounter* _perf_accumulated_time;
@ -222,7 +207,7 @@ class ClassLoader: AllStatic {
static void load_zip_library();
static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
bool lazy, bool throw_exception, TRAPS);
bool throw_exception, TRAPS);
// Canonicalizes path names, so strcmp will work properly. This is mainly
// to avoid confusing the zip library

View File

@ -494,7 +494,7 @@ const char* ClassLoaderData::loader_name() {
void ClassLoaderData::dump(outputStream * const out) {
ResourceMark rm;
out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {",
out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: " PTR_FORMAT " %s {",
p2i(this), p2i((void *)class_loader()),
p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
if (claimed()) out->print(" claimed ");
@ -513,7 +513,7 @@ void ClassLoaderData::dump(outputStream * const out) {
ResourceMark rm;
Klass* k = _klasses;
while (k != NULL) {
out->print_cr("klass "PTR_FORMAT", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
out->print_cr("klass " PTR_FORMAT ", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
k->has_modified_oops(), k->has_accumulated_modified_oops());
assert(k != k->next_link(), "no loops!");
k = k->next_link();

View File

@ -557,7 +557,7 @@ void ProtectionDomainCacheTable::print() {
}
void ProtectionDomainCacheEntry::print() {
tty->print_cr("entry "PTR_FORMAT" value "PTR_FORMAT" strongly_reachable %d next "PTR_FORMAT,
tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " strongly_reachable %d next " PTR_FORMAT,
this, (void*)literal(), _strongly_reachable, next());
}
#endif

View File

@ -370,7 +370,7 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
void print_on(outputStream* st) const {
symbol()->print_value_on(st);
st->print("/mode="INTX_FORMAT, symbol_mode());
st->print("/mode=" INTX_FORMAT, symbol_mode());
st->print(" -> ");
bool printed = false;
if (method() != NULL) {

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2015, 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.
*
*/
#include "runtime/thread.inline.hpp"
#include "precompiled.hpp"
#include "classfile/imageDecompressor.hpp"
#include "runtime/thread.hpp"
#include "utilities/bytes.hpp"
/*
* Allocate in C Heap not in resource area, otherwise JVM crashes.
* This array life time is the VM life time. Array is never freed and
* is not expected to contain more than few references.
*/
GrowableArray<ImageDecompressor*>* ImageDecompressor::_decompressors =
new(ResourceObj::C_HEAP, mtInternal) GrowableArray<ImageDecompressor*>(2, true);
static Symbol* createSymbol(const char* str) {
Thread* THREAD = Thread::current();
Symbol* sym = SymbolTable::lookup(str, (int) strlen(str), THREAD);
if (HAS_PENDING_EXCEPTION) {
warning("can't create symbol\n");
CLEAR_PENDING_EXCEPTION;
return NULL;
}
return sym;
}
/*
* Initialize the array of decompressors.
*/
bool image_decompressor_init() {
Symbol* zipSymbol = createSymbol("zip");
if (zipSymbol == NULL) {
return false;
}
ImageDecompressor::add_decompressor(new ZipDecompressor(zipSymbol));
return true;
}
/*
* Decompression entry point. Called from ImageFileReader::get_resource.
*/
void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap) {
bool has_header = false;
u1* decompressed_resource = compressed;
u1* compressed_resource = compressed;
// Resource could have been transformed by a stack of decompressors.
// Iterate and decompress resources until there is no more header.
do {
ResourceHeader _header;
memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
has_header = _header._magic == ResourceHeader::resource_header_magic;
if (has_header) {
// decompressed_resource array contains the result of decompression
// when a resource content is terminal, it means that it is an actual resource,
// not an intermediate not fully uncompressed content. In this case
// the resource is allocated as an mtClass, otherwise as an mtOther
decompressed_resource = is_C_heap && _header._is_terminal ?
NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtClass) :
NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtOther);
// Retrieve the decompressor name
const char* decompressor_name = strings->get(_header._decompressor_name_offset);
if (decompressor_name == NULL) warning("image decompressor not found\n");
guarantee(decompressor_name, "image decompressor not found");
// Retrieve the decompressor instance
ImageDecompressor* decompressor = get_decompressor(decompressor_name);
if (decompressor == NULL) {
warning("image decompressor %s not found\n", decompressor_name);
}
guarantee(decompressor, "image decompressor not found");
u1* compressed_resource_base = compressed_resource;
compressed_resource += ResourceHeader::resource_header_length;
// Ask the decompressor to decompress the compressed content
decompressor->decompress_resource(compressed_resource, decompressed_resource,
&_header, strings);
if (compressed_resource_base != compressed) {
FREE_C_HEAP_ARRAY(char, compressed_resource_base);
}
compressed_resource = decompressed_resource;
}
} while (has_header);
memcpy(uncompressed, decompressed_resource, uncompressed_size);
}
// Zip decompressor
void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed,
ResourceHeader* header, const ImageStrings* strings) {
char* msg = NULL;
jboolean res = ClassLoader::decompress(data, header->_size, uncompressed,
header->_uncompressed_size, &msg);
if (!res) warning("decompression failed due to %s\n", msg);
guarantee(res, "decompression failed");
}
// END Zip Decompressor

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2015, 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.
*
*/
#ifndef SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
#define SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP
#include "runtime/thread.inline.hpp"
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/imageFile.hpp"
#include "classfile/symbolTable.hpp"
#include "oops/symbol.hpp"
#include "utilities/growableArray.hpp"
/*
* Compressed resources located in image have an header.
* This header contains:
* - _magic: A magic u4, required to retrieved the header in the compressed content
* - _size: The size of the compressed resource.
* - _uncompressed_size: The uncompressed size of the compressed resource.
* - _decompressor_name_offset: The ImageDecompressor instance name StringsTable offset.
* - _decompressor_config_offset: StringsTable offset of configuration that could be needed by
* the decompressor in order to decompress.
* - _is_terminal: 1: the compressed content is terminal. Uncompressing it would
* create the actual resource. 0: the compressed content is not terminal. Uncompressing it
* will result in a compressed content to be decompressed (This occurs when a stack of compressors
* have been used to compress the resource.
*/
struct ResourceHeader {
/* Length of header, needed to retrieve content offset */
static const u1 resource_header_length = 21;
/* magic bytes that identifies a compressed resource header*/
static const u4 resource_header_magic = 0xCAFEFAFA;
u4 _magic; // Resource header
u4 _size; // Resource size
u4 _uncompressed_size; // Expected uncompressed size
u4 _decompressor_name_offset; // Strings table decompressor offset
u4 _decompressor_config_offset; // Strings table config offset
u1 _is_terminal; // Last decompressor 1, otherwise 0.
};
/*
* Resources located in jimage file can be compressed. Compression occurs at
* jimage file creation time. When compressed a resource is added an header that
* contains the name of the compressor that compressed it.
* Various compression strategies can be applied to compress a resource.
* The same resource can even be compressed multiple time by a stack of compressors.
* At runtime, a resource is decompressed in a loop until there is no more header
* meaning that the resource is equivalent to the not compressed resource.
* In each iteration, the name of the compressor located in the current header
* is used to retrieve the associated instance of ImageDecompressor.
* For example zip is the name of the compressor that compresses resources
* using the zip algorithm. The ZipDecompressor class name is also zip.
* ImageDecompressor instances are retrieved from a static array in which
* they are registered.
*/
class ImageDecompressor: public CHeapObj<mtClass> {
private:
const Symbol* _name;
/*
* Array of concrete decompressors. This array is used to retrieve the decompressor
* that can handle resource decompression.
*/
static GrowableArray<ImageDecompressor*>* _decompressors;
/*
* Identifier of a decompressor. This name is the identification key to retrieve
* decompressor from a resource header.
*/
inline const Symbol* get_name() const { return _name; }
protected:
ImageDecompressor(const Symbol* name) : _name(name) {
}
virtual void decompress_resource(u1* data, u1* uncompressed,
ResourceHeader* header, const ImageStrings* strings) = 0;
public:
inline static void add_decompressor(ImageDecompressor* decompressor) {
_decompressors->append(decompressor);
}
inline static ImageDecompressor* get_decompressor(const char * decompressor_name) {
Thread* THREAD = Thread::current();
TempNewSymbol sym = SymbolTable::new_symbol(decompressor_name,
(int) strlen(decompressor_name), CHECK_NULL);
if (HAS_PENDING_EXCEPTION) {
warning("can't create symbol\n");
CLEAR_PENDING_EXCEPTION;
return NULL;
}
for (int i = 0; i < _decompressors->length(); i++) {
ImageDecompressor* decompressor = _decompressors->at(i);
if (decompressor->get_name()->fast_compare(sym) == 0) {
return decompressor;
}
}
guarantee(false, "No decompressor found.");
return NULL;
}
static void decompress_resource(u1* compressed, u1* uncompressed,
u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap);
};
/**
* Zip decompressor.
*/
class ZipDecompressor : public ImageDecompressor {
public:
ZipDecompressor(const Symbol* sym) : ImageDecompressor(sym) { }
void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
const ImageStrings* strings);
};
#endif // SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -23,77 +23,311 @@
*/
#include "precompiled.hpp"
#include "classfile/imageDecompressor.hpp"
#include "classfile/imageFile.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.inline.hpp"
#include "utilities/bytes.hpp"
#include "utilities/endian.hpp"
#include "utilities/growableArray.hpp"
// Image files are an alternate file format for storing classes and resources. The
// goal is to supply file access which is faster and smaller than the jar format.
//
// (More detailed nodes in the header.)
//
// Compute the Perfect Hashing hash code for the supplied string.
u4 ImageStrings::hash_code(const char* string, u4 seed) {
// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
s4 ImageStrings::hash_code(const char* string, s4 seed) {
// Access bytes as unsigned.
u1* bytes = (u1*)string;
// Compute hash code.
for (u1 byte = *bytes++; byte; byte = *bytes++) {
seed = (seed * HASH_MULTIPLIER) ^ byte;
}
// Ensure the result is unsigned.
// Ensure the result is not signed.
return seed & 0x7FFFFFFF;
}
// Test to see if string begins with start. If so returns remaining portion
// of string. Otherwise, NULL.
// Match up a string in a perfect hash table. Result still needs validation
// for precise match (false positive.)
s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) {
// If the table is empty, then short cut.
if (redirect == NULL || length == 0) {
return NOT_FOUND;
}
// Compute the basic perfect hash for name.
s4 hash_code = ImageStrings::hash_code(name);
// Modulo table size.
s4 index = hash_code % length;
// Get redirect entry.
// value == 0 then not found
// value < 0 then -1 - value is true index
// value > 0 then value is seed for recomputing hash.
s4 value = endian->get(redirect[index]);
// if recompute is required.
if (value > 0) {
// Entry collision value, need to recompute hash.
hash_code = ImageStrings::hash_code(name, value);
// Modulo table size.
return hash_code % length;
} else if (value < 0) {
// Compute direct index.
return -1 - value;
}
// No entry found.
return NOT_FOUND;
}
// Test to see if UTF-8 string begins with the start UTF-8 string. If so,
// return non-NULL address of remaining portion of string. Otherwise, return
// NULL. Used to test sections of a path without copying from image string
// table.
const char* ImageStrings::starts_with(const char* string, const char* start) {
char ch1, ch2;
// Match up the strings the best we can.
while ((ch1 = *string) && (ch2 = *start)) {
if (ch1 != ch2) {
// Mismatch, return NULL.
return NULL;
}
// Next characters.
string++, start++;
}
// Return remainder of string.
return string;
}
ImageLocation::ImageLocation(u1* data) {
// Inflates the attribute stream into individual values stored in the long
// array _attributes. This allows an attribute value to be quickly accessed by
// direct indexing. Unspecified values default to zero (from constructor.)
void ImageLocation::set_data(u1* data) {
// Deflate the attribute stream into an array of attributes.
memset(_attributes, 0, sizeof(_attributes));
u1 byte;
while ((byte = *data) != ATTRIBUTE_END) {
// Repeat until end header is found.
while ((byte = *data)) {
// Extract kind from header byte.
u1 kind = attribute_kind(byte);
guarantee(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
// Extract length of data (in bytes).
u1 n = attribute_length(byte);
assert(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
// Read value (most significant first.)
_attributes[kind] = attribute_value(data + 1, n);
// Position to next attribute by skipping attribute header and data bytes.
data += n + 1;
}
}
ImageFile::ImageFile(const char* name) {
// Copy the image file name.
_name = NEW_C_HEAP_ARRAY(char, strlen(name)+1, mtClass);
strcpy(_name, name);
// Zero all attribute values.
void ImageLocation::clear_data() {
// Set defaults to zero.
memset(_attributes, 0, sizeof(_attributes));
}
// ImageModuleData constructor maps out sub-tables for faster access.
ImageModuleData::ImageModuleData(const ImageFileReader* image_file,
const char* module_data_name) :
_image_file(image_file),
_endian(image_file->endian()),
_strings(image_file->get_strings()) {
// Retrieve the resource containing the module data for the image file.
ImageLocation location;
bool found = image_file->find_location(module_data_name, location);
guarantee(found, "missing module data");
u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
_data = (u1*)NEW_C_HEAP_ARRAY(char, data_size, mtClass);
_image_file->get_resource(location, _data);
// Map out the header.
_header = (Header*)_data;
// Get the package to module entry count.
u4 ptm_count = _header->ptm_count(_endian);
// Get the module to package entry count.
u4 mtp_count = _header->mtp_count(_endian);
// Compute the offset of the package to module perfect hash redirect.
u4 ptm_redirect_offset = sizeof(Header);
// Compute the offset of the package to module data.
u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
// Compute the offset of the module to package perfect hash redirect.
u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
// Compute the offset of the module to package data.
u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
// Compute the offset of the module to package tables.
u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
// Compute the address of the package to module perfect hash redirect.
_ptm_redirect = (s4*)(_data + ptm_redirect_offset);
// Compute the address of the package to module data.
_ptm_data = (PTMData*)(_data + ptm_data_offset);
// Compute the address of the module to package perfect hash redirect.
_mtp_redirect = (s4*)(_data + mtp_redirect_offset);
// Compute the address of the module to package data.
_mtp_data = (MTPData*)(_data + mtp_data_offset);
// Compute the address of the module to package tables.
_mtp_packages = (s4*)(_data + mtp_packages_offset);
}
// Release module data resource.
ImageModuleData::~ImageModuleData() {
if (_data != NULL) {
FREE_C_HEAP_ARRAY(u1, _data);
}
}
// Return the name of the module data resource. Ex. "./lib/modules/file.jimage"
// yields "file.jdata"
void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) {
// Locate the last slash in the file name path.
const char* slash = strrchr(image_file_name, os::file_separator()[0]);
// Trim the path to name and extension.
const char* name = slash != NULL ? slash + 1 : (char *)image_file_name;
// Locate the extension period.
const char* dot = strrchr(name, '.');
guarantee(dot, "missing extension on jimage name");
// Trim to only base name.
int length = dot - name;
strncpy(buffer, name, length);
buffer[length] = '\0';
// Append extension.
strcat(buffer, ".jdata");
}
// Return the module in which a package resides. Returns NULL if not found.
const char* ImageModuleData::package_to_module(const char* package_name) {
// Search the package to module table.
s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
_header->ptm_count(_endian));
// If entry is found.
if (index != ImageStrings::NOT_FOUND) {
// Retrieve the package to module entry.
PTMData* data = _ptm_data + index;
// Verify that it is the correct data.
if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
return NULL;
}
// Return the module name.
return get_string(data->module_name_offset(_endian));
}
return NULL;
}
// Returns all the package names in a module. Returns NULL if module not found.
GrowableArray<const char*>* ImageModuleData::module_to_packages(const char* module_name) {
// Search the module to package table.
s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
_header->mtp_count(_endian));
// If entry is found.
if (index != ImageStrings::NOT_FOUND) {
// Retrieve the module to package entry.
MTPData* data = _mtp_data + index;
// Verify that it is the correct data.
if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
return NULL;
}
// Construct an array of all the package entries.
GrowableArray<const char*>* packages = new GrowableArray<const char*>();
s4 package_offset = data->package_offset(_endian);
for (u4 i = 0; i < data->package_count(_endian); i++) {
u4 package_name_offset = mtp_package(package_offset + i);
const char* package_name = get_string(package_name_offset);
packages->append(package_name);
}
return packages;
}
return NULL;
}
// Table to manage multiple opens of an image file.
GrowableArray<ImageFileReader*>* ImageFileReader::_reader_table =
new(ResourceObj::C_HEAP, mtInternal) GrowableArray<ImageFileReader*>(2, true);
// Open an image file, reuse structure if file already open.
ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) {
// Lock out _reader_table.
MutexLocker ml(ImageFileReaderTable_lock);
ImageFileReader* reader;
// Search for an exist image file.
for (int i = 0; i < _reader_table->length(); i++) {
// Retrieve table entry.
reader = _reader_table->at(i);
// If name matches, then reuse (bump up use count.)
if (strcmp(reader->name(), name) == 0) {
reader->inc_use();
return reader;
}
}
// Need a new image reader.
reader = new ImageFileReader(name, big_endian);
bool opened = reader->open();
// If failed to open.
if (!opened) {
delete reader;
return NULL;
}
// Bump use count and add to table.
reader->inc_use();
_reader_table->append(reader);
return reader;
}
// Close an image file if the file is not in use elsewhere.
void ImageFileReader::close(ImageFileReader *reader) {
// Lock out _reader_table.
MutexLocker ml(ImageFileReaderTable_lock);
// If last use then remove from table and then close.
if (reader->dec_use()) {
_reader_table->remove(reader);
delete reader;
}
}
// Return an id for the specifed ImageFileReader.
u8 ImageFileReader::readerToID(ImageFileReader *reader) {
// ID is just the cloaked reader address.
return (u8)reader;
}
// Validate the image id.
bool ImageFileReader::idCheck(u8 id) {
// Make sure the ID is a managed (_reader_table) reader.
MutexLocker ml(ImageFileReaderTable_lock);
return _reader_table->contains((ImageFileReader*)id);
}
// Return an id for the specifed ImageFileReader.
ImageFileReader* ImageFileReader::idToReader(u8 id) {
#ifdef PRODUCT
// Fast convert.
return (ImageFileReader*)id;
#else
// Do a slow check before fast convert.
return idCheck(id) ? (ImageFileReader*)id : NULL;
#endif
}
// Constructor intializes to a closed state.
ImageFileReader::ImageFileReader(const char* name, bool big_endian) {
// Copy the image file name.
_name = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtClass);
strcpy(_name, name);
// Initialize for a closed file.
_fd = -1;
_memory_mapped = true;
_endian = Endian::get_handler(big_endian);
_index_data = NULL;
}
ImageFile::~ImageFile() {
// Close image and free up data structures.
ImageFileReader::~ImageFileReader() {
// Ensure file is closed.
close();
// Free up name.
FREE_C_HEAP_ARRAY(char, _name);
if (_name != NULL) {
FREE_C_HEAP_ARRAY(char, _name);
_name = NULL;
}
}
bool ImageFile::open() {
// Open image file for read access.
bool ImageFileReader::open() {
// If file exists open for reading.
struct stat st;
if (os::stat(_name, &st) != 0 ||
@ -101,186 +335,212 @@ bool ImageFile::open() {
(_fd = os::open(_name, 0, O_RDONLY)) == -1) {
return false;
}
// Read image file header and verify.
u8 header_size = sizeof(ImageHeader);
if (os::read(_fd, &_header, header_size) != header_size ||
_header._magic != IMAGE_MAGIC ||
_header._major_version != MAJOR_VERSION ||
_header._minor_version != MINOR_VERSION) {
// Retrieve the file size.
_file_size = (u8)st.st_size;
// Read image file header and verify it has a valid header.
size_t header_size = sizeof(ImageHeader);
if (_file_size < header_size ||
!read_at((u1*)&_header, header_size, 0) ||
_header.magic(_endian) != IMAGE_MAGIC ||
_header.major_version(_endian) != MAJOR_VERSION ||
_header.minor_version(_endian) != MINOR_VERSION) {
close();
return false;
}
// Memory map index.
// Size of image index.
_index_size = index_size();
_index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, _index_size, true, false);
// Failing that, read index into C memory.
if (_index_data == NULL) {
_memory_mapped = false;
_index_data = NEW_RESOURCE_ARRAY(u1, _index_size);
if (os::seek_to_file_offset(_fd, 0) == -1) {
close();
return false;
}
if (os::read(_fd, _index_data, _index_size) != _index_size) {
close();
return false;
}
return true;
// Make sure file is large enough to contain the index.
if (_file_size < _index_size) {
return false;
}
// Used to advance a pointer, unstructured.
#undef nextPtr
#define nextPtr(base, fromType, count, toType) (toType*)((fromType*)(base) + (count))
// Pull tables out from the index.
_redirect_table = nextPtr(_index_data, u1, header_size, s4);
_offsets_table = nextPtr(_redirect_table, s4, _header._location_count, u4);
_location_bytes = nextPtr(_offsets_table, u4, _header._location_count, u1);
_string_bytes = nextPtr(_location_bytes, u1, _header._locations_size, u1);
#undef nextPtr
// Determine how much of the image is memory mapped.
off_t map_size = (off_t)(MemoryMapImage ? _file_size : _index_size);
// Memory map image (minimally the index.)
_index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, map_size, true, false);
guarantee(_index_data, "image file not memory mapped");
// Retrieve length of index perfect hash table.
u4 length = table_length();
// Compute offset of the perfect hash table redirect table.
u4 redirect_table_offset = (u4)header_size;
// Compute offset of index attribute offsets.
u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
// Compute offset of index location attribute data.
u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
// Compute offset of index string table.
u4 string_bytes_offset = location_bytes_offset + locations_size();
// Compute address of the perfect hash table redirect table.
_redirect_table = (s4*)(_index_data + redirect_table_offset);
// Compute address of index attribute offsets.
_offsets_table = (u4*)(_index_data + offsets_table_offset);
// Compute address of index location attribute data.
_location_bytes = _index_data + location_bytes_offset;
// Compute address of index string table.
_string_bytes = _index_data + string_bytes_offset;
// Successful open.
return true;
}
void ImageFile::close() {
// Close image file.
void ImageFileReader::close() {
// Dealllocate the index.
if (_index_data) {
if (_memory_mapped) {
os::unmap_memory((char*)_index_data, _index_size);
} else {
FREE_RESOURCE_ARRAY(u1, _index_data, _index_size);
}
if (_index_data != NULL) {
os::unmap_memory((char*)_index_data, _index_size);
_index_data = NULL;
}
// close file.
// Close file.
if (_fd != -1) {
os::close(_fd);
_fd = -1;
}
}
// Return the attribute stream for a named resourced.
u1* ImageFile::find_location_data(const char* path) const {
// Compute hash.
u4 hash = ImageStrings::hash_code(path) % _header._location_count;
s4 redirect = _redirect_table[hash];
if (!redirect) {
return NULL;
}
u4 index;
if (redirect < 0) {
// If no collision.
index = -redirect - 1;
} else {
// If collision, recompute hash code.
index = ImageStrings::hash_code(path, redirect) % _header._location_count;
}
assert(index < _header._location_count, "index exceeds location count");
u4 offset = _offsets_table[index];
assert(offset < _header._locations_size, "offset exceeds location attributes size");
if (offset == 0) {
return NULL;
}
return _location_bytes + offset;
// Read directly from the file.
bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
return os::read_at(_fd, data, size, offset) == size;
}
// Verify that a found location matches the supplied path.
bool ImageFile::verify_location(ImageLocation& location, const char* path) const {
// Retrieve each path component string.
ImageStrings strings(_string_bytes, _header._strings_size);
// Match a path with each subcomponent without concatenation (copy).
// Match up path parent.
// Find the location attributes associated with the path. Returns true if
// the location is found, false otherwise.
bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
// Locate the entry in the index perfect hash table.
s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
// If is found.
if (index != ImageStrings::NOT_FOUND) {
// Get address of first byte of location attribute stream.
u1* data = get_location_data(index);
// Expand location attributes.
location.set_data(data);
// Make sure result is not a false positive.
return verify_location(location, path);
}
return false;
}
// Assemble the location path from the string fragments indicated in the location attributes.
void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const {
// Manage the image string table.
ImageStrings strings(_string_bytes, _header.strings_size(_endian));
// Position to first character of the path buffer.
char* next = path;
// Temp for string length.
size_t length;
// Get module string.
const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
// If module string is not empty string.
if (*module != '\0') {
// Get length of module name.
length = strlen(module);
// Make sure there is no buffer overflow.
guarantee(next - path + length + 2 < max, "buffer overflow");
// Append '/module/'.
*next++ = '/';
strcpy(next, module); next += length;
*next++ = '/';
}
// Get parent (package) string.
const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
const char* next = ImageStrings::starts_with(path, parent);
// Continue only if a complete match.
if (!next) return false;
// Match up path base.
// If parent string is not empty string.
if (*parent != '\0') {
// Get length of module string.
length = strlen(parent);
// Make sure there is no buffer overflow.
guarantee(next - path + length + 1 < max, "buffer overflow");
// Append 'patent/' .
strcpy(next, parent); next += length;
*next++ = '/';
}
// Get base name string.
const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
next = ImageStrings::starts_with(next, base);
// Continue only if a complete match.
if (!next) return false;
// Match up path extension.
// Get length of base name.
length = strlen(base);
// Make sure there is no buffer overflow.
guarantee(next - path + length < max, "buffer overflow");
// Append base name.
strcpy(next, base); next += length;
// Get extension string.
const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
next = ImageStrings::starts_with(next, extension);
// If extension string is not empty string.
if (*extension != '\0') {
// Get length of extension string.
length = strlen(extension);
// Make sure there is no buffer overflow.
guarantee(next - path + length + 1 < max, "buffer overflow");
// Append '.extension' .
*next++ = '.';
strcpy(next, extension); next += length;
}
// Make sure there is no buffer overflow.
guarantee((size_t)(next - path) < max, "buffer overflow");
// Terminate string.
*next = '\0';
}
// Verify that a found location matches the supplied path (without copying.)
bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const {
// Manage the image string table.
ImageStrings strings(_string_bytes, _header.strings_size(_endian));
// Position to first character of the path string.
const char* next = path;
// Get module name string.
const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
// If module string is not empty.
if (*module != '\0') {
// Compare '/module/' .
if (*next++ != '/') return false;
if (!(next = ImageStrings::starts_with(next, module))) return false;
if (*next++ != '/') return false;
}
// Get parent (package) string
const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
// If parent string is not empty string.
if (*parent != '\0') {
// Compare 'parent/' .
if (!(next = ImageStrings::starts_with(next, parent))) return false;
if (*next++ != '/') return false;
}
// Get base name string.
const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
// Compare with basne name.
if (!(next = ImageStrings::starts_with(next, base))) return false;
// Get extension string.
const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
// If extension is not empty.
if (*extension != '\0') {
// Compare '.extension' .
if (*next++ != '.') return false;
if (!(next = ImageStrings::starts_with(next, extension))) return false;
}
// True only if complete match and no more characters.
return next && *next == '\0';
return *next == '\0';
}
// Return the resource for the supplied location.
u1* ImageFile::get_resource(ImageLocation& location) const {
// Return the resource data for the supplied location.
void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const {
// Retrieve the byte offset and size of the resource.
u8 offset = _index_size + location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
u8 read_size = compressed_size ? compressed_size : size;
// Allocate space for the resource.
u1* data = NEW_RESOURCE_ARRAY(u1, read_size);
bool is_read = os::read_at(_fd, data, read_size, offset) == read_size;
guarantee(is_read, "error reading from image or short read");
// If not compressed, just return the data.
if (!compressed_size) {
return data;
}
u1* uncompressed = NEW_RESOURCE_ARRAY(u1, size);
char* msg = NULL;
jboolean res = ClassLoader::decompress(data, compressed_size, uncompressed, size, &msg);
if (!res) warning("decompression failed due to %s\n", msg);
guarantee(res, "decompression failed");
return uncompressed;
}
void ImageFile::get_resource(const char* path, u1*& buffer, u8& size) const {
buffer = NULL;
size = 0;
u1* data = find_location_data(path);
if (data) {
ImageLocation location(data);
if (verify_location(location, path)) {
size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
buffer = get_resource(location);
if (compressed_size != 0) {
ResourceMark rm;
u1* compressed_data;
// If not memory mapped read in bytes.
if (!MemoryMapImage) {
// Allocate buffer for compression.
compressed_data = NEW_RESOURCE_ARRAY(u1, compressed_size);
// Read bytes from offset beyond the image index.
bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
guarantee(is_read, "error reading from image or short read");
} else {
compressed_data = get_data_address() + offset;
}
// Get image string table.
const ImageStrings strings = get_strings();
// Decompress resource.
ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size,
&strings, false);
} else {
// Read bytes from offset beyond the image index.
bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
guarantee(is_read, "error reading from image or short read");
}
}
GrowableArray<const char*>* ImageFile::packages(const char* name) {
char entry[JVM_MAXPATHLEN];
bool overflow = jio_snprintf(entry, sizeof(entry), "%s/packages.offsets", name) == -1;
guarantee(!overflow, "package name overflow");
u1* buffer;
u8 size;
get_resource(entry, buffer, size);
guarantee(buffer, "missing module packages reource");
ImageStrings strings(_string_bytes, _header._strings_size);
GrowableArray<const char*>* pkgs = new GrowableArray<const char*>();
int count = size / 4;
for (int i = 0; i < count; i++) {
u4 offset = Bytes::get_Java_u4(buffer + (i*4));
const char* p = strings.get(offset);
pkgs->append(p);
}
return pkgs;
}

View File

@ -28,13 +28,15 @@
#include "classfile/classLoader.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/endian.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
// Image files are an alternate file format for storing classes and resources. The
// goal is to supply file access which is faster and smaller that the jar format.
// It should be noted that unlike jars information stored in an image is in native
// endian format. This allows the image to be memory mapped into memory without
// endian translation. This also means that images are platform dependent.
// goal is to supply file access which is faster and smaller than the jar format.
// It should be noted that unlike jars, information stored in an image is in native
// endian format. This allows the image to be mapped into memory without endian
// translation. This also means that images are platform dependent.
//
// Image files are structured as three sections;
//
@ -42,7 +44,7 @@
// | Header |
// +-----------+
// | |
// | Directory |
// | Index |
// | |
// +-----------+
// | |
@ -60,7 +62,11 @@
// +------------+------------+
// | Major Vers | Minor Vers |
// +------------+------------+
// | Location Count |
// | Flags |
// +-------------------------+
// | Resource Count |
// +-------------------------+
// | Table Length |
// +-------------------------+
// | Attributes Size |
// +-------------------------+
@ -71,23 +77,24 @@
// special file extension.
// Major vers, minor vers - differences in version numbers indicate structural
// changes in the image.
// Location count - number of locations/resources in the file. This count is also
// the length of lookup tables used in the directory.
// Flags - various image wide flags (future).
// Resource count - number of resources in the file.
// Table length - the length of lookup tables used in the index.
// Attributes size - number of bytes in the region used to store location attribute
// streams.
// Strings size - the size of the region used to store strings used by the
// directory and meta data.
// index and meta data.
//
// The directory contains information related to resource lookup. The algorithm
// The index contains information related to resource lookup. The algorithm
// used for lookup is "A Practical Minimal Perfect Hashing Method"
// (http://homepages.dcc.ufmg.br/~nivio/papers/wea05.pdf). Given a path string
// in the form <package>/<base>.<extension> return the resource location
// in the form /<module>/<package>/<base>.<extension> return the resource location
// information;
//
// redirectIndex = hash(path, DEFAULT_SEED) % count;
// redirectIndex = hash(path, DEFAULT_SEED) % table_length;
// redirect = redirectTable[redirectIndex];
// if (redirect == 0) return not found;
// locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % count;
// locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % table_length;
// location = locationTable[locationIndex];
// if (!verify(location, path)) return not found;
// return location;
@ -97,7 +104,7 @@
// other seeds. The verify function guarantees the found resource location is
// indeed the resource we are looking for.
//
// The following is the format of the directory;
// The following is the format of the index;
//
// +-------------------+
// | Redirect Table |
@ -117,54 +124,74 @@
// offsets. Zero indicates not found.
// Attribute Offsets - Array of 32-bit unsigned values representing offsets into
// attribute data. Attribute offsets can be iterated to do a
// full survey of resources in the image.
// full survey of resources in the image. Offset of zero
// indicates no attributes.
// Attribute Data - Bytes representing compact attribute data for locations. (See
// comments in ImageLocation.)
// Strings - Collection of zero terminated UTF-8 strings used by the directory and
// Strings - Collection of zero terminated UTF-8 strings used by the index and
// image meta data. Each string is accessed by offset. Each string is
// unique. Offset zero is reserved for the empty string.
//
// Note that the memory mapped directory assumes 32 bit alignment of the image
// header, the redirect table and the attribute offsets.
// Note that the memory mapped index assumes 32 bit alignment of each component
// in the index.
//
// Endianness of an image.
// An image booted by hotspot is always in native endian. However, it is possible
// to read (by the JDK) in alternate endian format. Primarily, this is during
// cross platform scenarios. Ex, where javac needs to read an embedded image
// to access classes for crossing compilation.
//
class ImageFileReader; // forward declaration
// Manage image file string table.
class ImageStrings {
class ImageStrings VALUE_OBJ_CLASS_SPEC {
private:
// Data bytes for strings.
u1* _data;
// Number of bytes in the string table.
u4 _size;
u1* _data; // Data bytes for strings.
u4 _size; // Number of bytes in the string table.
public:
// Prime used to generate hash for Perfect Hashing.
static const u4 HASH_MULTIPLIER = 0x01000193;
enum {
// Not found result from find routine.
NOT_FOUND = -1,
// Prime used to generate hash for Perfect Hashing.
HASH_MULTIPLIER = 0x01000193
};
ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
// Return the UTF-8 string beginning at offset.
inline const char* get(u4 offset) const {
assert(offset < _size, "offset exceeds string table size");
guarantee(offset < _size, "offset exceeds string table size");
return (const char*)(_data + offset);
}
// Compute the Perfect Hashing hash code for the supplied string.
// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
inline static u4 hash_code(const char* string) {
return hash_code(string, HASH_MULTIPLIER);
}
// Compute the Perfect Hashing hash code for the supplied string, starting at seed.
static u4 hash_code(const char* string, u4 seed);
static s4 hash_code(const char* string, s4 seed);
// Test to see if string begins with start. If so returns remaining portion
// of string. Otherwise, NULL. Used to test sections of a path without
// copying.
// Match up a string in a perfect hash table. Result still needs validation
// for precise match.
static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
// Test to see if UTF-8 string begins with the start UTF-8 string. If so,
// return non-NULL address of remaining portion of string. Otherwise, return
// NULL. Used to test sections of a path without copying from image string
// table.
static const char* starts_with(const char* string, const char* start);
// Test to see if UTF-8 string begins with start char. If so, return non-NULL
// address of remaining portion of string. Otherwise, return NULL. Used
// to test a character of a path without copying.
inline static const char* starts_with(const char* string, const char ch) {
return *string == ch ? string + 1 : NULL;
}
};
// Manage image file location attribute streams. Within an image, a location's
// Manage image file location attribute data. Within an image, a location's
// attributes are compressed into a stream of bytes. An attribute stream is
// composed of individual attribute sequences. Each attribute sequence begins with
// a header byte containing the attribute 'kind' (upper 5 bits of header) and the
@ -188,7 +215,7 @@ public:
// stream.
// - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
// storing the resources. Thus, in an image this represents the number of bytes
// after the directory.
// after the index.
// - Currently, compressed resources are represented by having a non-zero
// ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the
// image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
@ -198,17 +225,19 @@ public:
// represented differently.
// - Package strings include trailing slash and extensions include prefix period.
//
class ImageLocation {
class ImageLocation VALUE_OBJ_CLASS_SPEC {
public:
// Attribute kind enumeration.
static const u1 ATTRIBUTE_END = 0; // End of attribute stream marker
static const u1 ATTRIBUTE_BASE = 1; // String table offset of resource path base
static const u1 ATTRIBUTE_PARENT = 2; // String table offset of resource path parent
static const u1 ATTRIBUTE_EXTENSION = 3; // String table offset of resource path extension
static const u1 ATTRIBUTE_OFFSET = 4; // Container byte offset of resource
static const u1 ATTRIBUTE_COMPRESSED = 5; // In image byte size of the compressed resource
static const u1 ATTRIBUTE_UNCOMPRESSED = 6; // In memory byte size of the uncompressed resource
static const u1 ATTRIBUTE_COUNT = 7; // Number of attribute kinds
enum {
ATTRIBUTE_END, // End of attribute stream marker
ATTRIBUTE_MODULE, // String table offset of module name
ATTRIBUTE_PARENT, // String table offset of resource path parent
ATTRIBUTE_BASE, // String table offset of resource path base
ATTRIBUTE_EXTENSION, // String table offset of resource path extension
ATTRIBUTE_OFFSET, // Container byte offset of resource
ATTRIBUTE_COMPRESSED, // In image byte size of the compressed resource
ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
ATTRIBUTE_COUNT // Number of attribute kinds
};
private:
// Values of inflated attributes.
@ -222,30 +251,43 @@ private:
// Return the attribute kind.
inline static u1 attribute_kind(u1 data) {
u1 kind = data >> 3;
assert(kind < ATTRIBUTE_COUNT, "invalid attribute kind");
guarantee(kind < ATTRIBUTE_COUNT, "invalid attribute kind");
return kind;
}
// Return the attribute length.
inline static u8 attribute_value(u1* data, u1 n) {
assert(0 < n && n <= 8, "invalid attribute value length");
guarantee(0 < n && n <= 8, "invalid attribute value length");
u8 value = 0;
// Most significant bytes first.
for (u1 i = 0; i < n; i++) {
value <<= 8;
value |= data[i];
}
return value;
}
public:
ImageLocation(u1* data);
ImageLocation() {
clear_data();
}
ImageLocation(u1* data) {
clear_data();
set_data(data);
}
// Inflates the attribute stream into individual values stored in the long
// array _attributes. This allows an attribute value to be quickly accessed by
// direct indexing. Unspecified values default to zero.
void set_data(u1* data);
// Zero all attribute values.
void clear_data();
// Retrieve an attribute value from the inflated array.
inline u8 get_attribute(u1 kind) const {
assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind");
guarantee(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind");
return _attributes[kind];
}
@ -255,89 +297,306 @@ public:
}
};
// Manage the image file.
class ImageFile: public CHeapObj<mtClass> {
private:
// Image file marker.
static const u4 IMAGE_MAGIC = 0xCAFEDADA;
// Image file major version number.
static const u2 MAJOR_VERSION = 0;
// Image file minor version number.
static const u2 MINOR_VERSION = 1;
struct ImageHeader {
u4 _magic; // Image file marker
u2 _major_version; // Image file major version number
u2 _minor_version; // Image file minor version number
u4 _location_count; // Number of locations managed in index.
u4 _locations_size; // Number of bytes in attribute table.
u4 _strings_size; // Number of bytes in string table.
//
// NOTE: needs revision.
// Each loader requires set of module meta data to identify which modules and
// packages are managed by that loader. Currently, there is one image file per
// builtin loader, so only one module meta data resource per file.
//
// Each element in the module meta data is a native endian 4 byte integer. Note
// that entries with zero offsets for string table entries should be ignored (
// padding for hash table lookup.)
//
// Format:
// Count of package to module entries
// Count of module to package entries
// Perfect Hash redirect table[Count of package to module entries]
// Package to module entries[Count of package to module entries]
// Offset to package name in string table
// Offset to module name in string table
// Perfect Hash redirect table[Count of module to package entries]
// Module to package entries[Count of module to package entries]
// Offset to module name in string table
// Count of packages in module
// Offset to first package in packages table
// Packages[]
// Offset to package name in string table
//
// Manage the image module meta data.
class ImageModuleData : public CHeapObj<mtClass> {
class Header VALUE_OBJ_CLASS_SPEC {
private:
u4 _ptm_count; // Count of package to module entries
u4 _mtp_count; // Count of module to package entries
public:
inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
};
char* _name; // Name of image
int _fd; // File descriptor
bool _memory_mapped; // Is file memory mapped
ImageHeader _header; // Image header
u8 _index_size; // Total size of index
u1* _index_data; // Raw index data
s4* _redirect_table; // Perfect hash redirect table
u4* _offsets_table; // Location offset table
u1* _location_bytes; // Location attributes
u1* _string_bytes; // String table
// Hashtable entry
class HashData VALUE_OBJ_CLASS_SPEC {
private:
u4 _name_offset; // Name offset in string table
public:
inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
};
// Package to module hashtable entry
class PTMData : public HashData {
private:
u4 _module_name_offset; // Module name offset in string table
public:
inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
};
// Module to package hashtable entry
class MTPData : public HashData {
private:
u4 _package_count; // Number of packages in module
u4 _package_offset; // Offset in package list
public:
inline u4 package_count(Endian* endian) const { return endian->get(_package_count); }
inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
};
const ImageFileReader* _image_file; // Source image file
Endian* _endian; // Endian handler
ImageStrings _strings; // Image file strings
u1* _data; // Module data resource data
u8 _data_size; // Size of resource data
Header* _header; // Module data header
s4* _ptm_redirect; // Package to module hashtable redirect
PTMData* _ptm_data; // Package to module data
s4* _mtp_redirect; // Module to packages hashtable redirect
MTPData* _mtp_data; // Module to packages data
s4* _mtp_packages; // Package data (name offsets)
// Return a string from the string table.
inline const char* get_string(u4 offset) {
return _strings.get(offset);
}
inline u4 mtp_package(u4 index) {
return _endian->get(_mtp_packages[index]);
}
public:
ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
~ImageModuleData();
// Return the name of the module data resource.
static void module_data_name(char* buffer, const char* image_file_name);
// Return the module in which a package resides. Returns NULL if not found.
const char* package_to_module(const char* package_name);
// Returns all the package names in a module. Returns NULL if module not found.
GrowableArray<const char*>* module_to_packages(const char* module_name);
};
// Image file header, starting at offset 0.
class ImageHeader VALUE_OBJ_CLASS_SPEC {
private:
u4 _magic; // Image file marker
u4 _version; // Image file major version number
u4 _flags; // Image file flags
u4 _resource_count; // Number of resources in file
u4 _table_length; // Number of slots in index tables
u4 _locations_size; // Number of bytes in attribute table
u4 _strings_size; // Number of bytes in string table
public:
u4 magic() const { return _magic; }
u4 magic(Endian* endian) const { return endian->get(_magic); }
void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
void set_version(Endian* endian, u4 major_version, u4 minor_version) {
return endian->set(_version, major_version << 16 | minor_version);
}
u4 flags(Endian* endian) const { return endian->get(_flags); }
void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
u4 table_length(Endian* endian) const { return endian->get(_table_length); }
void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
};
// Max path length limit independent of platform. Windows max path is 1024,
// other platforms use 4096. The JCK fails several tests when 1024 is used.
#define IMAGE_MAX_PATH 4096
// Manage the image file.
// ImageFileReader manages the content of an image file.
// Initially, the header of the image file is read for validation. If valid,
// values in the header are used calculate the size of the image index. The
// index is then memory mapped to allow load on demand and sharing. The
// -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
// An image can be used by Hotspot and multiple reference points in the JDK, thus
// it is desirable to share a reader. To accomodate sharing, a share table is
// defined (see ImageFileReaderTable in imageFile.cpp) To track the number of
// uses, ImageFileReader keeps a use count (_use). Use is incremented when
// 'opened' by reference point and decremented when 'closed'. Use of zero
// leads the ImageFileReader to be actually closed and discarded.
class ImageFileReader : public CHeapObj<mtClass> {
private:
// Manage a number of image files such that an image can be shared across
// multiple uses (ex. loader.)
static GrowableArray<ImageFileReader*>* _reader_table;
char* _name; // Name of image
s4 _use; // Use count
int _fd; // File descriptor
Endian* _endian; // Endian handler
u8 _file_size; // File size in bytes
ImageHeader _header; // Image header
size_t _index_size; // Total size of index
u1* _index_data; // Raw index data
s4* _redirect_table; // Perfect hash redirect table
u4* _offsets_table; // Location offset table
u1* _location_bytes; // Location attributes
u1* _string_bytes; // String table
ImageFileReader(const char* name, bool big_endian);
~ImageFileReader();
// Compute number of bytes in image file index.
inline u8 index_size() {
return sizeof(ImageHeader) +
_header._location_count * sizeof(u4) * 2 +
_header._locations_size +
_header._strings_size;
table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
}
public:
ImageFile(const char* name);
~ImageFile();
enum {
// Image file marker.
IMAGE_MAGIC = 0xCAFEDADA,
// Endian inverted Image file marker.
IMAGE_MAGIC_INVERT = 0xDADAFECA,
// Image file major version number.
MAJOR_VERSION = 1,
// Image file minor version number.
MINOR_VERSION = 0
};
// Open image file for access.
// Open an image file, reuse structure if file already open.
static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
// Close an image file if the file is not in use elsewhere.
static void close(ImageFileReader *reader);
// Return an id for the specifed ImageFileReader.
static u8 readerToID(ImageFileReader *reader);
// Validate the image id.
static bool idCheck(u8 id);
// Return an id for the specifed ImageFileReader.
static ImageFileReader* idToReader(u8 id);
// Open image file for read access.
bool open();
// Close image file.
void close();
// Read directly from the file.
bool read_at(u1* data, u8 size, u8 offset) const;
inline Endian* endian() const { return _endian; }
// Retrieve name of image file.
inline const char* name() const {
return _name;
}
// Retrieve size of image file.
inline u8 file_size() const {
return _file_size;
}
// Return first address of index data.
inline u1* get_index_address() const {
return _index_data;
}
// Return first address of resource data.
inline u1* get_data_address() const {
return _index_data + _index_size;
}
// Get the size of the index data.
size_t get_index_size() const {
return _index_size;
}
inline u4 table_length() const {
return _header.table_length(_endian);
}
inline u4 locations_size() const {
return _header.locations_size(_endian);
}
inline u4 strings_size()const {
return _header.strings_size(_endian);
}
inline u4* offsets_table() const {
return _offsets_table;
}
// Increment use count.
inline void inc_use() {
_use++;
}
// Decrement use count.
inline bool dec_use() {
return --_use == 0;
}
// Return a string table accessor.
inline const ImageStrings get_strings() const {
return ImageStrings(_string_bytes, _header._strings_size);
return ImageStrings(_string_bytes, _header.strings_size(_endian));
}
// Return number of locations in image file index.
inline u4 get_location_count() const {
return _header._location_count;
}
// Return location attribute stream for location i.
inline u1* get_location_data(u4 i) const {
u4 offset = _offsets_table[i];
// Return location attribute stream at offset.
inline u1* get_location_offset_data(u4 offset) const {
guarantee((u4)offset < _header.locations_size(_endian),
"offset exceeds location attributes size");
return offset != 0 ? _location_bytes + offset : NULL;
}
// Return the attribute stream for a named resourced.
u1* find_location_data(const char* path) const;
// Return location attribute stream for location i.
inline u1* get_location_data(u4 index) const {
guarantee((u4)index < _header.table_length(_endian),
"index exceeds location count");
u4 offset = _endian->get(_offsets_table[index]);
return get_location_offset_data(offset);
}
// Find the location attributes associated with the path. Returns true if
// the location is found, false otherwise.
bool find_location(const char* path, ImageLocation& location) const;
// Assemble the location path.
void location_path(ImageLocation& location, char* path, size_t max) const;
// Verify that a found location matches the supplied path.
bool verify_location(ImageLocation& location, const char* path) const;
// Return the resource for the supplied location info.
u1* get_resource(ImageLocation& location) const;
// Return the resource associated with the path else NULL if not found.
void get_resource(const char* path, u1*& buffer, u8& size) const;
// Return an array of packages for a given module
GrowableArray<const char*>* packages(const char* name);
// Return the resource for the supplied path.
void get_resource(ImageLocation& location, u1* uncompressed_data) const;
};
#endif // SHARE_VM_CLASSFILE_IMAGEFILE_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2015, 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
@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "code/codeBlob.hpp"
#include "code/codeCache.hpp"
#include "code/codeCacheExtensions.hpp"
#include "code/relocInfo.hpp"
#include "compiler/disassembler.hpp"
#include "interpreter/bytecode.hpp"
@ -88,6 +89,7 @@ CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_comple
_data_offset = size;
_frame_size = 0;
set_oop_maps(NULL);
_strings = CodeStrings();
}
@ -114,6 +116,7 @@ CodeBlob::CodeBlob(
_code_offset = _content_offset + cb->total_offset_of(cb->insts());
_data_offset = _content_offset + round_to(cb->total_content_size(), oopSize);
assert(_data_offset <= size, "codeBlob is too small");
_strings = CodeStrings();
cb->copy_code_and_locs_to(this);
set_oop_maps(oop_maps);
@ -192,6 +195,7 @@ BufferBlob* BufferBlob::create(const char* name, int buffer_size) {
BufferBlob* blob = NULL;
unsigned int size = sizeof(BufferBlob);
CodeCacheExtensions::size_blob(name, &buffer_size);
// align the size to CodeEntryAlignment
size = align_code_offset(size);
size += round_to(buffer_size, oopSize);
@ -275,6 +279,7 @@ MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
MethodHandlesAdapterBlob* blob = NULL;
unsigned int size = sizeof(MethodHandlesAdapterBlob);
CodeCacheExtensions::size_blob("MethodHandles adapters", &buffer_size);
// align the size to CodeEntryAlignment
size = align_code_offset(size);
size += round_to(buffer_size, oopSize);
@ -315,11 +320,13 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
{
RuntimeStub* stub = NULL;
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
{
if (!CodeCacheExtensions::skip_code_generation()) {
// bypass useless code generation
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
unsigned int size = allocation_size(cb, sizeof(RuntimeStub));
stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);
}
stub = (RuntimeStub*) CodeCacheExtensions::handle_generated_blob(stub, stub_name);
trace_new_stub(stub, "RuntimeStub - ", stub_name);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2015, 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
@ -38,7 +38,8 @@ struct CodeBlobType {
MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods
NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
All = 3, // All types (No code cache segmentation)
NumTypes = 4 // Number of CodeBlobTypes
Pregenerated = 4, // Special blobs, managed by CodeCacheExtensions
NumTypes = 5 // Number of CodeBlobTypes
};
};
@ -63,6 +64,7 @@ class DeoptimizationBlob;
class CodeBlob VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
friend class CodeCacheDumper;
private:
const char* _name;
@ -206,6 +208,14 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
void set_strings(CodeStrings& strings) {
_strings.assign(strings);
}
static ByteSize name_field_offset() {
return byte_offset_of(CodeBlob, _name);
}
static ByteSize oop_maps_field_offset() {
return byte_offset_of(CodeBlob, _oop_maps);
}
};
class WhiteBox;

View File

@ -409,7 +409,7 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool strict) {
}
if (PrintCodeCacheExtension) {
ResourceMark rm;
if (SegmentedCodeCache) {
if (_heaps->length() >= 1) {
tty->print("%s", heap->name());
} else {
tty->print("CodeCache");
@ -1211,7 +1211,7 @@ void CodeCache::print_internals() {
int i = 0;
FOR_ALL_HEAPS(heap) {
if (SegmentedCodeCache && Verbose) {
if ((_heaps->length() >= 1) && Verbose) {
tty->print_cr("-- %s --", (*heap)->name());
}
FOR_ALL_BLOBS(cb, *heap) {
@ -1360,7 +1360,7 @@ void CodeCache::print_summary(outputStream* st, bool detailed) {
FOR_ALL_HEAPS(heap_iterator) {
CodeHeap* heap = (*heap_iterator);
size_t total = (heap->high_boundary() - heap->low_boundary());
if (SegmentedCodeCache) {
if (_heaps->length() >= 1) {
st->print("%s:", heap->name());
} else {
st->print("CodeCache:");
@ -1397,7 +1397,7 @@ void CodeCache::print_codelist(outputStream* st) {
nmethod* nm = iter.method();
ResourceMark rm;
char *method_name = nm->method()->name_and_sig_as_C_string();
st->print_cr("%d %d %s ["INTPTR_FORMAT", "INTPTR_FORMAT" - "INTPTR_FORMAT"]",
st->print_cr("%d %d %s [" INTPTR_FORMAT ", " INTPTR_FORMAT " - " INTPTR_FORMAT "]",
nm->compile_id(), nm->comp_level(), method_name, (intptr_t)nm->header_begin(),
(intptr_t)nm->code_begin(), (intptr_t)nm->code_end());
}

View File

@ -78,6 +78,7 @@ class CodeCache : AllStatic {
friend class VMStructs;
friend class NMethodIterator;
friend class WhiteBox;
friend class CodeCacheLoader;
private:
// CodeHeaps of the cache
static GrowableArray<CodeHeap*>* _heaps;

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2012, 2015, 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.
*
*/
#ifndef SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_HPP
#define SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_HPP
#include "memory/allocation.hpp"
class CodeCacheExtensionsSteps: AllStatic {
public:
enum Step {
// Support for optional fine grain initialization hooks
// Note: these hooks must support refining the granularity
// (e.g. adding intermediate steps in the ordered enum
// if needed for future features)
Start,
VMVersion,
StubRoutines1,
Universe,
TemplateInterpreter,
Interpreter,
StubRoutines2,
InitGlobals,
CreateVM,
LastStep
};
};
#include "code/codeCacheExtensions_ext.hpp"
#endif // SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_HPP

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2012, 2015, 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.
*
*/
#ifndef SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP
#define SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP
#include "utilities/macros.hpp"
#include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp"
#include "interpreter/bytecodes.hpp"
class AdapterHandlerEntry;
class CodeBlob;
class CodeBuffer;
class InterpreterMacroAssembler;
class Template;
// All the methods defined here are placeholders for possible extensions.
class CodeCacheExtensions: AllStatic {
friend class CodeCacheDumper;
public:
// init both code saving and loading
// Must be called very early, before any code is generated.
static void initialize() {}
// Check whether the generated interpreter will be saved.
static bool saving_generated_interpreter() { return false; }
// Check whether a pregenerated interpreter is used.
static bool use_pregenerated_interpreter() { return false; }
// Placeholder for additional VM initialization code
static void complete_step(CodeCacheExtensionsSteps::Step phase) {}
// Return false for newly generated code, on systems where it is not
// executable.
static bool is_executable(void *pc) { return true; }
// Return whether dynamically generated code can be executable
static bool support_dynamic_code() { return true; }
// Skip new code generation when known to be useless.
static bool skip_code_generation() { return false; }
// Skip stubs used only for compiled code support.
static bool skip_compiler_support() { return false; }
// Ignore UseFastSignatureHandlers when returning false
static bool support_fast_signature_handlers() { return true; }
/////////////////////////
// Handle generated code:
// - allow newly generated code to be shared
// - allow pregenerated code to be used in place of the newly generated one
// (modifying pc).
// - support remapping when doing both save and load
// 'remap' can be set to false if the addresses handled are not referenced
// from code generated later.
// Associate a name to a generated codelet and possibly modify the pc
// Note: use instead the specialized versions when they exist:
// - handle_generated_blob for CodeBlob
// - handle_generated_handler for SignatureHandlers
// See also the optimized calls below that handle several PCs at once.
static void handle_generated_pc(address &pc, const char *name) {}
// Adds a safe definition of the codelet, for codelets used right after
// generation (else we would need to immediately stop the JVM and convert
// the generated code to executable format before being able to go further).
static void handle_generated_pc(address &pc, const char *name, address default_entry) {}
// Special cases
// Special case for CodeBlobs, which may require blob specific actions.
static CodeBlob* handle_generated_blob(CodeBlob* blob, const char *name = NULL) { return blob; }
// Special case for Signature Handlers.
static void handle_generated_handler(address &handler_start, const char *name, address handler_end) {}
// Support for generating different variants of the interpreter
// that can be dynamically selected after reload.
//
// - init_interpreter_assembler allows to configure the assembler for
// the current variant
//
// - needs_other_interpreter_variant returns true as long as other
// variants are needed.
//
// - skip_template_interpreter_entries returns true if new entries
// need not be generated for this masm setup and this bytecode
//
// - completed_template_interpreter_entries is called after new
// entries have been generated and installed, for any non skipped
// bytecode.
static void init_interpreter_assembler(InterpreterMacroAssembler* masm, CodeBuffer* code) {}
static bool needs_other_interpreter_variant() { return false; }
static bool skip_template_interpreter_entries(Bytecodes::Code code) { return false; }
static void completed_template_interpreter_entries(InterpreterMacroAssembler* masm, Bytecodes::Code code) {}
// Code size optimization. May optimize the requested size.
static void size_blob(const char* name, int *updatable_size) {}
// ergonomics
static void set_ergonomics_flags() {}
};
#endif // SHARE_VM_CODE_CODE_CACHE_EXTENSIONS_EXT_HPP

View File

@ -186,7 +186,7 @@ uint ImplicitExceptionTable::at( uint exec_off ) const {
void ImplicitExceptionTable::print(address base) const {
tty->print("{");
for( uint i=0; i<len(); i++ )
tty->print("< "INTPTR_FORMAT", "INTPTR_FORMAT" > ",base + *adr(i), base + *(adr(i)+1));
tty->print("< " INTPTR_FORMAT ", " INTPTR_FORMAT " > ",base + *adr(i), base + *(adr(i)+1));
tty->print_cr("}");
}

View File

@ -2118,7 +2118,7 @@ public:
void maybe_print(oop* p) {
if (_print_nm == NULL) return;
if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")",
tty->print_cr("" PTR_FORMAT "[offset=%d] detected scavengable oop " PTR_FORMAT " (found at " PTR_FORMAT ")",
_print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
(void *)(*p), (intptr_t)p);
(*p)->print();
@ -2518,7 +2518,7 @@ public:
_nm->print_nmethod(true);
_ok = false;
}
tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
tty->print_cr("*** non-oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
(void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
}
virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
@ -2642,7 +2642,7 @@ public:
_nm->print_nmethod(true);
_ok = false;
}
tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
tty->print_cr("*** scavengable oop " PTR_FORMAT " found at " PTR_FORMAT " (offset %d)",
(void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
(*p)->print();
}
@ -2687,7 +2687,7 @@ void nmethod::print() const {
print_on(tty, NULL);
if (WizardMode) {
tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
tty->print("((nmethod*) " INTPTR_FORMAT ") ", this);
tty->print(" for method " INTPTR_FORMAT , (address)method());
tty->print(" { ");
if (is_in_use()) tty->print("in_use ");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, 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
@ -261,3 +261,17 @@ void StubQueue::print() {
stub_print(s);
}
}
// Fixup for pregenerated code
void StubQueue::fix_buffer(address buffer, address queue_end, address buffer_end, int number_of_stubs) {
const int extra_bytes = CodeEntryAlignment;
_stub_buffer = buffer;
_queue_begin = 0;
_queue_end = queue_end - buffer;
_number_of_stubs = number_of_stubs;
int size = buffer_end - buffer;
// Note: _buffer_limit must differ from _queue_end in the iteration loops
// => add extra space at the end (preserving alignment for asserts) if needed
if (buffer_end == queue_end) size += extra_bytes;
_buffer_limit = _buffer_size = size;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, 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
@ -216,6 +216,9 @@ class StubQueue: public CHeapObj<mtCode> {
// Debugging/printing
void verify(); // verifies the stub queue
void print(); // prints information about the stub queue
// Fixup for pregenerated code
void fix_buffer(address buffer, address queue_end, address buffer_end, int number_of_stubs);
};
#endif // SHARE_VM_CODE_STUBS_HPP

View File

@ -172,7 +172,7 @@ class CompilationLog : public StringEventLog {
}
void log_nmethod(JavaThread* thread, nmethod* nm) {
log(thread, "nmethod %d%s " INTPTR_FORMAT " code ["INTPTR_FORMAT ", " INTPTR_FORMAT "]",
log(thread, "nmethod %d%s " INTPTR_FORMAT " code [" INTPTR_FORMAT ", " INTPTR_FORMAT "]",
nm->compile_id(), nm->is_osr_method() ? "%" : "",
p2i(nm), p2i(nm->code_begin()), p2i(nm->code_end()));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2015, 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
@ -578,7 +578,7 @@ static bool scan_line(const char * line,
int* bytes_read, const char*& error_msg) {
*bytes_read = 0;
error_msg = NULL;
if (2 == sscanf(line, "%*[ \t]%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, bytes_read)) {
if (2 == sscanf(line, "%*[ \t]%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, bytes_read)) {
*c_mode = check_mode(class_name, error_msg);
*m_mode = check_mode(method_name, error_msg);
return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
@ -586,8 +586,6 @@ static bool scan_line(const char * line,
return false;
}
// Scan next flag and value in line, return MethodMatcher object on success, NULL on failure.
// On failure, error_msg contains description for the first error.
// For future extensions: set error_msg on first error.
@ -665,7 +663,7 @@ static MethodMatcher* scan_flag_and_value(const char* type, const char* line, in
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
}
} else {
jio_snprintf(errorbuf, sizeof(errorbuf), " Value cannot be read for flag %s of type %s", flag, type);
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
}
} else if (strcmp(type, "double") == 0) {
char buffer[2][256];
@ -680,10 +678,10 @@ static MethodMatcher* scan_flag_and_value(const char* type, const char* line, in
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
}
} else {
jio_snprintf(errorbuf, sizeof(errorbuf), " Type %s not supported ", type);
jio_snprintf(errorbuf, buf_size, " Type %s not supported ", type);
}
} else {
jio_snprintf(errorbuf, sizeof(errorbuf), " Flag name for type %s should be alphanumeric ", type);
jio_snprintf(errorbuf, buf_size, " Flag name for type %s should be alphanumeric ", type);
}
return NULL;
}

View File

@ -65,7 +65,7 @@ bool Disassembler::_tried_to_load_library = false;
Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
Disassembler::decode_func Disassembler::_decode_instructions = NULL;
static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH;
static const char hsdis_library_name[] = "hsdis-" HOTSPOT_LIB_ARCH;
static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
static const char decode_instructions_name[] = "decode_instructions";
static bool use_new_version = true;

View File

@ -688,18 +688,18 @@ void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
"The CMS generation should be the old generation");
uint level = 1;
if (Verbose) {
gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]",
gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "(" SIZE_FORMAT ")]",
level, short_name(), s, used(), capacity());
} else {
gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]",
gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "K(" SIZE_FORMAT "K)]",
level, short_name(), s, used() / K, capacity() / K);
}
}
if (Verbose) {
gclog_or_tty->print(" "SIZE_FORMAT"("SIZE_FORMAT")",
gclog_or_tty->print(" " SIZE_FORMAT "(" SIZE_FORMAT ")",
gch->used(), gch->capacity());
} else {
gclog_or_tty->print(" "SIZE_FORMAT"K("SIZE_FORMAT"K)",
gclog_or_tty->print(" " SIZE_FORMAT "K(" SIZE_FORMAT "K)",
gch->used() / K, gch->capacity() / K);
}
}
@ -729,8 +729,8 @@ bool ConcurrentMarkSweepGeneration::promotion_attempt_is_safe(size_t max_promoti
bool res = (available >= av_promo) || (available >= max_promotion_in_bytes);
if (Verbose && PrintGCDetails) {
gclog_or_tty->print_cr(
"CMS: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
"max_promo("SIZE_FORMAT")",
"CMS: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "),"
"max_promo(" SIZE_FORMAT ")",
res? "":" not", available, res? ">=":"<",
av_promo, max_promotion_in_bytes);
}
@ -805,18 +805,18 @@ void ConcurrentMarkSweepGeneration::compute_new_size_free_list() {
desired_free_percentage);
gclog_or_tty->print_cr(" Maximum free fraction %f",
maximum_free_percentage);
gclog_or_tty->print_cr(" Capacity "SIZE_FORMAT, capacity()/1000);
gclog_or_tty->print_cr(" Desired capacity "SIZE_FORMAT,
gclog_or_tty->print_cr(" Capacity " SIZE_FORMAT, capacity()/1000);
gclog_or_tty->print_cr(" Desired capacity " SIZE_FORMAT,
desired_capacity/1000);
GenCollectedHeap* gch = GenCollectedHeap::heap();
assert(gch->is_old_gen(this), "The CMS generation should always be the old generation");
size_t young_size = gch->young_gen()->capacity();
gclog_or_tty->print_cr(" Young gen size " SIZE_FORMAT, young_size / 1000);
gclog_or_tty->print_cr(" unsafe_max_alloc_nogc "SIZE_FORMAT,
gclog_or_tty->print_cr(" unsafe_max_alloc_nogc " SIZE_FORMAT,
unsafe_max_alloc_nogc()/1000);
gclog_or_tty->print_cr(" contiguous available "SIZE_FORMAT,
gclog_or_tty->print_cr(" contiguous available " SIZE_FORMAT,
contiguous_available()/1000);
gclog_or_tty->print_cr(" Expand by "SIZE_FORMAT" (bytes)",
gclog_or_tty->print_cr(" Expand by " SIZE_FORMAT " (bytes)",
expand_bytes);
}
// safe if expansion fails
@ -1182,8 +1182,8 @@ bool CMSCollector::shouldConcurrentCollect() {
stats().print_on(gclog_or_tty);
gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
stats().time_until_cms_gen_full());
gclog_or_tty->print_cr("free="SIZE_FORMAT, _cmsGen->free());
gclog_or_tty->print_cr("contiguous_available="SIZE_FORMAT,
gclog_or_tty->print_cr("free=" SIZE_FORMAT, _cmsGen->free());
gclog_or_tty->print_cr("contiguous_available=" SIZE_FORMAT,
_cmsGen->contiguous_available());
gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
@ -2160,8 +2160,8 @@ void ConcurrentMarkSweepGeneration::gc_prologue_work(bool full,
assert(_numObjectsPromoted == 0, "check");
assert(_numWordsPromoted == 0, "check");
if (Verbose && PrintGC) {
gclog_or_tty->print("Allocated "SIZE_FORMAT" objects, "
SIZE_FORMAT" bytes concurrently",
gclog_or_tty->print("Allocated " SIZE_FORMAT " objects, "
SIZE_FORMAT " bytes concurrently",
_numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
}
_numObjectsAllocated = 0;
@ -2241,8 +2241,8 @@ void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
assert(_numObjectsAllocated == 0, "check");
assert(_numWordsAllocated == 0, "check");
if (Verbose && PrintGC) {
gclog_or_tty->print("Promoted "SIZE_FORMAT" objects, "
SIZE_FORMAT" bytes",
gclog_or_tty->print("Promoted " SIZE_FORMAT " objects, "
SIZE_FORMAT " bytes",
_numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
}
_numObjectsPromoted = 0;
@ -2252,7 +2252,7 @@ void ConcurrentMarkSweepGeneration::gc_epilogue_work(bool full) {
if (PrintGC && Verbose) {
// Call down the chain in contiguous_available needs the freelistLock
// so print this out before releasing the freeListLock.
gclog_or_tty->print(" Contiguous available "SIZE_FORMAT" bytes ",
gclog_or_tty->print(" Contiguous available " SIZE_FORMAT " bytes ",
contiguous_available());
}
}
@ -2340,7 +2340,7 @@ class VerifyMarkedClosure: public BitMapClosure {
HeapWord* addr = _marks->offsetToHeapWord(offset);
if (!_marks->isMarked(addr)) {
oop(addr)->print_on(gclog_or_tty);
gclog_or_tty->print_cr(" ("INTPTR_FORMAT" should have been marked)", p2i(addr));
gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
_failed = true;
}
return true;
@ -2702,9 +2702,11 @@ void CMSCollector::setup_cms_unloading_and_verification_state() {
// Not unloading classes this cycle
assert(!should_unload_classes(), "Inconsistency!");
// If we are not unloading classes then add SO_AllCodeCache to root
// scanning options.
add_root_scanning_option(rso);
if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
// Include symbols, strings and code cache elements to prevent their resurrection.
add_root_scanning_option(rso);
set_verifying(true);
} else if (verifying() && !should_verify) {
// We were verifying, but some verification flags got disabled.
@ -4269,7 +4271,7 @@ void CMSCollector::checkpointRootsFinal() {
verify_overflow_empty();
if (PrintGCDetails) {
gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
gclog_or_tty->print("[YG occupancy: " SIZE_FORMAT " K (" SIZE_FORMAT " K)]",
_young_gen->used() / K,
_young_gen->capacity() / K);
}
@ -4381,8 +4383,8 @@ void CMSCollector::checkpointRootsFinalWork() {
if (ser_ovflw > 0) {
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr("Marking stack overflow (benign) "
"(pmc_pc="SIZE_FORMAT", pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT
", kac_preclean="SIZE_FORMAT")",
"(pmc_pc=" SIZE_FORMAT ", pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT
", kac_preclean=" SIZE_FORMAT ")",
_ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
_ser_kac_ovflw, _ser_kac_preclean_ovflw);
}
@ -4395,7 +4397,7 @@ void CMSCollector::checkpointRootsFinalWork() {
if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr("Work queue overflow (benign) "
"(pmc_rm="SIZE_FORMAT", kac="SIZE_FORMAT")",
"(pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT ")",
_par_pmc_remark_ovflw, _par_kac_ovflw);
}
_par_pmc_remark_ovflw = 0;
@ -4403,12 +4405,12 @@ void CMSCollector::checkpointRootsFinalWork() {
}
if (PrintCMSStatistics != 0) {
if (_markStack._hit_limit > 0) {
gclog_or_tty->print_cr(" (benign) Hit max stack size limit ("SIZE_FORMAT")",
gclog_or_tty->print_cr(" (benign) Hit max stack size limit (" SIZE_FORMAT ")",
_markStack._hit_limit);
}
if (_markStack._failed_double > 0) {
gclog_or_tty->print_cr(" (benign) Failed stack doubling ("SIZE_FORMAT"),"
" current capacity "SIZE_FORMAT,
gclog_or_tty->print_cr(" (benign) Failed stack doubling (" SIZE_FORMAT "),"
" current capacity " SIZE_FORMAT,
_markStack._failed_double,
_markStack.capacity());
}
@ -5161,7 +5163,7 @@ void CMSCollector::do_remark_non_parallel() {
&markFromDirtyCardsClosure);
verify_work_stacks_empty();
if (PrintCMSStatistics != 0) {
gclog_or_tty->print(" (re-scanned "SIZE_FORMAT" dirty cards in cms gen) ",
gclog_or_tty->print(" (re-scanned " SIZE_FORMAT " dirty cards in cms gen) ",
markFromDirtyCardsClosure.num_dirty_cards());
}
}
@ -6035,8 +6037,8 @@ void CMSMarkStack::expand() {
} else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
// Failed to double capacity, continue;
// we print a detail message only once per CMS cycle.
gclog_or_tty->print(" (benign) Failed to expand marking stack from "SIZE_FORMAT"K to "
SIZE_FORMAT"K",
gclog_or_tty->print(" (benign) Failed to expand marking stack from " SIZE_FORMAT "K to "
SIZE_FORMAT "K",
_capacity / K, new_capacity / K);
}
}
@ -7335,25 +7337,25 @@ SweepClosure::~SweepClosure() {
ShouldNotReachHere();
}
if (Verbose && PrintGC) {
gclog_or_tty->print("Collected "SIZE_FORMAT" objects, " SIZE_FORMAT " bytes",
gclog_or_tty->print("Collected " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
_numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
gclog_or_tty->print_cr("\nLive "SIZE_FORMAT" objects, "
SIZE_FORMAT" bytes "
"Already free "SIZE_FORMAT" objects, "SIZE_FORMAT" bytes",
gclog_or_tty->print_cr("\nLive " SIZE_FORMAT " objects, "
SIZE_FORMAT " bytes "
"Already free " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
_numObjectsLive, _numWordsLive*sizeof(HeapWord),
_numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree)
* sizeof(HeapWord);
gclog_or_tty->print_cr("Total sweep: "SIZE_FORMAT" bytes", totalBytes);
gclog_or_tty->print_cr("Total sweep: " SIZE_FORMAT " bytes", totalBytes);
if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes();
size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes;
gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returned_bytes);
gclog_or_tty->print(" Indexed List Returned "SIZE_FORMAT" bytes",
gclog_or_tty->print("Returned " SIZE_FORMAT " bytes", returned_bytes);
gclog_or_tty->print(" Indexed List Returned " SIZE_FORMAT " bytes",
indexListReturnedBytes);
gclog_or_tty->print_cr(" Dictionary Returned "SIZE_FORMAT" bytes",
gclog_or_tty->print_cr(" Dictionary Returned " SIZE_FORMAT " bytes",
dict_returned_bytes);
}
}
@ -7432,12 +7434,12 @@ size_t SweepClosure::do_blk_careful(HeapWord* addr) {
// coalesced chunk to the appropriate free list.
if (inFreeRange()) {
assert(freeFinger() >= _sp->bottom() && freeFinger() < _limit,
err_msg("freeFinger() " PTR_FORMAT" is out-of-bounds", p2i(freeFinger())));
err_msg("freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger())));
flush_cur_free_chunk(freeFinger(),
pointer_delta(addr, freeFinger()));
if (CMSTraceSweeper) {
gclog_or_tty->print("Sweep: last chunk: ");
gclog_or_tty->print("put_free_blk " PTR_FORMAT " ("SIZE_FORMAT") "
gclog_or_tty->print("put_free_blk " PTR_FORMAT " (" SIZE_FORMAT ") "
"[coalesced:%d]\n",
p2i(freeFinger()), pointer_delta(addr, freeFinger()),
lastFreeRangeCoalesced() ? 1 : 0);

View File

@ -119,7 +119,7 @@ void CollectionSetChooser::verify() {
}
guarantee(sum_of_reclaimable_bytes == _remaining_reclaimable_bytes,
err_msg("reclaimable bytes inconsistent, "
"remaining: "SIZE_FORMAT" sum: "SIZE_FORMAT,
"remaining: " SIZE_FORMAT " sum: " SIZE_FORMAT,
_remaining_reclaimable_bytes, sum_of_reclaimable_bytes));
}
#endif // !PRODUCT

View File

@ -92,7 +92,7 @@ public:
regions_at_put(_curr_index, NULL);
assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
err_msg("remaining reclaimable bytes inconsistent "
"from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT,
"from region: " SIZE_FORMAT " remaining: " SIZE_FORMAT,
hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
_remaining_reclaimable_bytes -= hr->reclaimable_bytes();
_curr_index += 1;

View File

@ -307,7 +307,7 @@ void CMMarkStack::expand() {
if (PrintGCDetails && Verbose) {
// Failed to double capacity, continue;
gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from "
SIZE_FORMAT"K to " SIZE_FORMAT"K",
SIZE_FORMAT "K to " SIZE_FORMAT "K",
_capacity / K, new_capacity / K);
}
}
@ -555,7 +555,7 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev
_verbose_level = verbose_level;
if (verbose_low()) {
gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", "
gclog_or_tty->print_cr("[global] init, heap start = " PTR_FORMAT ", "
"heap end = " PTR_FORMAT, p2i(_heap_start), p2i(_heap_end));
}
@ -802,7 +802,7 @@ void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurren
// in a STW phase.
assert(!concurrent_marking_in_progress(), "invariant");
assert(out_of_regions(),
err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT,
err_msg("only way to get here: _finger: " PTR_FORMAT ", _heap_end: " PTR_FORMAT,
p2i(_finger), p2i(_heap_end)));
}
}
@ -1424,7 +1424,7 @@ public:
assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
err_msg("Preconditions not met - "
"start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT,
"start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT,
p2i(start), p2i(ntams), p2i(hr->end())));
// Find the first marked object at or after "start".
@ -1725,10 +1725,10 @@ class FinalCountDataUpdateClosure: public CMCountDataClosureBase {
}
assert(end_idx <= _card_bm->size(),
err_msg("oob: end_idx= "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
err_msg("oob: end_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
end_idx, _card_bm->size()));
assert(start_idx < _card_bm->size(),
err_msg("oob: start_idx= "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
err_msg("oob: start_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT,
start_idx, _card_bm->size()));
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
@ -2133,7 +2133,7 @@ class G1CMKeepAliveAndDrainClosure: public OopClosure {
oop obj = oopDesc::load_decode_heap_oop(p);
if (_cm->verbose_high()) {
gclog_or_tty->print_cr("\t[%u] we're looking at location "
"*"PTR_FORMAT" = "PTR_FORMAT,
"*" PTR_FORMAT " = " PTR_FORMAT,
_task->worker_id(), p2i(p), p2i((void*) obj));
}
@ -2660,9 +2660,9 @@ ConcurrentMark::claim_region(uint worker_id) {
HeapWord* limit = curr_region->next_top_at_mark_start();
if (verbose_low()) {
gclog_or_tty->print_cr("[%u] curr_region = "PTR_FORMAT" "
"["PTR_FORMAT", "PTR_FORMAT"), "
"limit = "PTR_FORMAT,
gclog_or_tty->print_cr("[%u] curr_region = " PTR_FORMAT " "
"[" PTR_FORMAT ", " PTR_FORMAT "), "
"limit = " PTR_FORMAT,
worker_id, p2i(curr_region), p2i(bottom), p2i(end), p2i(limit));
}
@ -2677,7 +2677,7 @@ ConcurrentMark::claim_region(uint worker_id) {
if (limit > bottom) {
if (verbose_low()) {
gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is not empty, "
gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is not empty, "
"returning it ", worker_id, p2i(curr_region));
}
return curr_region;
@ -2685,7 +2685,7 @@ ConcurrentMark::claim_region(uint worker_id) {
assert(limit == bottom,
"the region limit should be at bottom");
if (verbose_low()) {
gclog_or_tty->print_cr("[%u] region "PTR_FORMAT" is empty, "
gclog_or_tty->print_cr("[%u] region " PTR_FORMAT " is empty, "
"returning NULL", worker_id, p2i(curr_region));
}
// we return NULL and the caller should try calling
@ -2697,13 +2697,13 @@ ConcurrentMark::claim_region(uint worker_id) {
if (verbose_low()) {
if (curr_region == NULL) {
gclog_or_tty->print_cr("[%u] found uncommitted region, moving finger, "
"global finger = "PTR_FORMAT", "
"our finger = "PTR_FORMAT,
"global finger = " PTR_FORMAT ", "
"our finger = " PTR_FORMAT,
worker_id, p2i(_finger), p2i(finger));
} else {
gclog_or_tty->print_cr("[%u] somebody else moved the finger, "
"global finger = "PTR_FORMAT", "
"our finger = "PTR_FORMAT,
"global finger = " PTR_FORMAT ", "
"our finger = " PTR_FORMAT,
worker_id, p2i(_finger), p2i(finger));
}
}
@ -2739,7 +2739,7 @@ private:
void do_object_work(oop obj) {
guarantee(!_g1h->obj_in_cs(obj),
err_msg("obj: "PTR_FORMAT" in CSet, phase: %s, info: %d",
err_msg("obj: " PTR_FORMAT " in CSet, phase: %s, info: %d",
p2i((void*) obj), phase_str(), _info));
}
@ -2800,7 +2800,7 @@ void ConcurrentMark::verify_no_cset_oops() {
// here.
HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
err_msg("global finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
}
@ -2814,7 +2814,7 @@ void ConcurrentMark::verify_no_cset_oops() {
HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
!task_hr->in_collection_set(),
err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
err_msg("task finger: " PTR_FORMAT " region: " HR_FORMAT,
p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
}
}
@ -2856,8 +2856,8 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(),
err_msg("Preconditions not met - "
"start: "PTR_FORMAT", limit: "PTR_FORMAT", "
"top: "PTR_FORMAT", end: "PTR_FORMAT,
"start: " PTR_FORMAT ", limit: " PTR_FORMAT ", "
"top: " PTR_FORMAT ", end: " PTR_FORMAT,
p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end())));
assert(hr->next_marked_bytes() == 0, "Precondition");
@ -3118,7 +3118,7 @@ bool ConcurrentMark::do_yield_check(uint worker_id) {
#ifndef PRODUCT
// for debugging purposes
void ConcurrentMark::print_finger() {
gclog_or_tty->print_cr("heap ["PTR_FORMAT", "PTR_FORMAT"), global finger = "PTR_FORMAT,
gclog_or_tty->print_cr("heap [" PTR_FORMAT ", " PTR_FORMAT "), global finger = " PTR_FORMAT,
p2i(_heap_start), p2i(_heap_end), p2i(_finger));
for (uint i = 0; i < _max_worker_id; ++i) {
gclog_or_tty->print(" %u: " PTR_FORMAT, i, p2i(_tasks[i]->finger()));
@ -3203,7 +3203,7 @@ void CMTask::setup_for_region(HeapRegion* hr) {
"claim_region() should have filtered out continues humongous regions");
if (_cm->verbose_low()) {
gclog_or_tty->print_cr("[%u] setting up for region "PTR_FORMAT,
gclog_or_tty->print_cr("[%u] setting up for region " PTR_FORMAT,
_worker_id, p2i(hr));
}
@ -3220,7 +3220,7 @@ void CMTask::update_region_limit() {
if (limit == bottom) {
if (_cm->verbose_low()) {
gclog_or_tty->print_cr("[%u] found an empty region "
"["PTR_FORMAT", "PTR_FORMAT")",
"[" PTR_FORMAT ", " PTR_FORMAT ")",
_worker_id, p2i(bottom), p2i(limit));
}
// The region was collected underneath our feet.
@ -3252,7 +3252,7 @@ void CMTask::update_region_limit() {
void CMTask::giveup_current_region() {
assert(_curr_region != NULL, "invariant");
if (_cm->verbose_low()) {
gclog_or_tty->print_cr("[%u] giving up region "PTR_FORMAT,
gclog_or_tty->print_cr("[%u] giving up region " PTR_FORMAT,
_worker_id, p2i(_curr_region));
}
clear_region_fields();
@ -3374,7 +3374,7 @@ void CMTask::regular_clock_call() {
if (_cm->verbose_medium()) {
gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
"scanned = "SIZE_FORMAT"%s, refs reached = "SIZE_FORMAT"%s",
"scanned = " SIZE_FORMAT "%s, refs reached = " SIZE_FORMAT "%s",
_worker_id, last_interval_ms,
_words_scanned,
(_words_scanned >= _words_scanned_limit) ? " (*)" : "",
@ -3543,7 +3543,7 @@ void CMTask::drain_local_queue(bool partially) {
statsOnly( ++_local_pops );
if (_cm->verbose_high()) {
gclog_or_tty->print_cr("[%u] popped "PTR_FORMAT, _worker_id,
gclog_or_tty->print_cr("[%u] popped " PTR_FORMAT, _worker_id,
p2i((void*) obj));
}
@ -3900,8 +3900,8 @@ void CMTask::do_marking_step(double time_target_ms,
if (_cm->verbose_low()) {
gclog_or_tty->print_cr("[%u] we're scanning part "
"["PTR_FORMAT", "PTR_FORMAT") "
"of region "HR_FORMAT,
"[" PTR_FORMAT ", " PTR_FORMAT ") "
"of region " HR_FORMAT,
_worker_id, p2i(_finger), p2i(_region_limit),
HR_FORMAT_PARAMS(_curr_region));
}
@ -3988,7 +3988,7 @@ void CMTask::do_marking_step(double time_target_ms,
if (_cm->verbose_low()) {
gclog_or_tty->print_cr("[%u] we successfully claimed "
"region "PTR_FORMAT,
"region " PTR_FORMAT,
_worker_id, p2i(claimed_region));
}
@ -4049,7 +4049,7 @@ void CMTask::do_marking_step(double time_target_ms,
if (_cm->try_stealing(_worker_id, &_hash_seed, obj)) {
if (_cm->verbose_medium()) {
gclog_or_tty->print_cr("[%u] stolen "PTR_FORMAT" successfully",
gclog_or_tty->print_cr("[%u] stolen " PTR_FORMAT " successfully",
_worker_id, p2i((void*) obj));
}
@ -4257,7 +4257,7 @@ CMTask::CMTask(uint worker_id,
// identify them easily in a large log file.
#define G1PPRL_LINE_PREFIX "###"
#define G1PPRL_ADDR_BASE_FORMAT " "PTR_FORMAT"-"PTR_FORMAT
#define G1PPRL_ADDR_BASE_FORMAT " " PTR_FORMAT "-" PTR_FORMAT
#ifdef _LP64
#define G1PPRL_ADDR_BASE_H_FORMAT " %37s"
#else // _LP64
@ -4267,16 +4267,16 @@ CMTask::CMTask(uint worker_id,
// For per-region info
#define G1PPRL_TYPE_FORMAT " %-4s"
#define G1PPRL_TYPE_H_FORMAT " %4s"
#define G1PPRL_BYTE_FORMAT " "SIZE_FORMAT_W(9)
#define G1PPRL_BYTE_FORMAT " " SIZE_FORMAT_W(9)
#define G1PPRL_BYTE_H_FORMAT " %9s"
#define G1PPRL_DOUBLE_FORMAT " %14.1f"
#define G1PPRL_DOUBLE_H_FORMAT " %14s"
// For summary info
#define G1PPRL_SUM_ADDR_FORMAT(tag) " "tag":"G1PPRL_ADDR_BASE_FORMAT
#define G1PPRL_SUM_BYTE_FORMAT(tag) " "tag": "SIZE_FORMAT
#define G1PPRL_SUM_MB_FORMAT(tag) " "tag": %1.2f MB"
#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag)" / %1.2f %%"
#define G1PPRL_SUM_ADDR_FORMAT(tag) " " tag ":" G1PPRL_ADDR_BASE_FORMAT
#define G1PPRL_SUM_BYTE_FORMAT(tag) " " tag ": " SIZE_FORMAT
#define G1PPRL_SUM_MB_FORMAT(tag) " " tag ": %1.2f MB"
#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%"
G1PrintRegionLivenessInfoClosure::
G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)

View File

@ -197,8 +197,8 @@ inline bool CMBitMapRO::iterate(BitMapClosure* cl) {
assert(_bmStartWord <= (addr) && (addr) < (_bmStartWord + _bmWordSize), \
"outside underlying space?"); \
assert(G1CollectedHeap::heap()->is_in_exact(addr), \
err_msg("Trying to access not available bitmap "PTR_FORMAT \
" corresponding to "PTR_FORMAT" (%u)", \
err_msg("Trying to access not available bitmap " PTR_FORMAT \
" corresponding to " PTR_FORMAT " (%u)", \
p2i(this), p2i(addr), G1CollectedHeap::heap()->addr_to_region(addr)));
inline void CMBitMap::mark(HeapWord* addr) {
@ -344,7 +344,7 @@ inline void CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
inline void CMTask::deal_with_reference(oop obj) {
if (_cm->verbose_high()) {
gclog_or_tty->print_cr("[%u] we're dealing with reference = "PTR_FORMAT,
gclog_or_tty->print_cr("[%u] we're dealing with reference = " PTR_FORMAT,
_worker_id, p2i((void*) obj));
}
@ -393,7 +393,7 @@ inline void ConcurrentMark::grayRoot(oop obj, size_t word_size,
// assert that word_size is under an upper bound which is its
// containing region's capacity.
assert(word_size * HeapWordSize <= hr->capacity(),
err_msg("size: "SIZE_FORMAT" capacity: "SIZE_FORMAT" "HR_FORMAT,
err_msg("size: " SIZE_FORMAT " capacity: " SIZE_FORMAT " " HR_FORMAT,
word_size * HeapWordSize, hr->capacity(),
HR_FORMAT_PARAMS(hr)));

View File

@ -44,8 +44,7 @@ SurrogateLockerThread*
ConcurrentMarkThread::ConcurrentMarkThread(ConcurrentMark* cm) :
ConcurrentGCThread(),
_cm(cm),
_started(false),
_in_progress(false),
_state(Idle),
_vtime_accum(0.0),
_vtime_mark_accum(0.0) {
@ -307,7 +306,6 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() {
if (started()) {
set_in_progress();
clear_started();
}
}

View File

@ -47,8 +47,14 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
private:
ConcurrentMark* _cm;
volatile bool _started;
volatile bool _in_progress;
enum State {
Idle,
Started,
InProgress
};
volatile State _state;
void sleepBeforeNextCycle();
@ -68,23 +74,22 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
ConcurrentMark* cm() { return _cm; }
void set_started() { assert(!_in_progress, "cycle in progress"); _started = true; }
void clear_started() { assert(_in_progress, "must be starting a cycle"); _started = false; }
bool started() { return _started; }
void set_idle() { assert(_state != Started, "must not be starting a new cycle"); _state = Idle; }
bool idle() { return _state == Idle; }
void set_started() { assert(_state == Idle, "cycle in progress"); _state = Started; }
bool started() { return _state == Started; }
void set_in_progress() { assert(_state == Started, "must be starting a cycle"); _state = InProgress; }
bool in_progress() { return _state == InProgress; }
void set_in_progress() { assert(_started, "must be starting a cycle"); _in_progress = true; }
void clear_in_progress() { assert(!_started, "must not be starting a new cycle"); _in_progress = false; }
bool in_progress() { return _in_progress; }
// This flag returns true from the moment a marking cycle is
// Returns true from the moment a marking cycle is
// initiated (during the initial-mark pause when started() is set)
// to the moment when the cycle completes (just after the next
// marking bitmap has been cleared and in_progress() is
// cleared). While this flag is true we will not start another cycle
// cleared). While during_cycle() is true we will not start another cycle
// so that cycles do not overlap. We cannot use just in_progress()
// as the CM thread might take some time to wake up before noticing
// that started() is set and set in_progress().
bool during_cycle() { return started() || in_progress(); }
bool during_cycle() { return !idle(); }
// shutdown
void stop();

View File

@ -140,7 +140,7 @@ HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
}
void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) {
msg->append("[%s] %s c: %u b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT,
msg->append("[%s] %s c: %u b: %s r: " PTR_FORMAT " u: " SIZE_FORMAT,
_name, message, _count, BOOL_TO_STR(_bot_updates),
p2i(_alloc_region), _used_bytes_before);
}
@ -217,7 +217,7 @@ void G1AllocRegion::trace(const char* str, size_t word_size, HeapWord* result) {
if (G1_ALLOC_REGION_TRACING > 1) {
if (result != NULL) {
jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT" "PTR_FORMAT,
jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT " " PTR_FORMAT,
word_size, result);
} else if (word_size != 0) {
jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT, word_size);

View File

@ -76,7 +76,7 @@ public:
void decrease_used(size_t bytes) {
assert(_summary_bytes_used >= bytes,
err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" should be >= bytes: "SIZE_FORMAT,
err_msg("invariant: _summary_bytes_used: " SIZE_FORMAT " should be >= bytes: " SIZE_FORMAT,
_summary_bytes_used, bytes));
_summary_bytes_used -= bytes;
}

View File

@ -36,19 +36,19 @@ address G1BiasedMappedArrayBase::create_new_base_array(size_t length, size_t ele
#ifndef PRODUCT
void G1BiasedMappedArrayBase::verify_index(idx_t index) const {
guarantee(_base != NULL, "Array not initialized");
guarantee(index < length(), err_msg("Index out of bounds index: "SIZE_FORMAT" length: "SIZE_FORMAT, index, length()));
guarantee(index < length(), err_msg("Index out of bounds index: " SIZE_FORMAT " length: " SIZE_FORMAT, index, length()));
}
void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const {
guarantee(_biased_base != NULL, "Array not initialized");
guarantee(biased_index >= bias() && biased_index < (bias() + length()),
err_msg("Biased index out of bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
err_msg("Biased index out of bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, biased_index, bias(), length()));
}
void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const {
guarantee(_biased_base != NULL, "Array not initialized");
guarantee(biased_index >= bias() && biased_index <= (bias() + length()),
err_msg("Biased index out of inclusive bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
err_msg("Biased index out of inclusive bounds, index: " SIZE_FORMAT " bias: " SIZE_FORMAT " length: " SIZE_FORMAT, biased_index, bias(), length()));
}
class TestMappedArray : public G1BiasedMappedArray<int> {

View File

@ -71,10 +71,10 @@ protected:
assert(is_power_of_2(mapping_granularity_in_bytes),
err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes));
assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0,
err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT,
err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT,
mapping_granularity_in_bytes, p2i(bottom)));
assert((uintptr_t)end % mapping_granularity_in_bytes == 0,
err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT,
err_msg("end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT,
mapping_granularity_in_bytes, p2i(end)));
size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes);
idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes;

View File

@ -69,10 +69,10 @@ bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
#ifdef ASSERT
void G1BlockOffsetSharedArray::check_index(size_t index, const char* msg) const {
assert((index) < (_reserved.word_size() >> LogN_words),
err_msg("%s - index: "SIZE_FORMAT", _vs.committed_size: "SIZE_FORMAT,
err_msg("%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
msg, (index), (_reserved.word_size() >> LogN_words)));
assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
err_msg("Index "SIZE_FORMAT" corresponding to "PTR_FORMAT
err_msg("Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
" (%u) is not in committed area.",
(index),
p2i(address_for_index_raw(index)),
@ -430,11 +430,11 @@ void
G1BlockOffsetArray::print_on(outputStream* out) {
size_t from_index = _array->index_for(_bottom);
size_t to_index = _array->index_for(_end);
out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") "
"cards ["SIZE_FORMAT","SIZE_FORMAT")",
out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
"cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
p2i(_bottom), p2i(_end), from_index, to_index);
for (size_t i = from_index; i < to_index; ++i) {
out->print_cr(" entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u",
out->print_cr(" entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
i, p2i(_array->address_for_index(i)),
(uint) _array->offset_array(i));
}
@ -514,7 +514,7 @@ G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
void
G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
G1BlockOffsetArray::print_on(out);
out->print_cr(" next offset threshold: "PTR_FORMAT, p2i(_next_offset_threshold));
out->print_cr(" next offset index: "SIZE_FORMAT, _next_offset_index);
out->print_cr(" next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold));
out->print_cr(" next offset index: " SIZE_FORMAT, _next_offset_index);
}
#endif // !PRODUCT

View File

@ -150,7 +150,7 @@ private:
void check_offset(size_t offset, const char* msg) const {
assert(offset <= N_words,
err_msg("%s - "
"offset: " SIZE_FORMAT", N_words: %u",
"offset: " SIZE_FORMAT ", N_words: %u",
msg, offset, (uint)N_words));
}

View File

@ -53,7 +53,7 @@ size_t G1CardCounts::heap_map_factor() {
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
if (has_count_table()) {
assert(from_card_num < to_card_num,
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
err_msg("Wrong order? from: " SIZE_FORMAT ", to: " SIZE_FORMAT,
from_card_num, to_card_num));
Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
}
@ -96,7 +96,7 @@ uint G1CardCounts::add_card_count(jbyte* card_ptr) {
if (has_count_table()) {
size_t card_num = ptr_2_card_num(card_ptr);
assert(card_num < _reserved_max_card_num,
err_msg("Card "SIZE_FORMAT" outside of card counts table (max size "SIZE_FORMAT")",
err_msg("Card " SIZE_FORMAT " outside of card counts table (max size " SIZE_FORMAT ")",
card_num, _reserved_max_card_num));
count = (uint) _card_counts[card_num];
if (count < G1ConcRSHotCardLimit) {

View File

@ -91,7 +91,7 @@ class G1CardCounts: public CHeapObj<mtGC> {
jbyte* card_num_2_ptr(size_t card_num) {
assert(card_num < _reserved_max_card_num,
err_msg("card num out of range: "SIZE_FORMAT, card_num));
err_msg("card num out of range: " SIZE_FORMAT, card_num));
return (jbyte*) (_ct_bot + card_num);
}

View File

@ -350,11 +350,11 @@ class G1CodeRootSetTest {
assert(set1.is_empty(), "Code root set must be initially empty but is not.");
assert(G1CodeRootSet::static_mem_size() == sizeof(void*),
err_msg("The code root set's static memory usage is incorrect, "SIZE_FORMAT" bytes", G1CodeRootSet::static_mem_size()));
err_msg("The code root set's static memory usage is incorrect, " SIZE_FORMAT " bytes", G1CodeRootSet::static_mem_size()));
set1.add((nmethod*)1);
assert(set1.length() == 1, err_msg("Added exactly one element, but set contains "
SIZE_FORMAT" elements", set1.length()));
SIZE_FORMAT " elements", set1.length()));
const size_t num_to_add = (size_t)G1CodeRootSet::Threshold + 1;
@ -363,14 +363,14 @@ class G1CodeRootSetTest {
}
assert(set1.length() == 1,
err_msg("Duplicate detection should not have increased the set size but "
"is "SIZE_FORMAT, set1.length()));
"is " SIZE_FORMAT, set1.length()));
for (size_t i = 2; i <= num_to_add; i++) {
set1.add((nmethod*)(uintptr_t)(i));
}
assert(set1.length() == num_to_add,
err_msg("After adding in total "SIZE_FORMAT" distinct code roots, they "
"need to be in the set, but there are only "SIZE_FORMAT,
err_msg("After adding in total " SIZE_FORMAT " distinct code roots, they "
"need to be in the set, but there are only " SIZE_FORMAT,
num_to_add, set1.length()));
assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");
@ -385,7 +385,7 @@ class G1CodeRootSetTest {
}
}
assert(num_popped == num_to_add,
err_msg("Managed to pop "SIZE_FORMAT" code roots, but only "SIZE_FORMAT" "
err_msg("Managed to pop " SIZE_FORMAT " code roots, but only " SIZE_FORMAT " "
"were added", num_popped, num_to_add));
assert(CodeRootSetTable::_purge_list != NULL, "should have grown to large hashtable");

View File

@ -197,7 +197,7 @@ bool YoungList::check_list_well_formed() {
HeapRegion* last = NULL;
while (curr != NULL) {
if (!curr->is_young()) {
gclog_or_tty->print_cr("### YOUNG REGION "PTR_FORMAT"-"PTR_FORMAT" "
gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
"incorrectly tagged (y: %d, surv: %d)",
p2i(curr->bottom()), p2i(curr->end()),
curr->is_young(), curr->is_survivor());
@ -326,7 +326,7 @@ void YoungList::print() {
if (curr == NULL)
gclog_or_tty->print_cr(" empty");
while (curr != NULL) {
gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
gclog_or_tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
HR_FORMAT_PARAMS(curr),
p2i(curr->prev_top_at_mark_start()),
p2i(curr->next_top_at_mark_start()),
@ -430,7 +430,7 @@ G1CollectedHeap::new_region_try_secondary_free_list(bool is_old) {
HeapRegion* res = _hrm.allocate_free_region(is_old);
if (G1ConcRegionFreeingVerbose) {
gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
"allocated "HR_FORMAT" from secondary_free_list",
"allocated " HR_FORMAT " from secondary_free_list",
HR_FORMAT_PARAMS(res));
}
return res;
@ -1670,8 +1670,8 @@ resize_if_necessary_after_full_collection(size_t word_size) {
// This assert only makes sense here, before we adjust them
// with respect to the min and max heap size.
assert(minimum_desired_capacity <= maximum_desired_capacity,
err_msg("minimum_desired_capacity = "SIZE_FORMAT", "
"maximum_desired_capacity = "SIZE_FORMAT,
err_msg("minimum_desired_capacity = " SIZE_FORMAT ", "
"maximum_desired_capacity = " SIZE_FORMAT,
minimum_desired_capacity, maximum_desired_capacity));
// Should not be greater than the heap max size. No need to adjust
@ -2332,7 +2332,7 @@ public:
virtual bool doHeapRegion(HeapRegion* hr) {
unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
if (_gc_time_stamp != region_gc_time_stamp) {
gclog_or_tty->print_cr("Region "HR_FORMAT" has GC time stamp = %d, "
gclog_or_tty->print_cr("Region " HR_FORMAT " has GC time stamp = %d, "
"expected %d", HR_FORMAT_PARAMS(hr),
region_gc_time_stamp, _gc_time_stamp);
_failures = true;
@ -2487,7 +2487,7 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) {
// is set) so that if a waiter requests another System.gc() it doesn't
// incorrectly see that a marking cycle is still in progress.
if (concurrent) {
_cmThread->clear_in_progress();
_cmThread->set_idle();
}
// This notify_all() will ensure that a thread that called
@ -2926,10 +2926,10 @@ public:
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (_g1h->is_obj_dead_cond(obj, _vo)) {
gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
"points to dead obj "PTR_FORMAT, p2i(p), p2i(obj));
gclog_or_tty->print_cr("Root location " PTR_FORMAT " "
"points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
if (_vo == VerifyOption_G1UseMarkWord) {
gclog_or_tty->print_cr(" Mark word: "INTPTR_FORMAT, (intptr_t)obj->mark());
gclog_or_tty->print_cr(" Mark word: " INTPTR_FORMAT, (intptr_t)obj->mark());
}
obj->print_on(gclog_or_tty);
_failures = true;
@ -2976,9 +2976,9 @@ class G1VerifyCodeRootOopClosure: public OopClosure {
// Verify that the strong code root list for this region
// contains the nmethod
if (!hrrs->strong_code_roots_list_contains(_nm)) {
gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
"from nmethod "PTR_FORMAT" not in strong "
"code roots for region ["PTR_FORMAT","PTR_FORMAT")",
gclog_or_tty->print_cr("Code root location " PTR_FORMAT " "
"from nmethod " PTR_FORMAT " not in strong "
"code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
_failures = true;
}
@ -3157,9 +3157,9 @@ public:
r->object_iterate(&not_dead_yet_cl);
if (_vo != VerifyOption_G1UseNextMarking) {
if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
"max_live_bytes "SIZE_FORMAT" "
"< calculated "SIZE_FORMAT,
gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "
"max_live_bytes " SIZE_FORMAT " "
"< calculated " SIZE_FORMAT,
p2i(r->bottom()), p2i(r->end()),
r->max_live_bytes(),
not_dead_yet_cl.live_bytes());
@ -3444,7 +3444,7 @@ public:
size_t occupied = hrrs->occupied();
_occupied_sum += occupied;
gclog_or_tty->print_cr("Printing RSet for region "HR_FORMAT,
gclog_or_tty->print_cr("Printing RSet for region " HR_FORMAT,
HR_FORMAT_PARAMS(r));
if (occupied == 0) {
gclog_or_tty->print_cr(" RSet is empty");
@ -3463,7 +3463,7 @@ public:
}
~PrintRSetsClosure() {
gclog_or_tty->print_cr("Occupied Sum: "SIZE_FORMAT, _occupied_sum);
gclog_or_tty->print_cr("Occupied Sum: " SIZE_FORMAT, _occupied_sum);
gclog_or_tty->print_cr("========================================");
gclog_or_tty->cr();
}
@ -4308,7 +4308,7 @@ oop
G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state,
oop old) {
assert(obj_in_cs(old),
err_msg("obj: "PTR_FORMAT" should still be in the CSet",
err_msg("obj: " PTR_FORMAT " should still be in the CSet",
p2i(old)));
markOop m = old->mark();
oop forward_ptr = old->forward_to_atomic(old);
@ -4342,7 +4342,7 @@ G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_s
// space for this object (old != forward_ptr) or they beat us in
// self-forwarding it (old == forward_ptr).
assert(old == forward_ptr || !obj_in_cs(forward_ptr),
err_msg("obj: "PTR_FORMAT" forwarded to: "PTR_FORMAT" "
err_msg("obj: " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
"should not be in the CSet",
p2i(old), p2i(forward_ptr)));
return forward_ptr;
@ -4730,8 +4730,8 @@ public:
if (G1TraceStringSymbolTableScrubbing) {
gclog_or_tty->print_cr("Cleaned string and symbol table, "
"strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, "
"symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed",
"strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
"symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
strings_processed(), strings_removed(),
symbols_processed(), symbols_removed());
}
@ -5828,13 +5828,13 @@ void G1CollectedHeap::verify_dirty_young_regions() {
bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
HeapWord* tams, HeapWord* end) {
guarantee(tams <= end,
err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, p2i(tams), p2i(end)));
err_msg("tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end)));
HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
if (result < end) {
gclog_or_tty->cr();
gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
gclog_or_tty->print_cr("## wrong marked address on %s bitmap: " PTR_FORMAT,
bitmap_name, p2i(result));
gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
gclog_or_tty->print_cr("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT,
bitmap_name, p2i(tams), p2i(end));
return false;
}
@ -5860,7 +5860,7 @@ bool G1CollectedHeap::verify_bitmaps(const char* caller, HeapRegion* hr) {
res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
}
if (!res_p || !res_n) {
gclog_or_tty->print_cr("#### Bitmap verification failed for "HR_FORMAT,
gclog_or_tty->print_cr("#### Bitmap verification failed for " HR_FORMAT,
HR_FORMAT_PARAMS(hr));
gclog_or_tty->print_cr("#### Caller: %s", caller);
return false;
@ -6157,7 +6157,7 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure {
!r->rem_set()->is_empty()) {
if (G1TraceEagerReclaimHumongousObjects) {
gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
region_idx,
(size_t)obj->size() * HeapWordSize,
p2i(r->bottom()),
@ -6179,7 +6179,7 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure {
p2i(r->bottom())));
if (G1TraceEagerReclaimHumongousObjects) {
gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
region_idx,
(size_t)obj->size() * HeapWordSize,
p2i(r->bottom()),
@ -6333,7 +6333,7 @@ public:
NoYoungRegionsClosure() : _success(true) { }
bool doHeapRegion(HeapRegion* r) {
if (r->is_young()) {
gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young",
gclog_or_tty->print_cr("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
p2i(r->bottom()), p2i(r->end()));
_success = false;
}
@ -6470,7 +6470,7 @@ void G1CollectedHeap::rebuild_region_sets(bool free_list_only) {
}
assert(_allocator->used_unlocked() == recalculate_used(),
err_msg("inconsistent _allocator->used_unlocked(), "
"value: "SIZE_FORMAT" recalculated: "SIZE_FORMAT,
"value: " SIZE_FORMAT " recalculated: " SIZE_FORMAT,
_allocator->used_unlocked(), recalculate_used()));
}
@ -6697,8 +6697,8 @@ class RegisterNMethodOopClosure: public OopClosure {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
HeapRegion* hr = _g1h->heap_region_containing(obj);
assert(!hr->is_continues_humongous(),
err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
" starting at "HR_FORMAT,
err_msg("trying to add code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
" starting at " HR_FORMAT,
p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
// HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
@ -6724,8 +6724,8 @@ class UnregisterNMethodOopClosure: public OopClosure {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
HeapRegion* hr = _g1h->heap_region_containing(obj);
assert(!hr->is_continues_humongous(),
err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
" starting at "HR_FORMAT,
err_msg("trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
" starting at " HR_FORMAT,
p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
hr->remove_strong_code_root(_nm);

View File

@ -1109,6 +1109,8 @@ public:
// The STW reference processor....
ReferenceProcessor* ref_processor_stw() const { return _ref_processor_stw; }
G1NewTracer* gc_tracer_stw() const { return _gc_tracer_stw; }
// The Concurrent Marking reference processor...
ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }

View File

@ -82,7 +82,7 @@ inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at
inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
assert(is_in_reserved(addr),
err_msg("Cannot calculate region index for address "PTR_FORMAT" that is outside of the heap ["PTR_FORMAT", "PTR_FORMAT")",
err_msg("Cannot calculate region index for address " PTR_FORMAT " that is outside of the heap [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(addr), p2i(reserved_region().start()), p2i(reserved_region().end())));
return (uint)(pointer_delta(addr, reserved_region().start(), sizeof(uint8_t)) >> HeapRegion::LogOfHRGrainBytes);
}
@ -95,7 +95,7 @@ template <class T>
inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const T addr) const {
assert(addr != NULL, "invariant");
assert(is_in_g1_reserved((const void*) addr),
err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")",
err_msg("Address " PTR_FORMAT " is outside of the heap ranging from [" PTR_FORMAT " to " PTR_FORMAT ")",
p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end())));
return _hrm.addr_to_region((HeapWord*) addr);
}

View File

@ -184,7 +184,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
const size_t region_size = HeapRegion::GrainWords;
if (YoungPLABSize > region_size || OldPLABSize > region_size) {
char buffer[128];
jio_snprintf(buffer, sizeof(buffer), "%sPLABSize should be at most "SIZE_FORMAT,
jio_snprintf(buffer, sizeof(buffer), "%sPLABSize should be at most " SIZE_FORMAT,
OldPLABSize > region_size ? "Old" : "Young", region_size);
vm_exit_during_initialization(buffer);
}
@ -821,7 +821,7 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec) {
update_survivors_policy();
assert(_g1->used() == _g1->recalculate_used(),
err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
err_msg("sanity, used: " SIZE_FORMAT " recalculate_used: " SIZE_FORMAT,
_g1->used(), _g1->recalculate_used()));
double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
@ -865,7 +865,7 @@ void G1CollectorPolicy::record_concurrent_mark_remark_end() {
_cur_mark_stop_world_time_ms += elapsed_time_ms;
_prev_collection_pause_end_ms += elapsed_time_ms;
_mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec, true);
_mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec, _g1->gc_tracer_cm()->gc_id());
}
void G1CollectorPolicy::record_concurrent_mark_cleanup_start() {
@ -961,7 +961,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, Evacua
}
_mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
end_time_sec, false);
end_time_sec, _g1->gc_tracer_stw()->gc_id());
evacuation_info.set_collectionset_used_before(_collection_set_bytes_used_before);
evacuation_info.set_bytes_copied(_bytes_copied_during_gc);
@ -1216,10 +1216,10 @@ void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
(_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
gclog_or_tty->print(
" [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
"Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
"Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
" [Eden: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->" EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ") "
"Survivors: " EXT_SIZE_FORMAT "->" EXT_SIZE_FORMAT " "
"Heap: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->"
EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")]",
EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
@ -1597,7 +1597,7 @@ G1CollectorPolicy::record_concurrent_mark_cleanup_end() {
_concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
_cur_mark_stop_world_time_ms += elapsed_time_ms;
_prev_collection_pause_end_ms += elapsed_time_ms;
_mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
_mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, _g1->gc_tracer_cm()->gc_id());
}
// Add the heap region at the head of the non-incremental collection set
@ -1787,7 +1787,7 @@ void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream
while (csr != NULL) {
HeapRegion* next = csr->next_in_collection_set();
assert(csr->in_collection_set(), "bad CS");
st->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
HR_FORMAT_PARAMS(csr),
p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
csr->age_in_surv_rate_group_cond());

View File

@ -121,15 +121,15 @@ public:
// Single parameter format strings
#define ergo_format_str(_name_) ", " _name_ ": %s"
#define ergo_format_region(_name_) ", " _name_ ": %u regions"
#define ergo_format_byte(_name_) ", " _name_ ": "SIZE_FORMAT" bytes"
#define ergo_format_byte(_name_) ", " _name_ ": " SIZE_FORMAT " bytes"
#define ergo_format_double(_name_) ", " _name_ ": %1.2f"
#define ergo_format_perc(_name_) ", " _name_ ": %1.2f %%"
#define ergo_format_ms(_name_) ", " _name_ ": %1.2f ms"
#define ergo_format_size(_name_) ", " _name_ ": "SIZE_FORMAT
#define ergo_format_size(_name_) ", " _name_ ": " SIZE_FORMAT
// Double parameter format strings
#define ergo_format_byte_perc(_name_) \
", " _name_ ": "SIZE_FORMAT" bytes (%1.2f %%)"
", " _name_ ": " SIZE_FORMAT " bytes (%1.2f %%)"
// Generates the format string
#define ergo_format(_extra_format_) \

View File

@ -331,7 +331,7 @@ void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
}
void G1GCPhaseTimes::print_stats(int level, const char* str, size_t value) {
LineBuffer(level).append_and_print_cr("[%s: "SIZE_FORMAT"]", str, value);
LineBuffer(level).append_and_print_cr("[%s: " SIZE_FORMAT "]", str, value);
}
void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
@ -451,7 +451,7 @@ class G1GCParPhasePrinter : public StackObj {
if (phase->_thread_work_items != NULL) {
LineBuffer buf2(phase->_thread_work_items->_indent_level);
buf2.append_and_print_cr("[%s: "SIZE_FORMAT"]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
buf2.append_and_print_cr("[%s: " SIZE_FORMAT "]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
}
}

View File

@ -83,18 +83,18 @@ void G1HRPrinter::print(ActionType action, RegionType type,
if (type_str != NULL) {
if (top != NULL) {
gclog_or_tty->print_cr(G1HR_PREFIX" %s(%s) "PTR_FORMAT" "PTR_FORMAT,
gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT " " PTR_FORMAT,
action_str, type_str, p2i(bottom), p2i(top));
} else {
gclog_or_tty->print_cr(G1HR_PREFIX" %s(%s) "PTR_FORMAT,
gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT,
action_str, type_str, p2i(bottom));
}
} else {
if (top != NULL) {
gclog_or_tty->print_cr(G1HR_PREFIX" %s "PTR_FORMAT" "PTR_FORMAT,
gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT " " PTR_FORMAT,
action_str, p2i(bottom), p2i(top));
} else {
gclog_or_tty->print_cr(G1HR_PREFIX" %s "PTR_FORMAT,
gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT,
action_str, p2i(bottom));
}
}
@ -103,11 +103,11 @@ void G1HRPrinter::print(ActionType action, RegionType type,
void G1HRPrinter::print(ActionType action, HeapWord* bottom, HeapWord* end) {
const char* action_str = action_name(action);
gclog_or_tty->print_cr(G1HR_PREFIX" %s ["PTR_FORMAT","PTR_FORMAT"]",
gclog_or_tty->print_cr(G1HR_PREFIX " %s [" PTR_FORMAT "," PTR_FORMAT "]",
action_str, p2i(bottom), p2i(end));
}
void G1HRPrinter::print(PhaseType phase, size_t phase_num) {
const char* phase_str = phase_name(phase);
gclog_or_tty->print_cr(G1HR_PREFIX" #%s "SIZE_FORMAT, phase_str, phase_num);
gclog_or_tty->print_cr(G1HR_PREFIX " #%s " SIZE_FORMAT, phase_str, phase_num);
}

View File

@ -104,7 +104,7 @@ class G1InCSetStateFastTestBiasedMappedArray : public G1BiasedMappedArray<InCSet
public:
void set_humongous(uintptr_t index) {
assert(get_by_index(index).is_default(),
err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
set_by_index(index, InCSetState::Humongous);
}
@ -114,13 +114,13 @@ class G1InCSetStateFastTestBiasedMappedArray : public G1BiasedMappedArray<InCSet
void set_in_young(uintptr_t index) {
assert(get_by_index(index).is_default(),
err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
set_by_index(index, InCSetState::Young);
}
void set_in_old(uintptr_t index) {
assert(get_by_index(index).is_default(),
err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
err_msg("State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
set_by_index(index, InCSetState::Old);
}

View File

@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/g1/g1MMUTracker.hpp"
#include "gc/shared/gcTrace.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/ostream.hpp"
@ -75,7 +76,7 @@ double G1MMUTrackerQueue::calculate_gc_time(double current_time) {
return gc_time;
}
void G1MMUTrackerQueue::add_pause(double start, double end, bool gc_thread) {
void G1MMUTrackerQueue::add_pause(double start, double end, const GCId& gcId) {
double duration = end - start;
remove_expired_entries(end);
@ -102,6 +103,10 @@ void G1MMUTrackerQueue::add_pause(double start, double end, bool gc_thread) {
++_no_entries;
}
_array[_head_index] = G1MMUTrackerQueueElem(start, end);
// Current entry needs to be added before calculating the value
double slice_time = calculate_gc_time(end);
G1MMUTracer::report_mmu(gcId, _time_slice, slice_time, _max_gc_time);
}
// basically the _internal call does not remove expired entries

View File

@ -25,6 +25,7 @@
#ifndef SHARE_VM_GC_G1_G1MMUTRACKER_HPP
#define SHARE_VM_GC_G1_G1MMUTRACKER_HPP
#include "gc/shared/gcId.hpp"
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
@ -42,7 +43,7 @@ protected:
public:
G1MMUTracker(double time_slice, double max_gc_time);
virtual void add_pause(double start, double end, bool gc_thread) = 0;
virtual void add_pause(double start, double end, const GCId& gcId) = 0;
virtual double when_sec(double current_time, double pause_time) = 0;
double max_gc_time() {
@ -126,7 +127,7 @@ private:
public:
G1MMUTrackerQueue(double time_slice, double max_gc_time);
virtual void add_pause(double start, double end, bool gc_thread);
virtual void add_pause(double start, double end, const GCId& gcId);
virtual double when_sec(double current_time, double pause_time);
};

View File

@ -118,7 +118,7 @@ inline void G1CMOopClosure::do_oop_nv(T* p) {
oop obj = oopDesc::load_decode_heap_oop(p);
if (_cm->verbose_high()) {
gclog_or_tty->print_cr("[%u] we're looking at location "
"*"PTR_FORMAT" = "PTR_FORMAT,
"*" PTR_FORMAT " = " PTR_FORMAT,
_task->worker_id(), p2i(p), p2i((void*) obj));
}
_task->deal_with_reference(obj);

View File

@ -424,7 +424,7 @@ G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i,
bool check_for_refs_into_cset) {
assert(_g1->is_in_exact(_ct_bs->addr_for(card_ptr)),
err_msg("Card at "PTR_FORMAT" index "SIZE_FORMAT" representing heap at "PTR_FORMAT" (%u) must be in committed heap",
err_msg("Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
p2i(card_ptr),
_ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
p2i(_ct_bs->addr_for(card_ptr)),

View File

@ -187,22 +187,22 @@ public:
size_t code_root_elems() const { return _code_root_elems; }
void print_rs_mem_info_on(outputStream * out, size_t total) {
out->print_cr(" "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
out->print_cr(" " SIZE_FORMAT_W(8) "K (%5.1f%%) by " SIZE_FORMAT " %s regions",
round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
}
void print_cards_occupied_info_on(outputStream * out, size_t total) {
out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) entries by "SIZE_FORMAT" %s regions",
out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) entries by " SIZE_FORMAT " %s regions",
cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
}
void print_code_root_mem_info_on(outputStream * out, size_t total) {
out->print_cr(" "SIZE_FORMAT_W(8)"K (%5.1f%%) by "SIZE_FORMAT" %s regions",
out->print_cr(" " SIZE_FORMAT_W(8) "K (%5.1f%%) by " SIZE_FORMAT " %s regions",
round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
}
void print_code_root_elems_info_on(outputStream * out, size_t total) {
out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) elements by "SIZE_FORMAT" %s regions",
out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) elements by " SIZE_FORMAT " %s regions",
code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
}
};
@ -280,19 +280,19 @@ public:
RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
out->print_cr("\n Current rem set statistics");
out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K."
" Max = "SIZE_FORMAT"K.",
out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT "K."
" Max = " SIZE_FORMAT "K.",
round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
(*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
}
out->print_cr(" Static structures = "SIZE_FORMAT"K,"
" free_lists = "SIZE_FORMAT"K.",
out->print_cr(" Static structures = " SIZE_FORMAT "K,"
" free_lists = " SIZE_FORMAT "K.",
round_to_K(HeapRegionRemSet::static_mem_size()),
round_to_K(HeapRegionRemSet::fl_mem_size()));
out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
out->print_cr(" " SIZE_FORMAT " occupied cards represented.",
total_cards_occupied());
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
(*current)->print_cards_occupied_info_on(out, total_cards_occupied());
@ -300,30 +300,30 @@ public:
// Largest sized rem set region statistics
HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
out->print_cr(" Region with largest rem set = "HR_FORMAT", "
"size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
out->print_cr(" Region with largest rem set = " HR_FORMAT ", "
"size = " SIZE_FORMAT "K, occupied = " SIZE_FORMAT "K.",
HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
round_to_K(rem_set->mem_size()),
round_to_K(rem_set->occupied()));
// Strong code root statistics
HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K."
" Max = "SIZE_FORMAT"K.",
out->print_cr(" Total heap region code root sets sizes = " SIZE_FORMAT "K."
" Max = " SIZE_FORMAT "K.",
round_to_K(total_code_root_mem_sz()),
round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
(*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
}
out->print_cr(" "SIZE_FORMAT" code roots represented.",
out->print_cr(" " SIZE_FORMAT " code roots represented.",
total_code_root_elems());
for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
(*current)->print_code_root_elems_info_on(out, total_code_root_elems());
}
out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", "
"size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
out->print_cr(" Region with largest amount of code roots = " HR_FORMAT ", "
"size = " SIZE_FORMAT "K, num_elems = " SIZE_FORMAT ".",
HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
@ -332,16 +332,16 @@ public:
void G1RemSetSummary::print_on(outputStream* out) {
out->print_cr("\n Recent concurrent refinement statistics");
out->print_cr(" Processed "SIZE_FORMAT" cards",
out->print_cr(" Processed " SIZE_FORMAT " cards",
num_concurrent_refined_cards());
out->print_cr(" Of "SIZE_FORMAT" completed buffers:", num_processed_buf_total());
out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) by concurrent RS threads.",
out->print_cr(" Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total());
out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) by concurrent RS threads.",
num_processed_buf_total(),
percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
out->print_cr(" "SIZE_FORMAT_W(8)" (%5.1f%%) by mutator threads.",
out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) by mutator threads.",
num_processed_buf_mutator(),
percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
out->print_cr(" Did "SIZE_FORMAT" coarsenings.", num_coarsenings());
out->print_cr(" Did " SIZE_FORMAT " coarsenings.", num_coarsenings());
out->print_cr(" Concurrent RS threads times (s)");
out->print(" ");
for (uint i = 0; i < _num_vtimes; i++) {

View File

@ -155,7 +155,7 @@ void G1StringDedupQueue::unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* c
void G1StringDedupQueue::print_statistics(outputStream* st) {
st->print_cr(
" [Queue]\n"
" [Dropped: "UINTX_FORMAT"]", _queue->_dropped);
" [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
}
void G1StringDedupQueue::verify() {

View File

@ -80,8 +80,8 @@ void G1StringDedupStat::print_summary(outputStream* st, const G1StringDedupStat&
st->stamp(PrintGCTimeStamps);
st->print_cr(
"[GC concurrent-string-deduplication, "
G1_STRDEDUP_BYTES_FORMAT_NS"->"G1_STRDEDUP_BYTES_FORMAT_NS"("G1_STRDEDUP_BYTES_FORMAT_NS"), avg "
G1_STRDEDUP_PERCENT_FORMAT_NS", "G1_STRDEDUP_TIME_FORMAT"]",
G1_STRDEDUP_BYTES_FORMAT_NS "->" G1_STRDEDUP_BYTES_FORMAT_NS "(" G1_STRDEDUP_BYTES_FORMAT_NS "), avg "
G1_STRDEDUP_PERCENT_FORMAT_NS ", " G1_STRDEDUP_TIME_FORMAT "]",
G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes),
G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes - last_stat._deduped_bytes),
G1_STRDEDUP_BYTES_PARAM(last_stat._deduped_bytes),
@ -135,22 +135,22 @@ void G1StringDedupStat::print_statistics(outputStream* st, const G1StringDedupSt
if (total) {
st->print_cr(
" [Total Exec: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT", Idle: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT", Blocked: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT"]",
" [Total Exec: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Idle: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
stat._exec, stat._exec_elapsed, stat._idle, stat._idle_elapsed, stat._block, stat._block_elapsed);
} else {
st->print_cr(
" [Last Exec: "G1_STRDEDUP_TIME_FORMAT", Idle: "G1_STRDEDUP_TIME_FORMAT", Blocked: "UINTX_FORMAT"/"G1_STRDEDUP_TIME_FORMAT"]",
" [Last Exec: " G1_STRDEDUP_TIME_FORMAT ", Idle: " G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
stat._exec_elapsed, stat._idle_elapsed, stat._block, stat._block_elapsed);
}
st->print_cr(
" [Inspected: "G1_STRDEDUP_OBJECTS_FORMAT"]\n"
" [Skipped: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
" [Hashed: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
" [Known: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
" [New: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"]\n"
" [Deduplicated: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
" [Young: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]\n"
" [Old: "G1_STRDEDUP_OBJECTS_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT") "G1_STRDEDUP_BYTES_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT")]",
" [Inspected: " G1_STRDEDUP_OBJECTS_FORMAT "]\n"
" [Skipped: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
" [Hashed: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
" [Known: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
" [New: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]\n"
" [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
" [Young: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
" [Old: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
stat._inspected,
stat._skipped, skipped_percent,
stat._hashed, hashed_percent,

View File

@ -556,12 +556,12 @@ void G1StringDedupTable::trim_entry_cache() {
void G1StringDedupTable::print_statistics(outputStream* st) {
st->print_cr(
" [Table]\n"
" [Memory Usage: "G1_STRDEDUP_BYTES_FORMAT_NS"]\n"
" [Size: "SIZE_FORMAT", Min: "SIZE_FORMAT", Max: "SIZE_FORMAT"]\n"
" [Entries: "UINTX_FORMAT", Load: "G1_STRDEDUP_PERCENT_FORMAT_NS", Cached: " UINTX_FORMAT ", Added: "UINTX_FORMAT", Removed: "UINTX_FORMAT"]\n"
" [Resize Count: "UINTX_FORMAT", Shrink Threshold: "UINTX_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT_NS"), Grow Threshold: "UINTX_FORMAT"("G1_STRDEDUP_PERCENT_FORMAT_NS")]\n"
" [Rehash Count: "UINTX_FORMAT", Rehash Threshold: "UINTX_FORMAT", Hash Seed: 0x%x]\n"
" [Age Threshold: "UINTX_FORMAT"]",
" [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]\n"
" [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n"
" [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n"
" [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n"
" [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n"
" [Age Threshold: " UINTX_FORMAT "]",
G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)),
_table->_size, _min_size, _max_size,
_table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed,

View File

@ -327,7 +327,7 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark,
bool during_conc_mark,
size_t marked_bytes) {
assert(marked_bytes <= used(),
err_msg("marked: "SIZE_FORMAT" used: "SIZE_FORMAT, marked_bytes, used()));
err_msg("marked: " SIZE_FORMAT " used: " SIZE_FORMAT, marked_bytes, used()));
_prev_top_at_mark_start = top();
_prev_marked_bytes = marked_bytes;
}
@ -504,9 +504,9 @@ class VerifyStrongCodeRootOopClosure: public OopClosure {
// Object is in the region. Check that its less than top
if (_hr->top() <= (HeapWord*)obj) {
// Object is above top
gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
"["PTR_FORMAT", "PTR_FORMAT") is above "
"top "PTR_FORMAT,
gclog_or_tty->print_cr("Object " PTR_FORMAT " in region "
"[" PTR_FORMAT ", " PTR_FORMAT ") is above "
"top " PTR_FORMAT,
p2i(obj), p2i(_hr->bottom()), p2i(_hr->end()), p2i(_hr->top()));
_failures = true;
return;
@ -540,22 +540,22 @@ public:
if (nm != NULL) {
// Verify that the nemthod is live
if (!nm->is_alive()) {
gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has dead nmethod "
PTR_FORMAT" in its strong code roots",
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod "
PTR_FORMAT " in its strong code roots",
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true;
} else {
VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
nm->oops_do(&oop_cl);
if (!oop_cl.has_oops_in_region()) {
gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has nmethod "
PTR_FORMAT" in its strong code roots "
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod "
PTR_FORMAT " in its strong code roots "
"with no pointers into region",
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true;
} else if (oop_cl.failures()) {
gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has other "
"failures for nmethod "PTR_FORMAT,
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has other "
"failures for nmethod " PTR_FORMAT,
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true;
}
@ -589,8 +589,8 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
// on its strong code root list
if (is_empty()) {
if (strong_code_roots_length > 0) {
gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
"but has "SIZE_FORMAT" code root entries",
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is empty "
"but has " SIZE_FORMAT " code root entries",
p2i(bottom()), p2i(end()), strong_code_roots_length);
*failures = true;
}
@ -599,8 +599,8 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
if (is_continues_humongous()) {
if (strong_code_roots_length > 0) {
gclog_or_tty->print_cr("region "HR_FORMAT" is a continuation of a humongous "
"region but has "SIZE_FORMAT" code root entries",
gclog_or_tty->print_cr("region " HR_FORMAT " is a continuation of a humongous "
"region but has " SIZE_FORMAT " code root entries",
HR_FORMAT_PARAMS(this), strong_code_roots_length);
*failures = true;
}
@ -625,7 +625,7 @@ void HeapRegion::print_on(outputStream* st) const {
else
st->print(" ");
st->print(" TS %5d", _gc_time_stamp);
st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT,
st->print(" PTAMS " PTR_FORMAT " NTAMS " PTR_FORMAT,
p2i(prev_top_at_mark_start()), p2i(next_top_at_mark_start()));
G1OffsetTableContigSpace::print_on(st);
}
@ -686,25 +686,25 @@ public:
}
if (!_g1h->is_in_closed_subset(obj)) {
HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
gclog_or_tty->print_cr("Field "PTR_FORMAT
" of live obj "PTR_FORMAT" in region "
"["PTR_FORMAT", "PTR_FORMAT")",
gclog_or_tty->print_cr("Field " PTR_FORMAT
" of live obj " PTR_FORMAT " in region "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(p), p2i(_containing_obj),
p2i(from->bottom()), p2i(from->end()));
print_object(gclog_or_tty, _containing_obj);
gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
gclog_or_tty->print_cr("points to obj " PTR_FORMAT " not in the heap",
p2i(obj));
} else {
HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
gclog_or_tty->print_cr("Field "PTR_FORMAT
" of live obj "PTR_FORMAT" in region "
"["PTR_FORMAT", "PTR_FORMAT")",
gclog_or_tty->print_cr("Field " PTR_FORMAT
" of live obj " PTR_FORMAT " in region "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(p), p2i(_containing_obj),
p2i(from->bottom()), p2i(from->end()));
print_object(gclog_or_tty, _containing_obj);
gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
"["PTR_FORMAT", "PTR_FORMAT")",
gclog_or_tty->print_cr("points to dead obj " PTR_FORMAT " in region "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(obj), p2i(to->bottom()), p2i(to->end()));
print_object(gclog_or_tty, obj);
}
@ -740,14 +740,14 @@ public:
gclog_or_tty->print_cr("----------");
}
gclog_or_tty->print_cr("Missing rem set entry:");
gclog_or_tty->print_cr("Field "PTR_FORMAT" "
"of obj "PTR_FORMAT", "
"in region "HR_FORMAT,
gclog_or_tty->print_cr("Field " PTR_FORMAT " "
"of obj " PTR_FORMAT ", "
"in region " HR_FORMAT,
p2i(p), p2i(_containing_obj),
HR_FORMAT_PARAMS(from));
_containing_obj->print_on(gclog_or_tty);
gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
"in region "HR_FORMAT,
gclog_or_tty->print_cr("points to obj " PTR_FORMAT " "
"in region " HR_FORMAT,
p2i(obj),
HR_FORMAT_PARAMS(to));
obj->print_on(gclog_or_tty);
@ -783,8 +783,8 @@ void HeapRegion::verify(VerifyOption vo,
if (is_region_humongous != g1->is_humongous(obj_size) &&
!g1->is_obj_dead(obj, this)) { // Dead objects may have bigger block_size since they span several objects.
gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
SIZE_FORMAT" words) in a %shumongous region",
gclog_or_tty->print_cr("obj " PTR_FORMAT " is of %shumongous size ("
SIZE_FORMAT " words) in a %shumongous region",
p2i(p), g1->is_humongous(obj_size) ? "" : "non-",
obj_size, is_region_humongous ? "" : "non-");
*failures = true;
@ -798,12 +798,12 @@ void HeapRegion::verify(VerifyOption vo,
(vo == VerifyOption_G1UsePrevMarking &&
ClassLoaderDataGraph::unload_list_contains(klass));
if (!is_metaspace_object) {
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
"not metadata", p2i(klass), p2i(obj));
*failures = true;
return;
} else if (!klass->is_klass()) {
gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
"not a klass", p2i(klass), p2i(obj));
*failures = true;
return;
@ -819,7 +819,7 @@ void HeapRegion::verify(VerifyOption vo,
}
}
} else {
gclog_or_tty->print_cr(PTR_FORMAT" no an oop", p2i(obj));
gclog_or_tty->print_cr(PTR_FORMAT " no an oop", p2i(obj));
*failures = true;
return;
}
@ -833,8 +833,8 @@ void HeapRegion::verify(VerifyOption vo,
}
if (p != top()) {
gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
"does not match top "PTR_FORMAT, p2i(p), p2i(top()));
gclog_or_tty->print_cr("end of last object " PTR_FORMAT " "
"does not match top " PTR_FORMAT, p2i(p), p2i(top()));
*failures = true;
return;
}
@ -849,8 +849,8 @@ void HeapRegion::verify(VerifyOption vo,
HeapWord* addr_1 = p;
HeapWord* b_start_1 = _offsets.block_start_const(addr_1);
if (b_start_1 != p) {
gclog_or_tty->print_cr("BOT look up for top: "PTR_FORMAT" "
" yielded "PTR_FORMAT", expecting "PTR_FORMAT,
gclog_or_tty->print_cr("BOT look up for top: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_1), p2i(b_start_1), p2i(p));
*failures = true;
return;
@ -861,8 +861,8 @@ void HeapRegion::verify(VerifyOption vo,
if (addr_2 < the_end) {
HeapWord* b_start_2 = _offsets.block_start_const(addr_2);
if (b_start_2 != p) {
gclog_or_tty->print_cr("BOT look up for top + 1: "PTR_FORMAT" "
" yielded "PTR_FORMAT", expecting "PTR_FORMAT,
gclog_or_tty->print_cr("BOT look up for top + 1: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_2), p2i(b_start_2), p2i(p));
*failures = true;
return;
@ -875,8 +875,8 @@ void HeapRegion::verify(VerifyOption vo,
if (addr_3 < the_end) {
HeapWord* b_start_3 = _offsets.block_start_const(addr_3);
if (b_start_3 != p) {
gclog_or_tty->print_cr("BOT look up for top + diff: "PTR_FORMAT" "
" yielded "PTR_FORMAT", expecting "PTR_FORMAT,
gclog_or_tty->print_cr("BOT look up for top + diff: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_3), p2i(b_start_3), p2i(p));
*failures = true;
return;
@ -887,8 +887,8 @@ void HeapRegion::verify(VerifyOption vo,
HeapWord* addr_4 = the_end - 1;
HeapWord* b_start_4 = _offsets.block_start_const(addr_4);
if (b_start_4 != p) {
gclog_or_tty->print_cr("BOT look up for end - 1: "PTR_FORMAT" "
" yielded "PTR_FORMAT", expecting "PTR_FORMAT,
gclog_or_tty->print_cr("BOT look up for end - 1: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_4), p2i(b_start_4), p2i(p));
*failures = true;
return;
@ -896,8 +896,8 @@ void HeapRegion::verify(VerifyOption vo,
}
if (is_region_humongous && object_num > 1) {
gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
"but has "SIZE_FORMAT", objects",
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is humongous "
"but has " SIZE_FORMAT ", objects",
p2i(bottom()), p2i(end()), object_num);
*failures = true;
return;

View File

@ -51,7 +51,7 @@ class HeapRegion;
class HeapRegionSetBase;
class nmethod;
#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
#define HR_FORMAT "%u:(%s)[" PTR_FORMAT "," PTR_FORMAT "," PTR_FORMAT "]"
#define HR_FORMAT_PARAMS(_hr_) \
(_hr_)->hrm_index(), \
(_hr_)->get_short_type_str(), \
@ -538,8 +538,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
void set_containing_set(HeapRegionSetBase* containing_set) {
assert((containing_set == NULL && _containing_set != NULL) ||
(containing_set != NULL && _containing_set == NULL),
err_msg("containing_set: "PTR_FORMAT" "
"_containing_set: "PTR_FORMAT,
err_msg("containing_set: " PTR_FORMAT " "
"_containing_set: " PTR_FORMAT,
p2i(containing_set), p2i(_containing_set)));
_containing_set = containing_set;

View File

@ -113,7 +113,7 @@ HeapRegion::block_size(const HeapWord *addr) const {
assert(ClassUnloadingWithConcurrentMark,
err_msg("All blocks should be objects if G1 Class Unloading isn't used. "
"HR: ["PTR_FORMAT", "PTR_FORMAT", "PTR_FORMAT") "
"HR: [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ") "
"addr: " PTR_FORMAT,
p2i(bottom()), p2i(top()), p2i(end()), p2i(addr)));

View File

@ -486,7 +486,7 @@ void HeapRegionManager::verify() {
HeapRegion* hr = _regions.get_by_index(i);
guarantee(hr != NULL, err_msg("invariant: i: %u", i));
guarantee(!prev_committed || hr->bottom() == prev_end,
err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
err_msg("invariant i: %u " HR_FORMAT " prev_end: " PTR_FORMAT,
i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
guarantee(hr->hrm_index() == i,
err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index()));

View File

@ -31,9 +31,9 @@
inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
assert(addr < heap_end(),
err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end())));
err_msg("addr: " PTR_FORMAT " end: " PTR_FORMAT, p2i(addr), p2i(heap_end())));
assert(addr >= heap_bottom(),
err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
err_msg("addr: " PTR_FORMAT " bottom: " PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
HeapRegion* hr = _regions.get_by_address(addr);
return hr;

View File

@ -90,7 +90,7 @@ protected:
// concurrency.
if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print_cr(" PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
gclog_or_tty->print_cr(" PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
p2i(from),
UseCompressedOops
? p2i(oopDesc::load_decode_heap_oop((narrowOop*)from))
@ -376,7 +376,7 @@ void FromCardCache::initialize(uint n_par_rs, uint max_num_regions) {
void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
guarantee((size_t)start_idx + new_num_regions <= max_uintx,
err_msg("Trying to invalidate beyond maximum region, from %u size "SIZE_FORMAT,
err_msg("Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT,
start_idx, new_num_regions));
for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
uint end_idx = (start_idx + (uint)new_num_regions);
@ -630,13 +630,13 @@ void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
assert(_coarse_map.size() == region_bm->size(), "Precondition");
if (G1RSScrubVerbose) {
gclog_or_tty->print(" Coarse map: before = "SIZE_FORMAT"...",
gclog_or_tty->print(" Coarse map: before = " SIZE_FORMAT "...",
_n_coarse_entries);
}
_coarse_map.set_intersection(*region_bm);
_n_coarse_entries = _coarse_map.count_one_bits();
if (G1RSScrubVerbose) {
gclog_or_tty->print_cr(" after = "SIZE_FORMAT".", _n_coarse_entries);
gclog_or_tty->print_cr(" after = " SIZE_FORMAT ".", _n_coarse_entries);
}
// Now do the fine-grained maps.
@ -1013,7 +1013,7 @@ bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
card_index = _cur_region_card_offset + _cur_card_in_prt;
guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt));
err_msg("Card index " SIZE_FORMAT " must be within the region", _cur_card_in_prt));
return true;
}
@ -1182,8 +1182,8 @@ void PerRegionTable::test_fl_mem_size() {
size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;
assert(dummy->mem_size() > min_prt_size,
err_msg("PerRegionTable memory usage is suspiciously small, only has "SIZE_FORMAT" bytes. "
"Should be at least "SIZE_FORMAT" bytes.", dummy->mem_size(), min_prt_size));
err_msg("PerRegionTable memory usage is suspiciously small, only has " SIZE_FORMAT " bytes. "
"Should be at least " SIZE_FORMAT " bytes.", dummy->mem_size(), min_prt_size));
free(dummy);
guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
// try to reset the state

View File

@ -30,7 +30,7 @@
uint FreeRegionList::_unrealistically_long_length = 0;
void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
msg->append("[%s] %s ln: %u cy: "SIZE_FORMAT,
msg->append("[%s] %s ln: %u cy: " SIZE_FORMAT,
name(), message, length(), total_capacity_bytes());
fill_in_ext_msg_extra(msg);
}
@ -83,13 +83,13 @@ void HeapRegionSetBase::verify_end() {
void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
out->cr();
out->print_cr("Set: %s ("PTR_FORMAT")", name(), p2i(this));
out->print_cr("Set: %s (" PTR_FORMAT ")", name(), p2i(this));
out->print_cr(" Region Assumptions");
out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous()));
out->print_cr(" free : %s", BOOL_TO_STR(regions_free()));
out->print_cr(" Attributes");
out->print_cr(" length : %14u", length());
out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes",
out->print_cr(" total capacity : " SIZE_FORMAT_W(14) " bytes",
total_capacity_bytes());
}
@ -105,7 +105,7 @@ void FreeRegionList::set_unrealistically_long_length(uint len) {
}
void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, p2i(_head), p2i(_tail));
msg->append(" hd: " PTR_FORMAT " tl: " PTR_FORMAT, p2i(_head), p2i(_tail));
}
void FreeRegionList::remove_all() {
@ -276,8 +276,8 @@ void FreeRegionList::clear() {
void FreeRegionList::print_on(outputStream* out, bool print_contents) {
HeapRegionSetBase::print_on(out, print_contents);
out->print_cr(" Linking");
out->print_cr(" head : "PTR_FORMAT, p2i(_head));
out->print_cr(" tail : "PTR_FORMAT, p2i(_tail));
out->print_cr(" head : " PTR_FORMAT, p2i(_head));
out->print_cr(" tail : " PTR_FORMAT, p2i(_tail));
if (print_contents) {
out->print_cr(" Contents");
@ -305,7 +305,7 @@ void FreeRegionList::verify_list() {
count++;
guarantee(count < _unrealistically_long_length,
hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " "prev1: "PTR_FORMAT" length: %u",
hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: " PTR_FORMAT " prev0: " PTR_FORMAT " " "prev1: " PTR_FORMAT " length: %u",
name(), count, p2i(curr), p2i(prev0), p2i(prev1), length()));
if (curr->next() != NULL) {

View File

@ -200,8 +200,8 @@ void ObjPtrQueue::print(const char* name) {
void ObjPtrQueue::print(const char* name,
void** buf, size_t index, size_t sz) {
gclog_or_tty->print_cr(" SATB BUFFER [%s] buf: "PTR_FORMAT" "
"index: "SIZE_FORMAT" sz: "SIZE_FORMAT,
gclog_or_tty->print_cr(" SATB BUFFER [%s] buf: " PTR_FORMAT " "
"index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
name, p2i(buf), index, sz);
}
#endif // PRODUCT

View File

@ -85,7 +85,7 @@ void MutableNUMASpace::ensure_parsability() {
while (words_left_to_fill > 0) {
size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size());
assert(words_to_fill >= CollectedHeap::min_fill_size(),
err_msg("Remaining size ("SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
err_msg("Remaining size (" SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size()));
CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
if (!os::numa_has_static_binding()) {

View File

@ -65,9 +65,9 @@ class PSOldGen : public CHeapObj<mtGC> {
// Explictly capture current covered_region in a local
MemRegion covered_region = this->start_array()->covered_region();
assert(covered_region.contains(new_memregion),
err_msg("new region is not in covered_region [ "PTR_FORMAT", "PTR_FORMAT" ], "
"new region [ "PTR_FORMAT", "PTR_FORMAT" ], "
"object space [ "PTR_FORMAT", "PTR_FORMAT" ]",
err_msg("new region is not in covered_region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
"new region [ " PTR_FORMAT ", " PTR_FORMAT " ], "
"object space [ " PTR_FORMAT ", " PTR_FORMAT " ]",
p2i(covered_region.start()),
p2i(covered_region.end()),
p2i(new_memregion.start()),

Some files were not shown because too many files have changed in this diff Show More