--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 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();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CodeHeap.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/CodeHeap.java Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
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
//
--- a/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/aix/makefiles/mapfile-vers-product Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/aix/makefiles/mapfile-vers-product Thu Jul 16 19:28:37 2015 -0700
@@ -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;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/linux/makefiles/buildtree.make Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/linux/makefiles/buildtree.make Thu Jul 16 19:28:37 2015 -0700
@@ -118,7 +118,8 @@
$(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))
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/linux/makefiles/rules.make Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/linux/makefiles/rules.make Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
$(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 $@ $<
--- a/hotspot/make/linux/makefiles/vm.make Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Thu Jul 16 19:28:37 2015 -0700
@@ -54,7 +54,7 @@
# 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 @@
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 @@
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 @@
# 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 := ^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 $@
--- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Thu Jul 16 19:28:37 2015 -0700
@@ -141,6 +141,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;
--- a/hotspot/make/solaris/makefiles/vm.make Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/make/solaris/makefiles/vm.make Thu Jul 16 19:28:37 2015 -0700
@@ -143,7 +143,7 @@
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
--- a/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/assembler_aarch64.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -2270,17 +2270,21 @@
}
// CRC32 instructions
-#define INSN(NAME, sf, sz) \
+#define INSN(NAME, c, sf, sz) \
void NAME(Register Rd, Register Rn, Register Rm) { \
starti; \
- f(sf, 31), f(0b0011010110, 30, 21), f(0b0100, 15, 12), f(sz, 11, 10); \
- rf(Rm, 16), rf(Rn, 5), rf(Rd, 0); \
+ f(sf, 31), f(0b0011010110, 30, 21), f(0b010, 15, 13), f(c, 12); \
+ f(sz, 11, 10), rf(Rm, 16), rf(Rn, 5), rf(Rd, 0); \
}
- INSN(crc32b, 0, 0b00);
- INSN(crc32h, 0, 0b01);
- INSN(crc32w, 0, 0b10);
- INSN(crc32x, 1, 0b11);
+ INSN(crc32b, 0, 0, 0b00);
+ INSN(crc32h, 0, 0, 0b01);
+ INSN(crc32w, 0, 0, 0b10);
+ INSN(crc32x, 0, 1, 0b11);
+ INSN(crc32cb, 1, 0, 0b00);
+ INSN(crc32ch, 1, 0, 0b01);
+ INSN(crc32cw, 1, 0, 0b10);
+ INSN(crc32cx, 1, 1, 0b11);
#undef INSN
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,6 @@
const int StackAlignmentInBytes = 16;
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = true;
-
#define SUPPORTS_NATIVE_CX8
// The maximum B/BL offset range on AArch64 is 128MB.
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2914,6 +2914,65 @@
ornw(crc, zr, crc);
}
+/**
+ * @param crc register containing existing CRC (32-bit)
+ * @param buf register pointing to input byte buffer (byte*)
+ * @param len register containing number of bytes
+ * @param table register that will contain address of CRC table
+ * @param tmp scratch register
+ */
+void MacroAssembler::kernel_crc32c(Register crc, Register buf, Register len,
+ Register table0, Register table1, Register table2, Register table3,
+ Register tmp, Register tmp2, Register tmp3) {
+ Label L_exit;
+ Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop;
+
+ subs(len, len, 64);
+ br(Assembler::GE, CRC_by64_loop);
+ adds(len, len, 64-4);
+ br(Assembler::GE, CRC_by4_loop);
+ adds(len, len, 4);
+ br(Assembler::GT, CRC_by1_loop);
+ b(L_exit);
+
+ BIND(CRC_by4_loop);
+ ldrw(tmp, Address(post(buf, 4)));
+ subs(len, len, 4);
+ crc32cw(crc, crc, tmp);
+ br(Assembler::GE, CRC_by4_loop);
+ adds(len, len, 4);
+ br(Assembler::LE, L_exit);
+ BIND(CRC_by1_loop);
+ ldrb(tmp, Address(post(buf, 1)));
+ subs(len, len, 1);
+ crc32cb(crc, crc, tmp);
+ br(Assembler::GT, CRC_by1_loop);
+ b(L_exit);
+
+ align(CodeEntryAlignment);
+ BIND(CRC_by64_loop);
+ subs(len, len, 64);
+ ldp(tmp, tmp3, Address(post(buf, 16)));
+ crc32cx(crc, crc, tmp);
+ crc32cx(crc, crc, tmp3);
+ ldp(tmp, tmp3, Address(post(buf, 16)));
+ crc32cx(crc, crc, tmp);
+ crc32cx(crc, crc, tmp3);
+ ldp(tmp, tmp3, Address(post(buf, 16)));
+ crc32cx(crc, crc, tmp);
+ crc32cx(crc, crc, tmp3);
+ ldp(tmp, tmp3, Address(post(buf, 16)));
+ crc32cx(crc, crc, tmp);
+ crc32cx(crc, crc, tmp3);
+ br(Assembler::GE, CRC_by64_loop);
+ adds(len, len, 64-4);
+ br(Assembler::GE, CRC_by4_loop);
+ adds(len, len, 4);
+ br(Assembler::GT, CRC_by1_loop);
+ BIND(L_exit);
+ return;
+}
+
SkipIfEqual::SkipIfEqual(
MacroAssembler* masm, const bool* flag_addr, bool value) {
_masm = masm;
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -967,6 +967,10 @@
void kernel_crc32(Register crc, Register buf, Register len,
Register table0, Register table1, Register table2, Register table3,
Register tmp, Register tmp2, Register tmp3);
+ // CRC32 code for java.util.zip.CRC32C::updateBytes() instrinsic.
+ void kernel_crc32c(Register crc, Register buf, Register len,
+ Register table0, Register table1, Register table2, Register table3,
+ Register tmp, Register tmp2, Register tmp3);
#undef VIRTUAL
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2359,6 +2359,47 @@
/**
* Arguments:
*
+ * Inputs:
+ * c_rarg0 - int crc
+ * c_rarg1 - byte* buf
+ * c_rarg2 - int length
+ * c_rarg3 - int* table
+ *
+ * Ouput:
+ * rax - int crc result
+ */
+ address generate_updateBytesCRC32C() {
+ assert(UseCRC32CIntrinsics, "what are we doing here?");
+
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C");
+
+ address start = __ pc();
+
+ const Register crc = c_rarg0; // crc
+ const Register buf = c_rarg1; // source java byte array address
+ const Register len = c_rarg2; // length
+ const Register table0 = c_rarg3; // crc_table address
+ const Register table1 = c_rarg4;
+ const Register table2 = c_rarg5;
+ const Register table3 = c_rarg6;
+ const Register tmp3 = c_rarg7;
+
+ BLOCK_COMMENT("Entry:");
+ __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+ __ kernel_crc32c(crc, buf, len,
+ table0, table1, table2, table3, rscratch1, rscratch2, tmp3);
+
+ __ leave(); // required for proper stackwalking of RuntimeStub frame
+ __ ret(lr);
+
+ return start;
+ }
+
+ /**
+ * Arguments:
+ *
* Input:
* c_rarg0 - x address
* c_rarg1 - x length
@@ -2579,6 +2620,10 @@
StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true, "sha256_implCompressMB");
}
+ if (UseCRC32CIntrinsics) {
+ StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
+ }
+
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -199,9 +199,12 @@
UseCRC32Intrinsics = true;
}
- if (UseCRC32CIntrinsics) {
- if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics))
- warning("CRC32C intrinsics are not available on this CPU");
+ if (auxv & HWCAP_CRC32) {
+ if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
+ FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
+ }
+ } else if (UseCRC32CIntrinsics) {
+ warning("CRC32C is not available on the CPU");
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
}
@@ -214,34 +217,31 @@
FLAG_SET_DEFAULT(UseSHA, false);
}
- if (!UseSHA) {
+ if (UseSHA && (auxv & HWCAP_SHA1)) {
+ if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
+ }
+ } else if (UseSHA1Intrinsics) {
+ warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
- } else {
- if (auxv & HWCAP_SHA1) {
- if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
- }
- } else if (UseSHA1Intrinsics) {
- warning("SHA1 instruction is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+ }
+
+ if (UseSHA && (auxv & HWCAP_SHA2)) {
+ if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
}
- if (auxv & HWCAP_SHA2) {
- if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
- }
- } else if (UseSHA256Intrinsics) {
- warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
- }
- if (UseSHA512Intrinsics) {
- warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
- }
- if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA, false);
- }
+ } else if (UseSHA256Intrinsics) {
+ warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
+ FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+ }
+
+ if (UseSHA512Intrinsics) {
+ warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+ }
+
+ if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA, false);
}
// This machine allows unaligned memory accesses
--- a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -105,7 +105,7 @@
__ 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 @@
__ 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()));
--- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,12 +31,6 @@
const int StackAlignmentInBytes = 16;
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = true;
-
#define SUPPORTS_NATIVE_CX8
// The PPC CPUs are NOT multiple-copy-atomic.
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -465,7 +465,7 @@
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) {
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -731,23 +731,8 @@
case T_SHORT:
case T_INT:
// We must cast ints to longs and use full 64 bit stack slots
- // here. We do the cast in GraphKit::gen_stub() and just guard
- // here against loosing that change.
- assert(CCallingConventionRequiresIntsAsLongs,
- "argument of type int should be promoted to type long");
- guarantee(i > 0 && sig_bt[i-1] == T_LONG,
- "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
- "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
- // Do not count halves.
- regs[i].set_bad();
- --arg;
- break;
+ // here. Thus fall through, handle as long.
case T_LONG:
- guarantee(sig_bt[i+1] == T_VOID ||
- sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR ||
- sig_bt[i+1] == T_BYTE || sig_bt[i+1] == T_SHORT ||
- sig_bt[i+1] == T_INT,
- "expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
case T_OBJECT:
case T_ARRAY:
case T_ADDRESS:
@@ -1273,7 +1258,7 @@
static void int_move(MacroAssembler*masm,
VMRegPair src, VMRegPair dst,
Register r_caller_sp, Register r_temp) {
- assert(src.first()->is_valid() && src.second() == src.first()->next(), "incoming must be long-int");
+ assert(src.first()->is_valid(), "incoming must be int");
assert(dst.first()->is_valid() && dst.second() == dst.first()->next(), "outgoing must be long");
if (src.first()->is_stack()) {
@@ -1762,13 +1747,6 @@
// the jni function will expect them. To figure out where they go
// we convert the java signature to a C signature by inserting
// the hidden arguments as arg[0] and possibly arg[1] (static method)
- //
- // Additionally, on ppc64 we must convert integers to longs in the C
- // signature. We do this in advance in order to have no trouble with
- // indexes into the bt-arrays.
- // So convert the signature and registers now, and adjust the total number
- // of in-arguments accordingly.
- int i2l_argcnt = convert_ints_to_longints_argcnt(total_in_args, in_sig_bt); // PPC64: pass ints as longs.
// Calculate the total number of C arguments and create arrays for the
// signature and the outgoing registers.
@@ -1776,7 +1754,7 @@
// some floating-point arguments must be passed in registers _and_
// in stack locations.
bool method_is_static = method->is_static();
- int total_c_args = i2l_argcnt;
+ int total_c_args = total_in_args;
if (!is_critical_native) {
int n_hidden_args = method_is_static ? 2 : 1;
@@ -1785,7 +1763,7 @@
// No JNIEnv*, no this*, but unpacked arrays (base+length).
for (int i = 0; i < total_in_args; i++) {
if (in_sig_bt[i] == T_ARRAY) {
- total_c_args += 2; // PPC64: T_LONG, T_INT, T_ADDRESS (see convert_ints_to_longints and c_calling_convention)
+ total_c_args++;
}
}
}
@@ -1803,8 +1781,6 @@
int argc = 0;
if (!is_critical_native) {
- convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
-
out_sig_bt[argc++] = T_ADDRESS;
if (method->is_static()) {
out_sig_bt[argc++] = T_OBJECT;
@@ -1815,7 +1791,7 @@
}
} else {
Thread* THREAD = Thread::current();
- in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
+ in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
SignatureStream ss(method->signature());
int o = 0;
for (int i = 0; i < total_in_args ; i++, o++) {
@@ -1839,28 +1815,16 @@
}
} else {
in_elem_bt[o] = T_VOID;
- switch(in_sig_bt[i]) { // PPC64: pass ints as longs.
- case T_BOOLEAN:
- case T_CHAR:
- case T_BYTE:
- case T_SHORT:
- case T_INT: in_elem_bt[++o] = T_VOID; break;
- default: break;
- }
}
if (in_sig_bt[i] != T_VOID) {
assert(in_sig_bt[i] == ss.type(), "must match");
ss.next();
}
}
- assert(i2l_argcnt==o, "must match");
-
- convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
for (int i = 0; i < total_in_args ; i++ ) {
if (in_sig_bt[i] == T_ARRAY) {
// Arrays are passed as int, elem* pair.
- out_sig_bt[argc++] = T_LONG; // PPC64: pass ints as longs.
out_sig_bt[argc++] = T_INT;
out_sig_bt[argc++] = T_ADDRESS;
} else {
@@ -1921,7 +1885,8 @@
case T_BYTE:
case T_SHORT:
case T_CHAR:
- case T_INT: /*single_slots++;*/ break; // PPC64: pass ints as longs.
+ case T_INT:
+ // Fall through.
case T_ARRAY:
case T_LONG: double_slots++; break;
default: ShouldNotReachHere();
@@ -2019,7 +1984,7 @@
__ save_LR_CR(r_temp_1);
__ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
- __ mr(r_callers_sp, R1_SP); // Remember frame pointer.
+ __ mr(r_callers_sp, R1_SP); // Remember frame pointer.
__ push_frame(frame_size_in_bytes, r_temp_1); // Push the c2n adapter's frame.
frame_done_pc = (intptr_t)__ pc();
@@ -2098,24 +2063,16 @@
case T_BYTE:
case T_SHORT:
case T_INT:
- guarantee(in > 0 && in_sig_bt[in-1] == T_LONG,
- "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
+ // Move int and do sign extension.
+ int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
break;
case T_LONG:
- if (in_sig_bt[in+1] == T_VOID) {
- long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
- } else {
- guarantee(in_sig_bt[in+1] == T_BOOLEAN || in_sig_bt[in+1] == T_CHAR ||
- in_sig_bt[in+1] == T_BYTE || in_sig_bt[in+1] == T_SHORT ||
- in_sig_bt[in+1] == T_INT,
- "expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
- int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
- }
+ long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
break;
case T_ARRAY:
if (is_critical_native) {
int body_arg = out;
- out -= 2; // Point to length arg. PPC64: pass ints as longs.
+ out -= 1; // Point to length arg.
unpack_array_argument(masm, in_regs[in], in_elem_bt[in], out_regs[body_arg], out_regs[out],
r_callers_sp, r_temp_1, r_temp_2);
break;
@@ -2187,7 +2144,6 @@
// Make sure that thread is non-volatile; it crosses a bunch of VM calls below.
assert(R16_thread->is_nonvolatile(), "thread must be in non-volatile register");
-
# if 0
// DTrace method entry
# endif
--- a/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -30,12 +30,6 @@
const int StackAlignmentInBytes = (2*wordSize);
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
#define SUPPORTS_NATIVE_CX8
// The expected size in bytes of a cache line, used to pad data structures.
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -483,7 +483,7 @@
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));
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -329,39 +329,35 @@
FLAG_SET_DEFAULT(UseSHA, false);
}
- if (!UseSHA) {
+ if (UseSHA && has_sha1()) {
+ if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
+ }
+ } else if (UseSHA1Intrinsics) {
+ warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
- } else {
- if (has_sha1()) {
- if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
- }
- } else if (UseSHA1Intrinsics) {
- warning("SHA1 instruction is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+ }
+
+ if (UseSHA && has_sha256()) {
+ if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
}
- if (has_sha256()) {
- if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
- }
- } else if (UseSHA256Intrinsics) {
- warning("SHA256 instruction (for SHA-224 and SHA-256) is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
- }
+ } else if (UseSHA256Intrinsics) {
+ warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
+ FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+ }
- if (has_sha512()) {
- if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
- }
- } else if (UseSHA512Intrinsics) {
- warning("SHA512 instruction (for SHA-384 and SHA-512) is not available on this CPU.");
- FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+ if (UseSHA && has_sha512()) {
+ if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
}
- if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
- FLAG_SET_DEFAULT(UseSHA, false);
- }
+ } else if (UseSHA512Intrinsics) {
+ warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
+ FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
+ }
+
+ if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) {
+ FLAG_SET_DEFAULT(UseSHA, false);
}
// SPARC T4 and above should have support for CRC32C instruction
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -110,7 +110,7 @@
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 @@
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()));
--- a/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -27,12 +27,6 @@
const int StackAlignmentInBytes = 16;
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
#define SUPPORTS_NATIVE_CX8
// The expected size in bytes of a cache line, used to pad data structures.
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -5152,7 +5152,7 @@
{
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);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -484,7 +484,7 @@
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);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -23,6 +23,9 @@
*/
#include "precompiled.hpp"
+#ifndef _WINDOWS
+#include "alloca.h"
+#endif
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "code/debugInfoRec.hpp"
@@ -3511,6 +3514,250 @@
}
+//------------------------------Montgomery multiplication------------------------
+//
+
+#ifndef _WINDOWS
+
+#define ASM_SUBTRACT
+
+#ifdef ASM_SUBTRACT
+// Subtract 0:b from carry:a. Return carry.
+static unsigned long
+sub(unsigned long a[], unsigned long b[], unsigned long carry, long len) {
+ long i = 0, cnt = len;
+ unsigned long tmp;
+ asm volatile("clc; "
+ "0: ; "
+ "mov (%[b], %[i], 8), %[tmp]; "
+ "sbb %[tmp], (%[a], %[i], 8); "
+ "inc %[i]; dec %[cnt]; "
+ "jne 0b; "
+ "mov %[carry], %[tmp]; sbb $0, %[tmp]; "
+ : [i]"+r"(i), [cnt]"+r"(cnt), [tmp]"=&r"(tmp)
+ : [a]"r"(a), [b]"r"(b), [carry]"r"(carry)
+ : "memory");
+ return tmp;
+}
+#else // ASM_SUBTRACT
+typedef int __attribute__((mode(TI))) int128;
+
+// Subtract 0:b from carry:a. Return carry.
+static unsigned long
+sub(unsigned long a[], unsigned long b[], unsigned long carry, int len) {
+ int128 tmp = 0;
+ int i;
+ for (i = 0; i < len; i++) {
+ tmp += a[i];
+ tmp -= b[i];
+ a[i] = tmp;
+ tmp >>= 64;
+ assert(-1 <= tmp && tmp <= 0, "invariant");
+ }
+ return tmp + carry;
+}
+#endif // ! ASM_SUBTRACT
+
+// Multiply (unsigned) Long A by Long B, accumulating the double-
+// length result into the accumulator formed of T0, T1, and T2.
+#define MACC(A, B, T0, T1, T2) \
+do { \
+ unsigned long hi, lo; \
+ __asm__ ("mul %5; add %%rax, %2; adc %%rdx, %3; adc $0, %4" \
+ : "=&d"(hi), "=a"(lo), "+r"(T0), "+r"(T1), "+g"(T2) \
+ : "r"(A), "a"(B) : "cc"); \
+ } while(0)
+
+// As above, but add twice the double-length result into the
+// accumulator.
+#define MACC2(A, B, T0, T1, T2) \
+do { \
+ unsigned long hi, lo; \
+ __asm__ ("mul %5; add %%rax, %2; adc %%rdx, %3; adc $0, %4; " \
+ "add %%rax, %2; adc %%rdx, %3; adc $0, %4" \
+ : "=&d"(hi), "=a"(lo), "+r"(T0), "+r"(T1), "+g"(T2) \
+ : "r"(A), "a"(B) : "cc"); \
+ } while(0)
+
+// Fast Montgomery multiplication. The derivation of the algorithm is
+// in A Cryptographic Library for the Motorola DSP56000,
+// Dusse and Kaliski, Proc. EUROCRYPT 90, pp. 230-237.
+
+static void __attribute__((noinline))
+montgomery_multiply(unsigned long a[], unsigned long b[], unsigned long n[],
+ unsigned long m[], unsigned long inv, int len) {
+ unsigned long t0 = 0, t1 = 0, t2 = 0; // Triple-precision accumulator
+ int i;
+
+ assert(inv * n[0] == -1UL, "broken inverse in Montgomery multiply");
+
+ for (i = 0; i < len; i++) {
+ int j;
+ for (j = 0; j < i; j++) {
+ MACC(a[j], b[i-j], t0, t1, t2);
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ MACC(a[i], b[0], t0, t1, t2);
+ m[i] = t0 * inv;
+ MACC(m[i], n[0], t0, t1, t2);
+
+ assert(t0 == 0, "broken Montgomery multiply");
+
+ t0 = t1; t1 = t2; t2 = 0;
+ }
+
+ for (i = len; i < 2*len; i++) {
+ int j;
+ for (j = i-len+1; j < len; j++) {
+ MACC(a[j], b[i-j], t0, t1, t2);
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ m[i-len] = t0;
+ t0 = t1; t1 = t2; t2 = 0;
+ }
+
+ while (t0)
+ t0 = sub(m, n, t0, len);
+}
+
+// Fast Montgomery squaring. This uses asymptotically 25% fewer
+// multiplies so it should be up to 25% faster than Montgomery
+// multiplication. However, its loop control is more complex and it
+// may actually run slower on some machines.
+
+static void __attribute__((noinline))
+montgomery_square(unsigned long a[], unsigned long n[],
+ unsigned long m[], unsigned long inv, int len) {
+ unsigned long t0 = 0, t1 = 0, t2 = 0; // Triple-precision accumulator
+ int i;
+
+ assert(inv * n[0] == -1UL, "broken inverse in Montgomery multiply");
+
+ for (i = 0; i < len; i++) {
+ int j;
+ int end = (i+1)/2;
+ for (j = 0; j < end; j++) {
+ MACC2(a[j], a[i-j], t0, t1, t2);
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ if ((i & 1) == 0) {
+ MACC(a[j], a[j], t0, t1, t2);
+ }
+ for (; j < i; j++) {
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ m[i] = t0 * inv;
+ MACC(m[i], n[0], t0, t1, t2);
+
+ assert(t0 == 0, "broken Montgomery square");
+
+ t0 = t1; t1 = t2; t2 = 0;
+ }
+
+ for (i = len; i < 2*len; i++) {
+ int start = i-len+1;
+ int end = start + (len - start)/2;
+ int j;
+ for (j = start; j < end; j++) {
+ MACC2(a[j], a[i-j], t0, t1, t2);
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ if ((i & 1) == 0) {
+ MACC(a[j], a[j], t0, t1, t2);
+ }
+ for (; j < len; j++) {
+ MACC(m[j], n[i-j], t0, t1, t2);
+ }
+ m[i-len] = t0;
+ t0 = t1; t1 = t2; t2 = 0;
+ }
+
+ while (t0)
+ t0 = sub(m, n, t0, len);
+}
+
+// Swap words in a longword.
+static unsigned long swap(unsigned long x) {
+ return (x << 32) | (x >> 32);
+}
+
+// Copy len longwords from s to d, word-swapping as we go. The
+// destination array is reversed.
+static void reverse_words(unsigned long *s, unsigned long *d, int len) {
+ d += len;
+ while(len-- > 0) {
+ d--;
+ *d = swap(*s);
+ s++;
+ }
+}
+
+// The threshold at which squaring is advantageous was determined
+// experimentally on an i7-3930K (Ivy Bridge) CPU @ 3.5GHz.
+#define MONTGOMERY_SQUARING_THRESHOLD 64
+
+void SharedRuntime::montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints,
+ jint len, jlong inv,
+ jint *m_ints) {
+ assert(len % 2 == 0, "array length in montgomery_multiply must be even");
+ int longwords = len/2;
+
+ // Make very sure we don't use so much space that the stack might
+ // overflow. 512 jints corresponds to an 16384-bit integer and
+ // will use here a total of 8k bytes of stack space.
+ int total_allocation = longwords * sizeof (unsigned long) * 4;
+ guarantee(total_allocation <= 8192, "must be");
+ unsigned long *scratch = (unsigned long *)alloca(total_allocation);
+
+ // Local scratch arrays
+ unsigned long
+ *a = scratch + 0 * longwords,
+ *b = scratch + 1 * longwords,
+ *n = scratch + 2 * longwords,
+ *m = scratch + 3 * longwords;
+
+ reverse_words((unsigned long *)a_ints, a, longwords);
+ reverse_words((unsigned long *)b_ints, b, longwords);
+ reverse_words((unsigned long *)n_ints, n, longwords);
+
+ ::montgomery_multiply(a, b, n, m, (unsigned long)inv, longwords);
+
+ reverse_words(m, (unsigned long *)m_ints, longwords);
+}
+
+void SharedRuntime::montgomery_square(jint *a_ints, jint *n_ints,
+ jint len, jlong inv,
+ jint *m_ints) {
+ assert(len % 2 == 0, "array length in montgomery_square must be even");
+ int longwords = len/2;
+
+ // Make very sure we don't use so much space that the stack might
+ // overflow. 512 jints corresponds to an 16384-bit integer and
+ // will use here a total of 6k bytes of stack space.
+ int total_allocation = longwords * sizeof (unsigned long) * 3;
+ guarantee(total_allocation <= 8192, "must be");
+ unsigned long *scratch = (unsigned long *)alloca(total_allocation);
+
+ // Local scratch arrays
+ unsigned long
+ *a = scratch + 0 * longwords,
+ *n = scratch + 1 * longwords,
+ *m = scratch + 2 * longwords;
+
+ reverse_words((unsigned long *)a_ints, a, longwords);
+ reverse_words((unsigned long *)n_ints, n, longwords);
+
+ if (len >= MONTGOMERY_SQUARING_THRESHOLD) {
+ ::montgomery_square(a, n, m, (unsigned long)inv, longwords);
+ } else {
+ ::montgomery_multiply(a, a, n, m, (unsigned long)inv, longwords);
+ }
+
+ reverse_words(m, (unsigned long *)m_ints, longwords);
+}
+
+#endif // WINDOWS
+
#ifdef COMPILER2
// This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
//
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -4318,7 +4318,18 @@
if (UseMulAddIntrinsic) {
StubRoutines::_mulAdd = generate_mulAdd();
}
-#endif
+
+#ifndef _WINDOWS
+ if (UseMontgomeryMultiplyIntrinsic) {
+ StubRoutines::_montgomeryMultiply
+ = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_multiply);
+ }
+ if (UseMontgomerySquareIntrinsic) {
+ StubRoutines::_montgomerySquare
+ = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square);
+ }
+#endif // WINDOWS
+#endif // COMPILER2
}
public:
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -692,10 +692,19 @@
warning("SHA instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseSHA, false);
}
- if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) {
- warning("SHA intrinsics are not available on this CPU");
+
+ if (UseSHA1Intrinsics) {
+ warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
+ }
+
+ if (UseSHA256Intrinsics) {
+ warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
+ }
+
+ if (UseSHA512Intrinsics) {
+ warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
}
@@ -813,6 +822,12 @@
if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
UseMulAddIntrinsic = true;
}
+ if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
+ UseMontgomeryMultiplyIntrinsic = true;
+ }
+ if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
+ UseMontgomerySquareIntrinsic = true;
+ }
#else
if (UseMultiplyToLenIntrinsic) {
if (!FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
@@ -820,6 +835,18 @@
}
FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, false);
}
+ if (UseMontgomeryMultiplyIntrinsic) {
+ if (!FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
+ warning("montgomeryMultiply intrinsic is not available in 32-bit VM");
+ }
+ FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, false);
+ }
+ if (UseMontgomerySquareIntrinsic) {
+ if (!FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
+ warning("montgomerySquare intrinsic is not available in 32-bit VM");
+ }
+ FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, false);
+ }
if (UseSquareToLenIntrinsic) {
if (!FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
warning("squareToLen intrinsic is not available in 32-bit VM");
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -117,7 +117,7 @@
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 @@
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()));
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -112,7 +112,7 @@
__ 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 @@
__ 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()));
--- a/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2015, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,4 @@
#include <ffi.h>
-// Indicates whether the C calling conventions require that
-// 32-bit integer argument values are properly extended to 64 bits.
-// If set, SharedRuntime::c_calling_convention() must adapt
-// signatures accordingly.
-const bool CCallingConventionRequiresIntsAsLongs = false;
-
#endif // CPU_ZERO_VM_GLOBALDEFINITIONS_ZERO_HPP
--- a/hotspot/src/os/bsd/vm/jsig.c Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/bsd/vm/jsig.c Thu Jul 16 19:28:37 2015 -0700
@@ -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 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 @@
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 @@
bool sigused;
struct sigaction oldAct;
+ if (reentry) {
+ return call_os_sigaction(sig, act, oact);
+ }
+
signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0;
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
#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;
-};
-
-Semaphore::Semaphore() : _semaphore(0) {
- SEM_INIT(_semaphore, 0);
+#ifdef __APPLE__
+// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
+
+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 @@
}
#else
-
-bool Semaphore::trywait() {
- return sem_trywait(&_semaphore) == 0;
-}
-
-bool Semaphore::timedwait(unsigned int sec, int nsec) {
+// Use POSIX implementation of semaphores.
+
+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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/bsd/vm/semaphore_bsd.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
}
}
- 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 @@
// 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
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
}
}
}
+
+#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__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/posix/vm/semaphore_posix.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
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
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
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 @@
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 @@
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));
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/semaphore_windows.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -191,7 +191,7 @@
return CPUVisitor::visit(nodeh, state);
}
- PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
+ PICL(bool is_fujitsu, bool is_sun4v) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
if (!open_library()) {
return;
}
@@ -203,7 +203,7 @@
if (is_fujitsu) {
cpu_class = "core";
}
- CPUVisitor cpu_visitor(this, os::processor_count());
+ CPUVisitor cpu_visitor(this, (is_sun4v && !is_fujitsu) ? 1 : os::processor_count());
_picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
_L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
@@ -447,7 +447,7 @@
}
// Figure out cache line sizes using PICL
- PICL picl((features & sparc64_family_m) != 0);
+ PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);
_L1_data_cache_line_size = picl.L1_data_cache_line_size();
_L2_data_cache_line_size = picl.L2_data_cache_line_size();
--- a/hotspot/src/share/tools/hsdis/Makefile Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/tools/hsdis/Makefile Thu Jul 16 19:28:37 2015 -0700
@@ -70,7 +70,8 @@
else #linux
CPU = $(shell uname -m)
ARCH1=$(CPU:x86_64=amd64)
-ARCH=$(ARCH1:i686=i386)
+ARCH2=$(ARCH1:i686=i386)
+ARCH=$(ARCH2:ppc64le=ppc64)
ifdef LP64
CFLAGS/sparcv9 += -m64
CFLAGS/amd64 += -m64
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1093,9 +1093,11 @@
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 @@
}
}
+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();
}
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
// 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,13 +290,20 @@
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
+ }
};
// A CodeBuffer describes a memory space into which assembly
@@ -379,6 +387,7 @@
_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 @@
// 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);
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -161,7 +161,7 @@
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");
}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -3157,6 +3157,9 @@
// code for the inlined version will be different than the root
// compiled version which could lead to monotonicity problems on
// intel.
+ if (CheckIntrinsics && !scope->method()->intrinsic_candidate()) {
+ BAILOUT("failed to inline intrinsic, method not annotated");
+ }
// Set up a stream so that appending instructions works properly.
ciBytecodeStream s(scope->method());
@@ -3197,6 +3200,9 @@
// result in the referent being marked live and the reference
// object removed from the list of discovered references during
// reference processing.
+ if (CheckIntrinsics && !scope->method()->intrinsic_candidate()) {
+ BAILOUT("failed to inline intrinsic, method not annotated");
+ }
// Also we need intrinsic to prevent commoning reads from this field
// across safepoint since GC can change its value.
@@ -3317,7 +3323,8 @@
}
// handle intrinsics
- if (callee->intrinsic_id() != vmIntrinsics::_none) {
+ if (callee->intrinsic_id() != vmIntrinsics::_none &&
+ (CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
if (try_inline_intrinsics(callee)) {
print_inlining(callee, "intrinsic");
return true;
@@ -4278,7 +4285,7 @@
assert(result_type->is_int(), "int result");
Values* args = state()->pop_arguments(callee->arg_size());
- // Pop off some args to speically handle, then push back
+ // Pop off some args to specially handle, then push back
Value newval = args->pop();
Value cmpval = args->pop();
Value offset = args->pop();
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2208,7 +2208,15 @@
if (log2_scale != 0) {
// temporary fix (platform dependent code without shift on Intel would be better)
// TODO: ARM also allows embedded shift in the address
- __ shift_left(index_op, log2_scale, index_op);
+ LIR_Opr tmp = new_pointer_register();
+ if (TwoOperandLIRForm) {
+ __ move(index_op, tmp);
+ index_op = tmp;
+ }
+ __ shift_left(index_op, log2_scale, tmp);
+ if (!TwoOperandLIRForm) {
+ index_op = tmp;
+ }
}
LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
// create code buffer for code storage
CodeBuffer code(buffer_blob);
- Compilation::setup_code_buffer(&code, 0);
+ OopMapSet* oop_maps;
+ int frame_size;
+ bool must_gc_arguments;
- // 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");
+ 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 @@
#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 @@
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;
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1185,7 +1185,6 @@
vmIntrinsics::ID iid = method()->intrinsic_id();
if (iid == vmIntrinsics::_getClass ||
- iid == vmIntrinsics::_fillInStackTrace ||
iid == vmIntrinsics::_hashCode)
return iid;
else
@@ -1199,10 +1198,6 @@
case vmIntrinsics::_getClass:
_return_local = false;
break;
- case vmIntrinsics::_fillInStackTrace:
- arg.set(0); // 'this'
- set_returned(arg);
- break;
case vmIntrinsics::_hashCode:
// initialized state is correct
break;
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -178,9 +178,10 @@
// Code size for inlining decisions.
int code_size_for_inlining();
- bool caller_sensitive() const { return get_Method()->caller_sensitive(); }
- bool force_inline() const { return get_Method()->force_inline(); }
- bool dont_inline() const { return get_Method()->dont_inline(); }
+ bool caller_sensitive() const { return get_Method()->caller_sensitive(); }
+ bool force_inline() const { return get_Method()->force_inline(); }
+ bool dont_inline() const { return get_Method()->dont_inline(); }
+ bool intrinsic_candidate() const { return get_Method()->intrinsic_candidate(); }
int comp_level();
int highest_osr_comp_level();
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1751,6 +1751,10 @@
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Hidden;
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_HotSpotIntrinsicCandidate_signature):
+ if (_location != _in_method) break; // only allow for methods
+ if (!privileged) break; // only allow in privileged code
+ return _method_HotSpotIntrinsicCandidate;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature):
if (_location != _in_field) break; // only allow for fields
if (!privileged) break; // only allow in privileged code
@@ -1790,6 +1794,8 @@
m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
if (has_annotation(_method_LambdaForm_Hidden))
m->set_hidden(true);
+ if (has_annotation(_method_HotSpotIntrinsicCandidate) && !m->is_synthetic())
+ m->set_intrinsic_candidate(true);
}
void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
@@ -4132,9 +4138,78 @@
// (We used to do this lazily, but now we query it in Rewriter,
// which is eagerly done for every method, so we might as well do it now,
// when everything is fresh in memory.)
- if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) {
+ vmSymbols::SID klass_id = Method::klass_id_for_intrinsics(this_klass());
+ if (klass_id != vmSymbols::NO_SID) {
for (int j = 0; j < methods->length(); j++) {
- methods->at(j)->init_intrinsic_id();
+ Method* method = methods->at(j);
+ method->init_intrinsic_id();
+
+ if (CheckIntrinsics) {
+ // Check if an intrinsic is defined for method 'method',
+ // but the method is not annotated with @HotSpotIntrinsicCandidate.
+ if (method->intrinsic_id() != vmIntrinsics::_none &&
+ !method->intrinsic_candidate()) {
+ tty->print("Compiler intrinsic is defined for method [%s], "
+ "but the method is not annotated with @HotSpotIntrinsicCandidate.%s",
+ method->name_and_sig_as_C_string(),
+ NOT_DEBUG(" Method will not be inlined.") DEBUG_ONLY(" Exiting.")
+ );
+ tty->cr();
+ DEBUG_ONLY(vm_exit(1));
+ }
+ // Check is the method 'method' is annotated with @HotSpotIntrinsicCandidate,
+ // but there is no intrinsic available for it.
+ if (method->intrinsic_candidate() &&
+ method->intrinsic_id() == vmIntrinsics::_none) {
+ tty->print("Method [%s] is annotated with @HotSpotIntrinsicCandidate, "
+ "but no compiler intrinsic is defined for the method.%s",
+ method->name_and_sig_as_C_string(),
+ NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
+ );
+ tty->cr();
+ DEBUG_ONLY(vm_exit(1));
+ }
+ }
+ }
+
+ if (CheckIntrinsics) {
+ // Check for orphan methods in the current class. A method m
+ // of a class C is orphan if an intrinsic is defined for method m,
+ // but class C does not declare m.
+
+ for (int id = vmIntrinsics::FIRST_ID; id < (int)vmIntrinsics::ID_LIMIT; id++) {
+ if (id == vmIntrinsics::_compiledLambdaForm) {
+ // The _compiledLamdbdaForm intrinsic is a special marker for bytecode
+ // generated for the JVM from a LambdaForm and therefore no method
+ // is defined for it.
+ continue;
+ }
+
+ if (vmIntrinsics::class_for(vmIntrinsics::ID_from(id)) == klass_id) {
+ // Check if the current class contains a method with the same
+ // name, flags, signature.
+ bool match = false;
+ for (int j = 0; j < methods->length(); j++) {
+ Method* method = methods->at(j);
+ if (id == method->intrinsic_id()) {
+ match = true;
+ break;
+ }
+ }
+
+ if (!match) {
+ char buf[1000];
+ tty->print("Compiler intrinsic is defined for method [%s], "
+ "but the method is not available in class [%s].%s",
+ vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID_from(id), buf, sizeof(buf)),
+ this_klass->name()->as_C_string(),
+ NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
+ );
+ tty->cr();
+ DEBUG_ONLY(vm_exit(1));
+ }
+ }
+ }
}
}
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -130,6 +130,7 @@
_method_InjectedProfile,
_method_LambdaForm_Compiled,
_method_LambdaForm_Hidden,
+ _method_HotSpotIntrinsicCandidate,
_sun_misc_Contended,
_field_Stable,
_annotation_LIMIT
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
}
-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 @@
}
}
-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;
-}
-
-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;
-}
+ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) :
+ ClassPathEntry(),
+ _image(image),
+ _module_data(NULL) {
+ guarantee(image != NULL, "image file is null");
-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 @@
}
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 (!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) {
- if (buffer) {
+ 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 @@
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 @@
}
bool ClassPathImageEntry::is_jrt() {
- return string_ends_with(name(), "bootmodules.jimage");
+ return string_ends_with(name(), BOOT_IMAGE_NAME);
}
#endif
@@ -539,11 +486,8 @@
}
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,38 +501,38 @@
return NULL;
}
}
- // TODO - add proper criteria for selecting image file
- ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
- if (entry->is_open()) {
- new_entry = entry;
- } 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);
+ ImageFileReader* image = ImageFileReader::open(canonical_path);
+ if (image != NULL) {
+ new_entry = new ClassPathImageEntry(image);
} 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);
+ 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 {
- 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);
+ 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 (throw_exception) {
- THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
- } else {
- return NULL;
- }
- }
}
if (TraceClassLoading || TraceClassPaths) {
tty->print_cr("[Opened %s]", path);
@@ -666,7 +610,7 @@
// 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 @@
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);
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
}
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 @@
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 @@
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 @@
};
-// 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 @@
package_hash_table_size = 31 // Number of buckets
};
protected:
- friend class LazyClassPathEntry;
// Performance counters
static PerfCounter* _perf_accumulated_time;
@@ -222,7 +207,7 @@
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
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -494,7 +494,7 @@
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 @@
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();
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -557,7 +557,7 @@
}
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
--- a/hotspot/src/share/vm/classfile/dictionary.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -370,7 +370,7 @@
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) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/imageDecompressor.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/imageDecompressor.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/src/share/vm/classfile/imageFile.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/imageFile.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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"
-// Compute the Perfect Hashing hash code for the supplied string.
-u4 ImageStrings::hash_code(const char* string, u4 seed) {
+// 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 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) {
+// 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);
+ _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 @@
(_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;
}
+}
+// 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;
}
-// 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;
+// 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);
}
-
- 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;
-}
-
-// 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.
- 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.
- 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.
- const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
- next = ImageStrings::starts_with(next, extension);
-
- // True only if complete match and no more characters.
- return next && *next == '\0';
+ return false;
}
-// Return the resource for the supplied location.
-u1* ImageFile::get_resource(ImageLocation& location) 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 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;
+// 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++ = '/';
}
-
- 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;
+ // Get parent (package) string.
+ const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+ // 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);
+ // 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);
+ // 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';
}
-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);
- }
+// 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 == '\0';
}
-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 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 = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
+ u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+ u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
+ 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");
}
-
- return pkgs;
}
--- a/hotspot/src/share/vm/classfile/imageFile.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/imageFile.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
// 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 @@
// 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 @@
// 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 @@
}
};
-// 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;
+//
+// 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); }
+ };
- 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.
+ // 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); }
};
- 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
+ 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 an image file, reuse structure if file already open.
+ static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
- // Open image file for access.
+ // 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 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 location attribute stream for location i.
- inline u1* get_location_data(u4 i) const {
- u4 offset = _offsets_table[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 offset != 0 ? _location_bytes + offset : NULL;
+ return get_location_offset_data(offset);
}
- // Return the attribute stream for a named resourced.
- u1* find_location_data(const char* path) const;
+ // 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
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1707,8 +1707,7 @@
// - rest of the stack
if (!skip_fillInStackTrace_check) {
- if ((method->name() == vmSymbols::fillInStackTrace_name() ||
- method->name() == vmSymbols::fillInStackTrace0_name()) &&
+ if (method->name() == vmSymbols::fillInStackTrace_name() &&
throwable->is_a(method->method_holder())) {
continue;
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2346,9 +2346,6 @@
assert(!THREAD->is_Compiler_thread(), "");
Handle method_type =
SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
- if (false) { // FIXME: Decide if the Java upcall should resolve signatures.
- method_type = java_lang_String::create_from_symbol(signature, CHECK_(empty));
- }
KlassHandle mh_klass = SystemDictionary::MethodHandle_klass();
int ref_kind = JVM_REF_invokeVirtual;
@@ -2380,6 +2377,24 @@
return unpack_method_and_appendix(mname, accessing_klass, appendix_box, appendix_result, THREAD);
}
+// Decide if we can globally cache a lookup of this class, to be returned to any client that asks.
+// We must ensure that all class loaders everywhere will reach this class, for any client.
+// This is a safe bet for public classes in java.lang, such as Object and String.
+// We also include public classes in java.lang.invoke, because they appear frequently in system-level method types.
+// Out of an abundance of caution, we do not include any other classes, not even for packages like java.util.
+static bool is_always_visible_class(oop mirror) {
+ Klass* klass = java_lang_Class::as_Klass(mirror);
+ if (klass->oop_is_objArray()) {
+ klass = ObjArrayKlass::cast(klass)->bottom_klass(); // check element type
+ }
+ if (klass->oop_is_typeArray()) {
+ return true; // primitive array
+ }
+ assert(klass->oop_is_instance(), klass->external_name());
+ return klass->is_public() &&
+ (InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::Object_klass()) || // java.lang
+ InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke
+}
// Ask Java code to find or construct a java.lang.invoke.MethodType for the given
// signature, as interpreted relative to the given class loader.
@@ -2402,32 +2417,33 @@
}
Handle class_loader, protection_domain;
- bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader
+ if (accessing_klass.not_null()) {
+ class_loader = Handle(THREAD, InstanceKlass::cast(accessing_klass())->class_loader());
+ protection_domain = Handle(THREAD, InstanceKlass::cast(accessing_klass())->protection_domain());
+ }
+ bool can_be_cached = true;
int npts = ArgumentCount(signature).size();
objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
int arg = 0;
- Handle rt; // the return type from the signature
+ Handle rt; // the return type from the signature
ResourceMark rm(THREAD);
for (SignatureStream ss(signature); !ss.is_done(); ss.next()) {
oop mirror = NULL;
- if (is_on_bcp) {
- // Note: class_loader & protection_domain are both null at this point.
- mirror = ss.as_java_mirror(class_loader, protection_domain,
+ if (can_be_cached) {
+ // Use neutral class loader to lookup candidate classes to be placed in the cache.
+ mirror = ss.as_java_mirror(Handle(), Handle(),
SignatureStream::ReturnNull, CHECK_(empty));
- if (mirror == NULL) {
- // fall back from BCP to accessing_klass
- if (accessing_klass.not_null()) {
- class_loader = Handle(THREAD, InstanceKlass::cast(accessing_klass())->class_loader());
- protection_domain = Handle(THREAD, InstanceKlass::cast(accessing_klass())->protection_domain());
- }
- is_on_bcp = false;
+ if (mirror == NULL || (ss.is_object() && !is_always_visible_class(mirror))) {
+ // Fall back to accessing_klass context.
+ can_be_cached = false;
}
}
- if (!is_on_bcp) {
+ if (!can_be_cached) {
// Resolve, throwing a real error if it doesn't work.
mirror = ss.as_java_mirror(class_loader, protection_domain,
SignatureStream::NCDFError, CHECK_(empty));
}
+ assert(!oopDesc::is_null(mirror), ss.as_symbol(THREAD)->as_C_string());
if (ss.at_return_type())
rt = Handle(THREAD, mirror);
else
@@ -2459,7 +2475,7 @@
&args, CHECK_(empty));
Handle method_type(THREAD, (oop) result.get_jobject());
- if (is_on_bcp) {
+ if (can_be_cached) {
// We can cache this MethodType inside the JVM.
MutexLocker ml(SystemDictionary_lock, THREAD);
spe = invoke_method_table()->find_entry(index, hash, signature, null_iid);
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -258,6 +258,8 @@
/* Type Annotations (JDK 8 and above) */ \
template(type_annotations_name, "typeAnnotations") \
\
+ /* Intrinsic Annotation (JDK 9 and above) */ \
+ template(jdk_internal_HotSpotIntrinsicCandidate_signature, "Ljdk/internal/HotSpotIntrinsicCandidate;") \
\
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
@@ -345,7 +347,6 @@
template(dispatch_name, "dispatch") \
template(getSystemClassLoader_name, "getSystemClassLoader") \
template(fillInStackTrace_name, "fillInStackTrace") \
- template(fillInStackTrace0_name, "fillInStackTrace0") \
template(getCause_name, "getCause") \
template(initCause_name, "initCause") \
template(setProperty_name, "setProperty") \
@@ -635,7 +636,43 @@
// The F_xx is one of the Flags enum; see below.
//
// for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t))
+//
+//
+// There are two types of intrinsic methods: (1) Library intrinsics and (2) bytecode intrinsics.
+//
+// (1) A library intrinsic method may be replaced with hand-crafted assembly code,
+// with hand-crafted compiler IR, or with a combination of the two. The semantics
+// of the replacement code may differ from the semantics of the replaced code.
+//
+// (2) Bytecode intrinsic methods are not replaced by special code, but they are
+// treated in some other special way by the compiler. For example, the compiler
+// may delay inlining for some String-related intrinsic methods (e.g., some methods
+// defined in the StringBuilder and StringBuffer classes, see
+// Compile::should_delay_string_inlining() for more details).
+//
+// Due to the difference between the semantics of an intrinsic method as defined
+// in the (Java) source code and the semantics of the method as defined
+// by the code in the VM, intrinsic methods must be explicitly marked.
+//
+// Intrinsic methods are marked by the jdk.internal.HotSpotIntrinsicCandidate
+// annotation. If CheckIntrinsics is enabled, the VM performs the following
+// checks when a class C is loaded: (1) all intrinsics defined by the VM for
+// class C are present in the loaded class file and are marked;
+// (2) an intrinsic is defined by the VM for all marked methods of class C.
+//
+// If a mismatch is detected for a method, the VM behaves differently depending
+// on the type of build. A fastdebug build exits and reports an error on a mismatch.
+// A product build will not replace an unmarked library intrinsic method with
+// hand-crafted code, that is, unmarked library intrinsics are treated as ordinary
+// methods in a product build. The special treatment of a bytecode intrinsic method
+// persists even if the method not marked.
+//
+// When adding an intrinsic for a method, please make sure to appropriately
+// annotate the method in the source code. The list below contains all
+// library intrinsics followed by bytecode intrinsics. Please also make sure to
+// add the declaration of the intrinsic to the approriate section of the list.
#define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias) \
+ /* (1) Library intrinsics */ \
do_intrinsic(_hashCode, java_lang_Object, hashCode_name, void_int_signature, F_R) \
do_name( hashCode_name, "hashCode") \
do_intrinsic(_getClass, java_lang_Object, getClass_name, void_class_signature, F_R) \
@@ -792,12 +829,12 @@
\
do_class(sun_nio_cs_iso8859_1_Encoder, "sun/nio/cs/ISO_8859_1$Encoder") \
do_intrinsic(_encodeISOArray, sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S) \
- do_name( encodeISOArray_name, "encodeISOArray") \
+ do_name( encodeISOArray_name, "implEncodeISOArray") \
do_signature(encodeISOArray_signature, "([CI[BII)I") \
\
do_class(java_math_BigInteger, "java/math/BigInteger") \
- do_intrinsic(_multiplyToLen, java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_R) \
- do_name( multiplyToLen_name, "multiplyToLen") \
+ do_intrinsic(_multiplyToLen, java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S) \
+ do_name( multiplyToLen_name, "implMultiplyToLen") \
do_signature(multiplyToLen_signature, "([II[II[I)[I") \
\
do_intrinsic(_squareToLen, java_math_BigInteger, squareToLen_name, squareToLen_signature, F_S) \
@@ -808,6 +845,14 @@
do_name( mulAdd_name, "implMulAdd") \
do_signature(mulAdd_signature, "([I[IIII)I") \
\
+ do_intrinsic(_montgomeryMultiply, java_math_BigInteger, montgomeryMultiply_name, montgomeryMultiply_signature, F_S) \
+ do_name( montgomeryMultiply_name, "implMontgomeryMultiply") \
+ do_signature(montgomeryMultiply_signature, "([I[I[IIJ[I)[I") \
+ \
+ do_intrinsic(_montgomerySquare, java_math_BigInteger, montgomerySquare_name, montgomerySquare_signature, F_S) \
+ do_name( montgomerySquare_name, "implMontgomerySquare") \
+ do_signature(montgomerySquare_signature, "([I[IIJ[I)[I") \
+ \
/* java/lang/ref/Reference */ \
do_intrinsic(_Reference_get, java_lang_ref_Reference, get_name, void_object_signature, F_R) \
\
@@ -815,21 +860,21 @@
do_class(com_sun_crypto_provider_aescrypt, "com/sun/crypto/provider/AESCrypt") \
do_intrinsic(_aescrypt_encryptBlock, com_sun_crypto_provider_aescrypt, encryptBlock_name, byteArray_int_byteArray_int_signature, F_R) \
do_intrinsic(_aescrypt_decryptBlock, com_sun_crypto_provider_aescrypt, decryptBlock_name, byteArray_int_byteArray_int_signature, F_R) \
- do_name( encryptBlock_name, "encryptBlock") \
- do_name( decryptBlock_name, "decryptBlock") \
+ do_name( encryptBlock_name, "implEncryptBlock") \
+ do_name( decryptBlock_name, "implDecryptBlock") \
do_signature(byteArray_int_byteArray_int_signature, "([BI[BI)V") \
\
do_class(com_sun_crypto_provider_cipherBlockChaining, "com/sun/crypto/provider/CipherBlockChaining") \
do_intrinsic(_cipherBlockChaining_encryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, encrypt_name, byteArray_int_int_byteArray_int_signature, F_R) \
do_intrinsic(_cipherBlockChaining_decryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, decrypt_name, byteArray_int_int_byteArray_int_signature, F_R) \
- do_name( encrypt_name, "encrypt") \
- do_name( decrypt_name, "decrypt") \
+ do_name( encrypt_name, "implEncrypt") \
+ do_name( decrypt_name, "implDecrypt") \
do_signature(byteArray_int_int_byteArray_int_signature, "([BII[BI)I") \
\
/* support for sun.security.provider.SHA */ \
do_class(sun_security_provider_sha, "sun/security/provider/SHA") \
do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R) \
- do_name( implCompress_name, "implCompress") \
+ do_name( implCompress_name, "implCompress0") \
do_signature(implCompress_signature, "([BI)V") \
\
/* support for sun.security.provider.SHA2 */ \
@@ -843,7 +888,7 @@
/* support for sun.security.provider.DigestBase */ \
do_class(sun_security_provider_digestbase, "sun/security/provider/DigestBase") \
do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R) \
- do_name( implCompressMB_name, "implCompressMultiBlock") \
+ do_name( implCompressMB_name, "implCompressMultiBlock0") \
do_signature(implCompressMB_signature, "([BII)I") \
\
/* support for com.sun.crypto.provider.GHASH */ \
@@ -857,17 +902,18 @@
do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \
do_name( update_name, "update") \
do_intrinsic(_updateBytesCRC32, java_util_zip_CRC32, updateBytes_name, updateBytes_signature, F_SN) \
- do_name( updateBytes_name, "updateBytes") \
+ do_name( updateBytes_name, "updateBytes0") \
do_signature(updateBytes_signature, "(I[BII)I") \
do_intrinsic(_updateByteBufferCRC32, java_util_zip_CRC32, updateByteBuffer_name, updateByteBuffer_signature, F_SN) \
- do_name( updateByteBuffer_name, "updateByteBuffer") \
+ do_name( updateByteBuffer_name, "updateByteBuffer0") \
do_signature(updateByteBuffer_signature, "(IJII)I") \
\
/* support for java.util.zip.CRC32C */ \
do_class(java_util_zip_CRC32C, "java/util/zip/CRC32C") \
- do_intrinsic(_updateBytesCRC32C, java_util_zip_CRC32C, updateBytes_name, updateBytes_signature, F_S) \
- do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_name, updateByteBuffer_signature, F_S) \
- do_name( updateDirectByteBuffer_name, "updateDirectByteBuffer") \
+ do_intrinsic(_updateBytesCRC32C, java_util_zip_CRC32C, updateBytes_C_name, updateBytes_signature, F_S) \
+ do_name( updateBytes_C_name, "updateBytes") \
+ do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_C_name, updateByteBuffer_signature, F_S) \
+ do_name( updateDirectByteBuffer_C_name, "updateDirectByteBuffer") \
\
/* support for sun.misc.Unsafe */ \
do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
@@ -878,12 +924,6 @@
do_intrinsic(_copyMemory, sun_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
do_name( copyMemory_name, "copyMemory") \
do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \
- do_intrinsic(_park, sun_misc_Unsafe, park_name, park_signature, F_RN) \
- do_name( park_name, "park") \
- do_signature(park_signature, "(ZJ)V") \
- do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \
- do_name( unpark_name, "unpark") \
- do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
do_intrinsic(_loadFence, sun_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
do_name( loadFence_name, "loadFence") \
do_alias( loadFence_signature, void_method_signature) \
@@ -1066,11 +1106,15 @@
do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
do_name( getAndSetObject_name, "getAndSetObject") \
do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
- /*== LAST_COMPILER_INLINE*/ \
- /*the compiler does have special inlining code for these; bytecode inline is just fine */ \
+ \
+ /* (2) Bytecode intrinsics */ \
\
- do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
- \
+ do_intrinsic(_park, sun_misc_Unsafe, park_name, park_signature, F_RN) \
+ do_name( park_name, "park") \
+ do_signature(park_signature, "(ZJ)V") \
+ do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \
+ do_name( unpark_name, "unpark") \
+ do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
do_intrinsic(_StringBuilder_void, java_lang_StringBuilder, object_initializer_name, void_method_signature, F_R) \
do_intrinsic(_StringBuilder_int, java_lang_StringBuilder, object_initializer_name, int_void_signature, F_R) \
do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \
--- a/hotspot/src/share/vm/code/codeBlob.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
_data_offset = size;
_frame_size = 0;
set_oop_maps(NULL);
+ _strings = CodeStrings();
}
@@ -114,6 +116,7 @@
_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* 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* 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* 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);
--- a/hotspot/src/share/vm/code/codeBlob.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 CodeBlob VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
+ friend class CodeCacheDumper;
private:
const char* _name;
@@ -206,6 +208,14 @@
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;
--- a/hotspot/src/share/vm/code/codeCache.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -409,7 +409,7 @@
}
if (PrintCodeCacheExtension) {
ResourceMark rm;
- if (SegmentedCodeCache) {
+ if (_heaps->length() >= 1) {
tty->print("%s", heap->name());
} else {
tty->print("CodeCache");
@@ -1211,7 +1211,7 @@
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 @@
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 @@
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());
}
--- a/hotspot/src/share/vm/code/codeCache.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -78,6 +78,7 @@
friend class VMStructs;
friend class NMethodIterator;
friend class WhiteBox;
+ friend class CodeCacheLoader;
private:
// CodeHeaps of the cache
static GrowableArray<CodeHeap*>* _heaps;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/codeCacheExtensions.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/codeCacheExtensions_ext.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -186,7 +186,7 @@
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("}");
}
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2118,7 +2118,7 @@
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 @@
_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 @@
_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 @@
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 ");
--- a/hotspot/src/share/vm/code/stubs.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/stubs.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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;
+}
--- a/hotspot/src/share/vm/code/stubs.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/code/stubs.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
// 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
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -172,7 +172,7 @@
}
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()));
}
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
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 @@
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 @@
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;
}
--- a/hotspot/src/share/vm/compiler/disassembler.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -65,7 +65,7 @@
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;
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -688,18 +688,18 @@
"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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
}
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 @@
&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 @@
} 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 @@
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 @@
// 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);
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1021,7 +1021,7 @@
to()->set_concurrent_iteration_safe_limit(to()->top());
if (ResizePLAB) {
- plab_stats()->adjust_desired_plab_sz(active_workers);
+ plab_stats()->adjust_desired_plab_sz();
}
if (PrintGC && !PrintGCDetails) {
@@ -1059,6 +1059,10 @@
_gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
}
+size_t ParNewGeneration::desired_plab_sz() {
+ return _plab_stats.desired_plab_sz(GenCollectedHeap::heap()->workers()->active_workers());
+}
+
static int sum;
void ParNewGeneration::waste_some_time() {
for (int i = 0; i < 100; i++) {
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -411,9 +411,7 @@
return &_plab_stats;
}
- size_t desired_plab_sz() {
- return _plab_stats.desired_plab_sz();
- }
+ size_t desired_plab_sz();
const ParNewTracer* gc_tracer() const {
return &_gc_tracer;
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -119,7 +119,7 @@
}
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
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -92,7 +92,7 @@
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;
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -307,7 +307,7 @@
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 @@
_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 @@
// 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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
#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 @@
"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 @@
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::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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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)
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -197,8 +197,8 @@
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::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 @@
// 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)));
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -44,8 +44,7 @@
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 @@
if (started()) {
set_in_progress();
- clear_started();
}
}
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -47,8 +47,14 @@
private:
ConcurrentMark* _cm;
- volatile bool _started;
- volatile bool _in_progress;
+
+ enum State {
+ Idle,
+ Started,
+ InProgress
+ };
+
+ volatile State _state;
void sleepBeforeNextCycle();
@@ -68,23 +74,22 @@
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();
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -140,7 +140,7 @@
}
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 @@
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);
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -86,7 +86,7 @@
&_retained_old_gc_alloc_region);
}
-void G1DefaultAllocator::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
+void G1DefaultAllocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) {
AllocationContext_t context = AllocationContext::current();
evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() +
old_gc_alloc_region(context)->count());
@@ -102,8 +102,8 @@
}
if (ResizePLAB) {
- _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(no_of_gc_workers);
- _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(no_of_gc_workers);
+ _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz();
+ _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz();
}
}
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -53,7 +53,7 @@
virtual void release_mutator_alloc_region() = 0;
virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
- virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) = 0;
+ virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
virtual void abandon_gc_alloc_regions() = 0;
virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
@@ -76,7 +76,7 @@
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;
}
@@ -114,7 +114,7 @@
virtual void release_mutator_alloc_region();
virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
- virtual void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
+ virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info);
virtual void abandon_gc_alloc_regions();
virtual bool is_retained_old_region(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -36,19 +36,19 @@
#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> {
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -71,10 +71,10 @@
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;
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -69,10 +69,10 @@
#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 @@
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 @@
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
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -150,7 +150,7 @@
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));
}
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -53,7 +53,7 @@
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 @@
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) {
--- a/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CardCounts.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -91,7 +91,7 @@
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);
}
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -350,11 +350,11 @@
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 @@
}
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 @@
}
}
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");
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -197,7 +197,7 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
// 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 @@
r->object_iterate(¬_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 @@
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 @@
}
~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();
}
@@ -4273,7 +4273,7 @@
void G1CollectedHeap::remove_self_forwarding_pointers() {
double remove_self_forwards_start = os::elapsedTime();
- G1ParRemoveSelfForwardPtrsTask rsfp_task(this);
+ G1ParRemoveSelfForwardPtrsTask rsfp_task;
workers()->run_task(&rsfp_task);
// Now restore saved marks, if any.
@@ -4308,7 +4308,7 @@
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 @@
// 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 @@
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());
}
@@ -5644,7 +5644,7 @@
phase_times->record_string_dedup_fixup_time(fixup_time_ms);
}
- _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
+ _allocator->release_gc_alloc_regions(evacuation_info);
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
// Reset and re-enable the hot card cache.
@@ -5828,13 +5828,13 @@
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 @@
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 @@
!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 @@
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 @@
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 @@
}
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 @@
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 @@
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);
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -281,7 +281,7 @@
void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
// It releases the GC alloc regions at the end of a GC.
- void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
+ void release_gc_alloc_regions(EvacuationInfo& evacuation_info);
// It does any cleanup that needs to be done on the GC alloc regions
// before a Full GC.
@@ -1109,6 +1109,8 @@
// 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; }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -49,7 +49,7 @@
}
size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) {
- size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz();
+ size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(G1CollectedHeap::heap()->workers()->active_workers());
// Prevent humongous PLAB sizes for two reasons:
// * PLABs are allocated using a similar paths as oops, but should
// never be in a humongous region
@@ -82,7 +82,7 @@
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 @@
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);
}
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -184,7 +184,7 @@
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 @@
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 @@
_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 @@
}
_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 @@
(_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 @@
_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 @@
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());
--- a/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -121,15 +121,15 @@
// 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_) \
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -40,8 +40,8 @@
G1SATBCardTableModRefBS* _ct_bs;
public:
- UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
- _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
+ UpdateRSetDeferred(DirtyCardQueue* dcq) :
+ _g1(G1CollectedHeap::heap()), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
@@ -65,60 +65,41 @@
size_t _marked_bytes;
OopsInHeapRegionClosure *_update_rset_cl;
bool _during_initial_mark;
- bool _during_conc_mark;
uint _worker_id;
- HeapWord* _end_of_last_gap;
- HeapWord* _last_gap_threshold;
- HeapWord* _last_obj_threshold;
+ HeapWord* _last_forwarded_object_end;
public:
- RemoveSelfForwardPtrObjClosure(G1CollectedHeap* g1, ConcurrentMark* cm,
- HeapRegion* hr,
+ RemoveSelfForwardPtrObjClosure(HeapRegion* hr,
OopsInHeapRegionClosure* update_rset_cl,
bool during_initial_mark,
- bool during_conc_mark,
uint worker_id) :
- _g1(g1), _cm(cm), _hr(hr), _marked_bytes(0),
+ _g1(G1CollectedHeap::heap()),
+ _cm(_g1->concurrent_mark()),
+ _hr(hr),
+ _marked_bytes(0),
_update_rset_cl(update_rset_cl),
_during_initial_mark(during_initial_mark),
- _during_conc_mark(during_conc_mark),
_worker_id(worker_id),
- _end_of_last_gap(hr->bottom()),
- _last_gap_threshold(hr->bottom()),
- _last_obj_threshold(hr->bottom()) { }
+ _last_forwarded_object_end(hr->bottom()) { }
size_t marked_bytes() { return _marked_bytes; }
- // <original comment>
- // The original idea here was to coalesce evacuated and dead objects.
- // However that caused complications with the block offset table (BOT).
- // In particular if there were two TLABs, one of them partially refined.
- // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~|
- // The BOT entries of the unrefined part of TLAB_2 point to the start
- // of TLAB_2. If the last object of the TLAB_1 and the first object
- // of TLAB_2 are coalesced, then the cards of the unrefined part
- // would point into middle of the filler object.
- // The current approach is to not coalesce and leave the BOT contents intact.
- // </original comment>
- //
- // We now reset the BOT when we start the object iteration over the
- // region and refine its entries for every object we come across. So
- // the above comment is not really relevant and we should be able
- // to coalesce dead objects if we want to.
+ // Iterate over the live objects in the region to find self-forwarded objects
+ // that need to be kept live. We need to update the remembered sets of these
+ // objects. Further update the BOT and marks.
+ // We can coalesce and overwrite the remaining heap contents with dummy objects
+ // as they have either been dead or evacuated (which are unreferenced now, i.e.
+ // dead too) already.
void do_object(oop obj) {
HeapWord* obj_addr = (HeapWord*) obj;
assert(_hr->is_in(obj_addr), "sanity");
size_t obj_size = obj->size();
HeapWord* obj_end = obj_addr + obj_size;
- if (_end_of_last_gap != obj_addr) {
- // there was a gap before obj_addr
- _last_gap_threshold = _hr->cross_threshold(_end_of_last_gap, obj_addr);
- }
-
if (obj->is_forwarded() && obj->forwardee() == obj) {
// The object failed to move.
+ zap_dead_objects(_last_forwarded_object_end, obj_addr);
// We consider all objects that we find self-forwarded to be
// live. What we'll do is that we'll update the prev marking
// info so that they are all under PTAMS and explicitly marked.
@@ -154,24 +135,52 @@
// remembered set entries missing given that we skipped cards on
// the collection set. So, we'll recreate such entries now.
obj->oop_iterate(_update_rset_cl);
- } else {
+
+ _last_forwarded_object_end = obj_end;
+ _hr->cross_threshold(obj_addr, obj_end);
+ }
+ }
+
+ // Fill the memory area from start to end with filler objects, and update the BOT
+ // and the mark bitmap accordingly.
+ void zap_dead_objects(HeapWord* start, HeapWord* end) {
+ if (start == end) {
+ return;
+ }
+
+ size_t gap_size = pointer_delta(end, start);
+ MemRegion mr(start, gap_size);
+ if (gap_size >= CollectedHeap::min_fill_size()) {
+ CollectedHeap::fill_with_objects(start, gap_size);
- // The object has been either evacuated or is dead. Fill it with a
- // dummy object.
- MemRegion mr(obj_addr, obj_size);
- CollectedHeap::fill_with_object(mr);
+ HeapWord* end_first_obj = start + ((oop)start)->size();
+ _hr->cross_threshold(start, end_first_obj);
+ // Fill_with_objects() may have created multiple (i.e. two)
+ // objects, as the max_fill_size() is half a region.
+ // After updating the BOT for the first object, also update the
+ // BOT for the second object to make the BOT complete.
+ if (end_first_obj != end) {
+ _hr->cross_threshold(end_first_obj, end);
+#ifdef ASSERT
+ size_t size_second_obj = ((oop)end_first_obj)->size();
+ HeapWord* end_of_second_obj = end_first_obj + size_second_obj;
+ assert(end == end_of_second_obj,
+ err_msg("More than two objects were used to fill the area from " PTR_FORMAT " to " PTR_FORMAT ", "
+ "second objects size " SIZE_FORMAT " ends at " PTR_FORMAT,
+ p2i(start), p2i(end), size_second_obj, p2i(end_of_second_obj)));
+#endif
+ }
+ }
+ _cm->clearRangePrevBitmap(mr);
+ }
- // must nuke all dead objects which we skipped when iterating over the region
- _cm->clearRangePrevBitmap(MemRegion(_end_of_last_gap, obj_end));
- }
- _end_of_last_gap = obj_end;
- _last_obj_threshold = _hr->cross_threshold(obj_addr, obj_end);
+ void zap_remainder() {
+ zap_dead_objects(_last_forwarded_object_end, _hr->top());
}
};
class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
G1CollectedHeap* _g1h;
- ConcurrentMark* _cm;
uint _worker_id;
HeapRegionClaimer* _hrclaimer;
@@ -179,11 +188,27 @@
UpdateRSetDeferred _update_rset_cl;
public:
- RemoveSelfForwardPtrHRClosure(G1CollectedHeap* g1h,
- uint worker_id,
+ RemoveSelfForwardPtrHRClosure(uint worker_id,
HeapRegionClaimer* hrclaimer) :
- _g1h(g1h), _dcq(&g1h->dirty_card_queue_set()), _update_rset_cl(g1h, &_dcq),
- _worker_id(worker_id), _cm(_g1h->concurrent_mark()), _hrclaimer(hrclaimer) {
+ _g1h(G1CollectedHeap::heap()),
+ _dcq(&_g1h->dirty_card_queue_set()),
+ _update_rset_cl(&_dcq),
+ _worker_id(worker_id),
+ _hrclaimer(hrclaimer) {
+ }
+
+ size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr,
+ bool during_initial_mark) {
+ RemoveSelfForwardPtrObjClosure rspc(hr,
+ &_update_rset_cl,
+ during_initial_mark,
+ _worker_id);
+ _update_rset_cl.set_region(hr);
+ hr->object_iterate(&rspc);
+ // Need to zap the remainder area of the processed region.
+ rspc.zap_remainder();
+
+ return rspc.marked_bytes();
}
bool doHeapRegion(HeapRegion *hr) {
@@ -195,11 +220,6 @@
if (_hrclaimer->claim_region(hr->hrm_index())) {
if (hr->evacuation_failed()) {
- RemoveSelfForwardPtrObjClosure rspc(_g1h, _cm, hr, &_update_rset_cl,
- during_initial_mark,
- during_conc_mark,
- _worker_id);
-
hr->note_self_forwarding_removal_start(during_initial_mark,
during_conc_mark);
_g1h->check_bitmaps("Self-Forwarding Ptr Removal", hr);
@@ -214,26 +234,27 @@
// whenever this might be required in the future.
hr->rem_set()->reset_for_par_iteration();
hr->reset_bot();
- _update_rset_cl.set_region(hr);
- hr->object_iterate(&rspc);
+
+ size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_initial_mark);
hr->rem_set()->clean_strong_code_roots(hr);
hr->note_self_forwarding_removal_end(during_initial_mark,
during_conc_mark,
- rspc.marked_bytes());
+ live_bytes);
}
}
return false;
}
};
-G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h) :
- AbstractGangTask("G1 Remove Self-forwarding Pointers"), _g1h(g1h),
- _hrclaimer(g1h->workers()->active_workers()) {}
+G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask() :
+ AbstractGangTask("G1 Remove Self-forwarding Pointers"),
+ _g1h(G1CollectedHeap::heap()),
+ _hrclaimer(_g1h->workers()->active_workers()) { }
void G1ParRemoveSelfForwardPtrsTask::work(uint worker_id) {
- RemoveSelfForwardPtrHRClosure rsfp_cl(_g1h, worker_id, &_hrclaimer);
+ RemoveSelfForwardPtrHRClosure rsfp_cl(worker_id, &_hrclaimer);
HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
_g1h->collection_set_iterate_from(hr, &rsfp_cl);
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -40,7 +40,7 @@
HeapRegionClaimer _hrclaimer;
public:
- G1ParRemoveSelfForwardPtrsTask(G1CollectedHeap* g1h);
+ G1ParRemoveSelfForwardPtrsTask();
void work(uint worker_id);
};
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -331,7 +331,7 @@
}
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 @@
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));
}
}
--- a/hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -83,18 +83,18 @@
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, 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);
}
--- a/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -104,7 +104,7 @@
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 @@
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);
}
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
++_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
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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 @@
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 @@
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);
};
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -118,7 +118,7 @@
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);
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -424,7 +424,7 @@
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)),
--- a/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -187,22 +187,22 @@
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 @@
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 @@
// 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 @@
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++) {
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -155,7 +155,7 @@
void G1StringDedupQueue::print_statistics(outputStream* st) {
st->print_cr(
" [Queue]\n"
- " [Dropped: "UINTX_FORMAT"]", _queue->_dropped);
+ " [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
}
void G1StringDedupQueue::verify() {
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -80,8 +80,8 @@
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 @@
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,
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -556,12 +556,12 @@
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,
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -327,7 +327,7 @@
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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
(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 @@
}
}
} 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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
}
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;
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -51,7 +51,7 @@
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 @@
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;
--- a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -113,7 +113,7 @@
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)));
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -486,7 +486,7 @@
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()));
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -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;
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -90,7 +90,7 @@
// 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::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 @@
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 @@
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 @@
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
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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::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::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::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 @@
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) {
--- a/hotspot/src/share/vm/gc/g1/satbQueue.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/g1/satbQueue.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -200,8 +200,8 @@
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
--- a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -85,7 +85,7 @@
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()) {
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -130,8 +130,7 @@
// Update the pause time.
_major_timer.stop();
- if (!GCCause::is_user_requested_gc(gc_cause) ||
- UseAdaptiveSizePolicyWithSystemGC) {
+ if (should_update_promo_stats(gc_cause)) {
double major_pause_in_seconds = _major_timer.seconds();
double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -272,8 +272,7 @@
// Don't check if the size_policy is ready here. Let
// the size_policy check that internally.
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
- (!GCCause::is_user_requested_gc(gc_cause) ||
- UseAdaptiveSizePolicyWithSystemGC)) {
+ AdaptiveSizePolicy::should_update_promo_stats(gc_cause)) {
// Swap the survivor spaces if from_space is empty. The
// resize_young_gen() called below is normally used after
// a successful young GC and swapping of survivor spaces;
--- a/hotspot/src/share/vm/gc/parallel/psOldGen.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psOldGen.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -65,9 +65,9 @@
// 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()),
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2089,8 +2089,7 @@
// Don't check if the size_policy is ready here. Let
// the size_policy check that internally.
if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
- (!GCCause::is_user_requested_gc(gc_cause) ||
- UseAdaptiveSizePolicyWithSystemGC)) {
+ AdaptiveSizePolicy::should_update_promo_stats(gc_cause)) {
// Swap the survivor spaces if from_space is empty. The
// resize_young_gen() called below is normally used after
// a successful young GC and swapping of survivor spaces;
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -290,8 +290,7 @@
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
- if (!GCCause::is_user_requested_gc(gc_cause) ||
- UseAdaptiveSizePolicyWithSystemGC) {
+ if (AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) {
// Gather the feedback data for eden occupancy.
young_gen->eden_space()->accumulate_statistics();
}
@@ -559,9 +558,7 @@
// Don't check if the size_policy is ready at this
// level. Let the size_policy check that internally.
if (UseAdaptiveGenerationSizePolicyAtMinorCollection &&
- ((gc_cause != GCCause::_java_lang_system_gc) ||
- UseAdaptiveSizePolicyWithSystemGC)) {
-
+ (AdaptiveSizePolicy::should_update_eden_stats(gc_cause))) {
// Calculate optimal free space amounts
assert(young_gen->max_size() >
young_gen->from_space()->capacity_in_bytes() +
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -168,8 +168,8 @@
bool res = (available >= av_promo) || (available >= max_promotion_in_bytes);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(
- "Tenured: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT"),"
- "max_promo("SIZE_FORMAT")",
+ "Tenured: 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);
}
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -487,6 +487,18 @@
GCCause::Cause gc_cause,
CollectorPolicy* collector_policy);
+ static bool should_update_promo_stats(GCCause::Cause cause) {
+ return ((GCCause::is_user_requested_gc(cause) &&
+ UseAdaptiveSizePolicyWithSystemGC) ||
+ GCCause::is_tenured_allocation_failure_gc(cause));
+ }
+
+ static bool should_update_eden_stats(GCCause::Cause cause) {
+ return ((GCCause::is_user_requested_gc(cause) &&
+ UseAdaptiveSizePolicyWithSystemGC) ||
+ GCCause::is_allocation_failure_gc(cause));
+ }
+
// Printing support
virtual bool print_adaptive_size_policy_on(outputStream* st) const;
bool print_adaptive_size_policy_on(outputStream* st,
--- a/hotspot/src/share/vm/gc/shared/barrierSet.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/barrierSet.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -69,7 +69,7 @@
assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
"Expected heap word alignment of start and end");
#if 0
- warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT","INTPTR_FORMAT")\t",
+ warning("Post:\t" INTPTR_FORMAT "[" SIZE_FORMAT "] : [" INTPTR_FORMAT "," INTPTR_FORMAT ")\t",
start, count, aligned_start, aligned_end);
#endif
write_ref_array_work(MemRegion(aligned_start, aligned_end));
--- a/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -560,7 +560,7 @@
q = n;
n += _sp->block_size(n);
assert(n > q,
- err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT","
+ err_msg("Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT ","
" while querying blk_start(" PTR_FORMAT ")"
" on _sp = [" PTR_FORMAT "," PTR_FORMAT ")",
p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end())));
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -600,7 +600,7 @@
(val_equals) ? "" : "not ", val);
failures = true;
}
- tty->print_cr("== card "PTR_FORMAT" ["PTR_FORMAT","PTR_FORMAT"], "
+ tty->print_cr("== card " PTR_FORMAT " [" PTR_FORMAT "," PTR_FORMAT "], "
"val: %d", p2i(curr), p2i(addr_for(curr)),
p2i((HeapWord*) (((size_t) addr_for(curr)) + card_size)),
(int) curr_val);
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -158,8 +158,8 @@
// Mapping from address to card marking array entry
jbyte* byte_for(const void* p) const {
assert(_whole_heap.contains(p),
- err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of "
- " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")",
+ err_msg("Attempt to access p = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift];
assert(result >= _byte_map && result < _byte_map + _byte_map_size,
@@ -399,8 +399,8 @@
size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
HeapWord* result = (HeapWord*) (delta << card_shift);
assert(_whole_heap.contains(result),
- err_msg("Returning result = "PTR_FORMAT" out of bounds of "
- " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")",
+ err_msg("Returning result = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
return result;
}
@@ -408,8 +408,8 @@
// Mapping from address to card marking array index.
size_t index_for(void* p) {
assert(_whole_heap.contains(p),
- err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of "
- " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")",
+ err_msg("Attempt to access p = " PTR_FORMAT " out of bounds of "
+ " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())));
return byte_for(p) - _byte_map;
}
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -488,19 +488,17 @@
DEBUG_ONLY(fill_args_check(start, words);)
HandleMark hm; // Free handles before leaving.
-#ifdef _LP64
- // A single array can fill ~8G, so multiple objects are needed only in 64-bit.
- // First fill with arrays, ensuring that any remaining space is big enough to
- // fill. The remainder is filled with a single object.
+ // Multiple objects may be required depending on the filler array maximum size. Fill
+ // the range up to that with objects that are filler_array_max_size sized. The
+ // remainder is filled with a single object.
const size_t min = min_fill_size();
const size_t max = filler_array_max_size();
while (words > max) {
- const size_t cur = words - max >= min ? max : max - min;
+ const size_t cur = (words - max) >= min ? max : max - min;
fill_with_array(start, cur, zap);
start += cur;
words -= cur;
}
-#endif
fill_with_object_impl(start, words, zap);
}
--- a/hotspot/src/share/vm/gc/shared/gcCause.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcCause.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -92,6 +92,35 @@
cause == GCCause::_heap_dump);
}
+ // Causes for collection of the tenured gernation
+ inline static bool is_tenured_allocation_failure_gc(GCCause::Cause cause) {
+ assert(cause != GCCause::_old_generation_too_full_to_scavenge &&
+ cause != GCCause::_old_generation_expanded_on_last_scavenge,
+ err_msg("This GCCause may be correct but is not expected yet: %s",
+ to_string(cause)));
+ // _tenured_generation_full or _cms_generation_full for full tenured generations
+ // _adaptive_size_policy for a full collection after a young GC
+ // _allocation_failure is the generic cause a collection which could result
+ // in the collection of the tenured generation if there is not enough space
+ // in the tenured generation to support a young GC.
+ // _last_ditch_collection is a collection done to include SoftReferences.
+ return (cause == GCCause::_tenured_generation_full ||
+ cause == GCCause::_cms_generation_full ||
+ cause == GCCause::_adaptive_size_policy ||
+ cause == GCCause::_allocation_failure ||
+ cause == GCCause::_last_ditch_collection);
+ }
+
+ // Causes for collection of the young generation
+ inline static bool is_allocation_failure_gc(GCCause::Cause cause) {
+ // _allocation_failure is the generic cause a collection for allocation failure
+ // _adaptive_size_policy is for a collecton done before a full GC
+ // _last_ditch_collection is a collection done to include SoftReferences.
+ return (cause == GCCause::_allocation_failure ||
+ cause == GCCause::_adaptive_size_policy ||
+ cause == GCCause::_last_ditch_collection);
+ }
+
// Return a string describing the GCCause.
static const char* to_string(GCCause::Cause cause);
};
--- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -221,6 +221,12 @@
}
#if INCLUDE_ALL_GCS
+void G1MMUTracer::report_mmu(const GCId& gcId, double timeSlice, double gcTime, double maxTime) {
+ assert(!gcId.is_undefined(), "Undefined GC id");
+
+ send_g1_mmu_event(gcId, timeSlice, gcTime, maxTime);
+}
+
void G1NewTracer::report_yc_type(G1YCType type) {
assert_set_gc_id();
--- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -239,6 +239,13 @@
};
#if INCLUDE_ALL_GCS
+class G1MMUTracer : public AllStatic {
+ static void send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+
+ public:
+ static void report_mmu(const GCId& gcId, double timeSlice, double gcTime, double maxTime);
+};
+
class G1NewTracer : public YoungGCTracer {
G1YoungGCInfo _g1_young_gc_info;
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -199,6 +199,17 @@
}
}
+void G1MMUTracer::send_g1_mmu_event(const GCId& gcId, double timeSlice, double gcTime, double maxTime) {
+ EventGCG1MMU e;
+ if (e.should_commit()) {
+ e.set_gcId(gcId.id());
+ e.set_timeSlice(timeSlice);
+ e.set_gcTime(gcTime);
+ e.set_maxGcTime(maxTime);
+ e.commit();
+ }
+}
+
void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
EventEvacuationInfo e;
if (e.should_commit()) {
--- a/hotspot/src/share/vm/gc/shared/generation.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/generation.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -173,7 +173,7 @@
bool res = (available >= max_promotion_in_bytes);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(
- "Generation: promo attempt is%s safe: available("SIZE_FORMAT") %s max_promo("SIZE_FORMAT")",
+ "Generation: promo attempt is%s safe: available(" SIZE_FORMAT ") %s max_promo(" SIZE_FORMAT ")",
res? "":" not", available, res? ">=":"<",
max_promotion_in_bytes);
}
--- a/hotspot/src/share/vm/gc/shared/plab.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/plab.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -45,7 +45,7 @@
// ArrayOopDesc::header_size depends on command line initialization.
AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
assert(min_size() > AlignmentReserve,
- err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
+ err_msg("Minimum PLAB size " SIZE_FORMAT " must be larger than alignment reserve " SIZE_FORMAT " "
"to be able to contain objects", min_size(), AlignmentReserve));
}
@@ -109,10 +109,15 @@
}
}
-// Compute desired plab size and latch result for later
+// Calculates plab size for current number of gc worker threads.
+size_t PLABStats::desired_plab_sz(uint no_of_gc_workers) {
+ return MAX2(min_size(), (size_t)align_object_size(_desired_net_plab_sz / no_of_gc_workers));
+}
+
+// Compute desired plab size for one gc worker thread and latch result for later
// use. This should be called once at the end of parallel
// scavenge; it clears the sensor accumulators.
-void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
+void PLABStats::adjust_desired_plab_sz() {
assert(ResizePLAB, "Not set");
assert(is_object_aligned(max_size()) && min_size() <= max_size(),
@@ -121,10 +126,10 @@
if (_allocated == 0) {
assert(_unused == 0,
err_msg("Inconsistency in PLAB stats: "
- "_allocated: "SIZE_FORMAT", "
- "_wasted: "SIZE_FORMAT", "
- "_unused: "SIZE_FORMAT", "
- "_undo_wasted: "SIZE_FORMAT,
+ "_allocated: " SIZE_FORMAT ", "
+ "_wasted: " SIZE_FORMAT ", "
+ "_unused: " SIZE_FORMAT ", "
+ "_undo_wasted: " SIZE_FORMAT,
_allocated, _wasted, _unused, _undo_wasted));
_allocated = 1;
@@ -135,7 +140,8 @@
target_refills = 1;
}
size_t used = _allocated - _wasted - _unused;
- size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
+ // Assumed to have 1 gc worker thread
+ size_t recent_plab_sz = used / target_refills;
// Take historical weighted average
_filter.sample(recent_plab_sz);
// Clip from above and below, and align to object boundary
@@ -144,9 +150,9 @@
new_plab_sz = align_object_size(new_plab_sz);
// Latch the result
if (PrintPLAB) {
- gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
+ gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_net_plab_sz = " SIZE_FORMAT ") ", recent_plab_sz, new_plab_sz);
}
- _desired_plab_sz = new_plab_sz;
+ _desired_net_plab_sz = new_plab_sz;
reset();
}
--- a/hotspot/src/share/vm/gc/shared/plab.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/plab.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -150,13 +150,13 @@
// PLAB book-keeping.
class PLABStats VALUE_OBJ_CLASS_SPEC {
- size_t _allocated; // Total allocated
- size_t _wasted; // of which wasted (internal fragmentation)
- size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size)
- size_t _unused; // Unused in last buffer
- size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
+ size_t _allocated; // Total allocated
+ size_t _wasted; // of which wasted (internal fragmentation)
+ size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size)
+ size_t _unused; // Unused in last buffer
+ size_t _desired_net_plab_sz;// Output of filter (below), suitably trimmed and quantized
AdaptiveWeightedAverage
- _filter; // Integrator with decay
+ _filter; // Integrator with decay
void reset() {
_allocated = 0;
@@ -165,12 +165,12 @@
_unused = 0;
}
public:
- PLABStats(size_t desired_plab_sz_, unsigned wt) :
+ PLABStats(size_t desired_net_plab_sz_, unsigned wt) :
_allocated(0),
_wasted(0),
_undo_wasted(0),
_unused(0),
- _desired_plab_sz(desired_plab_sz_),
+ _desired_net_plab_sz(desired_net_plab_sz_),
_filter(wt)
{ }
@@ -182,13 +182,12 @@
return PLAB::max_size();
}
- size_t desired_plab_sz() {
- return _desired_plab_sz;
- }
+ // Calculates plab size for current number of gc worker threads.
+ size_t desired_plab_sz(uint no_of_gc_workers);
- // Updates the current desired PLAB size. Computes the new desired PLAB size,
+ // Updates the current desired PLAB size. Computes the new desired PLAB size with one gc worker thread,
// updates _desired_plab_sz and clears sensor accumulators.
- void adjust_desired_plab_sz(uint no_of_gc_workers);
+ void adjust_desired_plab_sz();
void add_allocated(size_t v) {
Atomic::add_ptr(v, &_allocated);
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -93,10 +93,10 @@
if (PrintTLAB && Verbose) {
Thread* thrd = myThread();
- gclog_or_tty->print("TLAB: %s thread: "INTPTR_FORMAT" [id: %2d]"
- " obj: "SIZE_FORMAT
- " free: "SIZE_FORMAT
- " waste: "SIZE_FORMAT"\n",
+ gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
+ " obj: " SIZE_FORMAT
+ " free: " SIZE_FORMAT
+ " waste: " SIZE_FORMAT "\n",
"slow", p2i(thrd), thrd->osthread()->thread_id(),
obj_size, free(), refill_waste_limit());
}
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
@@ -134,8 +134,10 @@
tty->print_cr("wasted space = %6dK bytes", (int)_code->available_space()/1024);
tty->cr();
tty->print_cr("# of codelets = %6d" , _code->number_of_stubs());
- tty->print_cr("avg codelet size = %6d bytes", _code->used_space() / _code->number_of_stubs());
- tty->cr();
+ if (_code->number_of_stubs() != 0) {
+ tty->print_cr("avg codelet size = %6d bytes", _code->used_space() / _code->number_of_stubs());
+ tty->cr();
+ }
_code->print();
tty->print_cr("----------------------------------------------------------------------");
tty->cr();
--- a/hotspot/src/share/vm/interpreter/interpreter.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -45,6 +45,7 @@
class InterpreterCodelet: public Stub {
friend class VMStructs;
+ friend class CodeCacheDumper; // possible extension [do not remove]
private:
int _size; // the size in bytes
const char* _description; // a description of the codelet, for debugging & printing
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -27,6 +27,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/collectedHeap.hpp"
@@ -1178,6 +1179,7 @@
ICache::invalidate_range(handler, insts_size);
_handler = handler + insts_size;
}
+ CodeCacheExtensions::handle_generated_handler(handler, buffer->name(), _handler);
return handler;
}
@@ -1186,7 +1188,7 @@
// use slow signature handler if we can't do better
int handler_index = -1;
// check if we can use customized (fast) signature handler
- if (UseFastSignatureHandlers && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) {
+ if (UseFastSignatureHandlers && CodeCacheExtensions::support_fast_signature_handlers() && method->size_of_parameters() <= Fingerprinter::max_size_of_parameters) {
// use customized signature handler
MutexLocker mu(SignatureHandlerLibrary_lock);
// make sure data structure is initialized
@@ -1203,14 +1205,23 @@
round_to((intptr_t)_buffer, CodeEntryAlignment) - (address)_buffer;
CodeBuffer buffer((address)(_buffer + align_offset),
SignatureHandlerLibrary::buffer_size - align_offset);
+ if (!CodeCacheExtensions::support_dynamic_code()) {
+ // we need a name for the signature (for lookups or saving)
+ const int SYMBOL_SIZE = 50;
+ char *symbolName = NEW_RESOURCE_ARRAY(char, SYMBOL_SIZE);
+ // support for named signatures
+ jio_snprintf(symbolName, SYMBOL_SIZE,
+ "native_" UINT64_FORMAT, fingerprint);
+ buffer.set_name(symbolName);
+ }
InterpreterRuntime::SignatureHandlerGenerator(method, &buffer).generate(fingerprint);
// copy into code heap
address handler = set_handler(&buffer);
if (handler == NULL) {
- // use slow signature handler
+ // use slow signature handler (without memorizing it in the fingerprints)
} else {
// debugging suppport
- if (PrintSignatureHandlers) {
+ if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) {
tty->cr();
tty->print_cr("argument handler #%d for: %s %s (fingerprint = " UINT64_FORMAT ", %d bytes generated)",
_handlers->length(),
@@ -1218,7 +1229,10 @@
method->name_and_sig_as_C_string(),
fingerprint,
buffer.insts_size());
- Disassembler::decode(handler, handler + buffer.insts_size());
+ if (buffer.insts_size() > 0) {
+ // buffer may be empty for pregenerated handlers
+ Disassembler::decode(handler, handler + buffer.insts_size());
+ }
#ifndef PRODUCT
address rh_begin = Interpreter::result_handler(method()->result_type());
if (CodeCache::contains(rh_begin)) {
@@ -1277,6 +1291,37 @@
#endif // ASSERT
}
+void SignatureHandlerLibrary::add(uint64_t fingerprint, address handler) {
+ int handler_index = -1;
+ // use customized signature handler
+ MutexLocker mu(SignatureHandlerLibrary_lock);
+ // make sure data structure is initialized
+ initialize();
+ fingerprint = InterpreterRuntime::normalize_fast_native_fingerprint(fingerprint);
+ handler_index = _fingerprints->find(fingerprint);
+ // create handler if necessary
+ if (handler_index < 0) {
+ if (PrintSignatureHandlers && (handler != Interpreter::slow_signature_handler())) {
+ tty->cr();
+ tty->print_cr("argument handler #%d at "PTR_FORMAT" for fingerprint " UINT64_FORMAT,
+ _handlers->length(),
+ handler,
+ fingerprint);
+ }
+ _fingerprints->append(fingerprint);
+ _handlers->append(handler);
+ } else {
+ if (PrintSignatureHandlers) {
+ tty->cr();
+ tty->print_cr("duplicate argument handler #%d for fingerprint " UINT64_FORMAT "(old: "PTR_FORMAT", new : "PTR_FORMAT")",
+ _handlers->length(),
+ fingerprint,
+ _handlers->at(handler_index),
+ handler);
+ }
+ }
+}
+
BufferBlob* SignatureHandlerLibrary::_handler_blob = NULL;
address SignatureHandlerLibrary::_handler = NULL;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -219,6 +219,7 @@
public:
static void add(methodHandle method);
+ static void add(uint64_t fingerprint, address handler);
};
#endif // SHARE_VM_INTERPRETER_INTERPRETERRUNTIME_HPP
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -107,7 +107,7 @@
// more complicated solution is required. A special return bytecode
// is used only by Object.<init> to signal the finalization
// registration point. Additionally local 0 must be preserved so it's
-// available to pass to the registration function. For simplicty we
+// available to pass to the registration function. For simplicity we
// require that local 0 is never overwritten so it's available as an
// argument for registration.
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterGenerator.hpp"
#include "interpreter/interpreterRuntime.hpp"
@@ -49,10 +50,33 @@
TraceTime timer("Interpreter generation", TraceStartupTime);
int code_size = InterpreterCodeSize;
NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
+#if INCLUDE_JVMTI
+ if (CodeCacheExtensions::saving_generated_interpreter()) {
+ // May requires several versions of the codelets.
+ // Final size will automatically be optimized.
+ code_size *= 2;
+ }
+#endif
_code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
"Interpreter");
InterpreterGenerator g(_code);
- if (PrintInterpreter) print();
+ }
+ if (PrintInterpreter) {
+ if (CodeCacheExtensions::saving_generated_interpreter() &&
+ CodeCacheExtensions::use_pregenerated_interpreter()) {
+ ResourceMark rm;
+ tty->print("Printing the newly generated interpreter first");
+ print();
+ tty->print("Printing the pregenerated interpreter next");
+ }
+ }
+
+ // Install the pregenerated interpreter code before printing it
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::TemplateInterpreter);
+
+ if (PrintInterpreter) {
+ ResourceMark rm;
+ print();
}
// initialize dispatch table
@@ -214,194 +238,203 @@
};
void TemplateInterpreterGenerator::generate_all() {
- AbstractInterpreterGenerator::generate_all();
+ // Loop, in case we need several variants of the interpreter entries
+ do {
+ if (!CodeCacheExtensions::skip_code_generation()) {
+ // bypass code generation when useless
+ AbstractInterpreterGenerator::generate_all();
- { CodeletMark cm(_masm, "error exits");
- _unimplemented_bytecode = generate_error_exit("unimplemented bytecode");
- _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
- }
+ { CodeletMark cm(_masm, "error exits");
+ _unimplemented_bytecode = generate_error_exit("unimplemented bytecode");
+ _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
+ }
#ifndef PRODUCT
- if (TraceBytecodes) {
- CodeletMark cm(_masm, "bytecode tracing support");
- Interpreter::_trace_code =
- EntryPoint(
- generate_trace_code(btos),
- generate_trace_code(ctos),
- generate_trace_code(stos),
- generate_trace_code(atos),
- generate_trace_code(itos),
- generate_trace_code(ltos),
- generate_trace_code(ftos),
- generate_trace_code(dtos),
- generate_trace_code(vtos)
- );
- }
+ if (TraceBytecodes) {
+ CodeletMark cm(_masm, "bytecode tracing support");
+ Interpreter::_trace_code =
+ EntryPoint(
+ generate_trace_code(btos),
+ generate_trace_code(ctos),
+ generate_trace_code(stos),
+ generate_trace_code(atos),
+ generate_trace_code(itos),
+ generate_trace_code(ltos),
+ generate_trace_code(ftos),
+ generate_trace_code(dtos),
+ generate_trace_code(vtos)
+ );
+ }
#endif // !PRODUCT
- { CodeletMark cm(_masm, "return entry points");
- const int index_size = sizeof(u2);
- for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
- Interpreter::_return_entry[i] =
- EntryPoint(
- generate_return_entry_for(itos, i, index_size),
- generate_return_entry_for(itos, i, index_size),
- generate_return_entry_for(itos, i, index_size),
- generate_return_entry_for(atos, i, index_size),
- generate_return_entry_for(itos, i, index_size),
- generate_return_entry_for(ltos, i, index_size),
- generate_return_entry_for(ftos, i, index_size),
- generate_return_entry_for(dtos, i, index_size),
- generate_return_entry_for(vtos, i, index_size)
- );
- }
- }
+ { CodeletMark cm(_masm, "return entry points");
+ const int index_size = sizeof(u2);
+ for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
+ Interpreter::_return_entry[i] =
+ EntryPoint(
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(atos, i, index_size),
+ generate_return_entry_for(itos, i, index_size),
+ generate_return_entry_for(ltos, i, index_size),
+ generate_return_entry_for(ftos, i, index_size),
+ generate_return_entry_for(dtos, i, index_size),
+ generate_return_entry_for(vtos, i, index_size)
+ );
+ }
+ }
- { CodeletMark cm(_masm, "invoke return entry points");
- const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
- const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
- const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
- const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
+ { CodeletMark cm(_masm, "invoke return entry points");
+ const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos};
+ const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
+ const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
+ const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
- for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
- TosState state = states[i];
- Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
- Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
- Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
- }
- }
+ for (int i = 0; i < Interpreter::number_of_return_addrs; i++) {
+ TosState state = states[i];
+ Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2));
+ Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2));
+ Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
+ }
+ }
- { CodeletMark cm(_masm, "earlyret entry points");
- Interpreter::_earlyret_entry =
- EntryPoint(
- generate_earlyret_entry_for(btos),
- generate_earlyret_entry_for(ctos),
- generate_earlyret_entry_for(stos),
- generate_earlyret_entry_for(atos),
- generate_earlyret_entry_for(itos),
- generate_earlyret_entry_for(ltos),
- generate_earlyret_entry_for(ftos),
- generate_earlyret_entry_for(dtos),
- generate_earlyret_entry_for(vtos)
- );
- }
+ { CodeletMark cm(_masm, "earlyret entry points");
+ Interpreter::_earlyret_entry =
+ EntryPoint(
+ generate_earlyret_entry_for(btos),
+ generate_earlyret_entry_for(ctos),
+ generate_earlyret_entry_for(stos),
+ generate_earlyret_entry_for(atos),
+ generate_earlyret_entry_for(itos),
+ generate_earlyret_entry_for(ltos),
+ generate_earlyret_entry_for(ftos),
+ generate_earlyret_entry_for(dtos),
+ generate_earlyret_entry_for(vtos)
+ );
+ }
- { CodeletMark cm(_masm, "deoptimization entry points");
- for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
- Interpreter::_deopt_entry[i] =
- EntryPoint(
- generate_deopt_entry_for(itos, i),
- generate_deopt_entry_for(itos, i),
- generate_deopt_entry_for(itos, i),
- generate_deopt_entry_for(atos, i),
- generate_deopt_entry_for(itos, i),
- generate_deopt_entry_for(ltos, i),
- generate_deopt_entry_for(ftos, i),
- generate_deopt_entry_for(dtos, i),
- generate_deopt_entry_for(vtos, i)
- );
- }
- }
+ { CodeletMark cm(_masm, "deoptimization entry points");
+ for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
+ Interpreter::_deopt_entry[i] =
+ EntryPoint(
+ generate_deopt_entry_for(itos, i),
+ generate_deopt_entry_for(itos, i),
+ generate_deopt_entry_for(itos, i),
+ generate_deopt_entry_for(atos, i),
+ generate_deopt_entry_for(itos, i),
+ generate_deopt_entry_for(ltos, i),
+ generate_deopt_entry_for(ftos, i),
+ generate_deopt_entry_for(dtos, i),
+ generate_deopt_entry_for(vtos, i)
+ );
+ }
+ }
- { CodeletMark cm(_masm, "result handlers for native calls");
- // The various result converter stublets.
- int is_generated[Interpreter::number_of_result_handlers];
- memset(is_generated, 0, sizeof(is_generated));
+ { CodeletMark cm(_masm, "result handlers for native calls");
+ // The various result converter stublets.
+ int is_generated[Interpreter::number_of_result_handlers];
+ memset(is_generated, 0, sizeof(is_generated));
- for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
- BasicType type = types[i];
- if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
- Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
+ for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
+ BasicType type = types[i];
+ if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
+ Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
+ }
+ }
}
- }
- }
- { CodeletMark cm(_masm, "continuation entry points");
- Interpreter::_continuation_entry =
- EntryPoint(
- generate_continuation_for(btos),
- generate_continuation_for(ctos),
- generate_continuation_for(stos),
- generate_continuation_for(atos),
- generate_continuation_for(itos),
- generate_continuation_for(ltos),
- generate_continuation_for(ftos),
- generate_continuation_for(dtos),
- generate_continuation_for(vtos)
- );
- }
+ { CodeletMark cm(_masm, "continuation entry points");
+ Interpreter::_continuation_entry =
+ EntryPoint(
+ generate_continuation_for(btos),
+ generate_continuation_for(ctos),
+ generate_continuation_for(stos),
+ generate_continuation_for(atos),
+ generate_continuation_for(itos),
+ generate_continuation_for(ltos),
+ generate_continuation_for(ftos),
+ generate_continuation_for(dtos),
+ generate_continuation_for(vtos)
+ );
+ }
- { CodeletMark cm(_masm, "safepoint entry points");
- Interpreter::_safept_entry =
- EntryPoint(
- generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
- generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
- );
- }
+ { CodeletMark cm(_masm, "safepoint entry points");
+ Interpreter::_safept_entry =
+ EntryPoint(
+ generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
+ generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
+ );
+ }
- { CodeletMark cm(_masm, "exception handling");
- // (Note: this is not safepoint safe because thread may return to compiled code)
- generate_throw_exception();
- }
+ { CodeletMark cm(_masm, "exception handling");
+ // (Note: this is not safepoint safe because thread may return to compiled code)
+ generate_throw_exception();
+ }
- { CodeletMark cm(_masm, "throw exception entrypoints");
- Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
- Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" );
- Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero");
- Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
- Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL );
- Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
- }
+ { CodeletMark cm(_masm, "throw exception entrypoints");
+ Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
+ Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" );
+ Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero");
+ Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
+ Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL );
+ Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
+ }
-#define method_entry(kind) \
- { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
- Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind); \
- }
+#define method_entry(kind) \
+ { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
+ Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind); \
+ }
- // all non-native method kinds
- method_entry(zerolocals)
- method_entry(zerolocals_synchronized)
- method_entry(empty)
- method_entry(accessor)
- method_entry(abstract)
- method_entry(java_lang_math_sin )
- method_entry(java_lang_math_cos )
- method_entry(java_lang_math_tan )
- method_entry(java_lang_math_abs )
- method_entry(java_lang_math_sqrt )
- method_entry(java_lang_math_log )
- method_entry(java_lang_math_log10)
- method_entry(java_lang_math_exp )
- method_entry(java_lang_math_pow )
- method_entry(java_lang_ref_reference_get)
+ // all non-native method kinds
+ method_entry(zerolocals)
+ method_entry(zerolocals_synchronized)
+ method_entry(empty)
+ method_entry(accessor)
+ method_entry(abstract)
+ method_entry(java_lang_math_sin )
+ method_entry(java_lang_math_cos )
+ method_entry(java_lang_math_tan )
+ method_entry(java_lang_math_abs )
+ method_entry(java_lang_math_sqrt )
+ method_entry(java_lang_math_log )
+ method_entry(java_lang_math_log10)
+ method_entry(java_lang_math_exp )
+ method_entry(java_lang_math_pow )
+ method_entry(java_lang_ref_reference_get)
- if (UseCRC32Intrinsics) {
- method_entry(java_util_zip_CRC32_update)
- method_entry(java_util_zip_CRC32_updateBytes)
- method_entry(java_util_zip_CRC32_updateByteBuffer)
- }
+ if (UseCRC32Intrinsics) {
+ method_entry(java_util_zip_CRC32_update)
+ method_entry(java_util_zip_CRC32_updateBytes)
+ method_entry(java_util_zip_CRC32_updateByteBuffer)
+ }
- initialize_method_handle_entries();
+ initialize_method_handle_entries();
- // all native method kinds (must be one contiguous block)
- Interpreter::_native_entry_begin = Interpreter::code()->code_end();
- method_entry(native)
- method_entry(native_synchronized)
- Interpreter::_native_entry_end = Interpreter::code()->code_end();
+ // all native method kinds (must be one contiguous block)
+ Interpreter::_native_entry_begin = Interpreter::code()->code_end();
+ method_entry(native)
+ method_entry(native_synchronized)
+ Interpreter::_native_entry_end = Interpreter::code()->code_end();
#undef method_entry
- // Bytecodes
- set_entry_points_for_all_bytes();
+ // Bytecodes
+ set_entry_points_for_all_bytes();
+ }
+ } while (CodeCacheExtensions::needs_other_interpreter_variant());
+
+ // installation of code in other places in the runtime
+ // (ExcutableCodeManager calls not needed to copy the entries)
set_safepoints_for_all_bytes();
}
@@ -445,6 +478,9 @@
void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
+ if (CodeCacheExtensions::skip_template_interpreter_entries(code)) {
+ return;
+ }
CodeletMark cm(_masm, Bytecodes::name(code), code);
// initialize entry points
assert(_unimplemented_bytecode != NULL, "should have been generated before");
@@ -474,6 +510,7 @@
EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
Interpreter::_normal_table.set_entry(code, entry);
Interpreter::_wentry_point[code] = wep;
+ CodeCacheExtensions::completed_template_interpreter_entries(_masm, code);
}
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -87,6 +87,7 @@
friend class TemplateInterpreterGenerator;
friend class InterpreterGenerator;
friend class TemplateTable;
+ friend class CodeCacheExtensions;
// friend class Interpreter;
public:
--- a/hotspot/src/share/vm/memory/allocation.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/memory/allocation.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -752,7 +752,7 @@
julong AllocStats::resource_bytes() { return Arena::_bytes_allocated - start_res_bytes; }
void AllocStats::print() {
tty->print_cr(UINT64_FORMAT " mallocs (" UINT64_FORMAT "MB), "
- UINT64_FORMAT" frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
+ UINT64_FORMAT " frees (" UINT64_FORMAT "MB), " UINT64_FORMAT "MB resrc",
num_mallocs(), alloc_bytes()/M, num_frees(), free_bytes()/M, resource_bytes()/M);
}
--- a/hotspot/src/share/vm/memory/heap.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/memory/heap.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -28,6 +28,7 @@
#include "code/codeBlob.hpp"
#include "memory/allocation.hpp"
#include "memory/virtualspace.hpp"
+#include "utilities/macros.hpp"
// Blocks
@@ -80,6 +81,7 @@
class CodeHeap : public CHeapObj<mtCode> {
friend class VMStructs;
+ friend class PregeneratedCodeHeap;
private:
VirtualSpace _memory; // the memory holding the blocks
VirtualSpace _segmap; // the memory holding the segment map
@@ -148,8 +150,8 @@
char* high() const { return _memory.high(); }
char* high_boundary() const { return _memory.high_boundary(); }
- bool contains(const void* p) const { return low_boundary() <= p && p < high(); }
- void* find_start(void* p) const; // returns the block containing p or NULL
+ virtual bool contains(const void* p) const { return low_boundary() <= p && p < high(); }
+ virtual void* find_start(void* p) const; // returns the block containing p or NULL
size_t alignment_unit() const; // alignment of any block
size_t alignment_offset() const; // offset of first byte of any block, within the enclosing alignment unit
static size_t header_size(); // returns the header size for each heap block
@@ -158,9 +160,9 @@
int freelist_length() const { return _freelist_length; } // number of elements in the freelist
// returns the first block or NULL
- void* first() const { return next_used(first_block()); }
+ virtual void* first() const { return next_used(first_block()); }
// returns the next block given a block p or NULL
- void* next(void* p) const { return next_used(next_block(block_start(p))); }
+ virtual void* next(void* p) const { return next_used(next_block(block_start(p))); }
// Statistics
size_t capacity() const;
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -805,7 +805,7 @@
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
assert(alignment <= Arguments::conservative_max_heap_alignment(),
- err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT,
+ err_msg("actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT,
alignment, Arguments::conservative_max_heap_alignment()));
size_t total_reserved = align_size_up(heap_size, alignment);
--- a/hotspot/src/share/vm/memory/virtualspace.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "memory/virtualspace.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
@@ -603,7 +604,7 @@
ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
size_t rs_align,
bool large) :
- ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
+ ReservedSpace(r_size, rs_align, large, /*executable*/ CodeCacheExtensions::support_dynamic_code()) {
MemTracker::record_virtual_memory_type((address)base(), mtCode);
}
--- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1467,7 +1467,7 @@
}
case JVM_CONSTANT_Long: {
u8 val = Bytes::get_Java_u8(bytes);
- printf("long "INT64_FORMAT, (int64_t) *(jlong *) &val);
+ printf("long " INT64_FORMAT, (int64_t) *(jlong *) &val);
ent_size = 8;
idx++; // Long takes two cpool slots
break;
--- a/hotspot/src/share/vm/oops/cpCache.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -308,7 +308,7 @@
adapter->size_of_parameters());
if (TraceInvokeDynamic) {
- tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
+ tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method_type=" PTR_FORMAT "%s method=" PTR_FORMAT " ",
invoke_code,
(void *)appendix(), (has_appendix ? "" : " (unused)"),
(void *)method_type(), (has_method_type ? "" : " (unused)"),
@@ -538,12 +538,12 @@
// print separator
if (index == 0) st->print_cr(" -------------");
// print entry
- st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this);
+ st->print("%3d (" PTR_FORMAT ") ", index, (intptr_t)this);
st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(),
constant_pool_index());
- st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f1);
- st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2);
- st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags);
+ st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_f1);
+ st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_f2);
+ st->print_cr(" [ " PTR_FORMAT "]", (intptr_t)_flags);
st->print_cr(" -------------");
}
--- a/hotspot/src/share/vm/oops/markOop.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/markOop.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -49,7 +49,7 @@
st->print("monitor=NULL");
else {
BasicLock * bl = (BasicLock *) mon->owner();
- st->print("monitor={count="INTPTR_FORMAT",waiters="INTPTR_FORMAT",recursions="INTPTR_FORMAT",owner="INTPTR_FORMAT"}",
+ st->print("monitor={count=" INTPTR_FORMAT ",waiters=" INTPTR_FORMAT ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
mon->count(), mon->waiters(), mon->recursions(), p2i(bl));
}
} else {
--- a/hotspot/src/share/vm/oops/method.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2019,9 +2019,9 @@
assert(is_method(), "must be method");
st->print_cr("%s", internal_name());
// get the effect of PrintOopAddress, always, for methods:
- st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)this);
+ st->print_cr(" - this oop: " INTPTR_FORMAT, (intptr_t)this);
st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr();
- st->print (" - constants: "INTPTR_FORMAT" ", (address)constants());
+ st->print (" - constants: " INTPTR_FORMAT " ", (address)constants());
constants()->print_value_on(st); st->cr();
st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr();
st->print (" - name: "); name()->print_value_on(st); st->cr();
--- a/hotspot/src/share/vm/oops/method.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -82,7 +82,8 @@
_dont_inline = 1 << 3,
_hidden = 1 << 4,
_has_injected_profile = 1 << 5,
- _running_emcp = 1 << 6
+ _running_emcp = 1 << 6,
+ _intrinsic_candidate = 1 << 7
};
u1 _flags;
@@ -815,6 +816,13 @@
_flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
}
+ bool intrinsic_candidate() {
+ return (_flags & _intrinsic_candidate) != 0;
+ }
+ void set_intrinsic_candidate(bool x) {
+ _flags = x ? (_flags | _intrinsic_candidate) : (_flags & ~_intrinsic_candidate);
+ }
+
bool has_injected_profile() {
return (_flags & _has_injected_profile) != 0;
}
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -466,7 +466,7 @@
if (i > max_objArray_print_length) {
st->print("..."); break;
}
- st->print(" "INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
+ st->print(" " INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
}
st->print(" }");
}
--- a/hotspot/src/share/vm/oops/oop.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -47,7 +47,7 @@
void oopDesc::print_address_on(outputStream* st) const {
if (PrintOopAddress) {
- st->print("{"INTPTR_FORMAT"}", this);
+ st->print("{" INTPTR_FORMAT "}", this);
}
}
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -688,6 +688,12 @@
product(bool, UseMulAddIntrinsic, false, \
"Enables intrinsification of BigInteger.mulAdd()") \
\
+ product(bool, UseMontgomeryMultiplyIntrinsic, false, \
+ "Enables intrinsification of BigInteger.montgomeryMultiply()") \
+ \
+ product(bool, UseMontgomerySquareIntrinsic, false, \
+ "Enables intrinsification of BigInteger.montgomerySquare()") \
+ \
product(bool, UseTypeSpeculation, true, \
"Speculatively propagate types from profiles") \
\
--- a/hotspot/src/share/vm/opto/callnode.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -342,7 +342,7 @@
const Type *t = n->bottom_type();
switch (t->base()) {
case Type::Int:
- st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con());
+ st->print(" %s%d]=#" INT32_FORMAT,msg,i,t->is_int()->get_con());
break;
case Type::AnyPtr:
assert( t == TypePtr::NULL_PTR || n->in_dump(), "" );
@@ -371,7 +371,7 @@
st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f);
break;
case Type::Long:
- st->print(" %s%d]=#"INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con()));
+ st->print(" %s%d]=#" INT64_FORMAT,msg,i,(int64_t)(t->is_long()->get_con()));
break;
case Type::Half:
case Type::Top:
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -976,8 +976,10 @@
strcmp(call->as_CallLeaf()->_name, "sha512_implCompressMB") == 0 ||
strcmp(call->as_CallLeaf()->_name, "multiplyToLen") == 0 ||
strcmp(call->as_CallLeaf()->_name, "squareToLen") == 0 ||
- strcmp(call->as_CallLeaf()->_name, "mulAdd") == 0)
- ))) {
+ strcmp(call->as_CallLeaf()->_name, "mulAdd") == 0 ||
+ strcmp(call->as_CallLeaf()->_name, "montgomery_multiply") == 0 ||
+ strcmp(call->as_CallLeaf()->_name, "montgomery_square") == 0)
+ ))) {
call->dump();
fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name));
}
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -118,19 +118,14 @@
// The C routines gets the base of thread-local storage passed in as an
// extra argument. Not all calls need it, but its cheap to add here.
for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
- // Convert ints to longs if required.
- if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
- fields[cnt++] = TypeLong::LONG;
- fields[cnt] = Type::HALF; // must add an additional half for a long
- } else {
- fields[cnt] = jdomain->field_at(pcnt);
- }
+ fields[cnt] = jdomain->field_at(pcnt);
}
fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
// Also pass in the caller's PC, if asked for.
- if( return_pc )
+ if (return_pc) {
fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
+ }
const TypeTuple* domain = TypeTuple::make(cnt,fields);
// The C routine we are about to call cannot return an oop; it can block on
@@ -143,21 +138,22 @@
const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
// Fixup oop returns
int retval_ptr = retval->isa_oop_ptr();
- if( retval_ptr ) {
+ if (retval_ptr) {
assert( pass_tls, "Oop must be returned thru TLS" );
// Fancy-jumps return address; others return void
rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
- } else if( retval->isa_int() ) { // Returning any integer subtype?
+ } else if (retval->isa_int()) { // Returning any integer subtype?
// "Fatten" byte, char & short return types to 'int' to show that
// the native C code can return values with junk high order bits.
// We'll sign-extend it below later.
rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
- } else if( jrange->cnt() >= TypeFunc::Parms+1 ) { // Else copy other types
+ } else if (jrange->cnt() >= TypeFunc::Parms+1) { // Else copy other types
rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
- if( jrange->cnt() == TypeFunc::Parms+2 )
+ if (jrange->cnt() == TypeFunc::Parms+2) {
rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
+ }
}
const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
@@ -181,14 +177,7 @@
// A little too aggressive on the parm copy; return address is not an input
call->set_req(TypeFunc::ReturnAdr, top());
for (; i < parm_cnt; i++) { // Regular input arguments
- // Convert ints to longs if required.
- if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(i)->isa_int()) {
- Node* int_as_long = _gvn.transform(new ConvI2LNode(map()->in(i)));
- call->init_req(cnt++, int_as_long); // long
- call->init_req(cnt++, top()); // half
- } else {
- call->init_req(cnt++, map()->in(i));
- }
+ call->init_req(cnt++, map()->in(i));
}
call->init_req( cnt++, thread );
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -297,6 +297,8 @@
bool inline_multiplyToLen();
bool inline_squareToLen();
bool inline_mulAdd();
+ bool inline_montgomeryMultiply();
+ bool inline_montgomerySquare();
bool inline_profileBoolean();
bool inline_isCompileConstant();
@@ -508,6 +510,13 @@
if (!UseMulAddIntrinsic) return NULL;
break;
+ case vmIntrinsics::_montgomeryMultiply:
+ if (!UseMontgomeryMultiplyIntrinsic) return NULL;
+ break;
+ case vmIntrinsics::_montgomerySquare:
+ if (!UseMontgomerySquareIntrinsic) return NULL;
+ break;
+
case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
if (!UseAESIntrinsics) return NULL;
@@ -642,7 +651,8 @@
const int bci = kit.bci();
// Try to inline the intrinsic.
- if (kit.try_to_inline(_last_predicate)) {
+ if ((CheckIntrinsics ? callee->intrinsic_candidate() : true) &&
+ kit.try_to_inline(_last_predicate)) {
if (C->print_intrinsics() || C->print_inlining()) {
C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)");
}
@@ -663,7 +673,13 @@
if (C->print_intrinsics() || C->print_inlining()) {
if (jvms->has_method()) {
// Not a root compile.
- const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+ const char* msg;
+ if (callee->intrinsic_candidate()) {
+ msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+ } else {
+ msg = is_virtual() ? "failed to inline (intrinsic, virtual), method not annotated"
+ : "failed to inline (intrinsic), method not annotated";
+ }
C->print_inlining(callee, jvms->depth() - 1, bci, msg);
} else {
// Root compile
@@ -942,6 +958,11 @@
case vmIntrinsics::_mulAdd:
return inline_mulAdd();
+ case vmIntrinsics::_montgomeryMultiply:
+ return inline_montgomeryMultiply();
+ case vmIntrinsics::_montgomerySquare:
+ return inline_montgomerySquare();
+
case vmIntrinsics::_ghash_processBlocks:
return inline_ghash_processBlocks();
@@ -5244,7 +5265,7 @@
//-------------inline_multiplyToLen-----------------------------------
bool LibraryCallKit::inline_multiplyToLen() {
- assert(UseMultiplyToLenIntrinsic, "not implementated on this platform");
+ assert(UseMultiplyToLenIntrinsic, "not implemented on this platform");
address stubAddr = StubRoutines::multiplyToLen();
if (stubAddr == NULL) {
@@ -5254,11 +5275,12 @@
assert(callee()->signature()->size() == 5, "multiplyToLen has 5 parameters");
- Node* x = argument(1);
- Node* xlen = argument(2);
- Node* y = argument(3);
- Node* ylen = argument(4);
- Node* z = argument(5);
+ // no receiver because it is a static method
+ Node* x = argument(0);
+ Node* xlen = argument(1);
+ Node* y = argument(2);
+ Node* ylen = argument(3);
+ Node* z = argument(4);
const Type* x_type = x->Value(&_gvn);
const Type* y_type = y->Value(&_gvn);
@@ -5437,6 +5459,121 @@
return true;
}
+//-------------inline_montgomeryMultiply-----------------------------------
+bool LibraryCallKit::inline_montgomeryMultiply() {
+ address stubAddr = StubRoutines::montgomeryMultiply();
+ if (stubAddr == NULL) {
+ return false; // Intrinsic's stub is not implemented on this platform
+ }
+
+ assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform");
+ const char* stubName = "montgomery_square";
+
+ assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters");
+
+ Node* a = argument(0);
+ Node* b = argument(1);
+ Node* n = argument(2);
+ Node* len = argument(3);
+ Node* inv = argument(4);
+ Node* m = argument(6);
+
+ const Type* a_type = a->Value(&_gvn);
+ const TypeAryPtr* top_a = a_type->isa_aryptr();
+ const Type* b_type = b->Value(&_gvn);
+ const TypeAryPtr* top_b = b_type->isa_aryptr();
+ const Type* n_type = a->Value(&_gvn);
+ const TypeAryPtr* top_n = n_type->isa_aryptr();
+ const Type* m_type = a->Value(&_gvn);
+ const TypeAryPtr* top_m = m_type->isa_aryptr();
+ if (top_a == NULL || top_a->klass() == NULL ||
+ top_b == NULL || top_b->klass() == NULL ||
+ top_n == NULL || top_n->klass() == NULL ||
+ top_m == NULL || top_m->klass() == NULL) {
+ // failed array check
+ return false;
+ }
+
+ BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType b_elem = b_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ if (a_elem != T_INT || b_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
+ return false;
+ }
+
+ // Make the call
+ {
+ Node* a_start = array_element_address(a, intcon(0), a_elem);
+ Node* b_start = array_element_address(b, intcon(0), b_elem);
+ Node* n_start = array_element_address(n, intcon(0), n_elem);
+ Node* m_start = array_element_address(m, intcon(0), m_elem);
+
+ Node* call = make_runtime_call(RC_LEAF,
+ OptoRuntime::montgomeryMultiply_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ a_start, b_start, n_start, len, inv, top(),
+ m_start);
+ set_result(m);
+ }
+
+ return true;
+}
+
+bool LibraryCallKit::inline_montgomerySquare() {
+ address stubAddr = StubRoutines::montgomerySquare();
+ if (stubAddr == NULL) {
+ return false; // Intrinsic's stub is not implemented on this platform
+ }
+
+ assert(UseMontgomerySquareIntrinsic, "not implemented on this platform");
+ const char* stubName = "montgomery_square";
+
+ assert(callee()->signature()->size() == 6, "montgomerySquare has 6 parameters");
+
+ Node* a = argument(0);
+ Node* n = argument(1);
+ Node* len = argument(2);
+ Node* inv = argument(3);
+ Node* m = argument(5);
+
+ const Type* a_type = a->Value(&_gvn);
+ const TypeAryPtr* top_a = a_type->isa_aryptr();
+ const Type* n_type = a->Value(&_gvn);
+ const TypeAryPtr* top_n = n_type->isa_aryptr();
+ const Type* m_type = a->Value(&_gvn);
+ const TypeAryPtr* top_m = m_type->isa_aryptr();
+ if (top_a == NULL || top_a->klass() == NULL ||
+ top_n == NULL || top_n->klass() == NULL ||
+ top_m == NULL || top_m->klass() == NULL) {
+ // failed array check
+ return false;
+ }
+
+ BasicType a_elem = a_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType n_elem = n_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType m_elem = m_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ if (a_elem != T_INT || n_elem != T_INT || m_elem != T_INT) {
+ return false;
+ }
+
+ // Make the call
+ {
+ Node* a_start = array_element_address(a, intcon(0), a_elem);
+ Node* n_start = array_element_address(n, intcon(0), n_elem);
+ Node* m_start = array_element_address(m, intcon(0), m_elem);
+
+ Node* call = make_runtime_call(RC_LEAF,
+ OptoRuntime::montgomerySquare_Type(),
+ stubAddr, stubName, TypePtr::BOTTOM,
+ a_start, n_start, len, inv, top(),
+ m_start);
+ set_result(m);
+ }
+
+ return true;
+}
+
/**
* Calculate CRC32 for byte.
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -2941,13 +2941,6 @@
_igvn.register_new_node_with_optimizer(store_value);
}
- if (CCallingConventionRequiresIntsAsLongs &&
- // See StubRoutines::select_fill_function for types. FLOAT has been converted to INT.
- (t == T_FLOAT || t == T_INT || is_subword_type(t))) {
- store_value = new ConvI2LNode(store_value);
- _igvn.register_new_node_with_optimizer(store_value);
- }
-
Node* mem_phi = store->in(MemNode::Memory);
Node* result_ctrl;
Node* result_mem;
@@ -2957,9 +2950,6 @@
uint cnt = 0;
call->init_req(TypeFunc::Parms + cnt++, from);
call->init_req(TypeFunc::Parms + cnt++, store_value);
- if (CCallingConventionRequiresIntsAsLongs) {
- call->init_req(TypeFunc::Parms + cnt++, C->top());
- }
#ifdef _LP64
len = new ConvI2LNode(len);
_igvn.register_new_node_with_optimizer(len);
--- a/hotspot/src/share/vm/opto/regmask.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/regmask.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "opto/ad.hpp"
#include "opto/compile.hpp"
+#include "opto/matcher.hpp"
+#include "opto/node.hpp"
#include "opto/regmask.hpp"
#define RM_SIZE _RM_SIZE /* a constant private to the class RegMask */
--- a/hotspot/src/share/vm/opto/runtime.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -779,18 +779,10 @@
const TypeFunc* OptoRuntime::array_fill_Type() {
const Type** fields;
int argp = TypeFunc::Parms;
- if (CCallingConventionRequiresIntsAsLongs) {
// create input type (domain): pointer, int, size_t
- fields = TypeTuple::fields(3 LP64_ONLY( + 2));
- fields[argp++] = TypePtr::NOTNULL;
- fields[argp++] = TypeLong::LONG;
- fields[argp++] = Type::HALF;
- } else {
- // create input type (domain): pointer, int, size_t
- fields = TypeTuple::fields(3 LP64_ONLY( + 1));
- fields[argp++] = TypePtr::NOTNULL;
- fields[argp++] = TypeInt::INT;
- }
+ fields = TypeTuple::fields(3 LP64_ONLY( + 1));
+ fields[argp++] = TypePtr::NOTNULL;
+ fields[argp++] = TypeInt::INT;
fields[argp++] = TypeX_X; // size in whatevers (size_t)
LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
const TypeTuple *domain = TypeTuple::make(argp, fields);
@@ -1010,6 +1002,53 @@
return TypeFunc::make(domain, range);
}
+const TypeFunc* OptoRuntime::montgomeryMultiply_Type() {
+ // create input type (domain)
+ int num_args = 7;
+ int argcnt = num_args;
+ const Type** fields = TypeTuple::fields(argcnt);
+ int argp = TypeFunc::Parms;
+ fields[argp++] = TypePtr::NOTNULL; // a
+ fields[argp++] = TypePtr::NOTNULL; // b
+ fields[argp++] = TypePtr::NOTNULL; // n
+ fields[argp++] = TypeInt::INT; // len
+ fields[argp++] = TypeLong::LONG; // inv
+ fields[argp++] = Type::HALF;
+ fields[argp++] = TypePtr::NOTNULL; // result
+ assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+ const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+ // result type needed
+ fields = TypeTuple::fields(1);
+ fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
+
+ const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+ return TypeFunc::make(domain, range);
+}
+
+const TypeFunc* OptoRuntime::montgomerySquare_Type() {
+ // create input type (domain)
+ int num_args = 6;
+ int argcnt = num_args;
+ const Type** fields = TypeTuple::fields(argcnt);
+ int argp = TypeFunc::Parms;
+ fields[argp++] = TypePtr::NOTNULL; // a
+ fields[argp++] = TypePtr::NOTNULL; // n
+ fields[argp++] = TypeInt::INT; // len
+ fields[argp++] = TypeLong::LONG; // inv
+ fields[argp++] = Type::HALF;
+ fields[argp++] = TypePtr::NOTNULL; // result
+ assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+ const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+ // result type needed
+ fields = TypeTuple::fields(1);
+ fields[TypeFunc::Parms+0] = TypePtr::NOTNULL;
+
+ const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+ return TypeFunc::make(domain, range);
+}
+
// GHASH block processing
const TypeFunc* OptoRuntime::ghash_processBlocks_Type() {
int argcnt = 4;
--- a/hotspot/src/share/vm/opto/runtime.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/opto/runtime.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -311,6 +311,8 @@
static const TypeFunc* digestBase_implCompressMB_Type();
static const TypeFunc* multiplyToLen_Type();
+ static const TypeFunc* montgomeryMultiply_Type();
+ static const TypeFunc* montgomerySquare_Type();
static const TypeFunc* squareToLen_Type();
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -57,12 +57,15 @@
# include "classfile/classFileParser.hpp"
# include "classfile/classFileStream.hpp"
# include "classfile/classLoader.hpp"
+# include "classfile/imageDecompressor.hpp"
+# include "classfile/imageFile.hpp"
# include "classfile/javaClasses.hpp"
# include "classfile/symbolTable.hpp"
# include "classfile/systemDictionary.hpp"
# include "classfile/vmSymbols.hpp"
# include "code/codeBlob.hpp"
# include "code/codeCache.hpp"
+# include "code/codeCacheExtensions.hpp"
# include "code/compressedStream.hpp"
# include "code/debugInfo.hpp"
# include "code/debugInfoRec.hpp"
@@ -229,6 +232,7 @@
# include "utilities/constantTag.hpp"
# include "utilities/copy.hpp"
# include "utilities/debug.hpp"
+# include "utilities/endian.hpp"
# include "utilities/exceptions.hpp"
# include "utilities/globalDefinitions.hpp"
# include "utilities/growableArray.hpp"
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -3848,6 +3848,7 @@
unit_test_function_call
// Forward declaration
+void test_semaphore();
void TestOS_test();
void TestReservedSpace_test();
void TestReserveMemorySpecial_test();
@@ -3873,6 +3874,7 @@
void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) {
tty->print_cr("Running internal VM tests");
+ run_unit_test(test_semaphore());
run_unit_test(TestOS_test());
run_unit_test(TestReservedSpace_test());
run_unit_test(TestReserveMemorySpecial_test());
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
+#include "classfile/imageDecompressor.hpp"
+#include "classfile/imageFile.hpp"
#include "classfile/javaAssertions.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
@@ -69,6 +71,7 @@
#include "utilities/copy.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
+#include "utilities/endian.hpp"
#include "utilities/events.hpp"
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
@@ -3665,3 +3668,244 @@
info->is_attachable = AttachListener::is_attach_supported();
}
JVM_END
+
+// jdk.internal.jimage /////////////////////////////////////////////////////////
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+
+// Java entry to open an image file for sharing.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian)) {
+ JVMWrapper("JVM_ImageOpen");
+ // Open image file for reading.
+ ImageFileReader* reader = ImageFileReader::open(nativePath, big_endian != JNI_FALSE);
+ // Return image ID as a jlong.
+ return ImageFileReader::readerToID(reader);
+}
+JVM_END
+
+// Java entry for closing a shared image file.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(void,
+JVM_ImageClose(JNIEnv *env, jlong id)) {
+ JVMWrapper("JVM_ImageClose");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // If valid reader the close.
+ if (reader != NULL) {
+ ImageFileReader::close(reader);
+ }
+}
+JVM_END
+
+// Java entry for accessing the base address of the image index.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageGetIndexAddress(JNIEnv *env, jlong id)) {
+ JVMWrapper("JVM_ImageGetIndexAddress");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // If valid reader return index base address (as jlong) else zero.
+ return reader != NULL ? (jlong)reader->get_index_address() : 0L;
+}
+JVM_END
+
+// Java entry for accessing the base address of the image data.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong,
+JVM_ImageGetDataAddress(JNIEnv *env, jlong id)) {
+ JVMWrapper("JVM_ImageGetDataAddress");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // If valid reader return data base address (as jlong) else zero.
+ return MemoryMapImage && reader != NULL ? (jlong)reader->get_data_address() : 0L;
+}
+JVM_END
+
+// Java entry for reading an uncompressed resource from the image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jboolean,
+JVM_ImageRead(JNIEnv *env, jlong id, jlong offset,
+ unsigned char* uncompressedAddress, jlong uncompressed_size)) {
+ JVMWrapper("JVM_ImageRead");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);\
+ // If not a valid reader the fail the read.
+ if (reader == NULL) return false;
+ // Get the file offset of resource data.
+ u8 file_offset = reader->get_index_size() + offset;
+ // Check validity of arguments.
+ if (offset < 0 ||
+ uncompressed_size < 0 ||
+ file_offset > reader->file_size() - uncompressed_size) {
+ return false;
+ }
+ // Read file content into buffer.
+ return (jboolean)reader->read_at((u1*)uncompressedAddress, uncompressed_size,
+ file_offset);
+}
+JVM_END
+
+// Java entry for reading a compressed resource from the image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jboolean,
+JVM_ImageReadCompressed(JNIEnv *env,
+ jlong id, jlong offset,
+ unsigned char* compressedAddress, jlong compressed_size,
+ unsigned char* uncompressedAddress, jlong uncompressed_size)) {
+ JVMWrapper("JVM_ImageReadCompressed");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // If not a valid reader the fail the read.
+ if (reader == NULL) return false;
+ // Get the file offset of resource data.
+ u8 file_offset = reader->get_index_size() + offset;
+ // Check validity of arguments.
+ if (offset < 0 ||
+ compressed_size < 0 ||
+ uncompressed_size < 0 ||
+ file_offset > reader->file_size() - compressed_size) {
+ return false;
+ }
+
+ // Read file content into buffer.
+ bool is_read = reader->read_at(compressedAddress, compressed_size,
+ file_offset);
+ // If successfully read then decompress.
+ if (is_read) {
+ const ImageStrings strings = reader->get_strings();
+ ImageDecompressor::decompress_resource(compressedAddress, uncompressedAddress,
+ uncompressed_size, &strings, true);
+ }
+ return (jboolean)is_read;
+}
+JVM_END
+
+// Java entry for retrieving UTF-8 bytes from image string table.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(const char*, JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset)) {
+ JVMWrapper("JVM_ImageGetStringBytes");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // Fail if not valid reader.
+ if (reader == NULL) return NULL;
+ // Manage image string table.
+ ImageStrings strings = reader->get_strings();
+ // Retrieve string adrress from table.
+ const char* data = strings.get(offset);
+ return data;
+}
+JVM_END
+
+// Utility function to copy location information into a jlong array.
+// WARNING: This function is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+static void image_expand_location(JNIEnv *env, jlong* rawAttributes, ImageLocation& location) {
+ // Copy attributes from location.
+ for (int kind = ImageLocation::ATTRIBUTE_END + 1;
+ kind < ImageLocation::ATTRIBUTE_COUNT;
+ kind++) {
+ rawAttributes[kind] = location.get_attribute(kind);
+ }
+}
+
+// Java entry for retrieving location attributes for attribute offset.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong*, JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset)) {
+ JVMWrapper("JVM_ImageGetAttributes");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // Fail if not valid reader.
+ if (reader == NULL) return NULL;
+ // Retrieve first byte address of resource's location attribute stream.
+ u1* data = reader->get_location_offset_data(offset);
+ // Fail if not valid offset.
+ if (data == NULL) return NULL;
+ // Expand stream into array.
+ ImageLocation location(data);
+ image_expand_location(env, rawAttributes, location);
+ return rawAttributes;
+}
+JVM_END
+
+// Java entry for retrieving location attributes count for attribute offset.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jsize, JVM_ImageGetAttributesCount(JNIEnv *env)) {
+ JVMWrapper("JVM_ImageGetAttributesCount");
+ return ImageLocation::ATTRIBUTE_COUNT;
+}
+JVM_END
+
+// Java entry for retrieving location attributes for named resource.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jlong*,
+JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id)) {
+ JVMWrapper("JVM_ImageFindAttributes");
+ // Mark for temporary buffers.
+ ResourceMark rm;
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // Fail if not valid reader.
+ if (reader == NULL) return NULL;
+ // Convert byte array to a cstring.
+ char* path = NEW_RESOURCE_ARRAY(char, size + 1);
+ memcpy(path, rawBytes, size);
+ path[size] = '\0';
+ // Locate resource location data.
+ ImageLocation location;
+ bool found = reader->find_location(path, location);
+ // Resource not found.
+ if (!found) return NULL;
+ // Expand stream into array.
+ image_expand_location(env, rawAttributes, location);
+ return rawAttributes;
+}
+JVM_END
+
+// Java entry for retrieving all the attribute stream offsets from an image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(jint*, JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id)) {
+ JVMWrapper("JVM_ImageAttributeOffsets");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // Fail if not valid reader.
+ if (reader == NULL) return NULL;
+ // Determine endian for reader.
+ Endian* endian = reader->endian();
+ // Get base address of attribute stream offsets table.
+ u4* offsets_table = reader->offsets_table();
+ // Allocate int array result.
+ // Copy values to result (converting endian.)
+ for (u4 i = 0; i < length; i++) {
+ rawOffsets[i] = endian->get(offsets_table[i]);
+ }
+ return rawOffsets;
+}
+JVM_END
+
+// Java entry for retrieving all the attribute stream offsets length from an image.
+// WARNING: This API is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+JVM_ENTRY(unsigned int, JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id)) {
+ JVMWrapper("JVM_ImageAttributeOffsetsLength");
+ // Convert image ID to image reader structure.
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ // Fail if not valid reader.
+ if (reader == NULL) return 0;
+ // Get perfect hash table length.
+ u4 length = reader->table_length();
+ return (jint) length;
+}
+JVM_END
--- a/hotspot/src/share/vm/prims/jvm.h Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h Thu Jul 16 19:28:37 2015 -0700
@@ -571,6 +571,52 @@
JNIEXPORT jboolean JNICALL
JVM_SupportsCX8(void);
+/*
+ * jdk.internal.jimage
+ * WARNING: This API is experimental and temporary during JDK 9 development
+ * cycle. It will not be supported in the eventual JDK 9 release.
+ */
+
+JNIEXPORT jlong JNICALL
+JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian);
+
+JNIEXPORT void JNICALL
+JVM_ImageClose(JNIEnv *env, jlong id);
+
+JNIEXPORT jlong JNICALL
+JVM_ImageGetIndexAddress(JNIEnv *env, jlong id);
+
+JNIEXPORT jlong JNICALL
+JVM_ImageGetDataAddress(JNIEnv *env,jlong id);
+
+JNIEXPORT jboolean JNICALL
+JVM_ImageRead(JNIEnv *env, jlong id, jlong offset,
+ unsigned char* uncompressedAddress, jlong uncompressed_size);
+
+
+JNIEXPORT jboolean JNICALL
+JVM_ImageReadCompressed(JNIEnv *env, jlong id, jlong offset,
+ unsigned char* compressedBuffer, jlong compressed_size,
+ unsigned char* uncompressedBuffer, jlong uncompressed_size);
+
+JNIEXPORT const char* JNICALL
+JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset);
+
+JNIEXPORT jlong* JNICALL
+JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset);
+
+JNIEXPORT jsize JNICALL
+JVM_ImageGetAttributesCount(JNIEnv *env);
+
+JNIEXPORT jlong* JNICALL
+JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id);
+
+JNIEXPORT jint* JNICALL
+JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id);
+
+JNIEXPORT unsigned int JNICALL
+JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id);
+
/*************************************************************************
PART 2: Support for the Verifier and Class File Format Checker
************************************************************************/
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -26,6 +26,7 @@
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
@@ -100,6 +101,7 @@
StubCodeMark mark(this, "MethodHandle::interpreter_entry", vmIntrinsics::name_at(iid));
address entry = MethodHandles::generate_method_handle_interpreter_entry(_masm, iid);
if (entry != NULL) {
+ CodeCacheExtensions::handle_generated_pc(entry, vmIntrinsics::name_at(iid));
Interpreter::set_entry_for_kind(mk, entry);
}
// If the entry is not set, it will throw AbstractMethodError.
@@ -1389,41 +1391,41 @@
#define LANG "Ljava/lang/"
#define JLINV "Ljava/lang/invoke/"
-#define OBJ LANG"Object;"
-#define CLS LANG"Class;"
-#define STRG LANG"String;"
-#define CS JLINV"CallSite;"
-#define MT JLINV"MethodType;"
-#define MH JLINV"MethodHandle;"
-#define MEM JLINV"MemberName;"
-#define CTX JLINV"MethodHandleNatives$CallSiteContext;"
+#define OBJ LANG "Object;"
+#define CLS LANG "Class;"
+#define STRG LANG "String;"
+#define CS JLINV "CallSite;"
+#define MT JLINV "MethodType;"
+#define MH JLINV "MethodHandle;"
+#define MEM JLINV "MemberName;"
+#define CTX JLINV "MethodHandleNatives$CallSiteContext;"
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
// These are the native methods on java.lang.invoke.MethodHandleNatives.
static JNINativeMethod MHN_methods[] = {
- {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
- {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
- {CC"resolve", CC"("MEM""CLS")"MEM, FN_PTR(MHN_resolve_Mem)},
+ {CC "init", CC "(" MEM "" OBJ ")V", FN_PTR(MHN_init_Mem)},
+ {CC "expand", CC "(" MEM ")V", FN_PTR(MHN_expand_Mem)},
+ {CC "resolve", CC "(" MEM "" CLS ")" MEM, FN_PTR(MHN_resolve_Mem)},
// static native int getNamedCon(int which, Object[] name)
- {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)},
+ {CC "getNamedCon", CC "(I[" OBJ ")I", FN_PTR(MHN_getNamedCon)},
// static native int getMembers(Class<?> defc, String matchName, String matchSig,
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
- {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
- {CC"objectFieldOffset", CC"("MEM")J", FN_PTR(MHN_objectFieldOffset)},
- {CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)},
- {CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
- {CC"clearCallSiteContext", CC"("CTX")V", FN_PTR(MHN_clearCallSiteContext)},
- {CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)},
- {CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)},
- {CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
+ {CC "getMembers", CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
+ {CC "objectFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_objectFieldOffset)},
+ {CC "setCallSiteTargetNormal", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetNormal)},
+ {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V", FN_PTR(MHN_setCallSiteTargetVolatile)},
+ {CC "clearCallSiteContext", CC "(" CTX ")V", FN_PTR(MHN_clearCallSiteContext)},
+ {CC "staticFieldOffset", CC "(" MEM ")J", FN_PTR(MHN_staticFieldOffset)},
+ {CC "staticFieldBase", CC "(" MEM ")" OBJ, FN_PTR(MHN_staticFieldBase)},
+ {CC "getMemberVMInfo", CC "(" MEM ")" OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
static JNINativeMethod MH_methods[] = {
// UnsupportedOperationException throwers
- {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
- {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
+ {CC "invoke", CC "([" OBJ ")" OBJ, FN_PTR(MH_invoke_UOE)},
+ {CC "invokeExact", CC "([" OBJ ")" OBJ, FN_PTR(MH_invokeExact_UOE)}
};
/**
--- a/hotspot/src/share/vm/prims/perf.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/perf.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -295,17 +295,17 @@
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
#define BB "Ljava/nio/ByteBuffer;"
#define JLS "Ljava/lang/String;"
-#define CL_ARGS CC"("JLS"IIJ)"BB
-#define CBA_ARGS CC"("JLS"II[BI)"BB
+#define CL_ARGS CC "(" JLS "IIJ)" BB
+#define CBA_ARGS CC "(" JLS "II[BI)" BB
static JNINativeMethod perfmethods[] = {
- {CC"attach", CC"("JLS"II)"BB, FN_PTR(Perf_Attach)},
- {CC"detach", CC"("BB")V", FN_PTR(Perf_Detach)},
- {CC"createLong", CL_ARGS, FN_PTR(Perf_CreateLong)},
- {CC"createByteArray", CBA_ARGS, FN_PTR(Perf_CreateByteArray)},
- {CC"highResCounter", CC"()J", FN_PTR(Perf_HighResCounter)},
- {CC"highResFrequency", CC"()J", FN_PTR(Perf_HighResFrequency)}
+ {CC "attach", CC "(" JLS "II)" BB, FN_PTR(Perf_Attach)},
+ {CC "detach", CC "(" BB ")V", FN_PTR(Perf_Detach)},
+ {CC "createLong", CL_ARGS, FN_PTR(Perf_CreateLong)},
+ {CC "createByteArray", CBA_ARGS, FN_PTR(Perf_CreateByteArray)},
+ {CC "highResCounter", CC "()J", FN_PTR(Perf_HighResCounter)},
+ {CC "highResFrequency", CC "()J", FN_PTR(Perf_HighResFrequency)}
};
#undef CBA_ARGS
--- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1206,39 +1206,39 @@
#define LANG "Ljava/lang/"
-#define OBJ LANG"Object;"
-#define CLS LANG"Class;"
-#define FLD LANG"reflect/Field;"
-#define THR LANG"Throwable;"
+#define OBJ LANG "Object;"
+#define CLS LANG "Class;"
+#define FLD LANG "reflect/Field;"
+#define THR LANG "Throwable;"
-#define DC_Args LANG"String;[BII" LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
-#define DAC_Args CLS"[B["OBJ
+#define DC_Args LANG "String;[BII" LANG "ClassLoader;" "Ljava/security/ProtectionDomain;"
+#define DAC_Args CLS "[B[" OBJ
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
#define DECLARE_GETPUTOOP(Boolean, Z) \
- {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \
- {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)}, \
- {CC"get"#Boolean"Volatile", CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean##Volatile)}, \
- {CC"put"#Boolean"Volatile", CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean##Volatile)}
+ {CC "get" #Boolean, CC "(" OBJ "J)" #Z, FN_PTR(Unsafe_Get##Boolean)}, \
+ {CC "put" #Boolean, CC "(" OBJ "J" #Z ")V", FN_PTR(Unsafe_Set##Boolean)}, \
+ {CC "get" #Boolean "Volatile", CC "(" OBJ "J)" #Z, FN_PTR(Unsafe_Get##Boolean##Volatile)}, \
+ {CC "put" #Boolean "Volatile", CC "(" OBJ "J" #Z ")V", FN_PTR(Unsafe_Set##Boolean##Volatile)}
#define DECLARE_GETPUTNATIVE(Byte, B) \
- {CC"get"#Byte, CC"("ADR")"#B, FN_PTR(Unsafe_GetNative##Byte)}, \
- {CC"put"#Byte, CC"("ADR#B")V", FN_PTR(Unsafe_SetNative##Byte)}
+ {CC "get" #Byte, CC "(" ADR ")" #B, FN_PTR(Unsafe_GetNative##Byte)}, \
+ {CC "put" #Byte, CC "(" ADR#B ")V", FN_PTR(Unsafe_SetNative##Byte)}
static JNINativeMethod methods[] = {
- {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)},
- {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)},
- {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)},
- {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)},
+ {CC "getObject", CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObject)},
+ {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObject)},
+ {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)},
+ {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObjectVolatile)},
- {CC"getUncompressedObject", CC"("ADR")"OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
- {CC"getJavaMirror", CC"("ADR")"CLS, FN_PTR(Unsafe_GetJavaMirror)},
- {CC"getKlassPointer", CC"("OBJ")"ADR, FN_PTR(Unsafe_GetKlassPointer)},
+ {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
+ {CC "getJavaMirror", CC "(" ADR ")" CLS, FN_PTR(Unsafe_GetJavaMirror)},
+ {CC "getKlassPointer", CC "(" OBJ ")" ADR, FN_PTR(Unsafe_GetKlassPointer)},
DECLARE_GETPUTOOP(Boolean, Z),
DECLARE_GETPUTOOP(Byte, B),
@@ -1257,49 +1257,49 @@
DECLARE_GETPUTNATIVE(Float, F),
DECLARE_GETPUTNATIVE(Double, D),
- {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)},
- {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)},
+ {CC "getAddress", CC "(" ADR ")" ADR, FN_PTR(Unsafe_GetNativeAddress)},
+ {CC "putAddress", CC "(" ADR "" ADR ")V", FN_PTR(Unsafe_SetNativeAddress)},
- {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)},
- {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)},
- {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)},
+ {CC "allocateMemory", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory)},
+ {CC "reallocateMemory", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory)},
+ {CC "freeMemory", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory)},
- {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)},
- {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)},
- {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)},
- {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)},
- {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)},
- {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)},
- {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)},
- {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)},
+ {CC "objectFieldOffset", CC "(" FLD ")J", FN_PTR(Unsafe_ObjectFieldOffset)},
+ {CC "staticFieldOffset", CC "(" FLD ")J", FN_PTR(Unsafe_StaticFieldOffset)},
+ {CC "staticFieldBase", CC "(" FLD ")" OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)},
+ {CC "ensureClassInitialized",CC "(" CLS ")V", FN_PTR(Unsafe_EnsureClassInitialized)},
+ {CC "arrayBaseOffset", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayBaseOffset)},
+ {CC "arrayIndexScale", CC "(" CLS ")I", FN_PTR(Unsafe_ArrayIndexScale)},
+ {CC "addressSize", CC "()I", FN_PTR(Unsafe_AddressSize)},
+ {CC "pageSize", CC "()I", FN_PTR(Unsafe_PageSize)},
- {CC"defineClass", CC"("DC_Args")"CLS, FN_PTR(Unsafe_DefineClass)},
- {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)},
- {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)},
- {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)},
- {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)},
- {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)},
- {CC"putOrderedObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetOrderedObject)},
- {CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)},
- {CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)},
- {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)},
- {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)},
+ {CC "defineClass", CC "(" DC_Args ")" CLS, FN_PTR(Unsafe_DefineClass)},
+ {CC "allocateInstance", CC "(" CLS ")" OBJ, FN_PTR(Unsafe_AllocateInstance)},
+ {CC "throwException", CC "(" THR ")V", FN_PTR(Unsafe_ThrowException)},
+ {CC "compareAndSwapObject", CC "(" OBJ "J" OBJ "" OBJ ")Z", FN_PTR(Unsafe_CompareAndSwapObject)},
+ {CC "compareAndSwapInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)},
+ {CC "compareAndSwapLong", CC "(" OBJ "J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)},
+ {CC "putOrderedObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetOrderedObject)},
+ {CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)},
+ {CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)},
+ {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)},
+ {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)},
- {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)},
+ {CC "getLoadAverage", CC "([DI)I", FN_PTR(Unsafe_Loadavg)},
- {CC"copyMemory", CC"("OBJ"J"OBJ"JJ)V", FN_PTR(Unsafe_CopyMemory)},
- {CC"setMemory", CC"("OBJ"JJB)V", FN_PTR(Unsafe_SetMemory)},
+ {CC "copyMemory", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory)},
+ {CC "setMemory", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory)},
- {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
+ {CC "defineAnonymousClass", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
- {CC"shouldBeInitialized",CC"("CLS")Z", FN_PTR(Unsafe_ShouldBeInitialized)},
+ {CC "shouldBeInitialized",CC "(" CLS ")Z", FN_PTR(Unsafe_ShouldBeInitialized)},
- {CC"loadFence", CC"()V", FN_PTR(Unsafe_LoadFence)},
- {CC"storeFence", CC"()V", FN_PTR(Unsafe_StoreFence)},
- {CC"fullFence", CC"()V", FN_PTR(Unsafe_FullFence)},
+ {CC "loadFence", CC "()V", FN_PTR(Unsafe_LoadFence)},
+ {CC "storeFence", CC "()V", FN_PTR(Unsafe_StoreFence)},
+ {CC "fullFence", CC "()V", FN_PTR(Unsafe_FullFence)},
- {CC"isBigEndian0", CC"()Z", FN_PTR(Unsafe_isBigEndian0)},
- {CC"unalignedAccess0", CC"()Z", FN_PTR(Unsafe_unalignedAccess0)}
+ {CC "isBigEndian0", CC "()Z", FN_PTR(Unsafe_isBigEndian0)},
+ {CC "unalignedAccess0", CC "()Z", FN_PTR(Unsafe_unalignedAccess0)}
};
#undef CC
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -27,6 +27,7 @@
#include <new>
#include "classfile/classLoaderData.hpp"
+#include "classfile/imageFile.hpp"
#include "classfile/stringTable.hpp"
#include "code/codeCache.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
@@ -159,8 +160,8 @@
WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
CollectorPolicy * p = Universe::heap()->collector_policy();
- gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
- SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Space alignment "SIZE_FORMAT" Heap alignment "SIZE_FORMAT,
+ gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
+ SIZE_FORMAT " Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT,
p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
p->space_alignment(), p->heap_alignment());
}
@@ -195,8 +196,8 @@
Universe::narrow_oop_use_implicit_null_checks() )) {
tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n "
"\tUseCompressedOops is %d\n"
- "\trhs.base() is "PTR_FORMAT"\n"
- "\tUniverse::narrow_oop_base() is "PTR_FORMAT"\n"
+ "\trhs.base() is " PTR_FORMAT "\n"
+ "\tUniverse::narrow_oop_base() is " PTR_FORMAT "\n"
"\tUniverse::narrow_oop_use_implicit_null_checks() is %d",
UseCompressedOops,
rhs.base(),
@@ -249,8 +250,8 @@
WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o,
jlong reserved_space_size, jlong magnitude, jlong iterations))
- tty->print_cr("reservedSpaceSize="JLONG_FORMAT", magnitude="JLONG_FORMAT", "
- "iterations="JLONG_FORMAT"\n", reserved_space_size, magnitude,
+ tty->print_cr("reservedSpaceSize=" JLONG_FORMAT ", magnitude=" JLONG_FORMAT ", "
+ "iterations=" JLONG_FORMAT "\n", reserved_space_size, magnitude,
iterations);
if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) {
tty->print_cr("One of variables printed above is negative. Can't proceed.\n");
@@ -1125,6 +1126,132 @@
return (jlong) MetaspaceGC::capacity_until_GC();
WB_END
+WB_ENTRY(jboolean, WB_ReadImageFile(JNIEnv* env, jobject wb, jstring imagefile))
+ const char* filename = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(imagefile));
+ return ImageFileReader::open(filename) != NULL;
+WB_END
+
+WB_ENTRY(jlong, WB_imageOpenImage(JNIEnv *env, jobject wb, jstring path, jboolean big_endian))
+ ThreadToNativeFromVM ttn(thread);
+ const char *nativePath = env->GetStringUTFChars(path, NULL);
+ jlong ret = JVM_ImageOpen(env, nativePath, big_endian);
+
+ env->ReleaseStringUTFChars(path, nativePath);
+ return ret;
+WB_END
+
+WB_ENTRY(void, WB_imageCloseImage(JNIEnv *env, jobject wb, jlong id))
+ ThreadToNativeFromVM ttn(thread);
+ JVM_ImageClose(env, id);
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetIndexAddress(JNIEnv *env, jobject wb, jlong id))
+ ThreadToNativeFromVM ttn(thread);
+ return JVM_ImageGetIndexAddress(env, id);
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetDataAddress(JNIEnv *env, jobject wb, jlong id))
+ ThreadToNativeFromVM ttn(thread);
+ return JVM_ImageGetDataAddress(env, id);
+WB_END
+
+WB_ENTRY(jboolean, WB_imageRead(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject uncompressedBuffer, jlong uncompressed_size))
+ ThreadToNativeFromVM ttn(thread);
+ if (uncompressedBuffer == NULL) {
+ return JNI_FALSE;
+ }
+ unsigned char* uncompressedAddress =
+ (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+ return JVM_ImageRead(env, id, offset, uncompressedAddress, uncompressed_size);
+WB_END
+
+WB_ENTRY(jboolean, WB_imageReadCompressed(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject compressedBuffer, jlong compressed_size, jobject uncompressedBuffer, jlong uncompressed_size))
+ ThreadToNativeFromVM ttn(thread);
+ if (uncompressedBuffer == NULL || compressedBuffer == NULL) {
+ return false;
+ }
+ // Get address of read direct buffer.
+ unsigned char* compressedAddress =
+ (unsigned char*) env->GetDirectBufferAddress(compressedBuffer);
+ // Get address of decompression direct buffer.
+ unsigned char* uncompressedAddress =
+ (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+ return JVM_ImageReadCompressed(env, id, offset, compressedAddress, compressed_size, uncompressedAddress, uncompressed_size);
+WB_END
+
+WB_ENTRY(jbyteArray, WB_imageGetStringBytes(JNIEnv *env, jobject wb, jlong id, jlong offset))
+ ThreadToNativeFromVM ttn(thread);
+ const char* data = JVM_ImageGetStringBytes(env, id, offset);
+ // Determine String length.
+ size_t size = strlen(data);
+ // Allocate byte array.
+ jbyteArray byteArray = env->NewByteArray((jsize) size);
+ // Get array base address.
+ jbyte* rawBytes = env->GetByteArrayElements(byteArray, NULL);
+ // Copy bytes from image string table.
+ memcpy(rawBytes, data, size);
+ // Release byte array base address.
+ env->ReleaseByteArrayElements(byteArray, rawBytes, 0);
+ return byteArray;
+WB_END
+
+WB_ENTRY(jlong, WB_imageGetStringsSize(JNIEnv *env, jobject wb, jlong id))
+ ImageFileReader* reader = ImageFileReader::idToReader(id);
+ return reader? reader->strings_size() : 0L;
+WB_END
+
+WB_ENTRY(jlongArray, WB_imageGetAttributes(JNIEnv *env, jobject wb, jlong id, jint offset))
+ ThreadToNativeFromVM ttn(thread);
+ // Allocate a jlong large enough for all location attributes.
+ jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env));
+ // Get base address for jlong array.
+ jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL);
+ jlong* ret = JVM_ImageGetAttributes(env, rawAttributes, id, offset);
+ // Release jlong array base address.
+ env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+ return ret == NULL ? NULL : attributes;
+WB_END
+
+WB_ENTRY(jlongArray, WB_imageFindAttributes(JNIEnv *env, jobject wb, jlong id, jbyteArray utf8))
+ ThreadToNativeFromVM ttn(thread);
+ // Allocate a jlong large enough for all location attributes.
+ jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env));
+ // Get base address for jlong array.
+ jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL);
+ jsize size = env->GetArrayLength(utf8);
+ jbyte* rawBytes = env->GetByteArrayElements(utf8, NULL);
+ jlong* ret = JVM_ImageFindAttributes(env, rawAttributes, rawBytes, size, id);
+ env->ReleaseByteArrayElements(utf8, rawBytes, 0);
+ env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+ return ret == NULL ? NULL : attributes;
+WB_END
+
+WB_ENTRY(jintArray, WB_imageAttributeOffsets(JNIEnv *env, jobject wb, jlong id))
+ ThreadToNativeFromVM ttn(thread);
+ unsigned int length = JVM_ImageAttributeOffsetsLength(env, id);
+ if (length == 0) {
+ return NULL;
+ }
+ jintArray offsets = env->NewIntArray(length);
+ // Get base address of result.
+ jint* rawOffsets = env->GetIntArrayElements(offsets, NULL);
+ jint* ret = JVM_ImageAttributeOffsets(env, rawOffsets, length, id);
+ // Release result base address.
+ env->ReleaseIntArrayElements(offsets, rawOffsets, 0);
+ return ret == NULL ? NULL : offsets;
+WB_END
+
+WB_ENTRY(jint, WB_imageGetIntAtAddress(JNIEnv *env, jobject wb, jlong address, jint offset, jboolean big_endian))
+ unsigned char* arr = (unsigned char*) address + offset;
+ jint uraw;
+ if (big_endian) {
+ uraw = arr[0] << 24 | arr[1]<<16 | (arr[2]<<8) | arr[3];
+ } else {
+ uraw = arr[0] | arr[1]<<8 | (arr[2]<<16) | arr[3]<<24;
+ }
+ return uraw;
+WB_END
+
WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
Monitor::_safepoint_check_always :
@@ -1428,8 +1555,23 @@
{CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob },
{CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize },
{CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize },
+ {CC"readImageFile", CC"(Ljava/lang/String;)Z", (void*)&WB_ReadImageFile },
+ {CC"imageOpenImage", CC"(Ljava/lang/String;Z)J",(void*)&WB_imageOpenImage },
+ {CC"imageCloseImage", CC"(J)V", (void*)&WB_imageCloseImage },
+ {CC"imageGetIndexAddress",CC"(J)J", (void*)&WB_imageGetIndexAddress},
+ {CC"imageGetDataAddress",CC"(J)J", (void*)&WB_imageGetDataAddress},
+ {CC"imageRead", CC"(JJLjava/nio/ByteBuffer;J)Z",
+ (void*)&WB_imageRead },
+ {CC"imageReadCompressed",CC"(JJLjava/nio/ByteBuffer;JLjava/nio/ByteBuffer;J)Z",
+ (void*)&WB_imageReadCompressed},
+ {CC"imageGetStringBytes",CC"(JI)[B", (void*)&WB_imageGetStringBytes},
+ {CC"imageGetStringsSize",CC"(J)J", (void*)&WB_imageGetStringsSize},
+ {CC"imageGetAttributes", CC"(JI)[J", (void*)&WB_imageGetAttributes},
+ {CC"imageFindAttributes",CC"(J[B)[J", (void*)&WB_imageFindAttributes},
+ {CC"imageAttributeOffsets",CC"(J)[I", (void*)&WB_imageAttributeOffsets},
+ {CC"imageGetIntAtAddress",CC"(JIZ)I", (void*)&WB_imageGetIntAtAddress},
{CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls },
- {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated },
+ {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated },
{CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint },
{CC"getMethodBooleanOption",
CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -27,6 +27,7 @@
#include "classfile/javaAssertions.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "compiler/compilerOracle.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genCollectedHeap.hpp"
@@ -275,6 +276,7 @@
{ "AdaptiveSizePausePolicy", JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "ParallelGCRetainPLAB", JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "ThreadSafetyMargin", JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "LazyBootClassLoader", JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ NULL, JDK_Version(0), JDK_Version(0) }
};
@@ -835,16 +837,19 @@
arg_len = equal_sign - argname;
}
- // Construct a string which consists only of the argument name without '+', '-', or '='.
- char stripped_argname[256];
- strncpy(stripped_argname, argname, arg_len);
- stripped_argname[arg_len] = '\0'; //strncpy doesn't null terminate.
-
- if (is_newly_obsolete(stripped_argname, &since)) {
- char version[256];
- since.to_string(version, sizeof(version));
- warning("ignoring option %s; support was removed in %s", stripped_argname, version);
- return true;
+ // Only make the obsolete check for valid arguments.
+ if (arg_len <= BUFLEN) {
+ // Construct a string which consists only of the argument name without '+', '-', or '='.
+ char stripped_argname[BUFLEN+1];
+ strncpy(stripped_argname, argname, arg_len);
+ stripped_argname[arg_len] = '\0'; // strncpy may not null terminate.
+
+ if (is_newly_obsolete(stripped_argname, &since)) {
+ char version[256];
+ since.to_string(version, sizeof(version));
+ warning("ignoring option %s; support was removed in %s", stripped_argname, version);
+ return true;
+ }
}
// For locked flags, report a custom error message if available.
@@ -1582,6 +1587,11 @@
// in vm_version initialization code.
#endif // _LP64
#endif // !ZERO
+
+ // Set up runtime image flags.
+ set_runtime_image_flags();
+
+ CodeCacheExtensions::set_ergonomics_flags();
}
void Arguments::set_parallel_gc_flags() {
@@ -1837,6 +1847,16 @@
}
}
+ // Set up runtime image flags
+void Arguments::set_runtime_image_flags() {
+#ifdef _LP64
+ // Memory map image file by default on 64 bit machines.
+ if (FLAG_IS_DEFAULT(MemoryMapImage)) {
+ FLAG_SET_ERGO(bool, MemoryMapImage, true);
+ }
+#endif
+}
+
// This must be called after ergonomics.
void Arguments::set_bytecode_flags() {
if (!RewriteBytecodes) {
@@ -2558,9 +2578,15 @@
round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) {
return JNI_EINVAL;
}
- // -Xoss
- } else if (match_option(option, "-Xoss", &tail)) {
- // HotSpot does not have separate native and Java stacks, ignore silently for compatibility
+ // -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads
+ } else if (match_option(option, "-Xoss", &tail) ||
+ match_option(option, "-Xsqnopause") ||
+ match_option(option, "-Xoptimize") ||
+ match_option(option, "-Xboundthreads")) {
+ // All these options are deprecated in JDK 9 and will be removed in a future release
+ char version[256];
+ JDK_Version::jdk(9).to_string(version, sizeof(version));
+ warning("ignoring option %s; support was removed in %s", option->optionString, version);
} else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) {
julong long_CodeCacheExpansionSize = 0;
ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size());
@@ -2633,9 +2659,6 @@
// -native
} else if (match_option(option, "-native")) {
// HotSpot always uses native threads, ignore silently for compatibility
- // -Xsqnopause
- } else if (match_option(option, "-Xsqnopause")) {
- // EVM option, ignore silently for compatibility
// -Xrs
} else if (match_option(option, "-Xrs")) {
// Classic/EVM option, new functionality
@@ -2647,9 +2670,6 @@
if (FLAG_SET_CMDLINE(bool, UseAltSigs, true) != Flag::SUCCESS) {
return JNI_EINVAL;
}
- // -Xoptimize
- } else if (match_option(option, "-Xoptimize")) {
- // EVM option, ignore silently for compatibility
// -Xprof
} else if (match_option(option, "-Xprof")) {
#if INCLUDE_FPROF
@@ -2795,8 +2815,6 @@
// -Xnoagent
} else if (match_option(option, "-Xnoagent")) {
// For compatibility with classic. HotSpot refuses to load the old style agent.dll.
- } else if (match_option(option, "-Xboundthreads")) {
- // Ignore silently for compatibility
} else if (match_option(option, "-Xloggc:", &tail)) {
// Redirect GC output to the file. -Xloggc:<filename>
// ostream_init_log(), when called will use this filename
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -224,6 +224,7 @@
class Arguments : AllStatic {
friend class VMStructs;
friend class JvmtiExport;
+ friend class CodeCacheExtensions;
public:
// Operation modi
enum Mode {
@@ -347,6 +348,8 @@
static julong limit_by_allocatable_memory(julong size);
// Setup heap size
static void set_heap_size();
+ // Set up runtime image flags
+ static void set_runtime_image_flags();
// Based on automatic selection criteria, should the
// low pause collector be used.
static bool should_auto_select_low_pause_collector();
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -84,7 +84,7 @@
}
void print(outputStream* st) {
- st->print("[ "INTX_FORMAT_W(-25)" ... "INTX_FORMAT_W(25)" ]", _min, _max);
+ st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max);
}
};
@@ -140,7 +140,7 @@
}
void print(outputStream* st) {
- st->print("[ "UINTX_FORMAT_W(-25)" ... "UINTX_FORMAT_W(25)" ]", _min, _max);
+ st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max);
}
};
@@ -168,7 +168,7 @@
}
void print(outputStream* st) {
- st->print("[ "UINT64_FORMAT_W(-25)" ... "UINT64_FORMAT_W(25)" ]", _min, _max);
+ st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max);
}
};
@@ -196,7 +196,7 @@
}
void print(outputStream* st) {
- st->print("[ "SIZE_FORMAT_W(-25)" ... "SIZE_FORMAT_W(25)" ]", _min, _max);
+ st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max);
}
};
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1340,7 +1340,7 @@
ttyLocker ttyl;
char buf[100];
if (xtty != NULL) {
- xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT"' %s",
+ xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT "' %s",
os::current_thread_id(),
format_trap_request(buf, sizeof(buf), trap_request));
nm->log_identity(xtty);
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1240,7 +1240,7 @@
size_ranges += sizeof(CommandLineFlagRange*);
}
}
- fprintf(stderr, "Size of %d ranges: "SIZE_FORMAT" bytes\n",
+ fprintf(stderr, "Size of %d ranges: " SIZE_FORMAT " bytes\n",
CommandLineFlagRangeList::length(), size_ranges);
}
{
@@ -1270,7 +1270,7 @@
size_constraints += sizeof(CommandLineFlagConstraint*);
}
}
- fprintf(stderr, "Size of %d constraints: "SIZE_FORMAT" bytes\n",
+ fprintf(stderr, "Size of %d constraints: " SIZE_FORMAT " bytes\n",
CommandLineFlagConstraintList::length(), size_constraints);
}
#endif // PRINT_RANGES_AND_CONSTRAINTS_SIZES
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -728,7 +728,8 @@
"Control whether AES instructions can be used on x86/x64") \
\
product(bool, UseSHA, false, \
- "Control whether SHA instructions can be used on SPARC") \
+ "Control whether SHA instructions can be used " \
+ "on SPARC and on ARM") \
\
product(bool, UseGHASHIntrinsics, false, \
"Use intrinsics for GHASH versions of crypto") \
@@ -837,13 +838,16 @@
"Use intrinsics for AES versions of crypto") \
\
product(bool, UseSHA1Intrinsics, false, \
- "Use intrinsics for SHA-1 crypto hash function") \
+ "Use intrinsics for SHA-1 crypto hash function. " \
+ "Requires that UseSHA is enabled.") \
\
product(bool, UseSHA256Intrinsics, false, \
- "Use intrinsics for SHA-224 and SHA-256 crypto hash functions") \
+ "Use intrinsics for SHA-224 and SHA-256 crypto hash functions. " \
+ "Requires that UseSHA is enabled.") \
\
product(bool, UseSHA512Intrinsics, false, \
- "Use intrinsics for SHA-384 and SHA-512 crypto hash functions") \
+ "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. " \
+ "Requires that UseSHA is enabled.") \
\
product(bool, UseCRC32Intrinsics, false, \
"use intrinsics for java.util.zip.CRC32") \
@@ -1032,6 +1036,10 @@
product(bool, CreateCoredumpOnCrash, true, \
"Create core/mini dump on VM fatal error") \
\
+ product(uintx, ErrorLogTimeout, 2 * 60, \
+ "Timeout, in seconds, to limit the time spent on writing an " \
+ "error log in case of a crash.") \
+ \
product_pd(bool, UseOSErrorReporting, \
"Let VM fatal error propagate to the OS (ie. WER on Windows)") \
\
@@ -1099,6 +1107,9 @@
product(bool, AlwaysRestoreFPU, false, \
"Restore the FPU control word after every JNI call (expensive)") \
\
+ product(bool, MemoryMapImage, false, \
+ "Memory map entire runtime image") \
+ \
diagnostic(bool, PrintCompilation2, false, \
"Print additional statistics per compilation") \
\
@@ -1361,9 +1372,6 @@
develop(uintx, PreallocatedOutOfMemoryErrorCount, 4, \
"Number of OutOfMemoryErrors preallocated with backtrace") \
\
- product(bool, LazyBootClassLoader, true, \
- "Enable/disable lazy opening of boot class path entries") \
- \
product(bool, UseXMMForArrayCopy, false, \
"Use SSE2 MOVQ instruction for Arraycopy") \
\
@@ -4120,7 +4128,16 @@
\
product_pd(bool, PreserveFramePointer, \
"Use the FP register for holding the frame pointer " \
- "and not as a general purpose register.")
+ "and not as a general purpose register.") \
+ \
+ diagnostic(bool, CheckIntrinsics, trueInDebug, \
+ "When a class C is loaded, check that " \
+ "(1) all intrinsics defined by the VM for class C are present "\
+ "in the loaded class file and are marked with the " \
+ "@HotSpotIntrinsicCandidate annotation and also that " \
+ "(2) there is an intrinsic registered for all loaded methods " \
+ "that are annotated with the @HotSpotIntrinsicCandidate " \
+ "annotation.")
/*
* Macros for factoring of globals
--- a/hotspot/src/share/vm/runtime/init.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/init.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/stringTable.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "code/icBuffer.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interpreter/bytecodes.hpp"
@@ -82,6 +83,7 @@
// during VM shutdown
void perfMemory_exit();
void ostream_exit();
+bool image_decompressor_init();
void vm_init_globals() {
check_ThreadShadow();
@@ -100,21 +102,29 @@
classLoader_init();
compilationPolicy_init();
codeCache_init();
+ CodeCacheExtensions::initialize();
VM_Version_init();
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::VMVersion);
os_init_globals();
stubRoutines_init1();
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::StubRoutines1);
jint status = universe_init(); // dependent on codeCache_init and
// stubRoutines_init1 and metaspace_init.
if (status != JNI_OK)
return status;
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Universe);
interpreter_init(); // before any methods loaded
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Interpreter);
invocationCounter_init(); // before any methods loaded
marksweep_init();
accessFlags_init();
templateTable_init();
InterfaceSupport_init();
SharedRuntime::generate_stubs();
+ if (!image_decompressor_init()) {
+ return JNI_ERR;
+ }
universe2_init(); // dependent on codeCache_init and stubRoutines_init1
referenceProcessor_init();
jni_handles_init();
@@ -133,6 +143,7 @@
}
javaClasses_init(); // must happen after vtable initialization
stubRoutines_init2(); // note: StubRoutines need 2-phase init
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::StubRoutines2);
#if INCLUDE_NMT
// Solaris stack is walkable only after stubRoutines are set up.
@@ -146,6 +157,7 @@
CommandLineFlags::printFlags(tty, false, PrintFlagsRanges);
}
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::InitGlobals);
return JNI_OK;
}
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -100,6 +100,8 @@
Mutex* ExceptionCache_lock = NULL;
Monitor* ObjAllocPost_lock = NULL;
Mutex* OsrList_lock = NULL;
+Mutex* ImageFileReaderTable_lock = NULL;
+
#ifndef PRODUCT
Mutex* FullGCALot_lock = NULL;
#endif
@@ -227,6 +229,7 @@
def(ProfilePrint_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
def(ExceptionCache_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing
def(OsrList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
+ def(ImageFileReaderTable_lock , Mutex , nonleaf, false, Monitor::_safepoint_check_always); // synchronize image readers open/close
def(Debug1_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
#ifndef PRODUCT
def(FullGCALot_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -102,6 +102,7 @@
extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles
extern Mutex* ExceptionCache_lock; // a lock used to synchronize exception cache updates
extern Mutex* OsrList_lock; // a lock used to serialize access to OSR queues
+extern Mutex* ImageFileReaderTable_lock; // a lock used to synchronize image readers open/close
#ifndef PRODUCT
extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT safe
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1237,7 +1237,7 @@
struct stat st;
// modular image if bootmodules.jimage exists
- char* jimage = format_boot_path("%/lib/modules/bootmodules.jimage", home, home_len, fileSep, pathSep);
+ char* jimage = format_boot_path("%/lib/modules/" BOOT_IMAGE_NAME, home, home_len, fileSep, pathSep);
if (jimage == NULL) return false;
bool has_jimage = (os::stat(jimage, &st) == 0);
if (has_jimage) {
--- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -1002,8 +1002,9 @@
vmSymbols::throwable_void_signature(),
&args);
} else {
- if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT)
+ if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) {
narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL);
+ }
return box((jvalue*) result.get_value_addr(), rtype, THREAD);
}
}
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -894,7 +894,7 @@
case _running:
default:
- tty->print_cr("restart thread "INTPTR_FORMAT" with state %d",
+ tty->print_cr("restart thread " INTPTR_FORMAT " with state %d",
_thread, _type);
_thread->print();
ShouldNotReachHere();
@@ -1193,7 +1193,7 @@
sstats = &_safepoint_stats[index];
tty->print("%.3f: ", sstats->_time_stamp);
tty->print("%-26s ["
- INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
+ INT32_FORMAT_W(8) INT32_FORMAT_W(11) INT32_FORMAT_W(15)
" ] ",
sstats->_vmop_type == -1 ? "no vm operation" :
VM_Operation::name(sstats->_vmop_type),
@@ -1202,9 +1202,9 @@
sstats->_nof_threads_wait_to_block);
// "/ MICROUNITS " is to convert the unit from nanos to millis.
tty->print(" ["
- INT64_FORMAT_W(6)INT64_FORMAT_W(6)
- INT64_FORMAT_W(6)INT64_FORMAT_W(6)
- INT64_FORMAT_W(6)" ] ",
+ INT64_FORMAT_W(6) INT64_FORMAT_W(6)
+ INT64_FORMAT_W(6) INT64_FORMAT_W(6)
+ INT64_FORMAT_W(6) " ] ",
sstats->_time_to_spin / MICROUNITS,
sstats->_time_to_wait_to_block / MICROUNITS,
sstats->_time_to_sync / MICROUNITS,
@@ -1212,9 +1212,9 @@
sstats->_time_to_exec_vmop / MICROUNITS);
if (need_to_track_page_armed_status) {
- tty->print(INT32_FORMAT" ", sstats->_page_armed);
+ tty->print(INT32_FORMAT " ", sstats->_page_armed);
}
- tty->print_cr(INT32_FORMAT" ", sstats->_nof_threads_hit_page_trap);
+ tty->print_cr(INT32_FORMAT " ", sstats->_nof_threads_hit_page_trap);
}
}
@@ -1249,17 +1249,17 @@
for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
if (_safepoint_reasons[index] != 0) {
- tty->print_cr("%-26s"UINT64_FORMAT_W(10), VM_Operation::name(index),
+ tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index),
_safepoint_reasons[index]);
}
}
- tty->print_cr(UINT64_FORMAT_W(5)" VM operations coalesced during safepoint",
+ tty->print_cr(UINT64_FORMAT_W(5) " VM operations coalesced during safepoint",
_coalesced_vmop_count);
- tty->print_cr("Maximum sync time "INT64_FORMAT_W(5)" ms",
+ tty->print_cr("Maximum sync time " INT64_FORMAT_W(5) " ms",
_max_sync_time / MICROUNITS);
tty->print_cr("Maximum vm operation time (except for Exit VM operation) "
- INT64_FORMAT_W(5)" ms",
+ INT64_FORMAT_W(5) " ms",
_max_vmop_time / MICROUNITS);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/semaphore.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,93 @@
+/*
+ * 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 "precompiled.hpp"
+#include "utilities/debug.hpp"
+#include "runtime/semaphore.hpp"
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+static void test_semaphore_single_separate(uint count) {
+ Semaphore sem(0);
+
+ for (uint i = 0; i < count; i++) {
+ sem.signal();
+ }
+
+ for (uint i = 0; i < count; i++) {
+ sem.wait();
+ }
+}
+
+static void test_semaphore_single_combined(uint count) {
+ Semaphore sem(0);
+
+ for (uint i = 0; i < count; i++) {
+ sem.signal();
+ sem.wait();
+ }
+}
+
+static void test_semaphore_many(uint value, uint max, uint increments) {
+ Semaphore sem(value);
+
+ uint total = value;
+
+ for (uint i = value; i + increments <= max; i += increments) {
+ sem.signal(increments);
+
+ total += increments;
+ }
+
+ for (uint i = 0; i < total; i++) {
+ sem.wait();
+ }
+}
+
+static void test_semaphore_many() {
+ for (uint max = 0; max < 10; max++) {
+ for (uint value = 0; value < max; value++) {
+ for (uint inc = 1; inc <= max - value; inc++) {
+ test_semaphore_many(value, max, inc);
+ }
+ }
+ }
+}
+
+void test_semaphore() {
+ for (uint i = 1; i < 10; i++) {
+ test_semaphore_single_separate(i);
+ }
+
+ for (uint i = 0; i < 10; i++) {
+ test_semaphore_single_combined(i);
+ }
+
+ test_semaphore_many();
+}
+
+#endif // PRODUCT
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/semaphore.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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_RUNTIME_SEMAPHORE_HPP
+#define SHARE_VM_RUNTIME_SEMAPHORE_HPP
+
+#include "memory/allocation.hpp"
+
+#if defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_solaris) || defined(TARGET_OS_FAMILY_aix)
+# include "semaphore_posix.hpp"
+#elif defined(TARGET_OS_FAMILY_bsd)
+# include "semaphore_bsd.hpp"
+#elif defined(TARGET_OS_FAMILY_windows)
+# include "semaphore_windows.hpp"
+#else
+# error "No semaphore implementation provided for this OS"
+#endif
+
+// Implements the limited, platform independent Semaphore API.
+class Semaphore : public CHeapObj<mtInternal> {
+ SemaphoreImpl _impl;
+
+ // Prevent copying and assignment of Semaphore instances.
+ Semaphore(const Semaphore&);
+ Semaphore& operator=(const Semaphore&);
+
+ public:
+ Semaphore(uint value = 0) : _impl(value) {}
+ ~Semaphore() {}
+
+ void signal(uint count = 1) { _impl.signal(count); }
+
+ void wait() { _impl.wait(); }
+};
+
+
+#endif // SHARE_VM_RUNTIME_SEMAPHORE_HPP
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -27,6 +27,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/compiledIC.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/abstractCompiler.hpp"
@@ -2307,19 +2308,35 @@
return _buffer;
}
+extern "C" void unexpected_adapter_call() {
+ ShouldNotCallThis();
+}
+
void AdapterHandlerLibrary::initialize() {
if (_adapters != NULL) return;
_adapters = new AdapterHandlerTable();
- // Create a special handler for abstract methods. Abstract methods
- // are never compiled so an i2c entry is somewhat meaningless, but
- // throw AbstractMethodError just in case.
- // Pass wrong_method_abstract for the c2i transitions to return
- // AbstractMethodError for invalid invocations.
- address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
- _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
- StubRoutines::throw_AbstractMethodError_entry(),
- wrong_method_abstract, wrong_method_abstract);
+ if (!CodeCacheExtensions::skip_compiler_support()) {
+ // Create a special handler for abstract methods. Abstract methods
+ // are never compiled so an i2c entry is somewhat meaningless, but
+ // throw AbstractMethodError just in case.
+ // Pass wrong_method_abstract for the c2i transitions to return
+ // AbstractMethodError for invalid invocations.
+ address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
+ _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
+ StubRoutines::throw_AbstractMethodError_entry(),
+ wrong_method_abstract, wrong_method_abstract);
+ } else {
+ // Adapters are not supposed to be used.
+ // Generate a special one to cause an error if used (and store this
+ // singleton in place of the useless _abstract_method_error adapter).
+ address entry = (address) &unexpected_adapter_call;
+ _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
+ entry,
+ entry,
+ entry);
+
+ }
}
AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
@@ -2346,6 +2363,15 @@
// make sure data structure is initialized
initialize();
+ if (CodeCacheExtensions::skip_compiler_support()) {
+ // adapters are useless and should not be used, including the
+ // abstract_method_handler. However, some callers check that
+ // an adapter was installed.
+ // Return the singleton adapter, stored into _abstract_method_handler
+ // and modified to cause an error if we ever call it.
+ return _abstract_method_handler;
+ }
+
if (method->is_abstract()) {
return _abstract_method_handler;
}
@@ -2616,71 +2642,6 @@
GC_locker::unlock_critical(thread);
JRT_END
-int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) {
- int argcnt = in_args_count;
- if (CCallingConventionRequiresIntsAsLongs) {
- for (int in = 0; in < in_args_count; in++) {
- BasicType bt = in_sig_bt[in];
- switch (bt) {
- case T_BOOLEAN:
- case T_CHAR:
- case T_BYTE:
- case T_SHORT:
- case T_INT:
- argcnt++;
- break;
- default:
- break;
- }
- }
- } else {
- assert(0, "This should not be needed on this platform");
- }
-
- return argcnt;
-}
-
-void SharedRuntime::convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
- BasicType*& in_sig_bt, VMRegPair*& in_regs) {
- if (CCallingConventionRequiresIntsAsLongs) {
- VMRegPair *new_in_regs = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt);
- BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
-
- int argcnt = 0;
- for (int in = 0; in < in_args_count; in++, argcnt++) {
- BasicType bt = in_sig_bt[in];
- VMRegPair reg = in_regs[in];
- switch (bt) {
- case T_BOOLEAN:
- case T_CHAR:
- case T_BYTE:
- case T_SHORT:
- case T_INT:
- // Convert (bt) to (T_LONG,bt).
- new_in_sig_bt[argcnt] = T_LONG;
- new_in_sig_bt[argcnt+1] = bt;
- assert(reg.first()->is_valid() && !reg.second()->is_valid(), "");
- new_in_regs[argcnt].set2(reg.first());
- new_in_regs[argcnt+1].set_bad();
- argcnt++;
- break;
- default:
- // No conversion needed.
- new_in_sig_bt[argcnt] = bt;
- new_in_regs[argcnt] = reg;
- break;
- }
- }
- assert(argcnt == i2l_argcnt, "must match");
-
- in_regs = new_in_regs;
- in_sig_bt = new_in_sig_bt;
- in_args_count = i2l_argcnt;
- } else {
- assert(0, "This should not be needed on this platform");
- }
-}
-
// -------------------------------------------------------------------------
// Java-Java calling convention
// (what you use when Java calls Java)
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -145,6 +145,12 @@
static double dsqrt(double f);
#endif
+ // Montgomery multiplication
+ static void montgomery_multiply(jint *a_ints, jint *b_ints, jint *n_ints,
+ jint len, jlong inv, jint *m_ints);
+ static void montgomery_square(jint *a_ints, jint *n_ints,
+ jint len, jlong inv, jint *m_ints);
+
#ifdef __SOFTFP__
// C++ compiler generates soft float instructions as well as passing
// float and double in registers.
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -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
@@ -26,6 +26,7 @@
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "compiler/disassembler.hpp"
#include "oops/oop.inline.hpp"
#include "prims/forte.hpp"
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, 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
@@ -67,14 +67,14 @@
static StubCodeDesc* desc_for_index(int); // returns the code descriptor for the index or NULL
static const char* name_for(address pc); // returns the name of the code containing pc or NULL
- StubCodeDesc(const char* group, const char* name, address begin) {
+ StubCodeDesc(const char* group, const char* name, address begin, address end = NULL) {
assert(name != NULL, "no name specified");
_next = _list;
_group = group;
_name = name;
_index = ++_count; // (never zero)
_begin = begin;
- _end = NULL;
+ _end = end;
_list = this;
};
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "asm/codeBuffer.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -142,6 +143,8 @@
address StubRoutines::_multiplyToLen = NULL;
address StubRoutines::_squareToLen = NULL;
address StubRoutines::_mulAdd = NULL;
+address StubRoutines::_montgomeryMultiply = NULL;
+address StubRoutines::_montgomerySquare = NULL;
double (* StubRoutines::_intrinsic_log )(double) = NULL;
double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
@@ -188,6 +191,12 @@
// simple tests of generated arraycopy functions
static void test_arraycopy_func(address func, int alignment) {
+ if (CodeCacheExtensions::use_pregenerated_interpreter() || !CodeCacheExtensions::is_executable(func)) {
+ // Exit safely if stubs were generated but cannot be used.
+ // Also excluding pregenerated interpreter since the code may depend on
+ // some registers being properly initialized (for instance Rthread)
+ return;
+ }
int v = 0xcc;
int v2 = 0x11;
jlong lbuffer[8];
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -202,6 +202,8 @@
static address _multiplyToLen;
static address _squareToLen;
static address _mulAdd;
+ static address _montgomeryMultiply;
+ static address _montgomerySquare;
// These are versions of the java.lang.Math methods which perform
// the same operations as the intrinsic version. They are used for
@@ -366,6 +368,8 @@
static address multiplyToLen() {return _multiplyToLen; }
static address squareToLen() {return _squareToLen; }
static address mulAdd() {return _mulAdd; }
+ static address montgomeryMultiply() { return _montgomeryMultiply; }
+ static address montgomerySquare() { return _montgomerySquare; }
static address select_fill_function(BasicType t, bool aligned, const char* &name);
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -28,6 +28,7 @@
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/gcLocker.inline.hpp"
@@ -1291,7 +1292,7 @@
if (!ShowMessageBoxOnError
&& (OnError == NULL || OnError[0] == '\0')
&& Arguments::abort_hook() == NULL) {
- os::sleep(this, 2 * 60 * 1000, false);
+ os::sleep(this, ErrorLogTimeout * 60 * 1000, false);
fdStream err(defaultStream::output_fd());
err.print_raw_cr("# [ timer expired, abort... ]");
// skip atexit/vm_exit/vm_abort hooks
@@ -3587,6 +3588,8 @@
}
}
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::CreateVM);
+
create_vm_timer.end();
#ifdef ASSERT
_vm_complete = true;
--- a/hotspot/src/share/vm/runtime/unhandledOops.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -105,7 +105,7 @@
_level --;
if (unhandled_oop_print) {
for (int i=0; i<_level; i++) tty->print(" ");
- tty->print_cr("u "INTPTR_FORMAT, op);
+ tty->print_cr("u " INTPTR_FORMAT, op);
}
int i = _oop_list->find_from_end(op, match_oop_entry);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -182,6 +182,8 @@
#include "runtime/vmStructs_trace.hpp"
#endif
+#include "runtime/vmStructs_ext.hpp"
+
#ifdef COMPILER2
#include "opto/addnode.hpp"
#include "opto/block.hpp"
@@ -2963,6 +2965,9 @@
GENERATE_STATIC_VM_STRUCT_ENTRY)
#endif
+ VM_STRUCTS_EXT(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_STATIC_VM_STRUCT_ENTRY)
+
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3013,6 +3018,9 @@
GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
#endif
+ VM_TYPES_EXT(GENERATE_VM_TYPE_ENTRY,
+ GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
+
VM_TYPES_CPU(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_OOP_VM_TYPE_ENTRY,
@@ -3122,6 +3130,9 @@
CHECK_STATIC_VM_STRUCT_ENTRY);
#endif
+ VM_STRUCTS_EXT(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
+ CHECK_STATIC_VM_STRUCT_ENTRY);
+
VM_STRUCTS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
@@ -3168,6 +3179,9 @@
CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
#endif
+ VM_TYPES_EXT(CHECK_VM_TYPE_ENTRY,
+ CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
+
VM_TYPES_CPU(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@@ -3236,6 +3250,9 @@
ENSURE_FIELD_TYPE_PRESENT));
#endif
+ debug_only(VM_STRUCTS_EXT(ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_FIELD_TYPE_PRESENT));
+
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs_ext.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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_RUNTIME_VMSTRUCTS_EXT_HPP
+#define SHARE_VM_RUNTIME_VMSTRUCTS_EXT_HPP
+
+#define VM_STRUCTS_EXT(a, b)
+
+#define VM_TYPES_EXT(a, b)
+
+
+#endif // SHARE_VM_RUNTIME_VMSTRUCTS_EXT_HPP
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -26,6 +26,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compilerOracle.hpp"
#include "gc/shared/isGCActiveMark.hpp"
@@ -369,6 +370,8 @@
Thread * VM_Exit::_shutdown_thread = NULL;
int VM_Exit::set_vm_exited() {
+ CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::LastStep);
+
Thread * thr_cur = ThreadLocalStorage::get_thread_slow();
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already");
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/codeCacheExtensions.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
@@ -155,6 +156,9 @@
const char* Abstract_VM_Version::vm_info_string() {
+ if (CodeCacheExtensions::use_pregenerated_interpreter()) {
+ return "interpreted mode, pregenerated";
+ }
switch (Arguments::mode()) {
case Arguments::_int:
return UseSharedSpaces ? "interpreted mode, sharing" : "interpreted mode";
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -89,7 +89,7 @@
size_t len, TRAPS) {
int scanned = -1;
if (str == NULL
- || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
+ || sscanf(str, JLONG_FORMAT "%n", &_value, &scanned) != 1
|| (size_t)scanned != len)
{
ResourceMark rm;
--- a/hotspot/src/share/vm/services/threadService.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/services/threadService.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -888,7 +888,7 @@
st->print(" waiting to lock monitor " INTPTR_FORMAT, waitingToLockMonitor);
oop obj = (oop)waitingToLockMonitor->object();
if (obj != NULL) {
- st->print(" (object "INTPTR_FORMAT ", a %s)", (address)obj,
+ st->print(" (object " INTPTR_FORMAT ", a %s)", (address)obj,
(InstanceKlass::cast(obj->klass()))->external_name());
if (!currentThread->current_pending_monitor_is_from_java()) {
--- a/hotspot/src/share/vm/trace/trace.xml Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/trace/trace.xml Thu Jul 16 19:28:37 2015 -0700
@@ -305,6 +305,13 @@
<value type="G1YCTYPE" field="type" label="Type" />
</event>
+ <event id="GCG1MMU" path="vm/gc/detailed/g1_mmu_info" label="G1 MMU Information" is_instant="true">
+ <value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
+ <value type="DOUBLE" field="timeSlice" label="Time slice used to calculate MMU"/>
+ <value type="DOUBLE" field="gcTime" label="Time spent on GC during last time slice"/>
+ <value type="DOUBLE" field="maxGcTime" label="Max time allowed to be spent on GC during last time slice"/>
+ </event>
+
<event id="EvacuationInfo" path="vm/gc/detailed/evacuation_info" label="Evacuation Information" is_instant="true">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<value type="UINT" field="cSetRegions" label="Collection Set Regions"/>
--- a/hotspot/src/share/vm/trace/traceStream.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/trace/traceStream.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -40,31 +40,31 @@
TraceStream(outputStream& stream): _st(stream) {}
void print_val(const char* label, u1 val) {
- _st.print("%s = "UINT32_FORMAT, label, val);
+ _st.print("%s = " UINT32_FORMAT, label, val);
}
void print_val(const char* label, u2 val) {
- _st.print("%s = "UINT32_FORMAT, label, val);
+ _st.print("%s = " UINT32_FORMAT, label, val);
}
void print_val(const char* label, s2 val) {
- _st.print("%s = "INT32_FORMAT, label, val);
+ _st.print("%s = " INT32_FORMAT, label, val);
}
void print_val(const char* label, u4 val) {
- _st.print("%s = "UINT32_FORMAT, label, val);
+ _st.print("%s = " UINT32_FORMAT, label, val);
}
void print_val(const char* label, s4 val) {
- _st.print("%s = "INT32_FORMAT, label, val);
+ _st.print("%s = " INT32_FORMAT, label, val);
}
void print_val(const char* label, u8 val) {
- _st.print("%s = "UINT64_FORMAT, label, val);
+ _st.print("%s = " UINT64_FORMAT, label, val);
}
void print_val(const char* label, s8 val) {
- _st.print("%s = "INT64_FORMAT, label, (int64_t) val);
+ _st.print("%s = " INT64_FORMAT, label, (int64_t) val);
}
void print_val(const char* label, bool val) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/endian.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * 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 "precompiled.hpp"
+#include "utilities/endian.hpp"
+#include "utilities/bytes.hpp"
+
+#ifndef bswap_16
+extern "C" inline u2 bswap_16(u2 x) {
+ return ((x & 0xFF) << 8) |
+ ((x >> 8) & 0xFF);
+}
+#endif
+
+#ifndef bswap_32
+extern "C" inline u4 bswap_32(u4 x) {
+ return ((x & 0xFF) << 24) |
+ ((x & 0xFF00) << 8) |
+ ((x >> 8) & 0xFF00) |
+ ((x >> 24) & 0xFF);
+}
+#endif
+
+#ifndef bswap_64
+extern "C" inline u8 bswap_64(u8 x) {
+ return (u8)bswap_32((u4)x) << 32 |
+ (u8)bswap_32((u4)(x >> 32));
+}
+#endif
+
+u2 NativeEndian::get(u2 x) { return x; }
+u4 NativeEndian::get(u4 x) { return x; }
+u8 NativeEndian::get(u8 x) { return x; }
+s2 NativeEndian::get(s2 x) { return x; }
+s4 NativeEndian::get(s4 x) { return x; }
+s8 NativeEndian::get(s8 x) { return x; }
+
+void NativeEndian::set(u2& x, u2 y) { x = y; }
+void NativeEndian::set(u4& x, u4 y) { x = y; }
+void NativeEndian::set(u8& x, u8 y) { x = y; }
+void NativeEndian::set(s2& x, s2 y) { x = y; }
+void NativeEndian::set(s4& x, s4 y) { x = y; }
+void NativeEndian::set(s8& x, s8 y) { x = y; }
+
+NativeEndian NativeEndian::_native;
+
+u2 SwappingEndian::get(u2 x) { return bswap_16(x); }
+u4 SwappingEndian::get(u4 x) { return bswap_32(x); }
+u8 SwappingEndian::get(u8 x) { return bswap_64(x); }
+s2 SwappingEndian::get(s2 x) { return bswap_16(x); }
+s4 SwappingEndian::get(s4 x) { return bswap_32(x); }
+s8 SwappingEndian::get(s8 x) { return bswap_64(x); }
+
+void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); }
+void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); }
+void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); }
+void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); }
+void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); }
+void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); }
+
+SwappingEndian SwappingEndian::_swapping;
+
+Endian* Endian::get_handler(bool big_endian) {
+ // If requesting little endian on a little endian machine or
+ // big endian on a big endian machine use native handler
+ if (big_endian == is_big_endian()) {
+ return NativeEndian::get_native();
+ } else {
+ // Use swapping handler.
+ return SwappingEndian::get_swapping();
+ }
+}
+
+Endian* Endian::get_native_handler() {
+ return NativeEndian::get_native();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/endian.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,119 @@
+/*
+ * 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_UTILITIES_ENDIAN_HPP
+#define SHARE_VM_UTILITIES_ENDIAN_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+// Selectable endian handling. Endian handlers are used when accessing values
+// that are of unknown (until runtime) endian. The only requirement of the values
+// accessed are that they are aligned to proper size boundaries (no misalignment.)
+// To select an endian handler, one should call Endian::get_handler(big_endian);
+// Where big_endian is true if big endian is required and false otherwise. The
+// native endian handler can be fetched with Endian::get_native_handler();
+// To retrieve a value using the approprate endian, use one of the overloaded
+// calls to get. To set a value, then use one of the overloaded set calls.
+// Ex.
+// s4 value; // Imported value;
+// ...
+// Endian* endian = Endian::get_handler(true); // Use big endian
+// s4 corrected = endian->get(value);
+// endian->set(value, 1);
+//
+class Endian {
+public:
+ virtual u2 get(u2 x) = 0;
+ virtual u4 get(u4 x) = 0;
+ virtual u8 get(u8 x) = 0;
+ virtual s2 get(s2 x) = 0;
+ virtual s4 get(s4 x) = 0;
+ virtual s8 get(s8 x) = 0;
+
+ virtual void set(u2& x, u2 y) = 0;
+ virtual void set(u4& x, u4 y) = 0;
+ virtual void set(u8& x, u8 y) = 0;
+ virtual void set(s2& x, s2 y) = 0;
+ virtual void set(s4& x, s4 y) = 0;
+ virtual void set(s8& x, s8 y) = 0;
+
+ // Quick little endian test.
+ static bool is_little_endian() { u4 x = 1; return *(u1 *)&x != 0; }
+
+ // Quick big endian test.
+ static bool is_big_endian() { return !is_little_endian(); }
+
+ // Select an appropriate endian handler.
+ static Endian* get_handler(bool big_endian);
+
+ // Return the native endian handler.
+ static Endian* get_native_handler();
+};
+
+// Normal endian handling.
+class NativeEndian : public Endian {
+private:
+ static NativeEndian _native;
+
+public:
+ u2 get(u2 x);
+ u4 get(u4 x);
+ u8 get(u8 x);
+ s2 get(s2 x);
+ s4 get(s4 x);
+ s8 get(s8 x);
+
+ void set(u2& x, u2 y);
+ void set(u4& x, u4 y);
+ void set(u8& x, u8 y);
+ void set(s2& x, s2 y);
+ void set(s4& x, s4 y);
+ void set(s8& x, s8 y);
+
+ static Endian* get_native() { return &_native; }
+};
+
+// Swapping endian handling.
+class SwappingEndian : public Endian {
+private:
+ static SwappingEndian _swapping;
+
+public:
+ u2 get(u2 x);
+ u4 get(u4 x);
+ u8 get(u8 x);
+ s2 get(s2 x);
+ s4 get(s4 x);
+ s8 get(s8 x);
+
+ void set(u2& x, u2 y);
+ void set(u4& x, u4 y);
+ void set(u8& x, u8 y);
+ void set(s2& x, s2 y);
+ void set(s4& x, s4 y);
+ void set(s8& x, s8 y);
+
+ static Endian* get_swapping() { return &_swapping; }
+};
+#endif // SHARE_VM_UTILITIES_ENDIAN_HPP
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Jul 16 19:28:37 2015 -0700
@@ -1367,6 +1367,7 @@
#define UINT32_FORMAT_W(width) "%" #width PRIu32
#define PTR32_FORMAT "0x%08" PRIx32
+#define PTR32_FORMAT_W(width) "0x%" #width PRIx32
// Format 64-bit quantities.
#define INT64_FORMAT "%" PRId64
--- a/hotspot/src/share/vm/utilities/ostream.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -274,7 +274,7 @@
size_t limit = (len + 16) / 16 * 16;
for (size_t i = 0; i < limit; ++i) {
if (i % 16 == 0) {
- indent().print(INTPTR_FORMAT_W(07)":", i);
+ indent().print(INTPTR_FORMAT_W(07) ":", i);
}
if (i % 2 == 0) {
print(" ");
@@ -946,7 +946,7 @@
// %%% Should be: jlong time_ms = os::start_time_milliseconds(), if
// we ever get round to introduce that method on the os class
xs->head("hotspot_log version='%d %d'"
- " process='%d' time_ms='"INT64_FORMAT"'",
+ " process='%d' time_ms='" INT64_FORMAT "'",
LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
os::current_process_id(), (int64_t)time_ms);
// Write VM version header immediately.
--- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Jul 16 19:28:37 2015 -0700
@@ -411,9 +411,10 @@
}
st->cr();
} else {
- if (_message != NULL)
+ if (_message != NULL) {
st->print("# ");
st->print_cr("%s", _message);
+ }
}
// In error file give some solutions
if (_verbose) {
--- a/hotspot/test/TEST.groups Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/TEST.groups Thu Jul 16 19:28:37 2015 -0700
@@ -241,7 +241,7 @@
gc/arguments/TestParallelGCThreads.java \
gc/arguments/TestUseCompressedOopsErgo.java \
gc/class_unloading/TestG1ClassUnloadingHWM.java \
- gc/ergonomics/TestDynamicNumberOfGCThreads.java
+ gc/ergonomics/TestDynamicNumberOfGCThreads.java \
gc/g1/ \
gc/metaspace/G1AddMetaspaceDependency.java \
gc/metaspace/TestMetaspacePerfCounters.java \
--- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Thu Jul 16 19:28:37 2015 -0700
@@ -34,6 +34,7 @@
* @library /testlibrary
* @modules java.base/sun.misc
* java.management
+ * java.base/jdk.internal
* @compile -XDignore.symbol.file java/lang/Object.java TestMonomorphicObjectCall.java
* @run main TestMonomorphicObjectCall
*/
--- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java Thu Jul 16 19:28:37 2015 -0700
@@ -25,25 +25,33 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* Slightly modified version of java.lang.Object that replaces
* finalize() by finalizeObject() to avoid overriding in subclasses.
*/
public class Object {
+ @HotSpotIntrinsicCandidate
+ public Object() {}
+
private static native void registerNatives();
static {
registerNatives();
}
+ @HotSpotIntrinsicCandidate
public final native Class<?> getClass();
+ @HotSpotIntrinsicCandidate
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
+ @HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/montgomerymultiply/MontgomeryMultiplyTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,277 @@
+//
+// Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2015, Red Hat Inc. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//
+//
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * @test
+ * @bug 8130150
+ * @library /testlibrary
+ * @summary Verify that the Montgomery multiply intrinsic works and correctly checks its arguments.
+ */
+
+public class MontgomeryMultiplyTest {
+
+ static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+ static final MethodHandle montgomeryMultiplyHandle, montgomerySquareHandle;
+ static final MethodHandle bigIntegerConstructorHandle;
+ static final Field bigIntegerMagField;
+
+ static {
+ // Use reflection to gain access to the methods we want to test.
+ try {
+ Method m = BigInteger.class.getDeclaredMethod("montgomeryMultiply",
+ /*a*/int[].class, /*b*/int[].class, /*n*/int[].class, /*len*/int.class,
+ /*inv*/long.class, /*product*/int[].class);
+ m.setAccessible(true);
+ montgomeryMultiplyHandle = lookup.unreflect(m);
+
+ m = BigInteger.class.getDeclaredMethod("montgomerySquare",
+ /*a*/int[].class, /*n*/int[].class, /*len*/int.class,
+ /*inv*/long.class, /*product*/int[].class);
+ m.setAccessible(true);
+ montgomerySquareHandle = lookup.unreflect(m);
+
+ Constructor c
+ = BigInteger.class.getDeclaredConstructor(int.class, int[].class);
+ c.setAccessible(true);
+ bigIntegerConstructorHandle = lookup.unreflectConstructor(c);
+
+ bigIntegerMagField = BigInteger.class.getDeclaredField("mag");
+ bigIntegerMagField.setAccessible(true);
+
+ } catch (Throwable ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ // Invoke either BigInteger.montgomeryMultiply or BigInteger.montgomerySquare.
+ int[] montgomeryMultiply(int[] a, int[] b, int[] n, int len, long inv,
+ int[] product) throws Throwable {
+ int[] result =
+ (a == b) ? (int[]) montgomerySquareHandle.invokeExact(a, n, len, inv, product)
+ : (int[]) montgomeryMultiplyHandle.invokeExact(a, b, n, len, inv, product);
+ return Arrays.copyOf(result, len);
+ }
+
+ // Invoke the private constructor BigInteger(int[]).
+ BigInteger newBigInteger(int[] val) throws Throwable {
+ return (BigInteger) bigIntegerConstructorHandle.invokeExact(1, val);
+ }
+
+ // Get the private field BigInteger.mag
+ int[] mag(BigInteger n) {
+ try {
+ return (int[]) bigIntegerMagField.get(n);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ // Montgomery multiplication
+ // Calculate a * b * r^-1 mod n)
+ //
+ // R is a power of the word size
+ // N' = R^-1 mod N
+ //
+ // T := ab
+ // m := (T mod R)N' mod R [so 0 <= m < R]
+ // t := (T + mN)/R
+ // if t >= N then return t - N else return t
+ //
+ BigInteger montgomeryMultiply(BigInteger a, BigInteger b, BigInteger N,
+ int len, BigInteger n_prime)
+ throws Throwable {
+ BigInteger T = a.multiply(b);
+ BigInteger R = BigInteger.ONE.shiftLeft(len*32);
+ BigInteger mask = R.subtract(BigInteger.ONE);
+ BigInteger m = (T.and(mask)).multiply(n_prime);
+ m = m.and(mask); // i.e. m.mod(R)
+ T = T.add(m.multiply(N));
+ T = T.shiftRight(len*32); // i.e. T.divide(R)
+ if (T.compareTo(N) > 0) {
+ T = T.subtract(N);
+ }
+ return T;
+ }
+
+ // Call the Montgomery multiply intrinsic.
+ BigInteger montgomeryMultiply(int[] a_words, int[] b_words, int[] n_words,
+ int len, BigInteger inv)
+ throws Throwable {
+ BigInteger t = montgomeryMultiply(
+ newBigInteger(a_words),
+ newBigInteger(b_words),
+ newBigInteger(n_words),
+ len, inv);
+ return t;
+ }
+
+ // Check that the Montgomery multiply intrinsic returns the same
+ // result as the longhand calculation.
+ void check(int[] a_words, int[] b_words, int[] n_words, int len, BigInteger inv)
+ throws Throwable {
+ BigInteger n = newBigInteger(n_words);
+ BigInteger slow = montgomeryMultiply(a_words, b_words, n_words, len, inv);
+ BigInteger fast
+ = newBigInteger(montgomeryMultiply
+ (a_words, b_words, n_words, len, inv.longValue(), null));
+ // The intrinsic may not return the same value as the longhand
+ // calculation but they must have the same residue mod N.
+ if (!slow.mod(n).equals(fast.mod(n))) {
+ throw new RuntimeException();
+ }
+ }
+
+ Random rnd = new Random(0);
+
+ // Return a random value of length <= bits in an array of even length
+ int[] random_val(int bits) {
+ int len = (bits+63)/64; // i.e. length in longs
+ int[] val = new int[len*2];
+ for (int i = 0; i < val.length; i++)
+ val[i] = rnd.nextInt();
+ int leadingZeros = 64 - (bits & 64);
+ if (leadingZeros >= 32) {
+ val[0] = 0;
+ val[1] &= ~(-1l << (leadingZeros & 31));
+ } else {
+ val[0] &= ~(-1l << leadingZeros);
+ }
+ return val;
+ }
+
+ void testOneLength(int lenInBits, int lenInInts) throws Throwable {
+ BigInteger mod = new BigInteger(lenInBits, 2, rnd);
+ BigInteger r = BigInteger.ONE.shiftLeft(lenInInts * 32);
+ BigInteger n_prime = mod.modInverse(r).negate();
+
+ // Make n.length even, padding with a zero if necessary
+ int[] n = mag(mod);
+ if (n.length < lenInInts) {
+ int[] x = new int[lenInInts];
+ System.arraycopy(n, 0, x, lenInInts-n.length, n.length);
+ n = x;
+ }
+
+ for (int i = 0; i < 10000; i++) {
+ // multiply
+ check(random_val(lenInBits), random_val(lenInBits), n, lenInInts, n_prime);
+ // square
+ int[] tmp = random_val(lenInBits);
+ check(tmp, tmp, n, lenInInts, n_prime);
+ }
+ }
+
+ // Test the Montgomery multiply intrinsic with a bunch of random
+ // values of varying lengths. Do this for long enough that the
+ // caller of the intrinsic is C2-compiled.
+ void testResultValues() throws Throwable {
+ // Test a couple of interesting edge cases.
+ testOneLength(1024, 32);
+ testOneLength(1025, 34);
+ for (int j = 10; j > 0; j--) {
+ // Construct a random prime whose length in words is even
+ int lenInBits = rnd.nextInt(2048) + 64;
+ int lenInInts = (lenInBits + 63)/64*2;
+ testOneLength(lenInBits, lenInInts);
+ }
+ }
+
+ // Range checks
+ void testOneMontgomeryMultiplyCheck(int[] a, int[] b, int[] n, int len, long inv,
+ int[] product, Class klass) {
+ try {
+ montgomeryMultiply(a, b, n, len, inv, product);
+ } catch (Throwable ex) {
+ if (klass.isAssignableFrom(ex.getClass()))
+ return;
+ throw new RuntimeException(klass + " expected, " + ex + " was thrown");
+ }
+ throw new RuntimeException(klass + " expected, was not thrown");
+ }
+
+ void testOneMontgomeryMultiplyCheck(int[] a, int[] b, BigInteger n, int len, BigInteger inv,
+ Class klass) {
+ testOneMontgomeryMultiplyCheck(a, b, mag(n), len, inv.longValue(), null, klass);
+ }
+
+ void testOneMontgomeryMultiplyCheck(int[] a, int[] b, BigInteger n, int len, BigInteger inv,
+ int[] product, Class klass) {
+ testOneMontgomeryMultiplyCheck(a, b, mag(n), len, inv.longValue(), product, klass);
+ }
+
+ void testMontgomeryMultiplyChecks() {
+ int[] blah = random_val(40);
+ int[] small = random_val(39);
+ BigInteger mod = new BigInteger(40*32 , 2, rnd);
+ BigInteger r = BigInteger.ONE.shiftLeft(40*32);
+ BigInteger n_prime = mod.modInverse(r).negate();
+
+ // Length out of range: square
+ testOneMontgomeryMultiplyCheck(blah, blah, mod, 41, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah, mod, 0, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah, mod, -1, n_prime, IllegalArgumentException.class);
+ // As above, but for multiply
+ testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 41, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+
+ // Length odd
+ testOneMontgomeryMultiplyCheck(small, small, mod, 39, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, small, mod, 0, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, small, mod, -1, n_prime, IllegalArgumentException.class);
+ // As above, but for multiply
+ testOneMontgomeryMultiplyCheck(small, small.clone(), mod, 39, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, small.clone(), mod, 0, n_prime, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, small.clone(), mod, -1, n_prime, IllegalArgumentException.class);
+
+ // array too small
+ testOneMontgomeryMultiplyCheck(blah, blah, mod, 40, n_prime, small, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah.clone(), mod, 40, n_prime, small, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, blah, mod, 40, n_prime, blah, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, small, mod, 40, n_prime, blah, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(blah, blah, mod, 40, n_prime, small, IllegalArgumentException.class);
+ testOneMontgomeryMultiplyCheck(small, small, mod, 40, n_prime, blah, IllegalArgumentException.class);
+ }
+
+ public static void main(String args[]) {
+ try {
+ new MontgomeryMultiplyTest().testMontgomeryMultiplyChecks();
+ new MontgomeryMultiplyTest().testResultValues();
+ } catch (Throwable ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
--- a/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/intrinsics/sha/cli/SHAOptionsBase.java Thu Jul 16 19:28:37 2015 -0700
@@ -47,16 +47,12 @@
// expressions, not just a plain strings.
protected static final String SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE
= "SHA instructions are not available on this CPU";
- protected static final String SHA1_INSTRUCTION_IS_NOT_AVAILABLE
- = "SHA1 instruction is not available on this CPU\\.";
- protected static final String SHA256_INSTRUCTION_IS_NOT_AVAILABLE
- = "SHA256 instruction \\(for SHA-224 and SHA-256\\) "
- + "is not available on this CPU\\.";
- protected static final String SHA512_INSTRUCTION_IS_NOT_AVAILABLE
- = "SHA512 instruction \\(for SHA-384 and SHA-512\\) "
- + "is not available on this CPU\\.";
- protected static final String SHA_INTRINSICS_ARE_NOT_AVAILABLE
- = "SHA intrinsics are not available on this CPU";
+ protected static final String SHA1_INTRINSICS_ARE_NOT_AVAILABLE
+ = "Intrinsics for SHA-1 crypto hash functions not available on this CPU.";
+ protected static final String SHA256_INTRINSICS_ARE_NOT_AVAILABLE
+ = "Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.";
+ protected static final String SHA512_INTRINSICS_ARE_NOT_AVAILABLE
+ = "Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.";
private final TestCase[] testCases;
@@ -71,33 +67,23 @@
* instructions required by the option are not supported.
*/
protected static String getWarningForUnsupportedCPU(String optionName) {
- if (Platform.isSparc() || Platform.isAArch64()) {
+ if (Platform.isSparc() || Platform.isAArch64() ||
+ Platform.isX64() || Platform.isX86()) {
switch (optionName) {
- case SHAOptionsBase.USE_SHA_OPTION:
- return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
- case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
- return SHAOptionsBase.SHA1_INSTRUCTION_IS_NOT_AVAILABLE;
- case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
- return SHAOptionsBase.SHA256_INSTRUCTION_IS_NOT_AVAILABLE;
- case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
- return SHAOptionsBase.SHA512_INSTRUCTION_IS_NOT_AVAILABLE;
- default:
- throw new Error("Unexpected option " + optionName);
- }
- } else if (Platform.isX64() || Platform.isX86()) {
- switch (optionName) {
- case SHAOptionsBase.USE_SHA_OPTION:
- return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
- case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
- case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
- case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
- return SHAOptionsBase.SHA_INTRINSICS_ARE_NOT_AVAILABLE;
- default:
- throw new Error("Unexpected option " + optionName);
+ case SHAOptionsBase.USE_SHA_OPTION:
+ return SHAOptionsBase.SHA_INSTRUCTIONS_ARE_NOT_AVAILABLE;
+ case SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION:
+ return SHAOptionsBase.SHA1_INTRINSICS_ARE_NOT_AVAILABLE;
+ case SHAOptionsBase.USE_SHA256_INTRINSICS_OPTION:
+ return SHAOptionsBase.SHA256_INTRINSICS_ARE_NOT_AVAILABLE;
+ case SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION:
+ return SHAOptionsBase.SHA512_INTRINSICS_ARE_NOT_AVAILABLE;
+ default:
+ throw new Error("Unexpected option " + optionName);
}
} else {
- throw new Error("Support for CPUs other then X86 or SPARC is not "
- + "implemented.");
+ throw new Error("Support for CPUs different fromn X86, SPARC, and AARCH64 "
+ + "is not implemented");
}
}
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedCPU.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedCPU.java Thu Jul 16 19:28:37 2015 -0700
@@ -64,18 +64,20 @@
SHAOptionsBase.USE_SHA_OPTION, true),
CommandLineOptionTest.prepareBooleanFlag(optionName, false));
- // Verify that it is possible to enable the tested option and disable
- // all SHA intrinsics via -UseSHA without any warnings.
- CommandLineOptionTest.verifySameJVMStartup(null, new String[] {
- SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
- }, shouldPassMessage, String.format("It should be able to "
- + "enable option '%s' even if %s was passed to JVM",
- optionName, CommandLineOptionTest.prepareBooleanFlag(
- SHAOptionsBase.USE_SHA_OPTION, false)),
- ExitCode.OK,
- CommandLineOptionTest.prepareBooleanFlag(
- SHAOptionsBase.USE_SHA_OPTION, false),
- CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+ if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+ // Verify that if -XX:-UseSHA is passed to the JVM, it is not possible
+ // to enable the tested option and a warning is printed.
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+ null,
+ shouldPassMessage,
+ String.format("Enabling option '%s' should not be possible and should result in a warning if %s was passed to JVM",
+ optionName,
+ CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false)),
+ ExitCode.OK,
+ CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+ }
}
@Override
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedAArch64CPU.java Thu Jul 16 19:28:37 2015 -0700
@@ -49,14 +49,22 @@
}, shouldPassMessage, shouldPassMessage, ExitCode.OK,
CommandLineOptionTest.prepareBooleanFlag(optionName, false));
- shouldPassMessage = String.format("JVM should start with '-XX:+"
- + "%s' flag, but output should contain warning.", optionName);
- // Verify that when the tested option is explicitly enabled, then
- // a warning will occur in VM output.
- CommandLineOptionTest.verifySameJVMStartup(new String[] {
- SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
- }, null, shouldPassMessage, shouldPassMessage, ExitCode.OK,
- CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+ shouldPassMessage = String.format("If JVM is started with '-XX:-"
+ + "%s' '-XX:+%s', output should contain warning.",
+ SHAOptionsBase.USE_SHA_OPTION, optionName);
+
+ // Verify that when the tested option is enabled, then
+ // a warning will occur in VM output if UseSHA is disabled.
+ if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+ null,
+ shouldPassMessage,
+ shouldPassMessage,
+ ExitCode.OK,
+ CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+ }
}
@Override
--- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java Thu Jul 16 19:28:37 2015 -0700
@@ -48,6 +48,19 @@
SHAOptionsBase.getWarningForUnsupportedCPU(optionName)
}, shouldPassMessage, shouldPassMessage, ExitCode.OK,
CommandLineOptionTest.prepareBooleanFlag(optionName, false));
+
+ // Verify that when the tested option is enabled, then
+ // a warning will occur in VM output if UseSHA is disabled.
+ if (!optionName.equals(SHAOptionsBase.USE_SHA_OPTION)) {
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) },
+ null,
+ shouldPassMessage,
+ shouldPassMessage,
+ ExitCode.OK,
+ CommandLineOptionTest.prepareBooleanFlag(SHAOptionsBase.USE_SHA_OPTION, false),
+ CommandLineOptionTest.prepareBooleanFlag(optionName, true));
+ }
}
@Override
--- a/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java Thu Jul 16 19:28:37 2015 -0700
@@ -23,7 +23,7 @@
/**
* @test TestShrinkDefragmentedHeap
- * @bug 8038423
+ * @bug 8038423 8129590
* @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
* 1. allocate small objects mixed with humongous ones
* "ssssHssssHssssHssssHssssHssssHssssH"
@@ -51,12 +51,14 @@
// To avoid this the Eden needs to be big enough to fit all the small objects.
private static final int INITIAL_HEAP_SIZE = 200 * 1024 * 1024;
private static final int MINIMAL_YOUNG_SIZE = 190 * 1024 * 1024;
+ private static final int MAXIMUM_HEAP_SIZE = 256 * 1024 * 1024;
private static final int REGION_SIZE = 1 * 1024 * 1024;
public static void main(String[] args) throws Exception, Throwable {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:InitialHeapSize=" + INITIAL_HEAP_SIZE,
"-Xmn" + MINIMAL_YOUNG_SIZE,
+ "-Xmx" + MAXIMUM_HEAP_SIZE,
"-XX:MinHeapFreeRatio=10",
"-XX:MaxHeapFreeRatio=11",
"-XX:+UseG1GC",
--- a/hotspot/test/gc/g1/TestSummarizeRSetStats.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStats.java Thu Jul 16 19:28:37 2015 -0700
@@ -23,7 +23,7 @@
/*
* @test TestSummarizeRSetStats.java
- * @bug 8013895
+ * @bug 8013895 8129977
* @library /testlibrary
* @modules java.base/sun.misc
* java.management/sun.management
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java Thu Jul 16 19:28:37 2015 -0700
@@ -23,7 +23,7 @@
/*
* @test TestSummarizeRSetStatsPerRegion.java
- * @bug 8014078
+ * @bug 8014078 8129977
* @library /testlibrary
* @modules java.base/sun.misc
* java.management/sun.management
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java Thu Jul 16 19:28:37 2015 -0700
@@ -87,6 +87,7 @@
String[] defaultArgs = new String[] {
"-XX:+UseG1GC",
"-Xmn4m",
+ "-Xms20m",
"-Xmx20m",
"-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
"-XX:+PrintGC",
--- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Thu Jul 16 19:28:37 2015 -0700
@@ -28,6 +28,7 @@
* when their age exceeded tenuring threshold are not aligned to
* SurvivorAlignmentInBytes value.
* @library /testlibrary /../../test/lib
+ * @ignore 8130308
* @modules java.base/sun.misc
* java.management
* @build TestPromotionFromSurvivorToTenuredAfterMinorGC
--- a/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Thu Jul 16 19:28:37 2015 -0700
@@ -31,6 +31,7 @@
* java.management
* @build TestPromotionToSurvivor
* SurvivorAlignmentTestMain AlignmentHelper
+ * @ignore 8129886
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java Thu Jul 16 19:28:37 2015 -0700
@@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
public class DoubleJVMOption extends JVMOption {
@@ -109,7 +110,7 @@
}
private String formatValue(double value) {
- return String.format("%f", value);
+ return String.format(Locale.US, "%f", value);
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/TestLongUnrecognizedVMOption.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8129786
+ * @summary Verify that JVM correctly processes very long unrecognized VM option
+ * @library /testlibrary
+ * @modules java.management
+ * @run main TestLongUnrecognizedVMOption
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+public class TestLongUnrecognizedVMOption {
+
+ /* Create option with very long length(greater than 500 characters) */
+ private static final String VERY_LONG_OPTION = String.format("%500s=10", "unrecognizedoption").replace(" ", "a");
+
+ public static void main(String[] args) throws Exception {
+ OutputAnalyzer output;
+
+ output = new OutputAnalyzer(ProcessTools.createJavaProcessBuilder("-XX:" + VERY_LONG_OPTION, "-version").start());
+ output.shouldHaveExitValue(1);
+ output.shouldContain(String.format("Unrecognized VM option '%s'", VERY_LONG_OPTION));
+ }
+}
--- a/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java Thu Jul 16 19:28:37 2015 -0700
@@ -23,12 +23,15 @@
/**
* @test
- * @library /runtime/testlibrary
* @library classes
- * @build test.Empty ClassUnloadCommon
+ * @build test.Empty
* @run main/othervm/timeout=200 FragmentMetaspaceSimple
*/
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.ArrayList;
/**
@@ -47,8 +50,14 @@
private static void runSimple(long time) {
long startTime = System.currentTimeMillis();
ArrayList<ClassLoader> cls = new ArrayList<>();
- for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
- ClassLoader ldr = ClassUnloadCommon.newClassLoader();
+ char sep = File.separatorChar;
+ String fileName = "classes" + sep + "test" + sep + "Empty.class";
+ File file = new File(System.getProperty("test.classes",".") + sep + fileName);
+ byte buff[] = read(file);
+
+ int i = 0;
+ for (i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+ ClassLoader ldr = new MyClassLoader(buff);
if (i % 1000 == 0) {
cls.clear();
}
@@ -59,11 +68,43 @@
Class<?> c = null;
try {
c = ldr.loadClass("test.Empty");
+ c.getClass().getClassLoader(); // make sure we have a valid class.
} catch (ClassNotFoundException ex) {
+ System.out.println("i=" + i + ", len" + buff.length);
throw new RuntimeException(ex);
}
c = null;
}
cls = null;
+ System.out.println("Finished " + i + " iterations in " +
+ (System.currentTimeMillis() - startTime) + " ms");
+ }
+
+ private static byte[] read(File file) {
+ byte buff[] = new byte[(int)(file.length())];
+ try {
+ DataInputStream din = new DataInputStream(new FileInputStream(file));
+ din.readFully(buff);
+ din.close();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ return buff;
+ }
+
+ static class MyClassLoader extends ClassLoader {
+ byte buff[];
+ MyClassLoader(byte buff[]) {
+ this.buff = buff;
+ }
+
+ public Class<?> loadClass() throws ClassNotFoundException {
+ String name = "test.Empty";
+ try {
+ return defineClass(name, buff, 0, buff.length);
+ } catch (Throwable e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageAttributeOffsetsTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/*
+ * Retrieves the array of offsets once with MemoryMapImage enabled once disabled.
+ * @test ImageAttributeOffsetsTest
+ * @summary Unit test for JVM_ImageAttributeOffsets() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageAttributeOffsetsTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageAttributeOffsetsTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageAttributeOffsetsTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageAttributeOffsetsTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+ boolean passed = true;
+ // Get offsets
+ int[] array = wb.imageAttributeOffsets(id);
+ assertNotNull(array, "Could not retrieve offsets of array");
+
+ wb.imageCloseImage(id);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageCloseTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test closing image opened multiple time. Test closing mutiple time an image.
+ * @test ImageCloseTest
+ * @summary Unit test for JVM_ImageClose() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageCloseTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageCloseTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+
+public class ImageCloseTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = 0;
+
+ // too many opens
+ for (int i = 0; i < 100; i++) {
+ id = wb.imageOpenImage(imageFile, bigEndian);
+ }
+ wb.imageCloseImage(id);
+
+ // too many closes
+ id = wb.imageOpenImage(imageFile, bigEndian);
+ for (int i = 0; i < 100; i++) {
+ wb.imageCloseImage(id);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageFileHeaderTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test that opening image containing wrong headers fails.
+ * @test ImageFileHeaderTest
+ * @library /testlibrary /../../test/lib
+ * @build ImageFileHeaderTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFileHeaderTest
+ */
+
+import java.nio.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageFileHeaderTest {
+
+ public static final int MAGIC = 0xCAFEDADA;
+ public static final short MAJOR = 0;
+ public static final short MINOR = 1;
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+ public static ByteBuffer buf;
+
+ public static void main(String... args) throws Exception {
+
+ ByteOrder endian = getEndian();
+
+ // Try to read a non-existing file
+ assertFalse(wb.readImageFile("bogus"));
+
+ // Incomplete header, only include the correct magic
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(MAGIC);
+ assertFalse(testImageFile("invalidheader.jimage"));
+
+ // Build a complete header but reverse the endian
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian == ByteOrder.LITTLE_ENDIAN ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ buf.putInt(MAGIC);
+ buf.putShort(MAJOR);
+ buf.putShort(MINOR);
+ assertFalse(testImageFile("wrongendian.jimage"));
+
+ // Use the wrong magic
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(0xBEEFCACE);
+ buf.putShort(MAJOR);
+ buf.putShort(MINOR);
+ assertFalse(testImageFile("wrongmagic.jimage"));
+
+ // Wrong major version (current + 1)
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(MAGIC);
+ buf.putShort((short)(MAJOR + 1));
+ buf.putShort((short)MINOR);
+ assertFalse(testImageFile("wrongmajorversion.jimage"));
+
+ // Wrong major version (negative)
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(MAGIC);
+ buf.putShort((short) -17);
+ buf.putShort((short)MINOR);
+ assertFalse(testImageFile("negativemajorversion.jimage"));
+
+ // Wrong minor version (current + 1)
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(MAGIC);
+ buf.putShort((short)MAJOR);
+ buf.putShort((short)(MINOR + 1));
+ assertFalse(testImageFile("wrongminorversion.jimage"));
+
+ // Wrong minor version (negative)
+ buf = ByteBuffer.allocate(100);
+ buf.order(endian);
+ buf.putInt(MAGIC);
+ buf.putShort((short)MAJOR);
+ buf.putShort((short) -17);
+ assertFalse(testImageFile("negativeminorversion.jimage"));
+ }
+
+ public static boolean testImageFile(String filename) throws Exception {
+ Files.write(Paths.get(filename), buf.array());
+ System.out.println("Calling ReadImageFile on " + filename);
+ return wb.readImageFile(filename);
+ }
+
+ public static ByteOrder getEndian() {
+ String endian = System.getProperty("sun.cpu.endian");
+ if (endian.equalsIgnoreCase("little")) {
+ return ByteOrder.LITTLE_ENDIAN;
+ } else if (endian.equalsIgnoreCase("big")) {
+ return ByteOrder.BIG_ENDIAN;
+ }
+ throw new RuntimeException("Unexpected sun.cpu.endian value: " + endian);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageFindAttributesTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/*
+ * Find the attributes of existing and invalid classes.
+ * @test ImageFindAttributesTest
+ * @summary Unit test for JVM_ImageFindAttributes() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageFindAttributesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFindAttributesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageFindAttributesTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+
+ // class resource
+ String className = "/java.base/java/lang/String.class";
+ long[] longArr = wb.imageFindAttributes(id, className.getBytes());
+
+ assertNotNull(longArr, "Could not retrieve attributes of class " + className);
+
+ // non-existent resource
+ String neClassName = "/java.base/java/lang/NonExistentClass.class";
+ longArr = wb.imageFindAttributes(id, neClassName.getBytes());
+
+ assertNull(longArr, "Failed. Returned not null for non-existent " + neClassName);
+
+ // garbage byte array
+ byte[] buf = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ longArr = wb.imageFindAttributes(id, buf);
+
+ assertNull(longArr, "Found attributes for garbage class");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetAttributesTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test getting all attributes,
+ * @test ImageGetAttributesTest
+ * @summary Unit test for JVM_ImageGetAttributes() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageGetAttributesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetAttributesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetAttributesTest implements LocationConstants {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ testImageGetAttributes(imageFile);
+ }
+
+ private static void testImageGetAttributes(String imageFile) {
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+ try {
+ long stringsSize = wb.imageGetStringsSize(id);
+ assertNE(stringsSize, 0, "strings size is 0");
+
+ int[] array = wb.imageAttributeOffsets(id);
+ assertNotNull(array, "Could not retrieve offsets of array");
+
+ // Get non-null attributes
+ boolean attFound = false;
+ int[] idx = {-1, -1, -1};
+ // first non-null attribute
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] != 0) {
+ attFound = true;
+ idx[0] = i;
+ break;
+ }
+ }
+
+ // middle non-null attribute
+ for (int i = array.length / 2; i < array.length; i++) {
+ if (array[i] != 0) {
+ attFound = true;
+ idx[1] = i;
+ break;
+ }
+ }
+
+ // last non-null attribute
+ for (int i = array.length - 1; i >= 0; i--) {
+ if (array[i] != 0) {
+ attFound = true;
+ idx[2] = i;
+ break;
+ }
+ }
+ assertTrue(attFound, "Failed. No non-null offset attributes");
+ // test cases above
+ for (int i = 0; i < 3; i++) {
+ if (idx[i] != -1) {
+ long[] attrs = wb.imageGetAttributes(id, (int) array[idx[i]]);
+ long module = attrs[LOCATION_ATTRIBUTE_MODULE];
+ long parent = attrs[LOCATION_ATTRIBUTE_PARENT];
+ long base = attrs[LOCATION_ATTRIBUTE_BASE];
+ long ext = attrs[LOCATION_ATTRIBUTE_EXTENSION];
+
+ if ((module >= 0) && (module < stringsSize)
+ && (parent >= 0) && (parent < stringsSize)
+ && (base != 0)
+ && (ext >= 0) && (ext < stringsSize)) {
+ } else {
+ System.out.printf("Failed. Read attribute offset %d (position %d) but wrong offsets\n",
+ array[idx[i]], idx[i]);
+ System.out.printf(" offsets: module = %d parent = %d base = %d extention = %d\n",
+ module, parent, base, ext);
+ throw new RuntimeException("Read attribute offset error");
+ }
+ } else {
+ System.out.printf("Failed. Could not read attribute offset %d (position %d)\n",
+ array[idx[i]], idx[i]);
+ throw new RuntimeException("Read attribute offset error");
+ }
+ }
+ } finally {
+ wb.imageCloseImage(id);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetDataAddressTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test accessing the data address of a jimage. This only makes sense when the
+ * entire jimage is mapped into memory.
+ * @test ImageGetDataAddressTest
+ * @summary Unit test for JVM_ImageGetDataAddress() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageGetDataAddressTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageGetDataAddressTest +
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageGetDataAddressTest -
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetDataAddressTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean isMMap = args[0].equals("+");
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+
+ // get data for valid id
+ long dataAddr = wb.imageGetDataAddress(id);
+ assertFalse((dataAddr == 0) && isMMap, "Failed. Data address is " + dataAddr + " for valid id\n");
+
+ // get data for invalid id == 0
+ dataAddr = wb.imageGetDataAddress(0);
+ assertTrue(dataAddr == 0, "Failed. Data address is " + dataAddr + " for zero id\n");
+
+ wb.imageCloseImage(id);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetIndexAddressTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test the address of the jimage index.
+ * @test ImageGetIndexAddressTest
+ * @summary Unit test for JVM_ImageGetIndexAddress() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageGetIndexAddressTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetIndexAddressTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetIndexAddressTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+
+ // get index for valid id
+ long indexAddr = wb.imageGetIndexAddress(id);
+ assertFalse(indexAddr == 0, "Failed. Index address is zero for valid id");
+
+ // get index for invalid id == 0
+ indexAddr = wb.imageGetIndexAddress(0);
+ assertTrue(indexAddr == 0, "Failed. Index address is" + indexAddr + " for zero id\n");
+
+ wb.imageCloseImage(id);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageGetStringBytesTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test that the string referenced by an attribute is retrieved.
+ * @test ImageGetStringBytesTest
+ * @summary Unit test for JVM_ImageGetStringBytes() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageGetStringBytesTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetStringBytesTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageGetStringBytesTest implements LocationConstants {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+ long id = wb.imageOpenImage(imageFile, bigEndian);
+
+ String className = "/java.base/java/lang/String.class";
+ long[] offsetArr = wb.imageFindAttributes(id, className.getBytes());
+
+ // Module
+ assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_MODULE, "Module"));
+
+ // Parent
+ assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_PARENT, "Parent"));
+
+ // Base
+ assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_BASE, "Base"));
+
+ // Extension
+ assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_EXTENSION, "Extension"));
+
+ wb.imageCloseImage(id);
+ }
+
+ private static boolean checkAttribute(long id, long[] offsetArr, int attrId, String attrName) {
+ long offset = offsetArr[attrId];
+ return wb.imageGetStringBytes(id, (int) offset) != null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageOpenTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test image opening/closing
+ * @test ImageOpenTest
+ * @summary Unit test for JVM_ImageOpen() method
+ * @library /testlibrary /../../test/lib
+ * @build ImageOpenTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageOpenTest
+ */
+
+import java.io.File;
+import java.nio.ByteOrder;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageOpenTest {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String nonexistentImageFile = javaHome + "/lib/modules/nonexistent.jimage";
+ String bootmodulesImageFile = javaHome + File.separator + "lib" + File.separator
+ + "modules" + File.separator + "bootmodules.jimage";
+
+ if (!(new File(bootmodulesImageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
+
+ // open nonexistent image
+ long id = wb.imageOpenImage(nonexistentImageFile, bigEndian);
+ assertTrue(id == 0L, "Failed. Get id " + id + "instead of 0 on opening nonexistent file\n");
+ wb.imageCloseImage(id);
+
+ // open bootmodules image
+ id = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+ assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage");
+ wb.imageCloseImage(id);
+
+ // non-native endian
+ id = wb.imageOpenImage(bootmodulesImageFile, !bigEndian);
+ assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage with non-native endian");
+ wb.imageCloseImage(id);
+
+ //
+ // open several times
+ //
+ id = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+ long id1 = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+ long id2 = wb.imageOpenImage(bootmodulesImageFile, bigEndian);
+ assertTrue((id == id1) && (id == id2), "Failed. Open thee times with ids " + id + " " + id1 + " " + id1);
+
+ wb.imageCloseImage(id);
+ wb.imageCloseImage(id1);
+ wb.imageCloseImage(id2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/ImageReadTest.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+/*
+ * Test reading resource content.
+ * @test ImageReadTest
+ * @summary Unit test for JVM_ImageRead() method
+ * @library /testlibrary /../../test/lib
+ * @build LocationConstants ImageReadTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageReadTest +
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageReadTest -
+ */
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import sun.hotspot.WhiteBox;
+import static jdk.test.lib.Asserts.*;
+
+public class ImageReadTest implements LocationConstants {
+
+ public static final WhiteBox wb = WhiteBox.getWhiteBox();
+
+ public static void main(String... args) throws Exception {
+ String javaHome = System.getProperty("java.home");
+ String imageFile = javaHome + File.separator + "lib"
+ + File.separator + "modules" + File.separator
+ + "bootmodules.jimage";
+
+ if (!(new File(imageFile)).exists()) {
+ System.out.printf("Test skipped.");
+ return;
+ }
+
+ boolean isMMap = args[0].equals("+");
+
+ long id = wb.imageOpenImage(imageFile, isMMap);
+
+ final String mm = isMMap ? "-XX:+MemoryMapImage" : "-XX:-MemoryMapImage";
+ final int magic = 0xCAFEBABE;
+
+ String className = "/java.base/java/lang/String.class";
+ long[] offsetArr = wb.imageFindAttributes(id, className.getBytes());
+ long offset = offsetArr[LOCATION_ATTRIBUTE_OFFSET];
+ long size = offsetArr[LOCATION_ATTRIBUTE_UNCOMPRESSED];
+
+ // positive: read
+ ByteBuffer buf = ByteBuffer.allocateDirect((int) size);
+ assertTrue(wb.imageRead(id, offset, buf, size), "Failed. Read operation returned false, should be true");
+ int m = buf.getInt();
+ assertTrue(m == magic, "Failed. Read operation returned true but wrong magic = " + magic);
+
+ // positive: mmap
+ if (isMMap) {
+ long dataAddr = wb.imageGetDataAddress(id);
+ assertFalse(dataAddr == 0L, "Failed. Did not obtain data address on mmapped test");
+ int data = wb.imageGetIntAtAddress(dataAddr, (int) offset, true);
+ assertTrue(data == magic, "Failed. MMap operation returned true but wrong magic = " + data);
+ }
+
+ // negative: wrong offset
+ boolean success = wb.imageRead(id, -100, buf, size);
+ assertFalse(success, "Failed. Read operation (wrong offset): returned true");
+
+ // negative: too big offset
+ long filesize = new File(imageFile).length();
+ success = wb.imageRead(id, filesize + 1, buf, size);
+ assertFalse(success, "Failed. Read operation (offset > file size) returned true");
+
+ // negative: negative size
+ success = wb.imageRead(id, offset, buf, -100);
+ assertFalse(success, "Failed. Read operation (negative size) returned true");
+
+ wb.imageCloseImage(id);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ImageFile/LocationConstants.java Thu Jul 16 19:28:37 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+public interface LocationConstants {
+ // keep this in sync with enum in ImageLocation C++ class in the
+ // hotspot's C++ header file imageFile.hpp
+ public static final int LOCATION_ATTRIBUTE_END = 0; // End of attribute stream marker
+ public static final int LOCATION_ATTRIBUTE_MODULE = 1; // String table offset of module name
+ public static final int LOCATION_ATTRIBUTE_PARENT = 2; // String table offset of resource path parent
+ public static final int LOCATION_ATTRIBUTE_BASE = 3; // String table offset of resource path base
+ public static final int LOCATION_ATTRIBUTE_EXTENSION = 4; // String table offset of resource path extension
+ public static final int LOCATION_ATTRIBUTE_OFFSET = 5; // Container byte offset of resource
+ public static final int LOCATION_ATTRIBUTE_COMPRESSED = 6; // In image byte size of the compressed resource
+ public static final int LOCATION_ATTRIBUTE_UNCOMPRESSED = 7; // In memory byte size of the uncompressed resource
+ public static final int LOCATION_ATTRIBUTE_COUNT = 8; // Number of attribute kinds
+}
--- a/hotspot/test/testlibrary/ctw/Makefile Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/testlibrary/ctw/Makefile Thu Jul 16 19:28:37 2015 -0700
@@ -8,7 +8,7 @@
#
# 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
+# 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).
#
--- a/hotspot/test/testlibrary/ctw/README Thu Jul 16 13:51:50 2015 -0700
+++ b/hotspot/test/testlibrary/ctw/README Thu Jul 16 19:28:37 2015 -0700
@@ -1,26 +1,26 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-#
+
+Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+
+
DESCRIPTION