Merge
This commit is contained in:
commit
4690e29e88
@ -96,9 +96,10 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
|
|||||||
|
|
||||||
public boolean containsProtectionDomain(Oop protectionDomain) {
|
public boolean containsProtectionDomain(Oop protectionDomain) {
|
||||||
InstanceKlass ik = (InstanceKlass) klass();
|
InstanceKlass ik = (InstanceKlass) klass();
|
||||||
if (protectionDomain.equals(ik.getProtectionDomain())) {
|
// Currently unimplemented and not used.
|
||||||
return true; // Succeeds trivially
|
// if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
|
||||||
}
|
// return true; // Succeeds trivially
|
||||||
|
// }
|
||||||
for (ProtectionDomainEntry current = pdSet(); current != null;
|
for (ProtectionDomainEntry current = pdSet(); current != null;
|
||||||
current = current.next()) {
|
current = current.next()) {
|
||||||
if (protectionDomain.equals(current.protectionDomain())) {
|
if (protectionDomain.equals(current.protectionDomain())) {
|
||||||
|
@ -75,8 +75,6 @@ public class InstanceKlass extends Klass {
|
|||||||
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
|
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
|
||||||
constants = new MetadataField(type.getAddressField("_constants"), 0);
|
constants = new MetadataField(type.getAddressField("_constants"), 0);
|
||||||
classLoaderData = type.getAddressField("_class_loader_data");
|
classLoaderData = type.getAddressField("_class_loader_data");
|
||||||
protectionDomain = new OopField(type.getOopField("_protection_domain"), 0);
|
|
||||||
signers = new OopField(type.getOopField("_signers"), 0);
|
|
||||||
sourceFileName = type.getAddressField("_source_file_name");
|
sourceFileName = type.getAddressField("_source_file_name");
|
||||||
sourceDebugExtension = type.getAddressField("_source_debug_extension");
|
sourceDebugExtension = type.getAddressField("_source_debug_extension");
|
||||||
innerClasses = type.getAddressField("_inner_classes");
|
innerClasses = type.getAddressField("_inner_classes");
|
||||||
@ -136,8 +134,6 @@ public class InstanceKlass extends Klass {
|
|||||||
private static CIntField javaFieldsCount;
|
private static CIntField javaFieldsCount;
|
||||||
private static MetadataField constants;
|
private static MetadataField constants;
|
||||||
private static AddressField classLoaderData;
|
private static AddressField classLoaderData;
|
||||||
private static OopField protectionDomain;
|
|
||||||
private static OopField signers;
|
|
||||||
private static AddressField sourceFileName;
|
private static AddressField sourceFileName;
|
||||||
private static AddressField sourceDebugExtension;
|
private static AddressField sourceDebugExtension;
|
||||||
private static AddressField innerClasses;
|
private static AddressField innerClasses;
|
||||||
@ -350,8 +346,6 @@ public class InstanceKlass extends Klass {
|
|||||||
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
||||||
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
|
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
|
||||||
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
|
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
|
||||||
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
|
|
||||||
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
|
|
||||||
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
|
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
|
||||||
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
|
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
|
||||||
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
||||||
@ -541,8 +535,6 @@ public class InstanceKlass extends Klass {
|
|||||||
// visitor.doOop(methods, true);
|
// visitor.doOop(methods, true);
|
||||||
// visitor.doOop(localInterfaces, true);
|
// visitor.doOop(localInterfaces, true);
|
||||||
// visitor.doOop(transitiveInterfaces, true);
|
// visitor.doOop(transitiveInterfaces, true);
|
||||||
visitor.doOop(protectionDomain, true);
|
|
||||||
visitor.doOop(signers, true);
|
|
||||||
visitor.doCInt(nonstaticFieldSize, true);
|
visitor.doCInt(nonstaticFieldSize, true);
|
||||||
visitor.doCInt(staticFieldSize, true);
|
visitor.doCInt(staticFieldSize, true);
|
||||||
visitor.doCInt(staticOopFieldCount, true);
|
visitor.doCInt(staticOopFieldCount, true);
|
||||||
|
@ -204,13 +204,13 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
|
|||||||
Oop loader = ik.getClassLoader();
|
Oop loader = ik.getClassLoader();
|
||||||
writeEdge(instance, loader, "loaded-by");
|
writeEdge(instance, loader, "loaded-by");
|
||||||
|
|
||||||
// write signers
|
// write signers NYI
|
||||||
Oop signers = ik.getSigners();
|
// Oop signers = ik.getJavaMirror().getSigners();
|
||||||
writeEdge(instance, signers, "signed-by");
|
writeEdge(instance, null, "signed-by");
|
||||||
|
|
||||||
// write protection domain
|
// write protection domain NYI
|
||||||
Oop protectionDomain = ik.getProtectionDomain();
|
// Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
|
||||||
writeEdge(instance, protectionDomain, "protection-domain");
|
writeEdge(instance, null, "protection-domain");
|
||||||
|
|
||||||
// write edges for static reference fields from this class
|
// write edges for static reference fields from this class
|
||||||
for (Iterator itr = refFields.iterator(); itr.hasNext();) {
|
for (Iterator itr = refFields.iterator(); itr.hasNext();) {
|
||||||
|
@ -477,8 +477,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
|||||||
if (k instanceof InstanceKlass) {
|
if (k instanceof InstanceKlass) {
|
||||||
InstanceKlass ik = (InstanceKlass) k;
|
InstanceKlass ik = (InstanceKlass) k;
|
||||||
writeObjectID(ik.getClassLoader());
|
writeObjectID(ik.getClassLoader());
|
||||||
writeObjectID(ik.getSigners());
|
writeObjectID(null); // ik.getJavaMirror().getSigners());
|
||||||
writeObjectID(ik.getProtectionDomain());
|
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
|
||||||
// two reserved id fields
|
// two reserved id fields
|
||||||
writeObjectID(null);
|
writeObjectID(null);
|
||||||
writeObjectID(null);
|
writeObjectID(null);
|
||||||
@ -516,8 +516,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
|||||||
if (bottomKlass instanceof InstanceKlass) {
|
if (bottomKlass instanceof InstanceKlass) {
|
||||||
InstanceKlass ik = (InstanceKlass) bottomKlass;
|
InstanceKlass ik = (InstanceKlass) bottomKlass;
|
||||||
writeObjectID(ik.getClassLoader());
|
writeObjectID(ik.getClassLoader());
|
||||||
writeObjectID(ik.getSigners());
|
writeObjectID(null); // ik.getJavaMirror().getSigners());
|
||||||
writeObjectID(ik.getProtectionDomain());
|
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
|
||||||
} else {
|
} else {
|
||||||
writeObjectID(null);
|
writeObjectID(null);
|
||||||
writeObjectID(null);
|
writeObjectID(null);
|
||||||
|
@ -47,8 +47,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
|||||||
private static final int FIELD_IS_SYNTHETIC = 13;
|
private static final int FIELD_IS_SYNTHETIC = 13;
|
||||||
private static final int FIELD_IS_INTERFACE = 14;
|
private static final int FIELD_IS_INTERFACE = 14;
|
||||||
private static final int FIELD_CLASS_LOADER = 15;
|
private static final int FIELD_CLASS_LOADER = 15;
|
||||||
private static final int FIELD_PROTECTION_DOMAIN = 16;
|
|
||||||
private static final int FIELD_SIGNERS = 17;
|
|
||||||
private static final int FIELD_STATICS = 18;
|
private static final int FIELD_STATICS = 18;
|
||||||
private static final int FIELD_UNDEFINED = -1;
|
private static final int FIELD_UNDEFINED = -1;
|
||||||
|
|
||||||
@ -100,10 +98,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
|||||||
return Boolean.valueOf(ik.isInterface());
|
return Boolean.valueOf(ik.isInterface());
|
||||||
case FIELD_CLASS_LOADER:
|
case FIELD_CLASS_LOADER:
|
||||||
return factory.newJSJavaObject(ik.getClassLoader());
|
return factory.newJSJavaObject(ik.getClassLoader());
|
||||||
case FIELD_PROTECTION_DOMAIN:
|
|
||||||
return factory.newJSJavaObject(ik.getProtectionDomain());
|
|
||||||
case FIELD_SIGNERS:
|
|
||||||
return factory.newJSJavaObject(ik.getSigners());
|
|
||||||
case FIELD_STATICS:
|
case FIELD_STATICS:
|
||||||
return getStatics();
|
return getStatics();
|
||||||
case FIELD_UNDEFINED:
|
case FIELD_UNDEFINED:
|
||||||
@ -246,8 +240,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
|||||||
addField("isSynthetic", FIELD_IS_SYNTHETIC);
|
addField("isSynthetic", FIELD_IS_SYNTHETIC);
|
||||||
addField("isInterface", FIELD_IS_INTERFACE);
|
addField("isInterface", FIELD_IS_INTERFACE);
|
||||||
addField("classLoader", FIELD_CLASS_LOADER);
|
addField("classLoader", FIELD_CLASS_LOADER);
|
||||||
addField("protectionDomain", FIELD_PROTECTION_DOMAIN);
|
|
||||||
addField("signers", FIELD_SIGNERS);
|
|
||||||
addField("statics", FIELD_STATICS);
|
addField("statics", FIELD_STATICS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ ifeq ($(INCLUDE_JVMTI), false)
|
|||||||
CXXFLAGS += -DINCLUDE_JVMTI=0
|
CXXFLAGS += -DINCLUDE_JVMTI=0
|
||||||
CFLAGS += -DINCLUDE_JVMTI=0
|
CFLAGS += -DINCLUDE_JVMTI=0
|
||||||
|
|
||||||
Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
|
Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
|
||||||
jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
|
jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
|
||||||
jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
|
jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
|
||||||
jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
|
jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
|
||||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
|||||||
|
|
||||||
HS_MAJOR_VER=25
|
HS_MAJOR_VER=25
|
||||||
HS_MINOR_VER=0
|
HS_MINOR_VER=0
|
||||||
HS_BUILD_NUMBER=34
|
HS_BUILD_NUMBER=35
|
||||||
|
|
||||||
JDK_MAJOR_VER=1
|
JDK_MAJOR_VER=1
|
||||||
JDK_MINOR_VER=8
|
JDK_MINOR_VER=8
|
||||||
|
@ -944,6 +944,8 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
|||||||
MINIDUMP_TYPE dumpType;
|
MINIDUMP_TYPE dumpType;
|
||||||
static const char* cwd;
|
static const char* cwd;
|
||||||
|
|
||||||
|
// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
|
||||||
|
#ifndef ASSERT
|
||||||
// If running on a client version of Windows and user has not explicitly enabled dumping
|
// If running on a client version of Windows and user has not explicitly enabled dumping
|
||||||
if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
|
if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
|
||||||
VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
|
VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
|
||||||
@ -953,6 +955,12 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
|||||||
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
|
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
|
||||||
|
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
|
dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
|
||||||
|
|
||||||
@ -1004,7 +1012,21 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
|||||||
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
|
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
|
||||||
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
|
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
|
||||||
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
|
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
|
||||||
VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
|
DWORD error = GetLastError();
|
||||||
|
LPTSTR msgbuf = NULL;
|
||||||
|
|
||||||
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {
|
||||||
|
|
||||||
|
jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
|
||||||
|
LocalFree(msgbuf);
|
||||||
|
} else {
|
||||||
|
// Call to FormatMessage failed, just include the result from GetLastError
|
||||||
|
jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
|
||||||
|
}
|
||||||
|
VMError::report_coredump_status(buffer, false);
|
||||||
} else {
|
} else {
|
||||||
VMError::report_coredump_status(buffer, true);
|
VMError::report_coredump_status(buffer, true);
|
||||||
}
|
}
|
||||||
|
@ -444,8 +444,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
|||||||
break;
|
break;
|
||||||
case JVM_REF_invokeStatic:
|
case JVM_REF_invokeStatic:
|
||||||
case JVM_REF_invokeSpecial:
|
case JVM_REF_invokeSpecial:
|
||||||
check_property(
|
check_property(tag.is_method() ||
|
||||||
tag.is_method() || tag.is_interface_method(),
|
((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
|
||||||
"Invalid constant pool index %u in class file %s (not a method)",
|
"Invalid constant pool index %u in class file %s (not a method)",
|
||||||
ref_index, CHECK_(nullHandle));
|
ref_index, CHECK_(nullHandle));
|
||||||
break;
|
break;
|
||||||
@ -3152,7 +3152,6 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int contended_count = nonstatic_contended_count;
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the starting byte offsets
|
// Calculate the starting byte offsets
|
||||||
@ -3177,35 +3176,52 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
|
|
||||||
next_nonstatic_field_offset = nonstatic_fields_start;
|
next_nonstatic_field_offset = nonstatic_fields_start;
|
||||||
|
|
||||||
|
bool is_contended_class = parsed_annotations->is_contended();
|
||||||
|
|
||||||
// Class is contended, pad before all the fields
|
// Class is contended, pad before all the fields
|
||||||
if (parsed_annotations->is_contended()) {
|
if (is_contended_class) {
|
||||||
next_nonstatic_field_offset += ContendedPaddingWidth;
|
next_nonstatic_field_offset += ContendedPaddingWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the non-contended fields count
|
// Compute the non-contended fields count.
|
||||||
|
// The packing code below relies on these counts to determine if some field
|
||||||
|
// can be squeezed into the alignment gap. Contended fields are obviously
|
||||||
|
// exempt from that.
|
||||||
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
|
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
|
||||||
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
|
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
|
||||||
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
|
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
|
||||||
unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
|
unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
|
||||||
unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
|
unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
|
||||||
|
|
||||||
|
// Total non-static fields count, including every contended field
|
||||||
|
unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
|
||||||
|
fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
|
||||||
|
fac->count[NONSTATIC_OOP];
|
||||||
|
|
||||||
bool super_has_nonstatic_fields =
|
bool super_has_nonstatic_fields =
|
||||||
(_super_klass() != NULL && _super_klass->has_nonstatic_fields());
|
(_super_klass() != NULL && _super_klass->has_nonstatic_fields());
|
||||||
bool has_nonstatic_fields = super_has_nonstatic_fields ||
|
bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0);
|
||||||
((nonstatic_double_count + nonstatic_word_count +
|
|
||||||
nonstatic_short_count + nonstatic_byte_count +
|
|
||||||
nonstatic_oop_count) != 0);
|
|
||||||
|
|
||||||
|
|
||||||
// Prepare list of oops for oop map generation.
|
// Prepare list of oops for oop map generation.
|
||||||
|
//
|
||||||
|
// "offset" and "count" lists are describing the set of contiguous oop
|
||||||
|
// regions. offset[i] is the start of the i-th region, which then has
|
||||||
|
// count[i] oops following. Before we know how many regions are required,
|
||||||
|
// we pessimistically allocate the maps to fit all the oops into the
|
||||||
|
// distinct regions.
|
||||||
|
//
|
||||||
|
// TODO: We add +1 to always allocate non-zero resource arrays; we need
|
||||||
|
// to figure out if we still need to do this.
|
||||||
int* nonstatic_oop_offsets;
|
int* nonstatic_oop_offsets;
|
||||||
unsigned int* nonstatic_oop_counts;
|
unsigned int* nonstatic_oop_counts;
|
||||||
unsigned int nonstatic_oop_map_count = 0;
|
unsigned int nonstatic_oop_map_count = 0;
|
||||||
|
unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1;
|
||||||
|
|
||||||
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
|
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||||
THREAD, int, nonstatic_oop_count + 1);
|
THREAD, int, max_nonstatic_oop_maps);
|
||||||
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
|
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||||
THREAD, unsigned int, nonstatic_oop_count + 1);
|
THREAD, unsigned int, max_nonstatic_oop_maps);
|
||||||
|
|
||||||
first_nonstatic_oop_offset = 0; // will be set for first oop field
|
first_nonstatic_oop_offset = 0; // will be set for first oop field
|
||||||
|
|
||||||
@ -3392,9 +3408,11 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
|
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
|
||||||
heapOopSize ) {
|
heapOopSize ) {
|
||||||
// Extend current oop map
|
// Extend current oop map
|
||||||
|
assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
|
||||||
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
|
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
|
||||||
} else {
|
} else {
|
||||||
// Create new oop map
|
// Create new oop map
|
||||||
|
assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
|
||||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
||||||
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
||||||
nonstatic_oop_map_count += 1;
|
nonstatic_oop_map_count += 1;
|
||||||
@ -3452,12 +3470,10 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
//
|
//
|
||||||
// Additionally, this should not break alignment for the fields, so we round the alignment up
|
// Additionally, this should not break alignment for the fields, so we round the alignment up
|
||||||
// for each field.
|
// for each field.
|
||||||
if (contended_count > 0) {
|
if (nonstatic_contended_count > 0) {
|
||||||
|
|
||||||
// if there is at least one contended field, we need to have pre-padding for them
|
// if there is at least one contended field, we need to have pre-padding for them
|
||||||
if (nonstatic_contended_count > 0) {
|
|
||||||
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
||||||
}
|
|
||||||
|
|
||||||
// collect all contended groups
|
// collect all contended groups
|
||||||
BitMap bm(_cp->size());
|
BitMap bm(_cp->size());
|
||||||
@ -3518,6 +3534,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
next_nonstatic_padded_offset += heapOopSize;
|
next_nonstatic_padded_offset += heapOopSize;
|
||||||
|
|
||||||
// Create new oop map
|
// Create new oop map
|
||||||
|
assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
|
||||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
||||||
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
||||||
nonstatic_oop_map_count += 1;
|
nonstatic_oop_map_count += 1;
|
||||||
@ -3554,18 +3571,17 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
// handle static fields
|
// handle static fields
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size of instances
|
|
||||||
int notaligned_offset = next_nonstatic_padded_offset;
|
|
||||||
|
|
||||||
// Entire class is contended, pad in the back.
|
// Entire class is contended, pad in the back.
|
||||||
// This helps to alleviate memory contention effects for subclass fields
|
// This helps to alleviate memory contention effects for subclass fields
|
||||||
// and/or adjacent object.
|
// and/or adjacent object.
|
||||||
if (parsed_annotations->is_contended()) {
|
if (is_contended_class) {
|
||||||
notaligned_offset += ContendedPaddingWidth;
|
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize);
|
int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
|
||||||
int instance_end = align_size_up(notaligned_offset, wordSize);
|
|
||||||
|
int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize);
|
||||||
|
int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize);
|
||||||
int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
|
int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
|
||||||
|
|
||||||
int static_field_size = (static_fields_end -
|
int static_field_size = (static_fields_end -
|
||||||
@ -3579,6 +3595,14 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
|||||||
(instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
|
(instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
|
||||||
wordSize) / wordSize), "consistent layout helper value");
|
wordSize) / wordSize), "consistent layout helper value");
|
||||||
|
|
||||||
|
// Invariant: nonstatic_field end/start should only change if there are
|
||||||
|
// nonstatic fields in the class, or if the class is contended. We compare
|
||||||
|
// against the non-aligned value, so that end alignment will not fail the
|
||||||
|
// assert without actually having the fields.
|
||||||
|
assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) ||
|
||||||
|
is_contended_class ||
|
||||||
|
(nonstatic_fields_count > 0), "double-check nonstatic start/end");
|
||||||
|
|
||||||
// Number of non-static oop map blocks allocated at end of klass.
|
// Number of non-static oop map blocks allocated at end of klass.
|
||||||
const unsigned int total_oop_map_count =
|
const unsigned int total_oop_map_count =
|
||||||
compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
|
compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
|
||||||
@ -4040,6 +4064,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate mirror and initialize static fields
|
||||||
|
java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
|
||||||
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (ParseAllGenericSignatures) {
|
if (ParseAllGenericSignatures) {
|
||||||
@ -4055,17 +4082,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||||||
this_klass(), &all_mirandas, CHECK_(nullHandle));
|
this_klass(), &all_mirandas, CHECK_(nullHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate mirror and initialize static fields
|
|
||||||
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
|
|
||||||
|
|
||||||
// Allocate a simple java object for locking during class initialization.
|
|
||||||
// This needs to be a java object because it can be held across a java call.
|
|
||||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
|
|
||||||
this_klass->set_init_lock(r);
|
|
||||||
|
|
||||||
// TODO: Move these oops to the mirror
|
|
||||||
this_klass->set_protection_domain(protection_domain());
|
|
||||||
|
|
||||||
// Update the loader_data graph.
|
// Update the loader_data graph.
|
||||||
record_defined_class_dependencies(this_klass, CHECK_NULL);
|
record_defined_class_dependencies(this_klass, CHECK_NULL);
|
||||||
|
|
||||||
|
@ -524,10 +524,10 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
create_mirror(k, CHECK);
|
create_mirror(k, Handle(NULL), CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
|
||||||
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
||||||
// Use this moment of initialization to cache modifier_flags also,
|
// Use this moment of initialization to cache modifier_flags also,
|
||||||
// to support Class.getModifiers(). Instance classes recalculate
|
// to support Class.getModifiers(). Instance classes recalculate
|
||||||
@ -563,6 +563,16 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
|||||||
set_array_klass(comp_mirror(), k());
|
set_array_klass(comp_mirror(), k());
|
||||||
} else {
|
} else {
|
||||||
assert(k->oop_is_instance(), "Must be");
|
assert(k->oop_is_instance(), "Must be");
|
||||||
|
|
||||||
|
// Allocate a simple java object for a lock.
|
||||||
|
// This needs to be a java object because during class initialization
|
||||||
|
// it can be held across a java call.
|
||||||
|
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
|
||||||
|
set_init_lock(mirror(), r);
|
||||||
|
|
||||||
|
// Set protection domain also
|
||||||
|
set_protection_domain(mirror(), protection_domain());
|
||||||
|
|
||||||
// Initialize static fields
|
// Initialize static fields
|
||||||
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
|
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
|
||||||
}
|
}
|
||||||
@ -597,6 +607,34 @@ void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
|
|||||||
java_class->int_field_put(_static_oop_field_count_offset, size);
|
java_class->int_field_put(_static_oop_field_count_offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oop java_lang_Class::protection_domain(oop java_class) {
|
||||||
|
assert(_protection_domain_offset != 0, "must be set");
|
||||||
|
return java_class->obj_field(_protection_domain_offset);
|
||||||
|
}
|
||||||
|
void java_lang_Class::set_protection_domain(oop java_class, oop pd) {
|
||||||
|
assert(_protection_domain_offset != 0, "must be set");
|
||||||
|
java_class->obj_field_put(_protection_domain_offset, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
oop java_lang_Class::init_lock(oop java_class) {
|
||||||
|
assert(_init_lock_offset != 0, "must be set");
|
||||||
|
return java_class->obj_field(_init_lock_offset);
|
||||||
|
}
|
||||||
|
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
|
||||||
|
assert(_init_lock_offset != 0, "must be set");
|
||||||
|
java_class->obj_field_put(_init_lock_offset, init_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
objArrayOop java_lang_Class::signers(oop java_class) {
|
||||||
|
assert(_signers_offset != 0, "must be set");
|
||||||
|
return (objArrayOop)java_class->obj_field(_signers_offset);
|
||||||
|
}
|
||||||
|
void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
|
||||||
|
assert(_signers_offset != 0, "must be set");
|
||||||
|
java_class->obj_field_put(_signers_offset, (oop)signers);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
|
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
|
||||||
// This should be improved by adding a field at the Java level or by
|
// This should be improved by adding a field at the Java level or by
|
||||||
// introducing a new VM klass (see comment in ClassFileParser)
|
// introducing a new VM klass (see comment in ClassFileParser)
|
||||||
@ -2934,6 +2972,9 @@ int java_lang_Class::_klass_offset;
|
|||||||
int java_lang_Class::_array_klass_offset;
|
int java_lang_Class::_array_klass_offset;
|
||||||
int java_lang_Class::_oop_size_offset;
|
int java_lang_Class::_oop_size_offset;
|
||||||
int java_lang_Class::_static_oop_field_count_offset;
|
int java_lang_Class::_static_oop_field_count_offset;
|
||||||
|
int java_lang_Class::_protection_domain_offset;
|
||||||
|
int java_lang_Class::_init_lock_offset;
|
||||||
|
int java_lang_Class::_signers_offset;
|
||||||
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
|
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
|
||||||
int java_lang_Throwable::backtrace_offset;
|
int java_lang_Throwable::backtrace_offset;
|
||||||
int java_lang_Throwable::detailMessage_offset;
|
int java_lang_Throwable::detailMessage_offset;
|
||||||
|
@ -208,7 +208,10 @@ class java_lang_String : AllStatic {
|
|||||||
macro(java_lang_Class, klass, intptr_signature, false) \
|
macro(java_lang_Class, klass, intptr_signature, false) \
|
||||||
macro(java_lang_Class, array_klass, intptr_signature, false) \
|
macro(java_lang_Class, array_klass, intptr_signature, false) \
|
||||||
macro(java_lang_Class, oop_size, int_signature, false) \
|
macro(java_lang_Class, oop_size, int_signature, false) \
|
||||||
macro(java_lang_Class, static_oop_field_count, int_signature, false)
|
macro(java_lang_Class, static_oop_field_count, int_signature, false) \
|
||||||
|
macro(java_lang_Class, protection_domain, object_signature, false) \
|
||||||
|
macro(java_lang_Class, init_lock, object_signature, false) \
|
||||||
|
macro(java_lang_Class, signers, object_signature, false)
|
||||||
|
|
||||||
class java_lang_Class : AllStatic {
|
class java_lang_Class : AllStatic {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
@ -222,15 +225,20 @@ class java_lang_Class : AllStatic {
|
|||||||
static int _oop_size_offset;
|
static int _oop_size_offset;
|
||||||
static int _static_oop_field_count_offset;
|
static int _static_oop_field_count_offset;
|
||||||
|
|
||||||
|
static int _protection_domain_offset;
|
||||||
|
static int _init_lock_offset;
|
||||||
|
static int _signers_offset;
|
||||||
|
|
||||||
static bool offsets_computed;
|
static bool offsets_computed;
|
||||||
static int classRedefinedCount_offset;
|
static int classRedefinedCount_offset;
|
||||||
static GrowableArray<Klass*>* _fixup_mirror_list;
|
static GrowableArray<Klass*>* _fixup_mirror_list;
|
||||||
|
|
||||||
|
static void set_init_lock(oop java_class, oop init_lock);
|
||||||
public:
|
public:
|
||||||
static void compute_offsets();
|
static void compute_offsets();
|
||||||
|
|
||||||
// Instance creation
|
// Instance creation
|
||||||
static oop create_mirror(KlassHandle k, TRAPS);
|
static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
|
||||||
static void fixup_mirror(KlassHandle k, TRAPS);
|
static void fixup_mirror(KlassHandle k, TRAPS);
|
||||||
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
|
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
|
||||||
// Conversion
|
// Conversion
|
||||||
@ -262,6 +270,13 @@ class java_lang_Class : AllStatic {
|
|||||||
static int classRedefinedCount(oop the_class_mirror);
|
static int classRedefinedCount(oop the_class_mirror);
|
||||||
static void set_classRedefinedCount(oop the_class_mirror, int value);
|
static void set_classRedefinedCount(oop the_class_mirror, int value);
|
||||||
|
|
||||||
|
// Support for embedded per-class oops
|
||||||
|
static oop protection_domain(oop java_class);
|
||||||
|
static void set_protection_domain(oop java_class, oop protection_domain);
|
||||||
|
static oop init_lock(oop java_class);
|
||||||
|
static objArrayOop signers(oop java_class);
|
||||||
|
static void set_signers(oop java_class, objArrayOop signers);
|
||||||
|
|
||||||
static int oop_size(oop java_class);
|
static int oop_size(oop java_class);
|
||||||
static void set_oop_size(oop java_class, int size);
|
static void set_oop_size(oop java_class, int size);
|
||||||
static int static_oop_field_count(oop java_class);
|
static int static_oop_field_count(oop java_class);
|
||||||
|
@ -737,7 +737,7 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringTable::unlink(BoolObjectClosure* is_alive) {
|
void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
|
||||||
// Readers of the table are unlocked, so we should only be removing
|
// Readers of the table are unlocked, so we should only be removing
|
||||||
// entries at a safepoint.
|
// entries at a safepoint.
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||||
@ -745,41 +745,31 @@ void StringTable::unlink(BoolObjectClosure* is_alive) {
|
|||||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
// Shared entries are normally at the end of the bucket and if we run into
|
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||||
// a shared entry, then there is nothing more to remove. However, if we
|
|
||||||
// have rehashed the table, then the shared entries are no longer at the
|
if (is_alive->do_object_b(entry->literal())) {
|
||||||
// end of the bucket.
|
if (f != NULL) {
|
||||||
if (entry->is_shared() && !use_alternate_hashcode()) {
|
f->do_oop((oop*)entry->literal_addr());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
assert(entry->literal() != NULL, "just checking");
|
|
||||||
if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
|
|
||||||
p = entry->next_addr();
|
p = entry->next_addr();
|
||||||
} else {
|
} else {
|
||||||
*p = entry->next();
|
*p = entry->next();
|
||||||
the_table()->free_entry(entry);
|
the_table()->free_entry(entry);
|
||||||
}
|
}
|
||||||
entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
|
entry = *p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringTable::oops_do(OopClosure* f) {
|
void StringTable::oops_do(OopClosure* f) {
|
||||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
|
||||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
|
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||||
|
|
||||||
f->do_oop((oop*)entry->literal_addr());
|
f->do_oop((oop*)entry->literal_addr());
|
||||||
|
|
||||||
// Did the closure remove the literal from the table?
|
entry = entry->next();
|
||||||
if (entry->literal() == NULL) {
|
|
||||||
assert(!entry->is_shared(), "immutable hashtable entry?");
|
|
||||||
*p = entry->next();
|
|
||||||
the_table()->free_entry(entry);
|
|
||||||
} else {
|
|
||||||
p = entry->next_addr();
|
|
||||||
}
|
|
||||||
entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,10 @@ public:
|
|||||||
|
|
||||||
// GC support
|
// GC support
|
||||||
// Delete pointers to otherwise-unreachable objects.
|
// Delete pointers to otherwise-unreachable objects.
|
||||||
static void unlink(BoolObjectClosure* cl);
|
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f);
|
||||||
|
static void unlink(BoolObjectClosure* cl) {
|
||||||
|
unlink_or_oops_do(cl, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke "f->do_oop" on the locations of all oops in the table.
|
// Invoke "f->do_oop" on the locations of all oops in the table.
|
||||||
static void oops_do(OopClosure* f);
|
static void oops_do(OopClosure* f);
|
||||||
|
@ -392,6 +392,9 @@
|
|||||||
template(array_klass_name, "array_klass") \
|
template(array_klass_name, "array_klass") \
|
||||||
template(oop_size_name, "oop_size") \
|
template(oop_size_name, "oop_size") \
|
||||||
template(static_oop_field_count_name, "static_oop_field_count") \
|
template(static_oop_field_count_name, "static_oop_field_count") \
|
||||||
|
template(protection_domain_name, "protection_domain") \
|
||||||
|
template(init_lock_name, "init_lock") \
|
||||||
|
template(signers_name, "signers_name") \
|
||||||
template(loader_data_name, "loader_data") \
|
template(loader_data_name, "loader_data") \
|
||||||
template(dependencies_name, "dependencies") \
|
template(dependencies_name, "dependencies") \
|
||||||
\
|
\
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -969,7 +969,7 @@ size_t CMSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
|
void CMSAdaptiveSizePolicy::compute_eden_space_size(size_t cur_eden,
|
||||||
size_t max_eden_size)
|
size_t max_eden_size)
|
||||||
{
|
{
|
||||||
size_t desired_eden_size = cur_eden;
|
size_t desired_eden_size = cur_eden;
|
||||||
@ -978,7 +978,7 @@ void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
|
|||||||
// Printout input
|
// Printout input
|
||||||
if (PrintGC && PrintAdaptiveSizePolicy) {
|
if (PrintGC && PrintAdaptiveSizePolicy) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"CMSAdaptiveSizePolicy::compute_young_generation_free_space: "
|
"CMSAdaptiveSizePolicy::compute_eden_space_size: "
|
||||||
"cur_eden " SIZE_FORMAT,
|
"cur_eden " SIZE_FORMAT,
|
||||||
cur_eden);
|
cur_eden);
|
||||||
}
|
}
|
||||||
@ -1024,7 +1024,7 @@ void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
|
|||||||
|
|
||||||
if (PrintGC && PrintAdaptiveSizePolicy) {
|
if (PrintGC && PrintAdaptiveSizePolicy) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"CMSAdaptiveSizePolicy::compute_young_generation_free_space limits:"
|
"CMSAdaptiveSizePolicy::compute_eden_space_size limits:"
|
||||||
" desired_eden_size: " SIZE_FORMAT
|
" desired_eden_size: " SIZE_FORMAT
|
||||||
" old_eden_size: " SIZE_FORMAT,
|
" old_eden_size: " SIZE_FORMAT,
|
||||||
desired_eden_size, cur_eden);
|
desired_eden_size, cur_eden);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -436,7 +436,7 @@ class CMSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
|||||||
|
|
||||||
size_t generation_alignment() { return _generation_alignment; }
|
size_t generation_alignment() { return _generation_alignment; }
|
||||||
|
|
||||||
virtual void compute_young_generation_free_space(size_t cur_eden,
|
virtual void compute_eden_space_size(size_t cur_eden,
|
||||||
size_t max_eden_size);
|
size_t max_eden_size);
|
||||||
// Calculates new survivor space size; returns a new tenuring threshold
|
// Calculates new survivor space size; returns a new tenuring threshold
|
||||||
// value. Stores new survivor size in _survivor_size.
|
// value. Stores new survivor size in _survivor_size.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -585,8 +585,7 @@ void ASParNewGeneration::compute_new_size() {
|
|||||||
size_policy->avg_young_live()->sample(used());
|
size_policy->avg_young_live()->sample(used());
|
||||||
size_policy->avg_eden_live()->sample(eden()->used());
|
size_policy->avg_eden_live()->sample(eden()->used());
|
||||||
|
|
||||||
size_policy->compute_young_generation_free_space(eden()->capacity(),
|
size_policy->compute_eden_space_size(eden()->capacity(), max_gen_size());
|
||||||
max_gen_size());
|
|
||||||
|
|
||||||
resize(size_policy->calculated_eden_size_in_bytes(),
|
resize(size_policy->calculated_eden_size_in_bytes(),
|
||||||
size_policy->calculated_survivor_size_in_bytes());
|
size_policy->calculated_survivor_size_in_bytes());
|
||||||
|
@ -120,6 +120,9 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|||||||
|
|
||||||
case system_dictionary:
|
case system_dictionary:
|
||||||
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
|
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case class_loader_data:
|
||||||
ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, &follow_klass_closure, true);
|
ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, &follow_klass_closure, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -98,7 +98,8 @@ class MarkFromRootsTask : public GCTask {
|
|||||||
management = 6,
|
management = 6,
|
||||||
jvmti = 7,
|
jvmti = 7,
|
||||||
system_dictionary = 8,
|
system_dictionary = 8,
|
||||||
code_cache = 9
|
class_loader_data = 9,
|
||||||
|
code_cache = 10
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
RootType _root_type;
|
RootType _root_type;
|
||||||
|
@ -194,7 +194,7 @@ void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
|
|||||||
|
|
||||||
// If this is not a full GC, only test and modify the young generation.
|
// If this is not a full GC, only test and modify the young generation.
|
||||||
|
|
||||||
void PSAdaptiveSizePolicy::compute_generation_free_space(
|
void PSAdaptiveSizePolicy::compute_generations_free_space(
|
||||||
size_t young_live,
|
size_t young_live,
|
||||||
size_t eden_live,
|
size_t eden_live,
|
||||||
size_t old_live,
|
size_t old_live,
|
||||||
@ -729,7 +729,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
|
|||||||
|
|
||||||
if (PrintAdaptiveSizePolicy && Verbose) {
|
if (PrintAdaptiveSizePolicy && Verbose) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"PSAdaptiveSizePolicy::compute_old_gen_free_space "
|
"PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
|
||||||
"adjusting gen sizes for major pause (avg %f goal %f). "
|
"adjusting gen sizes for major pause (avg %f goal %f). "
|
||||||
"desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
|
"desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
|
||||||
_avg_major_pause->average(), gc_pause_goal_sec(),
|
_avg_major_pause->average(), gc_pause_goal_sec(),
|
||||||
@ -786,7 +786,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
|
|||||||
|
|
||||||
if (PrintAdaptiveSizePolicy && Verbose) {
|
if (PrintAdaptiveSizePolicy && Verbose) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"PSAdaptiveSizePolicy::compute_eden_space_size "
|
"PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
|
||||||
"adjusting gen sizes for major pause (avg %f goal %f). "
|
"adjusting gen sizes for major pause (avg %f goal %f). "
|
||||||
"desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
|
"desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
|
||||||
_avg_major_pause->average(), gc_pause_goal_sec(),
|
_avg_major_pause->average(), gc_pause_goal_sec(),
|
||||||
@ -1001,7 +1001,7 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
|
|||||||
|
|
||||||
if (PrintAdaptiveSizePolicy && Verbose) {
|
if (PrintAdaptiveSizePolicy && Verbose) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"AdaptiveSizePolicy::compute_generation_free_space "
|
"AdaptiveSizePolicy::adjust_promo_for_footprint "
|
||||||
"adjusting tenured gen for footprint. "
|
"adjusting tenured gen for footprint. "
|
||||||
"starting promo size " SIZE_FORMAT
|
"starting promo size " SIZE_FORMAT
|
||||||
" reduced promo size " SIZE_FORMAT,
|
" reduced promo size " SIZE_FORMAT,
|
||||||
@ -1025,7 +1025,7 @@ size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
|
|||||||
|
|
||||||
if (PrintAdaptiveSizePolicy && Verbose) {
|
if (PrintAdaptiveSizePolicy && Verbose) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"AdaptiveSizePolicy::compute_generation_free_space "
|
"AdaptiveSizePolicy::adjust_eden_for_footprint "
|
||||||
"adjusting eden for footprint. "
|
"adjusting eden for footprint. "
|
||||||
" starting eden size " SIZE_FORMAT
|
" starting eden size " SIZE_FORMAT
|
||||||
" reduced eden size " SIZE_FORMAT
|
" reduced eden size " SIZE_FORMAT
|
||||||
@ -1280,7 +1280,7 @@ void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
|
|||||||
|
|
||||||
if (PrintAdaptiveSizePolicy) {
|
if (PrintAdaptiveSizePolicy) {
|
||||||
gclog_or_tty->print(
|
gclog_or_tty->print(
|
||||||
"AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
|
"AdaptiveSizePolicy::update_averages:"
|
||||||
" survived: " SIZE_FORMAT
|
" survived: " SIZE_FORMAT
|
||||||
" promoted: " SIZE_FORMAT
|
" promoted: " SIZE_FORMAT
|
||||||
" overflow: %s",
|
" overflow: %s",
|
||||||
|
@ -344,7 +344,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
|||||||
// Takes current used space in all generations as input, as well
|
// Takes current used space in all generations as input, as well
|
||||||
// as an indication if a full gc has just been performed, for use
|
// as an indication if a full gc has just been performed, for use
|
||||||
// in deciding if an OOM error should be thrown.
|
// in deciding if an OOM error should be thrown.
|
||||||
void compute_generation_free_space(size_t young_live,
|
void compute_generations_free_space(size_t young_live,
|
||||||
size_t eden_live,
|
size_t eden_live,
|
||||||
size_t old_live,
|
size_t old_live,
|
||||||
size_t cur_eden, // current eden in bytes
|
size_t cur_eden, // current eden in bytes
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -119,7 +119,7 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters {
|
|||||||
ps_size_policy()->change_old_gen_for_min_pauses());
|
ps_size_policy()->change_old_gen_for_min_pauses());
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute_generation_free_space() statistics
|
// compute_generations_free_space() statistics
|
||||||
|
|
||||||
inline void update_avg_major_pause() {
|
inline void update_avg_major_pause() {
|
||||||
_avg_major_pause->set_value(
|
_avg_major_pause->set_value(
|
||||||
|
@ -290,7 +290,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
|||||||
// Used for diagnostics
|
// Used for diagnostics
|
||||||
size_policy->clear_generation_free_space_flags();
|
size_policy->clear_generation_free_space_flags();
|
||||||
|
|
||||||
size_policy->compute_generation_free_space(young_live,
|
size_policy->compute_generations_free_space(young_live,
|
||||||
eden_live,
|
eden_live,
|
||||||
old_live,
|
old_live,
|
||||||
cur_eden,
|
cur_eden,
|
||||||
|
@ -2101,7 +2101,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
|
|||||||
// Used for diagnostics
|
// Used for diagnostics
|
||||||
size_policy->clear_generation_free_space_flags();
|
size_policy->clear_generation_free_space_flags();
|
||||||
|
|
||||||
size_policy->compute_generation_free_space(young_live,
|
size_policy->compute_generations_free_space(young_live,
|
||||||
eden_live,
|
eden_live,
|
||||||
old_live,
|
old_live,
|
||||||
cur_eden,
|
cur_eden,
|
||||||
@ -2338,6 +2338,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
|||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
|
||||||
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
|
||||||
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
|
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
|
||||||
|
|
||||||
|
@ -408,6 +408,7 @@ bool PSScavenge::invoke_no_policy() {
|
|||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
|
||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
|
||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
|
||||||
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
|
||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
|
||||||
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
|
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
|
||||||
|
|
||||||
@ -449,11 +450,9 @@ bool PSScavenge::invoke_no_policy() {
|
|||||||
reference_processor()->enqueue_discovered_references(NULL);
|
reference_processor()->enqueue_discovered_references(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlink any dead interned Strings
|
// Unlink any dead interned Strings and process the remaining live ones.
|
||||||
StringTable::unlink(&_is_alive_closure);
|
|
||||||
// Process the remaining live ones
|
|
||||||
PSScavengeRootsClosure root_closure(promotion_manager);
|
PSScavengeRootsClosure root_closure(promotion_manager);
|
||||||
StringTable::oops_do(&root_closure);
|
StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
|
||||||
|
|
||||||
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
|
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
|
||||||
PSPromotionManager::post_scavenge();
|
PSPromotionManager::post_scavenge();
|
||||||
|
@ -79,10 +79,11 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case system_dictionary:
|
case system_dictionary:
|
||||||
{
|
|
||||||
SystemDictionary::oops_do(&roots_closure);
|
SystemDictionary::oops_do(&roots_closure);
|
||||||
|
break;
|
||||||
|
|
||||||
// Move this to another root_type?
|
case class_loader_data:
|
||||||
|
{
|
||||||
PSScavengeKlassClosure klass_closure(pm);
|
PSScavengeKlassClosure klass_closure(pm);
|
||||||
ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
|
ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,10 @@ class ScavengeRootsTask : public GCTask {
|
|||||||
object_synchronizer = 4,
|
object_synchronizer = 4,
|
||||||
flat_profiler = 5,
|
flat_profiler = 5,
|
||||||
system_dictionary = 6,
|
system_dictionary = 6,
|
||||||
management = 7,
|
class_loader_data = 7,
|
||||||
jvmti = 8,
|
management = 8,
|
||||||
code_cache = 9
|
jvmti = 9,
|
||||||
|
code_cache = 10
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
RootType _root_type;
|
RootType _root_type;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -467,7 +467,7 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
|
|||||||
(free_in_old_gen < (size_t) mem_free_old_limit &&
|
(free_in_old_gen < (size_t) mem_free_old_limit &&
|
||||||
free_in_eden < (size_t) mem_free_eden_limit))) {
|
free_in_eden < (size_t) mem_free_eden_limit))) {
|
||||||
gclog_or_tty->print_cr(
|
gclog_or_tty->print_cr(
|
||||||
"PSAdaptiveSizePolicy::compute_generation_free_space limits:"
|
"PSAdaptiveSizePolicy::check_gc_overhead_limit:"
|
||||||
" promo_limit: " SIZE_FORMAT
|
" promo_limit: " SIZE_FORMAT
|
||||||
" max_eden_size: " SIZE_FORMAT
|
" max_eden_size: " SIZE_FORMAT
|
||||||
" total_free_limit: " SIZE_FORMAT
|
" total_free_limit: " SIZE_FORMAT
|
||||||
|
@ -45,6 +45,7 @@ enum SH_process_strong_roots_tasks {
|
|||||||
SH_PS_FlatProfiler_oops_do,
|
SH_PS_FlatProfiler_oops_do,
|
||||||
SH_PS_Management_oops_do,
|
SH_PS_Management_oops_do,
|
||||||
SH_PS_SystemDictionary_oops_do,
|
SH_PS_SystemDictionary_oops_do,
|
||||||
|
SH_PS_ClassLoaderDataGraph_oops_do,
|
||||||
SH_PS_jvmti_oops_do,
|
SH_PS_jvmti_oops_do,
|
||||||
SH_PS_StringTable_oops_do,
|
SH_PS_StringTable_oops_do,
|
||||||
SH_PS_CodeCache_oops_do,
|
SH_PS_CodeCache_oops_do,
|
||||||
@ -173,15 +174,21 @@ void SharedHeap::process_strong_roots(bool activate_scope,
|
|||||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
|
if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
|
||||||
if (so & SO_AllClasses) {
|
if (so & SO_AllClasses) {
|
||||||
SystemDictionary::oops_do(roots);
|
SystemDictionary::oops_do(roots);
|
||||||
ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
|
|
||||||
} else if (so & SO_SystemClasses) {
|
} else if (so & SO_SystemClasses) {
|
||||||
SystemDictionary::always_strong_oops_do(roots);
|
SystemDictionary::always_strong_oops_do(roots);
|
||||||
ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
|
|
||||||
} else {
|
} else {
|
||||||
fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
|
fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
|
||||||
|
if (so & SO_AllClasses) {
|
||||||
|
ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
|
||||||
|
} else if (so & SO_SystemClasses) {
|
||||||
|
ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
|
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
|
||||||
if (so & SO_Strings) {
|
if (so & SO_Strings) {
|
||||||
StringTable::oops_do(roots);
|
StringTable::oops_do(roots);
|
||||||
|
@ -228,11 +228,8 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
|
|||||||
|
|
||||||
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
|
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
|
||||||
if (size < alignment || size % alignment != 0) {
|
if (size < alignment || size % alignment != 0) {
|
||||||
ResourceMark rm;
|
vm_exit_during_initialization(
|
||||||
stringStream st;
|
err_msg("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment));
|
||||||
st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment);
|
|
||||||
char* error = st.as_string();
|
|
||||||
vm_exit_during_initialization(error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +913,7 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!total_rs.is_reserved()) {
|
if (!total_rs.is_reserved()) {
|
||||||
vm_exit_during_initialization(err_msg("Could not reserve enough space for object heap %d bytes", total_reserved));
|
vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K));
|
||||||
return total_rs;
|
return total_rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_kl
|
|||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
k->initialize_supers(super_klass(), CHECK);
|
k->initialize_supers(super_klass(), CHECK);
|
||||||
k->vtable()->initialize_vtable(false, CHECK);
|
k->vtable()->initialize_vtable(false, CHECK);
|
||||||
java_lang_Class::create_mirror(k, CHECK);
|
java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
|
GrowableArray<Klass*>* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
|
||||||
|
@ -1063,9 +1063,10 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
|
|||||||
int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
|
int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
|
||||||
int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
|
int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
|
||||||
int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
|
int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
|
||||||
bool match = compare_entry_to(k1, cp2, k2, CHECK_false) &&
|
// separate statements and variables because CHECK_false is used
|
||||||
compare_operand_to(i1, cp2, i2, CHECK_false);
|
bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false);
|
||||||
return match;
|
bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false);
|
||||||
|
return (match_entry && match_operand);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case JVM_CONSTANT_String:
|
case JVM_CONSTANT_String:
|
||||||
|
@ -268,8 +268,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
|
|||||||
set_fields(NULL, 0);
|
set_fields(NULL, 0);
|
||||||
set_constants(NULL);
|
set_constants(NULL);
|
||||||
set_class_loader_data(NULL);
|
set_class_loader_data(NULL);
|
||||||
set_protection_domain(NULL);
|
|
||||||
set_signers(NULL);
|
|
||||||
set_source_file_name(NULL);
|
set_source_file_name(NULL);
|
||||||
set_source_debug_extension(NULL, 0);
|
set_source_debug_extension(NULL, 0);
|
||||||
set_array_name(NULL);
|
set_array_name(NULL);
|
||||||
@ -279,7 +277,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
|
|||||||
set_is_marked_dependent(false);
|
set_is_marked_dependent(false);
|
||||||
set_init_state(InstanceKlass::allocated);
|
set_init_state(InstanceKlass::allocated);
|
||||||
set_init_thread(NULL);
|
set_init_thread(NULL);
|
||||||
set_init_lock(NULL);
|
|
||||||
set_reference_type(rt);
|
set_reference_type(rt);
|
||||||
set_oop_map_cache(NULL);
|
set_oop_map_cache(NULL);
|
||||||
set_jni_ids(NULL);
|
set_jni_ids(NULL);
|
||||||
@ -408,12 +405,6 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
|
|||||||
}
|
}
|
||||||
set_inner_classes(NULL);
|
set_inner_classes(NULL);
|
||||||
|
|
||||||
// Null out Java heap objects, although these won't be walked to keep
|
|
||||||
// alive once this InstanceKlass is deallocated.
|
|
||||||
set_protection_domain(NULL);
|
|
||||||
set_signers(NULL);
|
|
||||||
set_init_lock(NULL);
|
|
||||||
|
|
||||||
// We should deallocate the Annotations instance
|
// We should deallocate the Annotations instance
|
||||||
MetadataFactory::free_metadata(loader_data, annotations());
|
MetadataFactory::free_metadata(loader_data, annotations());
|
||||||
set_annotations(NULL);
|
set_annotations(NULL);
|
||||||
@ -451,6 +442,24 @@ void InstanceKlass::eager_initialize(Thread *thread) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JVMTI spec thinks there are signers and protection domain in the
|
||||||
|
// instanceKlass. These accessors pretend these fields are there.
|
||||||
|
// The hprof specification also thinks these fields are in InstanceKlass.
|
||||||
|
oop InstanceKlass::protection_domain() const {
|
||||||
|
// return the protection_domain from the mirror
|
||||||
|
return java_lang_Class::protection_domain(java_mirror());
|
||||||
|
}
|
||||||
|
|
||||||
|
// To remove these from requires an incompatible change and CCC request.
|
||||||
|
objArrayOop InstanceKlass::signers() const {
|
||||||
|
// return the signers from the mirror
|
||||||
|
return java_lang_Class::signers(java_mirror());
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile oop InstanceKlass::init_lock() const {
|
||||||
|
// return the init lock from the mirror
|
||||||
|
return java_lang_Class::init_lock(java_mirror());
|
||||||
|
}
|
||||||
|
|
||||||
void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
|
void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
|
||||||
EXCEPTION_MARK;
|
EXCEPTION_MARK;
|
||||||
@ -1883,16 +1892,6 @@ bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
|
|||||||
|
|
||||||
// Garbage collection
|
// Garbage collection
|
||||||
|
|
||||||
void InstanceKlass::oops_do(OopClosure* cl) {
|
|
||||||
Klass::oops_do(cl);
|
|
||||||
|
|
||||||
cl->do_oop(adr_protection_domain());
|
|
||||||
cl->do_oop(adr_signers());
|
|
||||||
cl->do_oop(adr_init_lock());
|
|
||||||
|
|
||||||
// Don't walk the arrays since they are walked from the ClassLoaderData objects.
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
template <class T> void assert_is_in(T *p) {
|
template <class T> void assert_is_in(T *p) {
|
||||||
T heap_oop = oopDesc::load_heap_oop(p);
|
T heap_oop = oopDesc::load_heap_oop(p);
|
||||||
@ -2241,9 +2240,6 @@ void InstanceKlass::remove_unshareable_info() {
|
|||||||
m->remove_unshareable_info();
|
m->remove_unshareable_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to reinstate when reading back the class.
|
|
||||||
set_init_lock(NULL);
|
|
||||||
|
|
||||||
// do array classes also.
|
// do array classes also.
|
||||||
array_klasses_do(remove_unshareable_in_class);
|
array_klasses_do(remove_unshareable_in_class);
|
||||||
}
|
}
|
||||||
@ -2275,13 +2271,6 @@ void InstanceKlass::restore_unshareable_info(TRAPS) {
|
|||||||
ik->itable()->initialize_itable(false, CHECK);
|
ik->itable()->initialize_itable(false, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a simple java object for a lock.
|
|
||||||
// This needs to be a java object because during class initialization
|
|
||||||
// it can be held across a java call.
|
|
||||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
|
|
||||||
Handle h(THREAD, (oop)r);
|
|
||||||
ik->set_init_lock(h());
|
|
||||||
|
|
||||||
// restore constant pool resolved references
|
// restore constant pool resolved references
|
||||||
ik->constants()->restore_unshareable_info(CHECK);
|
ik->constants()->restore_unshareable_info(CHECK);
|
||||||
|
|
||||||
@ -2331,11 +2320,16 @@ void InstanceKlass::release_C_heap_structures() {
|
|||||||
FreeHeap(jmeths);
|
FreeHeap(jmeths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deallocate MemberNameTable
|
||||||
|
{
|
||||||
|
Mutex* lock_or_null = SafepointSynchronize::is_at_safepoint() ? NULL : MemberNameTable_lock;
|
||||||
|
MutexLockerEx ml(lock_or_null, Mutex::_no_safepoint_check_flag);
|
||||||
MemberNameTable* mnt = member_names();
|
MemberNameTable* mnt = member_names();
|
||||||
if (mnt != NULL) {
|
if (mnt != NULL) {
|
||||||
delete mnt;
|
delete mnt;
|
||||||
set_member_names(NULL);
|
set_member_names(NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int* indices = methods_cached_itable_indices_acquire();
|
int* indices = methods_cached_itable_indices_acquire();
|
||||||
if (indices != (int*)NULL) {
|
if (indices != (int*)NULL) {
|
||||||
@ -2765,15 +2759,28 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceKlass::add_member_name(Handle mem_name) {
|
void InstanceKlass::add_member_name(int index, Handle mem_name) {
|
||||||
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
|
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
|
||||||
MutexLocker ml(MemberNameTable_lock);
|
MutexLocker ml(MemberNameTable_lock);
|
||||||
|
assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
|
||||||
DEBUG_ONLY(No_Safepoint_Verifier nsv);
|
DEBUG_ONLY(No_Safepoint_Verifier nsv);
|
||||||
|
|
||||||
if (_member_names == NULL) {
|
if (_member_names == NULL) {
|
||||||
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
|
_member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
|
||||||
}
|
}
|
||||||
_member_names->add_member_name(mem_name_wref);
|
_member_names->add_member_name(index, mem_name_wref);
|
||||||
|
}
|
||||||
|
|
||||||
|
oop InstanceKlass::get_member_name(int index) {
|
||||||
|
MutexLocker ml(MemberNameTable_lock);
|
||||||
|
assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
|
||||||
|
DEBUG_ONLY(No_Safepoint_Verifier nsv);
|
||||||
|
|
||||||
|
if (_member_names == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
oop mem_name =_member_names->get_member_name(index);
|
||||||
|
return mem_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
@ -2836,10 +2843,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
|||||||
class_loader_data()->print_value_on(st);
|
class_loader_data()->print_value_on(st);
|
||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
|
|
||||||
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
|
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
|
||||||
st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
|
|
||||||
st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr();
|
|
||||||
if (source_file_name() != NULL) {
|
if (source_file_name() != NULL) {
|
||||||
st->print(BULLET"source file: ");
|
st->print(BULLET"source file: ");
|
||||||
source_file_name()->print_value_on(st);
|
source_file_name()->print_value_on(st);
|
||||||
@ -3040,7 +3044,6 @@ void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
|
|||||||
n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
|
n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
|
||||||
n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
|
n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
|
||||||
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
|
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
|
||||||
n += (sz->_signers_bytes = sz->count_array(signers()));
|
|
||||||
n += (sz->_fields_bytes = sz->count_array(fields()));
|
n += (sz->_fields_bytes = sz->count_array(fields()));
|
||||||
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
|
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
|
||||||
sz->_ro_bytes += n;
|
sz->_ro_bytes += n;
|
||||||
@ -3206,17 +3209,11 @@ void InstanceKlass::verify_on(outputStream* st) {
|
|||||||
guarantee(constants()->is_metadata(), "should be in metaspace");
|
guarantee(constants()->is_metadata(), "should be in metaspace");
|
||||||
guarantee(constants()->is_constantPool(), "should be constant pool");
|
guarantee(constants()->is_constantPool(), "should be constant pool");
|
||||||
}
|
}
|
||||||
if (protection_domain() != NULL) {
|
|
||||||
guarantee(protection_domain()->is_oop(), "should be oop");
|
|
||||||
}
|
|
||||||
const Klass* host = host_klass();
|
const Klass* host = host_klass();
|
||||||
if (host != NULL) {
|
if (host != NULL) {
|
||||||
guarantee(host->is_metadata(), "should be in metaspace");
|
guarantee(host->is_metadata(), "should be in metaspace");
|
||||||
guarantee(host->is_klass(), "should be klass");
|
guarantee(host->is_klass(), "should be klass");
|
||||||
}
|
}
|
||||||
if (signers() != NULL) {
|
|
||||||
guarantee(signers()->is_objArray(), "should be obj array");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
|
void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
|
||||||
|
@ -58,8 +58,6 @@
|
|||||||
// [fields ]
|
// [fields ]
|
||||||
// [constants ]
|
// [constants ]
|
||||||
// [class loader ]
|
// [class loader ]
|
||||||
// [protection domain ]
|
|
||||||
// [signers ]
|
|
||||||
// [source file name ]
|
// [source file name ]
|
||||||
// [inner classes ]
|
// [inner classes ]
|
||||||
// [static field size ]
|
// [static field size ]
|
||||||
@ -180,16 +178,6 @@ class InstanceKlass: public Klass {
|
|||||||
static volatile int _total_instanceKlass_count;
|
static volatile int _total_instanceKlass_count;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Protection domain.
|
|
||||||
oop _protection_domain;
|
|
||||||
// Class signers.
|
|
||||||
objArrayOop _signers;
|
|
||||||
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
|
|
||||||
// Must be one per class and it has to be a VM internal object so java code
|
|
||||||
// cannot lock it (like the mirror).
|
|
||||||
// It has to be an object not a Mutex because it's held through java calls.
|
|
||||||
volatile oop _init_lock;
|
|
||||||
|
|
||||||
// Annotations for this class
|
// Annotations for this class
|
||||||
Annotations* _annotations;
|
Annotations* _annotations;
|
||||||
// Array classes holding elements of this class.
|
// Array classes holding elements of this class.
|
||||||
@ -527,8 +515,10 @@ class InstanceKlass: public Klass {
|
|||||||
void set_constants(ConstantPool* c) { _constants = c; }
|
void set_constants(ConstantPool* c) { _constants = c; }
|
||||||
|
|
||||||
// protection domain
|
// protection domain
|
||||||
oop protection_domain() { return _protection_domain; }
|
oop protection_domain() const;
|
||||||
void set_protection_domain(oop pd) { klass_oop_store(&_protection_domain, pd); }
|
|
||||||
|
// signers
|
||||||
|
objArrayOop signers() const;
|
||||||
|
|
||||||
// host class
|
// host class
|
||||||
Klass* host_klass() const {
|
Klass* host_klass() const {
|
||||||
@ -575,10 +565,6 @@ class InstanceKlass: public Klass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// signers
|
|
||||||
objArrayOop signers() const { return _signers; }
|
|
||||||
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
|
|
||||||
|
|
||||||
// source file name
|
// source file name
|
||||||
Symbol* source_file_name() const { return _source_file_name; }
|
Symbol* source_file_name() const { return _source_file_name; }
|
||||||
void set_source_file_name(Symbol* n);
|
void set_source_file_name(Symbol* n);
|
||||||
@ -912,8 +898,6 @@ class InstanceKlass: public Klass {
|
|||||||
Method* method_at_itable(Klass* holder, int index, TRAPS);
|
Method* method_at_itable(Klass* holder, int index, TRAPS);
|
||||||
|
|
||||||
// Garbage collection
|
// Garbage collection
|
||||||
virtual void oops_do(OopClosure* cl);
|
|
||||||
|
|
||||||
void oop_follow_contents(oop obj);
|
void oop_follow_contents(oop obj);
|
||||||
int oop_adjust_pointers(oop obj);
|
int oop_adjust_pointers(oop obj);
|
||||||
|
|
||||||
@ -999,14 +983,12 @@ private:
|
|||||||
|
|
||||||
// Lock during initialization
|
// Lock during initialization
|
||||||
public:
|
public:
|
||||||
volatile oop init_lock() const {return _init_lock; }
|
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
|
||||||
|
// Must be one per class and it has to be a VM internal object so java code
|
||||||
|
// cannot lock it (like the mirror).
|
||||||
|
// It has to be an object not a Mutex because it's held through java calls.
|
||||||
|
volatile oop init_lock() const;
|
||||||
private:
|
private:
|
||||||
void set_init_lock(oop value) { klass_oop_store(&_init_lock, value); }
|
|
||||||
|
|
||||||
// Offsets for memory management
|
|
||||||
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
|
|
||||||
oop* adr_signers() const { return (oop*)&this->_signers;}
|
|
||||||
oop* adr_init_lock() const { return (oop*)&this->_init_lock;}
|
|
||||||
|
|
||||||
// Static methods that are used to implement member methods where an exposed this pointer
|
// Static methods that are used to implement member methods where an exposed this pointer
|
||||||
// is needed due to possible GCs
|
// is needed due to possible GCs
|
||||||
@ -1040,7 +1022,8 @@ public:
|
|||||||
// JSR-292 support
|
// JSR-292 support
|
||||||
MemberNameTable* member_names() { return _member_names; }
|
MemberNameTable* member_names() { return _member_names; }
|
||||||
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
|
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
|
||||||
void add_member_name(Handle member_name);
|
void add_member_name(int index, Handle member_name);
|
||||||
|
oop get_member_name(int index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// JVMTI support
|
// JVMTI support
|
||||||
|
@ -511,8 +511,9 @@ void Klass::restore_unshareable_info(TRAPS) {
|
|||||||
// (same order as class file parsing)
|
// (same order as class file parsing)
|
||||||
loader_data->add_class(this);
|
loader_data->add_class(this);
|
||||||
|
|
||||||
// Recreate the class mirror
|
// Recreate the class mirror. The protection_domain is always null for
|
||||||
java_lang_Class::create_mirror(this, CHECK);
|
// boot loader, for now.
|
||||||
|
java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* Klass::array_klass_or_null(int rank) {
|
Klass* Klass::array_klass_or_null(int rank) {
|
||||||
|
@ -445,7 +445,7 @@ class Klass : public Metadata {
|
|||||||
Klass* array_klass_or_null(int rank);
|
Klass* array_klass_or_null(int rank);
|
||||||
Klass* array_klass_or_null();
|
Klass* array_klass_or_null();
|
||||||
|
|
||||||
virtual oop protection_domain() { return NULL; }
|
virtual oop protection_domain() const = 0;
|
||||||
|
|
||||||
oop class_loader() const;
|
oop class_loader() const;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class ObjArrayKlass : public ArrayKlass {
|
|||||||
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
|
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
|
||||||
|
|
||||||
// Compute protection domain
|
// Compute protection domain
|
||||||
oop protection_domain() { return bottom_klass()->protection_domain(); }
|
oop protection_domain() const { return bottom_klass()->protection_domain(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Either oop or narrowOop depending on UseCompressedOops.
|
// Either oop or narrowOop depending on UseCompressedOops.
|
||||||
|
@ -67,6 +67,8 @@ class TypeArrayKlass : public ArrayKlass {
|
|||||||
typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); }
|
typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); }
|
||||||
oop multi_allocate(int rank, jint* sizes, TRAPS);
|
oop multi_allocate(int rank, jint* sizes, TRAPS);
|
||||||
|
|
||||||
|
oop protection_domain() const { return NULL; }
|
||||||
|
|
||||||
// Copying
|
// Copying
|
||||||
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
|
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
|
||||||
|
|
||||||
|
@ -35,6 +35,19 @@
|
|||||||
#include "runtime/vframe.hpp"
|
#include "runtime/vframe.hpp"
|
||||||
#include "runtime/vframeArray.hpp"
|
#include "runtime/vframeArray.hpp"
|
||||||
|
|
||||||
|
// call frame copied from old .h file and renamed
|
||||||
|
typedef struct {
|
||||||
|
jint lineno; // line number in the source file
|
||||||
|
jmethodID method_id; // method executed in this frame
|
||||||
|
} ASGCT_CallFrame;
|
||||||
|
|
||||||
|
// call trace copied from old .h file and renamed
|
||||||
|
typedef struct {
|
||||||
|
JNIEnv *env_id; // Env where trace was recorded
|
||||||
|
jint num_frames; // number of frames in this trace
|
||||||
|
ASGCT_CallFrame *frames; // frames
|
||||||
|
} ASGCT_CallTrace;
|
||||||
|
|
||||||
// These name match the names reported by the forte quality kit
|
// These name match the names reported by the forte quality kit
|
||||||
enum {
|
enum {
|
||||||
ticks_no_Java_frame = 0,
|
ticks_no_Java_frame = 0,
|
||||||
@ -50,6 +63,8 @@ enum {
|
|||||||
ticks_safepoint = -10
|
ticks_safepoint = -10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if INCLUDE_JVMTI
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
||||||
// Native interfaces for use by Forte tools.
|
// Native interfaces for use by Forte tools.
|
||||||
@ -360,20 +375,6 @@ static bool find_initial_Java_frame(JavaThread* thread,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// call frame copied from old .h file and renamed
|
|
||||||
typedef struct {
|
|
||||||
jint lineno; // line number in the source file
|
|
||||||
jmethodID method_id; // method executed in this frame
|
|
||||||
} ASGCT_CallFrame;
|
|
||||||
|
|
||||||
// call trace copied from old .h file and renamed
|
|
||||||
typedef struct {
|
|
||||||
JNIEnv *env_id; // Env where trace was recorded
|
|
||||||
jint num_frames; // number of frames in this trace
|
|
||||||
ASGCT_CallFrame *frames; // frames
|
|
||||||
} ASGCT_CallTrace;
|
|
||||||
|
|
||||||
static void forte_fill_call_trace_given_top(JavaThread* thd,
|
static void forte_fill_call_trace_given_top(JavaThread* thd,
|
||||||
ASGCT_CallTrace* trace,
|
ASGCT_CallTrace* trace,
|
||||||
int depth,
|
int depth,
|
||||||
@ -634,3 +635,12 @@ void Forte::register_stub(const char* name, address start, address end) {
|
|||||||
pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
|
pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
|
||||||
#endif // !_WINDOWS && !IA64
|
#endif // !_WINDOWS && !IA64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else // INCLUDE_JVMTI
|
||||||
|
extern "C" {
|
||||||
|
JNIEXPORT
|
||||||
|
void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
|
||||||
|
trace->num_frames = ticks_no_class_load; // -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // INCLUDE_JVMTI
|
||||||
|
@ -1072,11 +1072,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
objArrayOop signers = java_lang_Class::signers(JNIHandles::resolve_non_null(cls));
|
||||||
objArrayOop signers = NULL;
|
|
||||||
if (k->oop_is_instance()) {
|
|
||||||
signers = InstanceKlass::cast(k)->signers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are no signers set in the class, or if the class
|
// If there are no signers set in the class, or if the class
|
||||||
// is an array, return NULL.
|
// is an array, return NULL.
|
||||||
@ -1102,7 +1098,7 @@ JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signer
|
|||||||
// be called with an array. Only the bootstrap loader creates arrays.
|
// be called with an array. Only the bootstrap loader creates arrays.
|
||||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
|
||||||
if (k->oop_is_instance()) {
|
if (k->oop_is_instance()) {
|
||||||
InstanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers)));
|
java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JVM_END
|
JVM_END
|
||||||
@ -1119,8 +1115,8 @@ JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
|
oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
|
||||||
return (jobject) JNIHandles::make_local(env, k->protection_domain());
|
return (jobject) JNIHandles::make_local(env, pd);
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
@ -1139,7 +1135,7 @@ JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protect
|
|||||||
if (k->oop_is_instance()) {
|
if (k->oop_is_instance()) {
|
||||||
oop pd = JNIHandles::resolve(protection_domain);
|
oop pd = JNIHandles::resolve(protection_domain);
|
||||||
assert(pd == NULL || pd->is_oop(), "just checking");
|
assert(pd == NULL || pd->is_oop(), "just checking");
|
||||||
InstanceKlass::cast(k)->set_protection_domain(pd);
|
java_lang_Class::set_protection_domain(k->java_mirror(), pd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JVM_END
|
JVM_END
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -232,7 +232,8 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
|
|||||||
// This is done eagerly, since it is readily available without
|
// This is done eagerly, since it is readily available without
|
||||||
// constructing any new objects.
|
// constructing any new objects.
|
||||||
// TO DO: maybe intern mname_oop
|
// TO DO: maybe intern mname_oop
|
||||||
m->method_holder()->add_member_name(mname);
|
m->method_holder()->add_member_name(m->method_idnum(), mname);
|
||||||
|
|
||||||
return mname();
|
return mname();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +302,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
|
|||||||
// Although the fieldDescriptor::_index would also identify the field,
|
// Although the fieldDescriptor::_index would also identify the field,
|
||||||
// we do not use it, because it is harder to decode.
|
// we do not use it, because it is harder to decode.
|
||||||
// TO DO: maybe intern mname_oop
|
// TO DO: maybe intern mname_oop
|
||||||
InstanceKlass::cast(field_holder())->add_member_name(mname);
|
|
||||||
return mname();
|
return mname();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,7 +943,8 @@ int MethodHandles::find_MemberNames(KlassHandle k,
|
|||||||
// MemberNameTable
|
// MemberNameTable
|
||||||
//
|
//
|
||||||
|
|
||||||
MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) {
|
MemberNameTable::MemberNameTable(int methods_cnt)
|
||||||
|
: GrowableArray<jweak>(methods_cnt, true) {
|
||||||
assert_locked_or_safepoint(MemberNameTable_lock);
|
assert_locked_or_safepoint(MemberNameTable_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,29 +958,18 @@ MemberNameTable::~MemberNameTable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return entry index if found, return -1 otherwise.
|
void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
|
||||||
int MemberNameTable::find_member_name(oop mem_name) {
|
|
||||||
assert_locked_or_safepoint(MemberNameTable_lock);
|
assert_locked_or_safepoint(MemberNameTable_lock);
|
||||||
int len = this->length();
|
this->at_put_grow(index, mem_name_wref);
|
||||||
|
|
||||||
for (int idx = 0; idx < len; idx++) {
|
|
||||||
jweak ref = this->at(idx);
|
|
||||||
oop entry = JNIHandles::resolve(ref);
|
|
||||||
if (entry == mem_name) {
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemberNameTable::add_member_name(jweak mem_name_wref) {
|
// Return a member name oop or NULL.
|
||||||
|
oop MemberNameTable::get_member_name(int index) {
|
||||||
assert_locked_or_safepoint(MemberNameTable_lock);
|
assert_locked_or_safepoint(MemberNameTable_lock);
|
||||||
oop mem_name = JNIHandles::resolve(mem_name_wref);
|
|
||||||
|
|
||||||
// Each member name may appear just once: add only if not found
|
jweak ref = this->at(index);
|
||||||
if (find_member_name(mem_name) == -1) {
|
oop mem_name = JNIHandles::resolve(ref);
|
||||||
this->append(mem_name_wref);
|
return mem_name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -219,7 +219,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// MethodHandlesAdapterGenerator
|
// MethodHandlesAdapterGenerator
|
||||||
//
|
//
|
||||||
@ -233,13 +232,13 @@ public:
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// MemberNameTable
|
// MemberNameTable
|
||||||
//
|
//
|
||||||
|
|
||||||
class MemberNameTable : public GrowableArray<jweak> {
|
class MemberNameTable : public GrowableArray<jweak> {
|
||||||
public:
|
public:
|
||||||
MemberNameTable();
|
MemberNameTable(int methods_cnt);
|
||||||
~MemberNameTable();
|
~MemberNameTable();
|
||||||
void add_member_name(jweak mem_name_ref);
|
void add_member_name(int index, jweak mem_name_ref);
|
||||||
private:
|
oop get_member_name(int index);
|
||||||
int find_member_name(oop mem_name);
|
|
||||||
|
|
||||||
#if INCLUDE_JVMTI
|
#if INCLUDE_JVMTI
|
||||||
public:
|
public:
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "utilities/debug.hpp"
|
#include "utilities/debug.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
|
#include "utilities/exceptions.hpp"
|
||||||
|
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
#include "gc_implementation/g1/concurrentMark.hpp"
|
#include "gc_implementation/g1/concurrentMark.hpp"
|
||||||
@ -330,8 +331,18 @@ WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
|
|||||||
WB_END
|
WB_END
|
||||||
|
|
||||||
|
|
||||||
WB_ENTRY(jlong, WB_ReserveMemory(JNIEnv* env, jobject o, jlong size))
|
WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
|
||||||
return (jlong)os::reserve_memory(size, NULL, 0);
|
// static+volatile in order to force the read to happen
|
||||||
|
// (not be eliminated by the compiler)
|
||||||
|
static char c;
|
||||||
|
static volatile char* p;
|
||||||
|
|
||||||
|
p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
|
||||||
|
if (p == NULL) {
|
||||||
|
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *p;
|
||||||
WB_END
|
WB_END
|
||||||
|
|
||||||
//Some convenience methods to deal with objects from java
|
//Some convenience methods to deal with objects from java
|
||||||
@ -437,7 +448,7 @@ static JNINativeMethod methods[] = {
|
|||||||
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
|
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
|
||||||
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
|
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
|
||||||
|
|
||||||
{CC"reserveMemory", CC"(J)J", (void*)&WB_ReserveMemory },
|
{CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CC
|
#undef CC
|
||||||
|
@ -294,8 +294,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
|||||||
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
|
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
|
||||||
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
|
nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
|
||||||
nonstatic_field(InstanceKlass, _class_loader_data, ClassLoaderData*) \
|
nonstatic_field(InstanceKlass, _class_loader_data, ClassLoaderData*) \
|
||||||
nonstatic_field(InstanceKlass, _protection_domain, oop) \
|
|
||||||
nonstatic_field(InstanceKlass, _signers, objArrayOop) \
|
|
||||||
nonstatic_field(InstanceKlass, _source_file_name, Symbol*) \
|
nonstatic_field(InstanceKlass, _source_file_name, Symbol*) \
|
||||||
nonstatic_field(InstanceKlass, _source_debug_extension, char*) \
|
nonstatic_field(InstanceKlass, _source_debug_extension, char*) \
|
||||||
nonstatic_field(InstanceKlass, _inner_classes, Array<jushort>*) \
|
nonstatic_field(InstanceKlass, _inner_classes, Array<jushort>*) \
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "services/memReporter.hpp"
|
#include "services/memReporter.hpp"
|
||||||
#include "services/memTracker.hpp"
|
#include "services/memTracker.hpp"
|
||||||
#include "utilities/decoder.hpp"
|
#include "utilities/decoder.hpp"
|
||||||
|
#include "utilities/defaultStream.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
bool NMT_track_callsite = false;
|
bool NMT_track_callsite = false;
|
||||||
@ -77,7 +78,15 @@ void MemTracker::init_tracking_options(const char* option_line) {
|
|||||||
if (strcmp(option_line, "=summary") == 0) {
|
if (strcmp(option_line, "=summary") == 0) {
|
||||||
_tracking_level = NMT_summary;
|
_tracking_level = NMT_summary;
|
||||||
} else if (strcmp(option_line, "=detail") == 0) {
|
} else if (strcmp(option_line, "=detail") == 0) {
|
||||||
|
// detail relies on a stack-walking ability that may not
|
||||||
|
// be available depending on platform and/or compiler flags
|
||||||
|
if (PLATFORM_NMT_DETAIL_SUPPORTED) {
|
||||||
_tracking_level = NMT_detail;
|
_tracking_level = NMT_detail;
|
||||||
|
} else {
|
||||||
|
jio_fprintf(defaultStream::error_stream(),
|
||||||
|
"NMT detail is not supported on this platform. Using NMT summary instead.");
|
||||||
|
_tracking_level = NMT_summary;
|
||||||
|
}
|
||||||
} else if (strcmp(option_line, "=off") != 0) {
|
} else if (strcmp(option_line, "=off") != 0) {
|
||||||
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
|
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
|
||||||
}
|
}
|
||||||
|
@ -380,6 +380,14 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlass
|
|||||||
# include "globalDefinitions_ppc.hpp"
|
# include "globalDefinitions_ppc.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a platform does not support NMT_detail
|
||||||
|
* the platform specific globalDefinitions (above)
|
||||||
|
* can set PLATFORM_NMT_DETAIL_SUPPORTED to false
|
||||||
|
*/
|
||||||
|
#ifndef PLATFORM_NMT_DETAIL_SUPPORTED
|
||||||
|
#define PLATFORM_NMT_DETAIL_SUPPORTED true
|
||||||
|
#endif
|
||||||
|
|
||||||
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
|
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
|
||||||
// Note: this value must be a power of 2
|
// Note: this value must be a power of 2
|
||||||
|
64
hotspot/test/runtime/Metaspace/FragmentMetaspace.java
Normal file
64
hotspot/test/runtime/Metaspace/FragmentMetaspace.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @library /runtime/testlibrary
|
||||||
|
* @build GeneratedClassLoader
|
||||||
|
* @run main/othervm/timeout=200 FragmentMetaspace
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that tries to fragment the native memory used by class loaders.
|
||||||
|
* This test creates class loaders that load classes of increasing size for every
|
||||||
|
* iteration. By increasing the size of the class meta data needed for every iteration
|
||||||
|
* we stress the subsystem for allocating native memory for meta data.
|
||||||
|
*/
|
||||||
|
public class FragmentMetaspace {
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
runGrowing(Long.valueOf(System.getProperty("time", "80000")));
|
||||||
|
// try to clean up and unload classes to decrease
|
||||||
|
// class verification time in debug vm
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runGrowing(long time) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
|
||||||
|
try {
|
||||||
|
GeneratedClassLoader gcl = new GeneratedClassLoader();
|
||||||
|
|
||||||
|
Class<?> c = gcl.getGeneratedClasses(i, 100)[0];
|
||||||
|
c.newInstance();
|
||||||
|
c = null;
|
||||||
|
|
||||||
|
gcl = null;
|
||||||
|
} catch (IOException|InstantiationException|IllegalAccessException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java
Normal file
69
hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @library /runtime/testlibrary
|
||||||
|
* @library classes
|
||||||
|
* @build test.Empty ClassUnloadCommon
|
||||||
|
* @run main/othervm/timeout=200 FragmentMetaspaceSimple
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that tries to fragment the native memory used by class loaders.
|
||||||
|
* Keeps every other class loader alive in order to fragment the memory space
|
||||||
|
* used to store classes and meta data. Since the memory is probably allocated in
|
||||||
|
* chunks per class loader this will cause a lot of fragmentation if not handled
|
||||||
|
* properly since every other chunk will be unused.
|
||||||
|
*/
|
||||||
|
public class FragmentMetaspaceSimple {
|
||||||
|
public static void main(String... args) {
|
||||||
|
runSimple(Long.valueOf(System.getProperty("time", "80000")));
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
if (i % 1000 == 0) {
|
||||||
|
cls.clear();
|
||||||
|
}
|
||||||
|
// only keep every other class loader alive
|
||||||
|
if (i % 2 == 1) {
|
||||||
|
cls.add(ldr);
|
||||||
|
}
|
||||||
|
Class<?> c = null;
|
||||||
|
try {
|
||||||
|
c = ldr.loadClass("test.Empty");
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
c = null;
|
||||||
|
}
|
||||||
|
cls = null;
|
||||||
|
}
|
||||||
|
}
|
28
hotspot/test/runtime/Metaspace/classes/test/Empty.java
Normal file
28
hotspot/test/runtime/Metaspace/classes/test/Empty.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package test;
|
||||||
|
|
||||||
|
public class Empty {
|
||||||
|
public String toString() { return "nothing"; }
|
||||||
|
}
|
75
hotspot/test/runtime/contended/HasNonStatic.java
Normal file
75
hotspot/test/runtime/contended/HasNonStatic.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.Class;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import sun.misc.Contended;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8015270
|
||||||
|
* @summary \@Contended: fix multiple issues in the layout code
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:-RestrictContended HasNonStatic
|
||||||
|
*/
|
||||||
|
public class HasNonStatic {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
R1 r1 = new R1();
|
||||||
|
R2 r2 = new R2();
|
||||||
|
R3 r3 = new R3();
|
||||||
|
R4 r4 = new R4();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class R1 {
|
||||||
|
@Contended
|
||||||
|
Object o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
public static class R2 {
|
||||||
|
Object o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
public static class R3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class R4 extends R3 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
166
hotspot/test/runtime/contended/OopMaps.java
Normal file
166
hotspot/test/runtime/contended/OopMaps.java
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.Class;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
import sun.misc.Contended;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8015270
|
||||||
|
* @bug 8015493
|
||||||
|
* @summary \@Contended: fix multiple issues in the layout code
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:-RestrictContended -XX:ContendedPaddingWidth=128 -Xmx128m OopMaps
|
||||||
|
*/
|
||||||
|
public class OopMaps {
|
||||||
|
|
||||||
|
public static final int COUNT = 10000;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Object o01 = new Object();
|
||||||
|
Object o02 = new Object();
|
||||||
|
Object o03 = new Object();
|
||||||
|
Object o04 = new Object();
|
||||||
|
Object o05 = new Object();
|
||||||
|
Object o06 = new Object();
|
||||||
|
Object o07 = new Object();
|
||||||
|
Object o08 = new Object();
|
||||||
|
Object o09 = new Object();
|
||||||
|
Object o10 = new Object();
|
||||||
|
Object o11 = new Object();
|
||||||
|
Object o12 = new Object();
|
||||||
|
Object o13 = new Object();
|
||||||
|
Object o14 = new Object();
|
||||||
|
|
||||||
|
R1[] rs = new R1[COUNT];
|
||||||
|
|
||||||
|
for (int i = 0; i < COUNT; i++) {
|
||||||
|
R1 r1 = new R1();
|
||||||
|
r1.o01 = o01;
|
||||||
|
r1.o02 = o02;
|
||||||
|
r1.o03 = o03;
|
||||||
|
r1.o04 = o04;
|
||||||
|
r1.o05 = o05;
|
||||||
|
r1.o06 = o06;
|
||||||
|
r1.o07 = o07;
|
||||||
|
r1.o08 = o08;
|
||||||
|
r1.o09 = o09;
|
||||||
|
r1.o10 = o10;
|
||||||
|
r1.o11 = o11;
|
||||||
|
r1.o12 = o12;
|
||||||
|
r1.o13 = o13;
|
||||||
|
r1.o14 = o14;
|
||||||
|
r1.i1 = 1;
|
||||||
|
r1.i2 = 2;
|
||||||
|
r1.i3 = 3;
|
||||||
|
r1.i4 = 4;
|
||||||
|
rs[i] = r1;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.gc();
|
||||||
|
|
||||||
|
for (int i = 0; i < COUNT; i++) {
|
||||||
|
R1 r1 = rs[i];
|
||||||
|
if (r1.o01 != o01) throw new Error("Test Error: o01");
|
||||||
|
if (r1.o02 != o02) throw new Error("Test Error: o02");
|
||||||
|
if (r1.o03 != o03) throw new Error("Test Error: o03");
|
||||||
|
if (r1.o04 != o04) throw new Error("Test Error: o04");
|
||||||
|
if (r1.o05 != o05) throw new Error("Test Error: o05");
|
||||||
|
if (r1.o06 != o06) throw new Error("Test Error: o06");
|
||||||
|
if (r1.o07 != o07) throw new Error("Test Error: o07");
|
||||||
|
if (r1.o08 != o08) throw new Error("Test Error: o08");
|
||||||
|
if (r1.o09 != o09) throw new Error("Test Error: o09");
|
||||||
|
if (r1.o10 != o10) throw new Error("Test Error: o10");
|
||||||
|
if (r1.o11 != o11) throw new Error("Test Error: o11");
|
||||||
|
if (r1.o12 != o12) throw new Error("Test Error: o12");
|
||||||
|
if (r1.o13 != o13) throw new Error("Test Error: o13");
|
||||||
|
if (r1.o14 != o14) throw new Error("Test Error: o14");
|
||||||
|
if (r1.i1 != 1) throw new Error("Test Error: i1");
|
||||||
|
if (r1.i2 != 2) throw new Error("Test Error: i2");
|
||||||
|
if (r1.i3 != 3) throw new Error("Test Error: i3");
|
||||||
|
if (r1.i4 != 4) throw new Error("Test Error: i4");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class R0 {
|
||||||
|
int i1;
|
||||||
|
int i2;
|
||||||
|
|
||||||
|
Object o01;
|
||||||
|
Object o02;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o03;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o04;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o05;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o06;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o07;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class R1 extends R0 {
|
||||||
|
int i3;
|
||||||
|
int i4;
|
||||||
|
|
||||||
|
Object o08;
|
||||||
|
Object o09;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o10;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o11;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o12;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o13;
|
||||||
|
|
||||||
|
@Contended
|
||||||
|
Object o14;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -34,29 +34,20 @@
|
|||||||
|
|
||||||
import com.oracle.java.testlibrary.*;
|
import com.oracle.java.testlibrary.*;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import sun.hotspot.WhiteBox;
|
import sun.hotspot.WhiteBox;
|
||||||
import sun.misc.Unsafe;
|
|
||||||
|
|
||||||
public class ReserveMemory {
|
public class ReserveMemory {
|
||||||
private static Unsafe getUnsafe() throws Exception {
|
|
||||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
|
||||||
f.setAccessible(true);
|
|
||||||
return (Unsafe)f.get(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isWindows() {
|
private static boolean isWindows() {
|
||||||
return System.getProperty("os.name").toLowerCase().startsWith("win");
|
return System.getProperty("os.name").toLowerCase().startsWith("win");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isOsx() {
|
||||||
|
return System.getProperty("os.name").toLowerCase().startsWith("mac");
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception {
|
public static void main(String args[]) throws Exception {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
long address = WhiteBox.getWhiteBox().reserveMemory(4096);
|
WhiteBox.getWhiteBox().readReservedMemory();
|
||||||
|
|
||||||
System.out.println("Reserved memory at address: 0x" + Long.toHexString(address));
|
|
||||||
System.out.println("Will now read from the address, expecting a crash!");
|
|
||||||
|
|
||||||
int x = getUnsafe().getInt(address);
|
|
||||||
|
|
||||||
throw new Exception("Read of reserved/uncommitted memory unexpectedly succeeded, expected crash!");
|
throw new Exception("Read of reserved/uncommitted memory unexpectedly succeeded, expected crash!");
|
||||||
}
|
}
|
||||||
@ -71,6 +62,8 @@ public class ReserveMemory {
|
|||||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||||
if (isWindows()) {
|
if (isWindows()) {
|
||||||
output.shouldContain("EXCEPTION_ACCESS_VIOLATION");
|
output.shouldContain("EXCEPTION_ACCESS_VIOLATION");
|
||||||
|
} else if (isOsx()) {
|
||||||
|
output.shouldContain("SIGBUS");
|
||||||
} else {
|
} else {
|
||||||
output.shouldContain("SIGSEGV");
|
output.shouldContain("SIGSEGV");
|
||||||
}
|
}
|
||||||
|
202
hotspot/test/runtime/testlibrary/GeneratedClassLoader.java
Normal file
202
hotspot/test/runtime/testlibrary/GeneratedClassLoader.java
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class loader that generates new classes.
|
||||||
|
* The generated classes are made by first emitting java sources with nested
|
||||||
|
* static classes, these are then compiled and the class files are read back.
|
||||||
|
* Some efforts are made to make the class instances unique and of not insignificant
|
||||||
|
* size.
|
||||||
|
*/
|
||||||
|
public class GeneratedClassLoader extends ClassLoader {
|
||||||
|
/**
|
||||||
|
* Holds a pair of class bytecodes and class name (for use with defineClass).
|
||||||
|
*/
|
||||||
|
private static class GeneratedClass {
|
||||||
|
public byte[] bytes;
|
||||||
|
public String name;
|
||||||
|
public GeneratedClass(byte[] bytes, String name) {
|
||||||
|
this.bytes = bytes; this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to uniquely name every class generated.
|
||||||
|
*/
|
||||||
|
private static int count = 0;
|
||||||
|
/**
|
||||||
|
* Used to enable/disable keeping the class files and java sources for
|
||||||
|
* the generated classes.
|
||||||
|
*/
|
||||||
|
private static boolean deleteFiles = Boolean.parseBoolean(
|
||||||
|
System.getProperty("GeneratedClassLoader.deleteFiles", "true"));
|
||||||
|
|
||||||
|
private static String bigstr =
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
||||||
|
+ "In facilisis scelerisque vehicula. Donec congue nisi a "
|
||||||
|
+ "leo posuere placerat lobortis felis ultrices. Pellentesque "
|
||||||
|
+ "habitant morbi tristique senectus et netus et malesuada "
|
||||||
|
+ "fames ac turpis egestas. Nam tristique velit at felis "
|
||||||
|
+ "iaculis at tempor sem vestibulum. Sed adipiscing lectus "
|
||||||
|
+ "non mi molestie sagittis. Morbi eu purus urna. Nam tempor "
|
||||||
|
+ "tristique massa eget semper. Mauris cursus, nulla et ornare "
|
||||||
|
+ "vehicula, leo dolor scelerisque metus, sit amet rutrum erat "
|
||||||
|
+ "sapien quis dui. Nullam eleifend risus et velit accumsan sed "
|
||||||
|
+ "suscipit felis pulvinar. Nullam faucibus suscipit gravida. "
|
||||||
|
+ "Pellentesque habitant morbi tristique senectus et netus et "
|
||||||
|
+ "malesuada fames ac turpis egestas. Nullam ut massa augue, "
|
||||||
|
+ "nec viverra mauris.";
|
||||||
|
|
||||||
|
private static int getNextCount() {
|
||||||
|
return count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
////// end statics
|
||||||
|
|
||||||
|
private JavaCompiler javac;
|
||||||
|
private String nameBase;
|
||||||
|
|
||||||
|
public GeneratedClassLoader() {
|
||||||
|
javac = ToolProvider.getSystemJavaCompiler();
|
||||||
|
nameBase = "TestSimpleClass";
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getBigValue(int which) {
|
||||||
|
// > 65536 is too large to encode in the bytecode
|
||||||
|
// so this will force us to emit a constant pool entry for this int
|
||||||
|
return (long)which + 65537;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBigString(int which) {
|
||||||
|
return bigstr + which;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getClassName(int count) {
|
||||||
|
return nameBase + count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateSource(int count, int sizeFactor, int numClasses) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("public class ").append(getClassName(count)).append("{\n");
|
||||||
|
for (int j = 0; j < numClasses; ++j) {
|
||||||
|
sb.append("public static class ")
|
||||||
|
.append("Class")
|
||||||
|
.append(j)
|
||||||
|
.append("{\n");
|
||||||
|
for (int i = 0; i < sizeFactor; ++i) {
|
||||||
|
int value = i;
|
||||||
|
sb.append("private long field")
|
||||||
|
.append(i).append(" = ")
|
||||||
|
.append(getBigValue(value++))
|
||||||
|
.append(";\n");
|
||||||
|
sb.append("public long method")
|
||||||
|
.append(i)
|
||||||
|
.append("() {\n");
|
||||||
|
sb.append("return ")
|
||||||
|
.append(getBigValue(value++))
|
||||||
|
.append(";");
|
||||||
|
sb.append("}\n");
|
||||||
|
sb.append("private String str").append(i)
|
||||||
|
.append(" = \"")
|
||||||
|
.append(getBigString(i))
|
||||||
|
.append("\";");
|
||||||
|
}
|
||||||
|
sb.append("\n}");
|
||||||
|
}
|
||||||
|
sb.append("\n}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
|
||||||
|
int uniqueCount = getNextCount();
|
||||||
|
String src = generateSource(uniqueCount, sizeFactor, numClasses);
|
||||||
|
String className = getClassName(uniqueCount);
|
||||||
|
File file = new File(className + ".java");
|
||||||
|
try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
|
||||||
|
pw.append(src);
|
||||||
|
pw.flush();
|
||||||
|
}
|
||||||
|
int exitcode = javac.run(null, null, null, file.getCanonicalPath());
|
||||||
|
if (exitcode != 0) {
|
||||||
|
throw new RuntimeException("javac failure when compiling: " +
|
||||||
|
file.getCanonicalPath());
|
||||||
|
} else {
|
||||||
|
if (deleteFiles) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GeneratedClass[] gc = new GeneratedClass[numClasses];
|
||||||
|
for (int i = 0; i < numClasses; ++i) {
|
||||||
|
String name = className + "$" + "Class" + i;
|
||||||
|
File classFile = new File(name + ".class");
|
||||||
|
byte[] bytes;
|
||||||
|
try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
|
||||||
|
bytes = new byte[dis.available()];
|
||||||
|
dis.readFully(bytes);
|
||||||
|
}
|
||||||
|
if (deleteFiles) {
|
||||||
|
classFile.delete();
|
||||||
|
}
|
||||||
|
gc[i] = new GeneratedClass(bytes, name);
|
||||||
|
}
|
||||||
|
if (deleteFiles) {
|
||||||
|
new File(className + ".class").delete();
|
||||||
|
}
|
||||||
|
return gc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a single class, compile it and load it.
|
||||||
|
* @param sizeFactor Fuzzy measure of how large the class should be.
|
||||||
|
* @return the Class instance.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Class<?> generateClass(int sizeFactor) throws IOException {
|
||||||
|
return getGeneratedClasses(sizeFactor, 1)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate several classes, compile and load them.
|
||||||
|
* @param sizeFactor Fuzzy measure of how large each class should be.
|
||||||
|
* @param numClasses The number of classes to create
|
||||||
|
* @return an array of the Class instances.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Class<?>[] getGeneratedClasses(int sizeFactor, int numClasses) throws IOException {
|
||||||
|
GeneratedClass[] gc = getGeneratedClass(sizeFactor, numClasses);
|
||||||
|
Class<?>[] classes = new Class[numClasses];
|
||||||
|
for (int i = 0; i < numClasses; ++i) {
|
||||||
|
classes[i] = defineClass(gc[i].name, gc[i].bytes, 0 , gc[i].bytes.length);
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
}
|
@ -115,7 +115,7 @@ public class WhiteBox {
|
|||||||
public native boolean isInStringTable(String str);
|
public native boolean isInStringTable(String str);
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
public native long reserveMemory(long size);
|
public native void readReservedMemory();
|
||||||
|
|
||||||
// force Full GC
|
// force Full GC
|
||||||
public native void fullGC();
|
public native void fullGC();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user