mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-01 05:58:29 +00:00
Merge
This commit is contained in:
commit
df0d844ee4
3
.hgtags
3
.hgtags
@ -151,3 +151,6 @@ e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22
|
||||
c51754cddc037b9609e202b9ed38363d8683e7a8 jdk8-b27
|
||||
16ba58282d117247f480aae7a79b88141ade52a3 jdk8-b28
|
||||
e070119aa56ee4dc5506c19d2c4d2eecab8ad429 jdk8-b29
|
||||
23da7804aca0c9c4e6e86532a1453125a76d95ee jdk8-b30
|
||||
bac81e9f7d57b75fba5ab31b571f3fe0dc08af69 jdk8-b31
|
||||
2c5208ccb863db936eab523f49450b3fcd230348 jdk8-b32
|
||||
|
||||
@ -151,3 +151,6 @@ cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21
|
||||
1533dfab9903e4edcfead3b0192643f38c418b9b jdk8-b27
|
||||
6e2541d60f4e342b5b67140271d7611643929dc3 jdk8-b28
|
||||
41460de042580bc4a4ce3f863779c66f39cb8578 jdk8-b29
|
||||
6cea54809b51db92979c22fd8aa8fcb1cb13d12e jdk8-b30
|
||||
0b66f43b89a6c0ac1c15d7ec51992c541cdc9089 jdk8-b31
|
||||
88176171e940f02916a312c265a34c32552a8376 jdk8-b32
|
||||
|
||||
@ -151,3 +151,6 @@ e45d6b406d5f91ff5256a5c82456ab1e7eb8becd jdk8-b25
|
||||
4fffe75e4edd39a2517f10b743941bf94edb143d jdk8-b27
|
||||
2082eb35d49a9c2aab90b8d4fd31cefb7a23b82e jdk8-b28
|
||||
6117395d422682f89d228347e319fcaac7edc729 jdk8-b29
|
||||
4605f8418bf562e78be79b25b6b8a5110281acae jdk8-b30
|
||||
1954151dfae8f73db24e396380f7c02bdd47c486 jdk8-b31
|
||||
5d820cb6b1afd75b619e7fd69e4f2b0eb1d5d6a1 jdk8-b32
|
||||
|
||||
@ -149,8 +149,8 @@ strip_prop_options_clean:
|
||||
# Strip the properties files
|
||||
strip_all_props: $(STRIPPROPERTIES_JARFILE) $(STRIP_PROP_options)
|
||||
@if [ -s $(STRIP_PROP_options) ] ; then \
|
||||
$(ECHO) "$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) -optionsfile $(STRIP_PROP_options)" ; \
|
||||
$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) -optionsfile $(STRIP_PROP_options) ; \
|
||||
$(ECHO) "$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) @$(STRIP_PROP_options)" ; \
|
||||
$(BOOT_JAVA_CMD) -jar $(STRIPPROPERTIES_JARFILE) @$(STRIP_PROP_options) ; \
|
||||
fi
|
||||
@$(java-vm-cleanup)
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2011, 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
|
||||
@ -36,6 +36,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -43,7 +44,7 @@ import java.util.Properties;
|
||||
* Reads a properties file from standard input and writes an equivalent
|
||||
* properties file without comments to standard output.
|
||||
*/
|
||||
public class StripProperties {
|
||||
public class StripPropertiesCorba {
|
||||
|
||||
private static void error(String msg, Exception e) {
|
||||
System.err.println("ERROR: stripproperties: " + msg);
|
||||
@ -53,82 +54,89 @@ public class StripProperties {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> parseOptions(String args[]) {
|
||||
List<String> files = new ArrayList<String>();
|
||||
private static List<String> infiles = new ArrayList<String>();
|
||||
private static List<String> outfiles = new ArrayList<String>();
|
||||
|
||||
private static boolean parseOptions(String args[]) {
|
||||
boolean ok = true;
|
||||
|
||||
for ( int i = 0; i < args.length ; i++ ) {
|
||||
if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) {
|
||||
String filename = args[++i];
|
||||
if ( "-clean".equals(args[i]) && i+2 < args.length ) {
|
||||
infiles.add(args[++i]);
|
||||
outfiles.add(args[++i]);
|
||||
} else if ( args[i].charAt(0)=='@') {
|
||||
String filename = args[i].substring(1);
|
||||
FileInputStream finput = null;
|
||||
byte contents[] = null;
|
||||
try {
|
||||
finput = new FileInputStream(filename);
|
||||
int byteCount = finput.available();
|
||||
if ( byteCount <= 0 ) {
|
||||
error("The -optionsfile file is empty", null);
|
||||
files = null;
|
||||
error("The @file is empty", null);
|
||||
ok = false;
|
||||
} else {
|
||||
contents = new byte[byteCount];
|
||||
int bytesRead = finput.read(contents);
|
||||
if ( byteCount != bytesRead ) {
|
||||
error("Cannot read all of -optionsfile file", null);
|
||||
files = null;
|
||||
error("Cannot read all of @file", null);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} catch ( IOException e ) {
|
||||
error("cannot open " + filename, e);
|
||||
files = null;
|
||||
ok = false;
|
||||
}
|
||||
if ( finput != null ) {
|
||||
try {
|
||||
finput.close();
|
||||
} catch ( IOException e ) {
|
||||
files = null;
|
||||
ok = false;
|
||||
error("cannot close " + filename, e);
|
||||
}
|
||||
}
|
||||
if ( files != null && contents != null ) {
|
||||
if ( ok && contents != null ) {
|
||||
String tokens[] = (new String(contents)).split("\\s+");
|
||||
if ( tokens.length > 0 ) {
|
||||
List<String> ofiles = parseOptions(tokens);
|
||||
if ( ofiles != null ) {
|
||||
files.addAll(ofiles);
|
||||
} else {
|
||||
error("No files found in file", null);
|
||||
files = null;
|
||||
}
|
||||
ok = parseOptions(tokens);
|
||||
}
|
||||
}
|
||||
if ( files == null ) {
|
||||
if ( !ok ) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
files.add(args[i]);
|
||||
infiles.add(args[i]);
|
||||
outfiles.add(args[i]);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
return ok;
|
||||
}
|
||||
|
||||
private static boolean stripFiles(List<String> files) {
|
||||
private static boolean stripFiles(List<String> infiles, List<String> outfiles) {
|
||||
boolean ok = true;
|
||||
for ( String file : files ) {
|
||||
Iterator<String> inIter = infiles.iterator();
|
||||
Iterator<String> outIter = outfiles.iterator();
|
||||
|
||||
for (; inIter.hasNext(); ) {
|
||||
String infile = inIter.next();
|
||||
String outfile = outIter.next();
|
||||
|
||||
Properties prop = new Properties();
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new BufferedInputStream(new FileInputStream(file));
|
||||
in = new BufferedInputStream(new FileInputStream(infile));
|
||||
prop.load(in);
|
||||
} catch ( FileNotFoundException e ) {
|
||||
error("Cannot access file " + file, e);
|
||||
error("Cannot access file " + infile, e);
|
||||
ok = false;
|
||||
} catch ( IOException e ) {
|
||||
error("IO exception processing file " + file, e);
|
||||
error("IO exception processing file " + infile, e);
|
||||
ok = false;
|
||||
}
|
||||
if ( in != null ) {
|
||||
try {
|
||||
in.close();
|
||||
} catch ( IOException e ) {
|
||||
error("IO exception closing file " + file, e);
|
||||
error("IO exception closing file " + infile, e);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
@ -138,18 +146,18 @@ public class StripProperties {
|
||||
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
out = new FileOutputStream(outfile);
|
||||
storeProperties(prop, out);
|
||||
out.flush();
|
||||
} catch ( IOException e ) {
|
||||
error("IO exception processing file " + file, e);
|
||||
error("IO exception processing file " + outfile, e);
|
||||
ok = false;
|
||||
}
|
||||
if ( out != null ) {
|
||||
try {
|
||||
out.close();
|
||||
} catch ( IOException e ) {
|
||||
error("IO exception closing file " + file, e);
|
||||
error("IO exception closing file " + outfile, e);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
@ -166,8 +174,8 @@ public class StripProperties {
|
||||
* @param args Names of properties files to process and replace contents
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
List<String> files = parseOptions(args);
|
||||
if ( files == null || !stripFiles(files) ) {
|
||||
boolean ok = parseOptions(args);
|
||||
if ( !ok || !stripFiles(infiles, outfiles) ) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@ -246,7 +254,7 @@ public class StripProperties {
|
||||
throws IOException {
|
||||
BufferedWriter awriter;
|
||||
awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
|
||||
for (Enumeration e = properties.keys(); e.hasMoreElements();) {
|
||||
for (Enumeration<Object> e = properties.keys(); e.hasMoreElements();) {
|
||||
String key = (String)e.nextElement();
|
||||
String val = (String)properties.get(key);
|
||||
key = saveConvert(key, true);
|
||||
@ -34,7 +34,7 @@ PROGRAM = stripproperties
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
|
||||
BUILDTOOL_MAIN = $(PKGDIR)/StripProperties.java
|
||||
BUILDTOOL_MAIN = $(PKGDIR)/StripPropertiesCorba.java
|
||||
|
||||
#
|
||||
# Build tool jar rules.
|
||||
|
||||
@ -229,3 +229,10 @@ f92a171cf0071ca6c3fa8231d7d570377f8b2f4d hs23-b16
|
||||
b183b0863611b85dbac16f3b08b40ba978756d19 jdk8-b28
|
||||
030b5306d60f140e822e4a6d301744cb110ff0c8 hs24-b02
|
||||
b45b5c564098c58ea69e7cff3f7d341f0254dd1d jdk8-b29
|
||||
d61761bf305031c94f7f8eca49abd978b7d3c5da jdk8-b30
|
||||
dfae0140457cfb2c381d7679735fbedbae862c62 hs24-b03
|
||||
f4767e53d6e0d5da7e3f1775904076cce54247c1 hs24-b04
|
||||
0cd147eaa673d1642b2f466f5dc257cf192db524 jdk8-b31
|
||||
27863e4586de38be7dd17da4163f542038f4d1d7 hs24-b05
|
||||
25410a347ebb0bef166c4338a90d9dea82463a20 jdk8-b32
|
||||
cd47da9383cd932cb2b659064057feafa2a91134 hs24-b06
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2012, 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
|
||||
@ -217,8 +217,8 @@ abstract class ConnectorImpl implements Connector {
|
||||
}
|
||||
|
||||
protected void checkNativeLink(SecurityManager sm, String os) {
|
||||
if (os.equals("SunOS") || os.equals("Linux")) {
|
||||
// link "saproc" - SA native library on SunOS and Linux?
|
||||
if (os.equals("SunOS") || os.equals("Linux") || os.contains("OS X")) {
|
||||
// link "saproc" - SA native library on SunOS, Linux, and Mac OS X
|
||||
sm.checkLink("saproc");
|
||||
} else if (os.startsWith("Windows")) {
|
||||
// link "sawindbg" - SA native library on Windows.
|
||||
|
||||
@ -359,6 +359,12 @@ public class InstanceKlass extends Klass {
|
||||
public static final int innerClassNextOffset = 4;
|
||||
};
|
||||
|
||||
public static interface EnclosingMethodAttributeOffset {
|
||||
public static final int enclosing_method_class_index_offset = 0;
|
||||
public static final int enclosing_method_method_index_offset = 1;
|
||||
public static final int enclosing_method_attribute_size = 2;
|
||||
};
|
||||
|
||||
// refer to compute_modifier_flags in VM code.
|
||||
public long computeModifierFlags() {
|
||||
long access = getAccessFlags();
|
||||
@ -367,9 +373,14 @@ public class InstanceKlass extends Klass {
|
||||
int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
|
||||
if (length > 0) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
|
||||
Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
|
||||
length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
|
||||
"just checking");
|
||||
}
|
||||
for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
|
||||
if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
|
||||
break;
|
||||
}
|
||||
int ioff = innerClassList.getShortAt(i +
|
||||
InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
|
||||
// 'ioff' can be zero.
|
||||
@ -419,9 +430,14 @@ public class InstanceKlass extends Klass {
|
||||
int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
|
||||
if (length > 0) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
|
||||
Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
|
||||
length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
|
||||
"just checking");
|
||||
}
|
||||
for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
|
||||
if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
|
||||
break;
|
||||
}
|
||||
int ioff = innerClassList.getShortAt(i +
|
||||
InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
|
||||
// 'ioff' can be zero.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -43,7 +43,7 @@ public class PlatformInfo {
|
||||
return "bsd";
|
||||
} else if (os.equals("OpenBSD")) {
|
||||
return "bsd";
|
||||
} else if (os.equals("Darwin") || os.startsWith("Mac OS X")) {
|
||||
} else if (os.equals("Darwin") || os.contains("OS X")) {
|
||||
return "bsd";
|
||||
} else if (os.startsWith("Windows")) {
|
||||
return "win32";
|
||||
@ -52,17 +52,17 @@ public class PlatformInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns "sparc" if on SPARC, "x86" if on x86. */
|
||||
/* Returns "sparc" for SPARC based platforms and "x86" for x86 based
|
||||
platforms. Otherwise returns the value of os.arch. If the value
|
||||
is not recognized as supported, an exception is thrown instead. */
|
||||
public static String getCPU() throws UnsupportedPlatformException {
|
||||
String cpu = System.getProperty("os.arch");
|
||||
if (cpu.equals("i386")) {
|
||||
if (cpu.equals("i386") || cpu.equals("x86")) {
|
||||
return "x86";
|
||||
} else if (cpu.equals("sparc") || cpu.equals("x86") || cpu.equals("ia64")) {
|
||||
return cpu;
|
||||
} else if (cpu.equals("sparcv9")) {
|
||||
} else if (cpu.equals("sparc") || cpu.equals("sparcv9")) {
|
||||
return "sparc";
|
||||
} else if (cpu.equals("x86_64") || cpu.equals("amd64")) {
|
||||
return "amd64";
|
||||
} else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64")) {
|
||||
return cpu;
|
||||
} else {
|
||||
throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
|
||||
}
|
||||
|
||||
@ -271,23 +271,25 @@ KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
|
||||
ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
|
||||
SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
|
||||
|
||||
# Misc files and generated files need to come from C1 or C2 area
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
MISC_DIR=$(SHARK_DIR)
|
||||
GEN_DIR=$(SHARK_BASE_DIR)/generated
|
||||
else
|
||||
MISC_DIR=$(ZERO_DIR)
|
||||
GEN_DIR=$(ZERO_BASE_DIR)/generated
|
||||
ifeq ($(JVM_VARIANT_SERVER), true)
|
||||
MISC_DIR=$(C2_DIR)
|
||||
GEN_DIR=$(C2_BASE_DIR)/generated
|
||||
endif
|
||||
else
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
MISC_DIR=$(C1_DIR)
|
||||
GEN_DIR=$(C1_BASE_DIR)/generated
|
||||
else
|
||||
MISC_DIR=$(C2_DIR)
|
||||
GEN_DIR=$(C2_BASE_DIR)/generated
|
||||
ifeq ($(JVM_VARIANT_CLIENT), true)
|
||||
MISC_DIR=$(C1_DIR)
|
||||
GEN_DIR=$(C1_BASE_DIR)/generated
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL), true)
|
||||
MISC_DIR=$(C2_DIR)
|
||||
GEN_DIR=$(C2_BASE_DIR)/generated
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
MISC_DIR=$(SHARK_DIR)
|
||||
GEN_DIR=$(SHARK_BASE_DIR)/generated
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
MISC_DIR=$(ZERO_DIR)
|
||||
GEN_DIR=$(ZERO_BASE_DIR)/generated
|
||||
endif
|
||||
|
||||
# Bin files (windows)
|
||||
@ -332,52 +334,55 @@ endif
|
||||
|
||||
# Shared Library
|
||||
ifneq ($(OSNAME),windows)
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
else
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
ifeq ($(JVM_VARIANT_SERVER), true)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_CLIENT), true)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
endif
|
||||
else
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
|
||||
$(install-file)
|
||||
|
||||
# Debug info for shared library
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_CLIENT_DIR)/64/%.debuginfo: $(C1_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
$(EXPORT_SERVER_DIR)/64/%.debuginfo: $(C2_DIR)/%.debuginfo
|
||||
$(install-file)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Jar file (sa-jdi.jar)
|
||||
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
|
||||
$(install-file)
|
||||
|
||||
$(EXPORT_JRE_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
|
||||
$(install-file)
|
||||
|
||||
# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
|
||||
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
|
||||
$(install-file)
|
||||
@ -447,18 +452,19 @@ $(JDK_IMAGE_DIR)/jre/lib/rt.jar:
|
||||
($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
|
||||
|
||||
test_jdk:
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
ifneq ($(ZERO_BUILD), true)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d32 -client -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d32 -client -version
|
||||
endif
|
||||
$(JDK_IMAGE_DIR)/bin/java -d32 -server -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d32 -server -version
|
||||
endif
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d64 -server -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d64 -server -version
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_CLIENT), true)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -version
|
||||
endif
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_SERVER)\
|
||||
$(JVM_VARIANT_ZERO)$(JVM_VARIANT_ZEROSHARK)), true)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -version
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL), true)
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -Xinternalversion
|
||||
$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -version
|
||||
endif
|
||||
|
||||
copy_product_jdk::
|
||||
$(RM) -r $(JDK_IMAGE_DIR)
|
||||
|
||||
@ -188,7 +188,7 @@ VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
|
||||
# in the build.sh script:
|
||||
TARGETS = debug jvmg fastdebug optimized profiled product
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
|
||||
else
|
||||
SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
|
||||
|
||||
@ -69,7 +69,7 @@ QUIETLY$(MAKE_VERBOSE) = @
|
||||
# For now, until the compiler is less wobbly:
|
||||
TESTFLAGS = -Xbatch -showversion
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
|
||||
else
|
||||
ifdef USE_SUNCC
|
||||
|
||||
@ -38,7 +38,7 @@ else
|
||||
endif
|
||||
|
||||
# zero
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
MAKE_ARGS += LP64=1
|
||||
endif
|
||||
@ -124,6 +124,18 @@ ifeq ($(ARCH), ppc)
|
||||
HS_ARCH = ppc
|
||||
endif
|
||||
|
||||
# On 32 bit bsd we build server and client, on 64 bit just server.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
JVM_VARIANTS:=client,server
|
||||
JVM_VARIANT_CLIENT:=true
|
||||
JVM_VARIANT_SERVER:=true
|
||||
else
|
||||
JVM_VARIANTS:=server
|
||||
JVM_VARIANT_SERVER:=true
|
||||
endif
|
||||
endif
|
||||
|
||||
JDK_INCLUDE_SUBDIR=bsd
|
||||
|
||||
# Library suffix
|
||||
@ -144,16 +156,16 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
|
||||
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
|
||||
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
|
||||
|
||||
ifndef BUILD_CLIENT_ONLY
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
|
||||
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
endif
|
||||
|
||||
ifneq ($(ZERO_BUILD), true)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_CLIENT),true)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
endif
|
||||
|
||||
# Serviceability Binaries
|
||||
|
||||
@ -105,11 +105,12 @@ VM_PICFLAG/LIBJVM = $(PICFLAG)
|
||||
VM_PICFLAG/AOUT =
|
||||
VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
CFLAGS += $(LIBFFI_CFLAGS)
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
CFLAGS += $(LIBFFI_CFLAGS)
|
||||
endif
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
CFLAGS += $(LLVM_CFLAGS)
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
CFLAGS += $(LIBFFI_CFLAGS)
|
||||
CFLAGS += $(LLVM_CFLAGS)
|
||||
endif
|
||||
CFLAGS += $(VM_PICFLAG)
|
||||
CFLAGS += -fno-rtti
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,7 @@ DEP_DIR = $(GENERATED)/dependencies
|
||||
-include $(DEP_DIR)/*.d
|
||||
|
||||
# read machine-specific adjustments (%%% should do this via buildtree.make?)
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
include $(MAKEFILES_DIR)/zeroshark.make
|
||||
else
|
||||
include $(MAKEFILES_DIR)/$(BUILDARCH).make
|
||||
@ -271,12 +271,12 @@ else
|
||||
|
||||
LIBS_VM += $(LIBS)
|
||||
endif
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
LIBS_VM += $(LIBFFI_LIBS)
|
||||
endif
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
LIBS_VM += $(LIBFFI_LIBS) $(LLVM_LIBS)
|
||||
LFLAGS_VM += $(LLVM_LDFLAGS)
|
||||
LIBS_VM += $(LLVM_LIBS)
|
||||
endif
|
||||
|
||||
|
||||
@ -335,6 +335,9 @@ include $(MAKEFILES_DIR)/jsig.make
|
||||
# Serviceability agent
|
||||
include $(MAKEFILES_DIR)/saproc.make
|
||||
|
||||
# Whitebox testing API
|
||||
include $(MAKEFILES_DIR)/wb.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
@ -342,10 +345,10 @@ $(LIBJVM).dSYM: $(LIBJVM)
|
||||
dsymutil $(LIBJVM)
|
||||
|
||||
# no libjvm_db for macosx
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM $(WB_JAR)
|
||||
echo "Doing vm.make build:"
|
||||
else
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
|
||||
endif
|
||||
|
||||
install: install_jvm install_jsig install_saproc
|
||||
|
||||
46
hotspot/make/bsd/makefiles/wb.make
Normal file
46
hotspot/make/bsd/makefiles/wb.make
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build whitebox testing library, used by vm.make
|
||||
WB = wb
|
||||
|
||||
WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
|
||||
|
||||
WB_JAR = $(GENERATED)/$(WB).jar
|
||||
|
||||
WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
|
||||
WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
|
||||
|
||||
WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
|
||||
$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
|
||||
|
||||
$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
|
||||
$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
|
||||
|
||||
$(WB_JAR): $(WB_JAVA_CLASSES)
|
||||
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
|
||||
|
||||
$(WB_JAVA_CLASSDIR):
|
||||
$(QUIETLY) mkdir -p $@
|
||||
|
||||
@ -55,6 +55,27 @@ define prep-target
|
||||
@$(RM) $@
|
||||
endef
|
||||
|
||||
# Default values for JVM_VARIANT* variables if configure hasn't set
|
||||
# it already.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
JVM_VARIANTS:=zeroshark
|
||||
JVM_VARIANT_ZEROSHARK:=true
|
||||
else
|
||||
JVM_VARIANTS:=zero
|
||||
JVM_VARIANT_ZERO:=true
|
||||
endif
|
||||
else
|
||||
# A default is needed
|
||||
ifeq ($(BUILD_CLIENT_ONLY), true)
|
||||
JVM_VARIANTS:=client
|
||||
JVM_VARIANT_CLIENT:=true
|
||||
endif
|
||||
# Further defaults are platform and arch specific
|
||||
endif
|
||||
endif
|
||||
|
||||
# Directory paths and user name
|
||||
# Unless GAMMADIR is set on the command line, search upward from
|
||||
# the current directory for a parent directory containing "src/share/vm".
|
||||
|
||||
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
|
||||
|
||||
HS_MAJOR_VER=24
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=02
|
||||
HS_BUILD_NUMBER=06
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2012, 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
|
||||
@ -54,58 +54,72 @@ jprt.sync.push=false
|
||||
# Define the Solaris platforms we want for the various releases
|
||||
jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
|
||||
jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
|
||||
jprt.my.solaris.sparc.jdk7u4=${jprt.my.solaris.sparc.jdk7}
|
||||
jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
|
||||
jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
|
||||
jprt.my.solaris.sparcv9.jdk7u4=${jprt.my.solaris.sparcv9.jdk7}
|
||||
jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.i586.jdk8=solaris_i586_5.10
|
||||
jprt.my.solaris.i586.jdk7=solaris_i586_5.10
|
||||
jprt.my.solaris.i586.jdk7u4=${jprt.my.solaris.i586.jdk7}
|
||||
jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.solaris.x64.jdk8=solaris_x64_5.10
|
||||
jprt.my.solaris.x64.jdk7=solaris_x64_5.10
|
||||
jprt.my.solaris.x64.jdk7u4=${jprt.my.solaris.x64.jdk7}
|
||||
jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.i586.jdk8=linux_i586_2.6
|
||||
jprt.my.linux.i586.jdk7=linux_i586_2.6
|
||||
jprt.my.linux.i586.jdk7u4=${jprt.my.linux.i586.jdk7}
|
||||
jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.x64.jdk8=linux_x64_2.6
|
||||
jprt.my.linux.x64.jdk7=linux_x64_2.6
|
||||
jprt.my.linux.x64.jdk7u4=${jprt.my.linux.x64.jdk7}
|
||||
jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.ppc.jdk8=linux_ppc_2.6
|
||||
jprt.my.linux.ppc.jdk7=linux_ppc_2.6
|
||||
jprt.my.linux.ppc.jdk7u4=${jprt.my.linux.ppc.jdk7}
|
||||
jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
|
||||
jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
|
||||
jprt.my.linux.ppcv2.jdk7u4=${jprt.my.linux.ppcv2.jdk7}
|
||||
jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
|
||||
jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
|
||||
jprt.my.linux.ppcsflt.jdk7u4=${jprt.my.linux.ppcsflt.jdk7}
|
||||
jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
|
||||
jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
|
||||
jprt.my.linux.armvfp.jdk7u4=${jprt.my.linux.armvfp.jdk7}
|
||||
jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
|
||||
jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
|
||||
jprt.my.linux.armsflt.jdk7u4=${jprt.my.linux.armsflt.jdk7}
|
||||
jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.macosx.x64.jdk8=macosx_x64_10.7
|
||||
jprt.my.macosx.x64.jdk7=macosx_x64_10.7
|
||||
jprt.my.macosx.x64.jdk7u4=${jprt.my.macosx.x64.jdk7}
|
||||
jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.windows.i586.jdk8=windows_i586_5.1
|
||||
jprt.my.windows.i586.jdk7=windows_i586_5.1
|
||||
jprt.my.windows.i586.jdk7u4=${jprt.my.windows.i586.jdk7}
|
||||
jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
|
||||
|
||||
jprt.my.windows.x64.jdk8=windows_x64_5.2
|
||||
jprt.my.windows.x64.jdk7=windows_x64_5.2
|
||||
jprt.my.windows.x64.jdk7u4=${jprt.my.windows.x64.jdk7}
|
||||
jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
|
||||
|
||||
# Standard list of jprt build targets for this source tree
|
||||
@ -139,16 +153,7 @@ jprt.build.targets.all=${jprt.build.targets.standard}, \
|
||||
|
||||
jprt.build.targets.jdk8=${jprt.build.targets.all}
|
||||
jprt.build.targets.jdk7=${jprt.build.targets.all}
|
||||
jprt.build.targets.jdk7temp=${jprt.build.targets.all}
|
||||
jprt.build.targets.jdk7b107=${jprt.build.targets.all}
|
||||
jprt.build.targets.jdk6=${jprt.build.targets.standard}
|
||||
jprt.build.targets.jdk6perf=${jprt.build.targets.standard}
|
||||
jprt.build.targets.jdk6u10=${jprt.build.targets.standard}
|
||||
jprt.build.targets.jdk6u14=${jprt.build.targets.standard}
|
||||
jprt.build.targets.jdk6u18=${jprt.build.targets.standard}
|
||||
jprt.build.targets.jdk6u20=${jprt.build.targets.standard}
|
||||
jprt.build.targets.ejdk6=${jprt.build.targets.all}
|
||||
jprt.build.targets.ejdk7=${jprt.build.targets.all}
|
||||
jprt.build.targets.jdk7u4=${jprt.build.targets.all}
|
||||
jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
|
||||
|
||||
# Subset lists of test targets for this source tree
|
||||
@ -441,6 +446,7 @@ jprt.test.targets.embedded= \
|
||||
|
||||
jprt.test.targets.jdk8=${jprt.test.targets.standard}
|
||||
jprt.test.targets.jdk7=${jprt.test.targets.standard}
|
||||
jprt.test.targets.jdk7u4=${jprt.test.targets.jdk7}
|
||||
jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
|
||||
|
||||
# The default test/Makefile targets that should be run
|
||||
@ -474,16 +480,32 @@ jprt.make.rule.test.targets.standard.internalvmtests = \
|
||||
${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
|
||||
${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
|
||||
|
||||
|
||||
jprt.make.rule.test.targets.standard.wbapi = \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
|
||||
${jprt.my.solaris.sparc}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.solaris.i586}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
|
||||
${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
|
||||
|
||||
jprt.make.rule.test.targets.standard = \
|
||||
${jprt.make.rule.test.targets.standard.client}, \
|
||||
${jprt.make.rule.test.targets.standard.server}, \
|
||||
${jprt.make.rule.test.targets.standard.internalvmtests}
|
||||
${jprt.make.rule.test.targets.standard.internalvmtests}, \
|
||||
${jprt.make.rule.test.targets.standard.wbapi}
|
||||
|
||||
jprt.make.rule.test.targets.embedded = \
|
||||
${jprt.make.rule.test.targets.standard.client}
|
||||
|
||||
jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
|
||||
jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
|
||||
jprt.make.rule.test.targets.jdk7u4=${jprt.make.rule.test.targets.jdk7}
|
||||
jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
|
||||
|
||||
|
||||
@ -188,7 +188,7 @@ VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
|
||||
# in the build.sh script:
|
||||
TARGETS = debug jvmg fastdebug optimized profiled product
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
|
||||
else
|
||||
SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
|
||||
|
||||
@ -66,7 +66,7 @@ QUIETLY$(MAKE_VERBOSE) = @
|
||||
# For now, until the compiler is less wobbly:
|
||||
TESTFLAGS = -Xbatch -showversion
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
|
||||
else
|
||||
ifdef USE_SUNCC
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,7 @@ else
|
||||
endif
|
||||
|
||||
# zero
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||
MAKE_ARGS += LP64=1
|
||||
endif
|
||||
@ -114,6 +114,18 @@ ifeq ($(ARCH), ppc)
|
||||
HS_ARCH = ppc
|
||||
endif
|
||||
|
||||
# On 32 bit linux we build server and client, on 64 bit just server.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
JVM_VARIANTS:=client,server
|
||||
JVM_VARIANT_CLIENT:=true
|
||||
JVM_VARIANT_SERVER:=true
|
||||
else
|
||||
JVM_VARIANTS:=server
|
||||
JVM_VARIANT_SERVER:=true
|
||||
endif
|
||||
endif
|
||||
|
||||
# determine if HotSpot is being built in JDK6 or earlier version
|
||||
JDK6_OR_EARLIER=0
|
||||
ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
|
||||
@ -193,22 +205,22 @@ endif
|
||||
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
|
||||
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
|
||||
|
||||
ifndef BUILD_CLIENT_ONLY
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
|
||||
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(ZERO_BUILD), true)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_CLIENT),true)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
|
||||
endif
|
||||
endif
|
||||
|
||||
# Serviceability Binaries
|
||||
|
||||
@ -72,10 +72,11 @@ VM_PICFLAG/LIBJVM = $(PICFLAG)
|
||||
VM_PICFLAG/AOUT =
|
||||
VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
|
||||
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
CFLAGS += $(LIBFFI_CFLAGS)
|
||||
endif
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
CFLAGS += $(LIBFFI_CFLAGS)
|
||||
CFLAGS += $(LLVM_CFLAGS)
|
||||
endif
|
||||
CFLAGS += $(VM_PICFLAG)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,7 +42,7 @@ DEP_DIR = $(GENERATED)/dependencies
|
||||
-include $(DEP_DIR)/*.d
|
||||
|
||||
# read machine-specific adjustments (%%% should do this via buildtree.make?)
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
|
||||
include $(MAKEFILES_DIR)/zeroshark.make
|
||||
else
|
||||
include $(MAKEFILES_DIR)/$(BUILDARCH).make
|
||||
@ -236,7 +236,7 @@ mapfile_reorder : mapfile $(REORDERFILE)
|
||||
vm.def: $(Res_Files) $(Obj_Files)
|
||||
sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
|
||||
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
STATIC_CXX = false
|
||||
else
|
||||
ifeq ($(ZERO_LIBARCH), ppc64)
|
||||
@ -268,12 +268,12 @@ else
|
||||
|
||||
LIBS_VM += $(LIBS)
|
||||
endif
|
||||
ifeq ($(ZERO_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZERO), true)
|
||||
LIBS_VM += $(LIBFFI_LIBS)
|
||||
endif
|
||||
ifeq ($(SHARK_BUILD), true)
|
||||
ifeq ($(JVM_VARIANT_ZEROSHARK), true)
|
||||
LIBS_VM += $(LIBFFI_LIBS) $(LLVM_LIBS)
|
||||
LFLAGS_VM += $(LLVM_LDFLAGS)
|
||||
LIBS_VM += $(LLVM_LIBS)
|
||||
endif
|
||||
|
||||
LINK_VM = $(LINK_LIB.CC)
|
||||
@ -368,9 +368,12 @@ include $(MAKEFILES_DIR)/jsig.make
|
||||
# Serviceability agent
|
||||
include $(MAKEFILES_DIR)/saproc.make
|
||||
|
||||
# Whitebox testing API
|
||||
include $(MAKEFILES_DIR)/wb.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
|
||||
|
||||
install: install_jvm install_jsig install_saproc
|
||||
|
||||
|
||||
46
hotspot/make/linux/makefiles/wb.make
Normal file
46
hotspot/make/linux/makefiles/wb.make
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build whitebox testing library, used by vm.make
|
||||
WB = wb
|
||||
|
||||
WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
|
||||
|
||||
WB_JAR = $(GENERATED)/$(WB).jar
|
||||
|
||||
WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
|
||||
WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
|
||||
|
||||
WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
|
||||
$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
|
||||
|
||||
$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
|
||||
$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
|
||||
|
||||
$(WB_JAR): $(WB_JAVA_CLASSES)
|
||||
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
|
||||
|
||||
$(WB_JAVA_CLASSDIR):
|
||||
$(QUIETLY) mkdir -p $@
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2012, 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
|
||||
@ -59,6 +59,18 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# On 32 bit solaris we build server and client, on 64 bit just server.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
JVM_VARIANTS:=client,server
|
||||
JVM_VARIANT_CLIENT:=true
|
||||
JVM_VARIANT_SERVER:=true
|
||||
else
|
||||
JVM_VARIANTS:=server
|
||||
JVM_VARIANT_SERVER:=true
|
||||
endif
|
||||
endif
|
||||
|
||||
# determine if HotSpot is being built in JDK6 or earlier version
|
||||
JDK6_OR_EARLIER=0
|
||||
ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
|
||||
@ -148,40 +160,42 @@ ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.debuginfo
|
||||
endif
|
||||
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
|
||||
|
||||
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
|
||||
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
|
||||
|
||||
ifneq ($(BUILD_CLIENT_ONLY),true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
ifeq ($(JVM_VARIANT_SERVER),true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
ifeq ($(ARCH_DATA_MODEL),32)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
endif
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.debuginfo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
ifeq ($(JVM_VARIANT_CLIENT),true)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
ifeq ($(ARCH_DATA_MODEL),32)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
endif
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
|
||||
endif
|
||||
ifneq ($(BUILD_CLIENT_ONLY), true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
|
||||
ifneq ($(OBJCOPY),)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo
|
||||
ifeq ($(ARCH_DATA_MODEL),32)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1998, 2012, 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
|
||||
@ -321,9 +321,12 @@ include $(MAKEFILES_DIR)/jsig.make
|
||||
# Serviceability agent
|
||||
include $(MAKEFILES_DIR)/saproc.make
|
||||
|
||||
# Whitebox testing API
|
||||
include $(MAKEFILES_DIR)/wb.make
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck
|
||||
build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
|
||||
|
||||
install: install_jvm install_jsig install_saproc
|
||||
|
||||
|
||||
46
hotspot/make/solaris/makefiles/wb.make
Normal file
46
hotspot/make/solaris/makefiles/wb.make
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
|
||||
# Rules to build whitebox testing library, used by vm.make
|
||||
|
||||
WB = wb
|
||||
|
||||
WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
|
||||
|
||||
WB_JAR = $(GENERATED)/$(WB).jar
|
||||
|
||||
WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
|
||||
WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
|
||||
|
||||
WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
|
||||
$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
|
||||
|
||||
$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
|
||||
$(REMOTE) $(COMPILE.JAVAC) -nowarn -d $(WB_JAVA_CLASSDIR) $<
|
||||
|
||||
$(WB_JAR): $(WB_JAVA_CLASSES)
|
||||
$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
|
||||
|
||||
$(WB_JAVA_CLASSDIR):
|
||||
$(QUIETLY) mkdir -p $@
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1997, 2012, 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
|
||||
@ -33,7 +33,7 @@ GENERATED=../generated
|
||||
BUILD_PCH_FILE=_build_pch_file.obj
|
||||
!endif
|
||||
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
|
||||
|
||||
!include ../local.make
|
||||
!include compile.make
|
||||
@ -65,3 +65,4 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
|
||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/launcher.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/wb.make
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2012, 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
|
||||
@ -107,6 +107,19 @@ ifneq ($(shell $(ECHO) $(PROCESSOR_IDENTIFIER) | $(GREP) EM64T),)
|
||||
endif
|
||||
endif
|
||||
|
||||
# On 32 bit windows we build server, client and kernel, on 64 bit just server.
|
||||
ifeq ($(JVM_VARIANTS),)
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
JVM_VARIANTS:=client,server,kernel
|
||||
JVM_VARIANT_CLIENT:=true
|
||||
JVM_VARIANT_SERVER:=true
|
||||
JVM_VARIANT_KERNEL:=true
|
||||
else
|
||||
JVM_VARIANTS:=server
|
||||
JVM_VARIANT_SERVER:=true
|
||||
endif
|
||||
endif
|
||||
|
||||
JDK_INCLUDE_SUBDIR=win32
|
||||
|
||||
# Library suffix
|
||||
@ -177,23 +190,28 @@ EXPORT_SERVER_DIR = $(EXPORT_JRE_BIN_DIR)/server
|
||||
EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
|
||||
EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
|
||||
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
|
||||
EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
|
||||
ifeq ($(ARCH_DATA_MODEL), 32)
|
||||
ifeq ($(JVM_VARIANT_SERVER),true)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
|
||||
EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
|
||||
EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_CLIENT),true)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.pdb
|
||||
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
|
||||
# kernel vm
|
||||
endif
|
||||
ifeq ($(JVM_VARIANT_KERNEL),true)
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.pdb
|
||||
EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.map
|
||||
endif
|
||||
|
||||
EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
|
||||
|
||||
ifeq ($(BUILD_WIN_SA), 1)
|
||||
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
|
||||
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2012, 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
|
||||
@ -33,7 +33,7 @@ GENERATED=../generated
|
||||
BUILD_PCH_FILE=_build_pch_file.obj
|
||||
!endif
|
||||
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
|
||||
|
||||
!include ../local.make
|
||||
!include compile.make
|
||||
@ -65,3 +65,4 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
|
||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/launcher.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/wb.make
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 2012, 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
|
||||
@ -32,7 +32,7 @@ GENERATED=../generated
|
||||
BUILD_PCH_FILE=_build_pch_file.obj
|
||||
!endif
|
||||
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
|
||||
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
|
||||
|
||||
!include ../local.make
|
||||
!include compile.make
|
||||
@ -76,3 +76,4 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def
|
||||
!include $(WorkSpace)/make/windows/makefiles/shared.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/launcher.make
|
||||
!include $(WorkSpace)/make/windows/makefiles/wb.make
|
||||
|
||||
54
hotspot/make/windows/makefiles/wb.make
Normal file
54
hotspot/make/windows/makefiles/wb.make
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# This makefile is used to build the whitebox testing lib
|
||||
# and compile the tests which use it
|
||||
|
||||
!include $(WorkSpace)/make/windows/makefiles/rules.make
|
||||
|
||||
WBSRCDIR = $(WorkSpace)/src/share/tools/whitebox
|
||||
|
||||
# turn GENERATED into a windows path to get sane dependencies
|
||||
WB_CLASSES=$(GENERATED:/=\)\wb\classes
|
||||
WB_JAR=$(GENERATED:/=\)\wb.jar
|
||||
|
||||
# call recursive make to do wildcard expansion
|
||||
.SUFFIXES : .java .class
|
||||
wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLASSES)
|
||||
$(MAKE) -f $(WorkSpace)\make\windows\makefiles\$(BUILD_FLAVOR).make $(**:.java=.class)
|
||||
|
||||
|
||||
{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class::
|
||||
$(COMPILE_JAVAC) -d $(WB_CLASSES) $<
|
||||
|
||||
$(WB_JAR): wb_java_srcs
|
||||
$(RUN_JAR) cf $@ -C $(WB_CLASSES) .
|
||||
|
||||
# turn $@ to a unix path because mkdir in PATH is cygwin/mks mkdir
|
||||
$(WB_CLASSES):
|
||||
mkdir -p $(@:\=/)
|
||||
|
||||
# main target to build wb
|
||||
wb: $(WB_JAR)
|
||||
|
||||
@ -2221,7 +2221,7 @@ public:
|
||||
// traps as per trap.h (SPARC ABI?)
|
||||
|
||||
void breakpoint_trap();
|
||||
void breakpoint_trap(Condition c, CC cc = icc);
|
||||
void breakpoint_trap(Condition c, CC cc);
|
||||
void flush_windows_trap();
|
||||
void clean_windows_trap();
|
||||
void get_psr_trap();
|
||||
|
||||
@ -1187,7 +1187,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
|
||||
#ifdef ASSERT
|
||||
__ tst(O1);
|
||||
__ breakpoint_trap(Assembler::zero);
|
||||
__ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
|
||||
#endif // ASSERT
|
||||
|
||||
const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
|
||||
|
||||
@ -3325,7 +3325,7 @@ static void gen_new_frame(MacroAssembler* masm, bool deopt) {
|
||||
// make sure that the frames are aligned properly
|
||||
#ifndef _LP64
|
||||
__ btst(wordSize*2-1, SP);
|
||||
__ breakpoint_trap(Assembler::notZero);
|
||||
__ breakpoint_trap(Assembler::notZero, Assembler::ptr_cc);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -3407,7 +3407,7 @@ static void make_new_frames(MacroAssembler* masm, bool deopt) {
|
||||
#ifdef ASSERT
|
||||
// make sure that there is at least one entry in the array
|
||||
__ tst(O4array_size);
|
||||
__ breakpoint_trap(Assembler::zero);
|
||||
__ breakpoint_trap(Assembler::zero, Assembler::icc);
|
||||
#endif
|
||||
|
||||
// Now push the new interpreter frames
|
||||
|
||||
@ -1832,6 +1832,8 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||
case Op_CountLeadingZerosL:
|
||||
case Op_CountTrailingZerosI:
|
||||
case Op_CountTrailingZerosL:
|
||||
case Op_PopCountI:
|
||||
case Op_PopCountL:
|
||||
if (!UsePopCountInstruction)
|
||||
return false;
|
||||
break;
|
||||
|
||||
@ -379,7 +379,7 @@ void InterpreterGenerator::lock_method(void) {
|
||||
|
||||
#ifdef ASSERT
|
||||
__ tst(O0);
|
||||
__ breakpoint_trap(Assembler::zero);
|
||||
__ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
|
||||
#endif // ASSERT
|
||||
|
||||
__ bind(done);
|
||||
@ -2050,7 +2050,7 @@ void TemplateInterpreterGenerator::stop_interpreter_at() {
|
||||
AddressLiteral stop_at(&StopInterpreterAt);
|
||||
__ load_ptr_contents(stop_at, G4_scratch);
|
||||
__ cmp(G3_scratch, G4_scratch);
|
||||
__ breakpoint_trap(Assembler::equal);
|
||||
__ breakpoint_trap(Assembler::equal, Assembler::icc);
|
||||
}
|
||||
#endif // not PRODUCT
|
||||
#endif // !CC_INTERP
|
||||
|
||||
@ -1293,6 +1293,14 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||
if (!has_match_rule(opcode))
|
||||
return false;
|
||||
|
||||
switch (opcode) {
|
||||
case Op_PopCountI:
|
||||
case Op_PopCountL:
|
||||
if (!UsePopCountInstruction)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
}
|
||||
|
||||
|
||||
@ -1714,6 +1714,14 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||
if (!has_match_rule(opcode))
|
||||
return false;
|
||||
|
||||
switch (opcode) {
|
||||
case Op_PopCountI:
|
||||
case Op_PopCountL:
|
||||
if (!UsePopCountInstruction)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2012, 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
|
||||
@ -206,10 +206,15 @@ int BsdAttachListener::init() {
|
||||
// put in listen mode, set permissions, and rename into place
|
||||
res = ::listen(listener, 5);
|
||||
if (res == 0) {
|
||||
RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
|
||||
RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
|
||||
if (res == 0) {
|
||||
// make sure the file is owned by the effective user and effective group
|
||||
// (this is the default on linux, but not on mac os)
|
||||
RESTARTABLE(::chown(initial_path, geteuid(), getegid()), res);
|
||||
if (res == 0) {
|
||||
res = ::rename(initial_path, path);
|
||||
res = ::rename(initial_path, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res == -1) {
|
||||
RESTARTABLE(::close(listener), res);
|
||||
|
||||
@ -2547,7 +2547,14 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
|
||||
}
|
||||
|
||||
void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
|
||||
commit_memory(addr, bytes, alignment_hint, false);
|
||||
// This method works by doing an mmap over an existing mmaping and effectively discarding
|
||||
// the existing pages. However it won't work for SHM-based large pages that cannot be
|
||||
// uncommitted at all. We don't do anything in this case to avoid creating a segment with
|
||||
// small pages on top of the SHM segment. This method always works for small pages, so we
|
||||
// allow that in any case.
|
||||
if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
|
||||
commit_memory(addr, bytes, alignment_hint, false);
|
||||
}
|
||||
}
|
||||
|
||||
void os::numa_make_global(char *addr, size_t bytes) {
|
||||
|
||||
70
hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
Normal file
70
hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 sun.hotspot;
|
||||
import java.security.BasicPermission;
|
||||
|
||||
public class WhiteBox {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class WhiteBoxPermission extends BasicPermission {
|
||||
public WhiteBoxPermission(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
private WhiteBox() {}
|
||||
private static final WhiteBox instance = new WhiteBox();
|
||||
private static native void registerNatives();
|
||||
|
||||
/**
|
||||
* Returns the singleton WhiteBox instance.
|
||||
*
|
||||
* The returned WhiteBox object should be carefully guarded
|
||||
* by the caller, since it can be used to read and write data
|
||||
* at arbitrary memory addresses. It must never be passed to
|
||||
* untrusted code.
|
||||
*/
|
||||
public synchronized static WhiteBox getWhiteBox() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new WhiteBoxPermission("getInstance"));
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static {
|
||||
registerNatives();
|
||||
}
|
||||
|
||||
// Memory
|
||||
public native long getObjectAddress(Object o);
|
||||
public native int getHeapOopSize();
|
||||
|
||||
// G1
|
||||
public native boolean g1InConcurrentMark();
|
||||
public native boolean g1IsHumongous(Object o);
|
||||
public native long g1NumFreeRegions();
|
||||
public native int g1RegionSize();
|
||||
}
|
||||
@ -1306,6 +1306,7 @@ void GraphBuilder::table_switch() {
|
||||
if (sw.dest_offset_at(i) < 0) has_bb = true;
|
||||
}
|
||||
// add default successor
|
||||
if (sw.default_offset() < 0) has_bb = true;
|
||||
sux->at_put(i, block_at(bci() + sw.default_offset()));
|
||||
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
||||
Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
|
||||
@ -1350,6 +1351,7 @@ void GraphBuilder::lookup_switch() {
|
||||
keys->at_put(i, pair.match());
|
||||
}
|
||||
// add default successor
|
||||
if (sw.default_offset() < 0) has_bb = true;
|
||||
sux->at_put(i, block_at(bci() + sw.default_offset()));
|
||||
ValueStack* state_before = has_bb ? copy_state_before() : NULL;
|
||||
Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
|
||||
|
||||
@ -2315,13 +2315,32 @@ void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantP
|
||||
#define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
|
||||
|
||||
// Return number of classes in the inner classes attribute table
|
||||
u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
|
||||
u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
|
||||
bool parsed_enclosingmethod_attribute,
|
||||
u2 enclosing_method_class_index,
|
||||
u2 enclosing_method_method_index,
|
||||
constantPoolHandle cp,
|
||||
instanceKlassHandle k, TRAPS) {
|
||||
ClassFileStream* cfs = stream();
|
||||
cfs->guarantee_more(2, CHECK_0); // length
|
||||
u2 length = cfs->get_u2_fast();
|
||||
u1* current_mark = cfs->current();
|
||||
u2 length = 0;
|
||||
if (inner_classes_attribute_start != NULL) {
|
||||
cfs->set_current(inner_classes_attribute_start);
|
||||
cfs->guarantee_more(2, CHECK_0); // length
|
||||
length = cfs->get_u2_fast();
|
||||
}
|
||||
|
||||
// 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
|
||||
typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
|
||||
// 4-tuples of shorts of inner classes data and 2 shorts of enclosing
|
||||
// method data:
|
||||
// [inner_class_info_index,
|
||||
// outer_class_info_index,
|
||||
// inner_name_index,
|
||||
// inner_class_access_flags,
|
||||
// ...
|
||||
// enclosing_method_class_index,
|
||||
// enclosing_method_method_index]
|
||||
int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
|
||||
typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
|
||||
typeArrayHandle inner_classes(THREAD, ic);
|
||||
int index = 0;
|
||||
int cp_size = cp->length();
|
||||
@ -2372,8 +2391,8 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
||||
|
||||
// 4347400: make sure there's no duplicate entry in the classes array
|
||||
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
for(int i = 0; i < inner_classes->length(); i += 4) {
|
||||
for(int j = i + 4; j < inner_classes->length(); j += 4) {
|
||||
for(int i = 0; i < length * 4; i += 4) {
|
||||
for(int j = i + 4; j < length * 4; j += 4) {
|
||||
guarantee_property((inner_classes->ushort_at(i) != inner_classes->ushort_at(j) ||
|
||||
inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
|
||||
inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
|
||||
@ -2384,8 +2403,19 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
|
||||
}
|
||||
}
|
||||
|
||||
// Set EnclosingMethod class and method indexes.
|
||||
if (parsed_enclosingmethod_attribute) {
|
||||
inner_classes->short_at_put(index++, enclosing_method_class_index);
|
||||
inner_classes->short_at_put(index++, enclosing_method_method_index);
|
||||
}
|
||||
assert(index == size, "wrong size");
|
||||
|
||||
// Update instanceKlass with inner class info.
|
||||
k->set_inner_classes(inner_classes());
|
||||
|
||||
// Restore buffer's current position.
|
||||
cfs->set_current(current_mark);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -2490,6 +2520,10 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
||||
int runtime_visible_annotations_length = 0;
|
||||
u1* runtime_invisible_annotations = NULL;
|
||||
int runtime_invisible_annotations_length = 0;
|
||||
u1* inner_classes_attribute_start = NULL;
|
||||
u4 inner_classes_attribute_length = 0;
|
||||
u2 enclosing_method_class_index = 0;
|
||||
u2 enclosing_method_method_index = 0;
|
||||
// Iterate over attributes
|
||||
while (attributes_count--) {
|
||||
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
|
||||
@ -2522,11 +2556,9 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
||||
} else {
|
||||
parsed_innerclasses_attribute = true;
|
||||
}
|
||||
u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
|
||||
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
|
||||
"Wrong InnerClasses attribute length in class file %s", CHECK);
|
||||
}
|
||||
inner_classes_attribute_start = cfs->get_u1_buffer();
|
||||
inner_classes_attribute_length = attribute_length;
|
||||
cfs->skip_u1(inner_classes_attribute_length, CHECK);
|
||||
} else if (tag == vmSymbols::tag_synthetic()) {
|
||||
// Check for Synthetic tag
|
||||
// Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
|
||||
@ -2568,22 +2600,21 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
||||
parsed_enclosingmethod_attribute = true;
|
||||
}
|
||||
cfs->guarantee_more(4, CHECK); // class_index, method_index
|
||||
u2 class_index = cfs->get_u2_fast();
|
||||
u2 method_index = cfs->get_u2_fast();
|
||||
if (class_index == 0) {
|
||||
enclosing_method_class_index = cfs->get_u2_fast();
|
||||
enclosing_method_method_index = cfs->get_u2_fast();
|
||||
if (enclosing_method_class_index == 0) {
|
||||
classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
// Validate the constant pool indices and types
|
||||
if (!cp->is_within_bounds(class_index) ||
|
||||
!is_klass_reference(cp, class_index)) {
|
||||
if (!cp->is_within_bounds(enclosing_method_class_index) ||
|
||||
!is_klass_reference(cp, enclosing_method_class_index)) {
|
||||
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
if (method_index != 0 &&
|
||||
(!cp->is_within_bounds(method_index) ||
|
||||
!cp->tag_at(method_index).is_name_and_type())) {
|
||||
if (enclosing_method_method_index != 0 &&
|
||||
(!cp->is_within_bounds(enclosing_method_method_index) ||
|
||||
!cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
|
||||
classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
|
||||
}
|
||||
k->set_enclosing_method_indices(class_index, method_index);
|
||||
} else if (tag == vmSymbols::tag_bootstrap_methods() &&
|
||||
_major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
if (parsed_bootstrap_methods_attribute)
|
||||
@ -2606,6 +2637,20 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
|
||||
CHECK);
|
||||
k->set_class_annotations(annotations());
|
||||
|
||||
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
|
||||
u2 num_of_classes = parse_classfile_inner_classes_attribute(
|
||||
inner_classes_attribute_start,
|
||||
parsed_innerclasses_attribute,
|
||||
enclosing_method_class_index,
|
||||
enclosing_method_method_index,
|
||||
cp, k, CHECK);
|
||||
if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
|
||||
guarantee_property(
|
||||
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
|
||||
"Wrong InnerClasses attribute length in class file %s", CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
if (_max_bootstrap_specifier_index >= 0) {
|
||||
guarantee_property(parsed_bootstrap_methods_attribute,
|
||||
"Missing BootstrapMethods attribute in class file %s", CHECK);
|
||||
|
||||
@ -130,7 +130,11 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
void parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
|
||||
void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
|
||||
instanceKlassHandle k, int length, TRAPS);
|
||||
u2 parse_classfile_inner_classes_attribute(constantPoolHandle cp,
|
||||
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
|
||||
bool parsed_enclosingmethod_attribute,
|
||||
u2 enclosing_method_class_index,
|
||||
u2 enclosing_method_method_index,
|
||||
constantPoolHandle cp,
|
||||
instanceKlassHandle k, TRAPS);
|
||||
void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
|
||||
void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
|
||||
|
||||
@ -285,7 +285,7 @@ size_t CollectionSetChooser::calcMinOldCSetLength() {
|
||||
// that the result is the same during all mixed GCs that follow a cycle.
|
||||
|
||||
const size_t region_num = (size_t) _length;
|
||||
const size_t gc_num = (size_t) G1MaxMixedGCNum;
|
||||
const size_t gc_num = (size_t) G1MixedGCCountTarget;
|
||||
size_t result = region_num / gc_num;
|
||||
// emulate ceiling
|
||||
if (result * gc_num < region_num) {
|
||||
|
||||
@ -155,7 +155,7 @@ void ConcurrentMarkThread::run() {
|
||||
|
||||
CMCheckpointRootsFinalClosure final_cl(_cm);
|
||||
sprintf(verbose_str, "GC remark");
|
||||
VM_CGC_Operation op(&final_cl, verbose_str);
|
||||
VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */);
|
||||
VMThread::execute(&op);
|
||||
}
|
||||
if (cm()->restart_for_overflow() &&
|
||||
@ -189,7 +189,7 @@ void ConcurrentMarkThread::run() {
|
||||
|
||||
CMCleanUp cl_cl(_cm);
|
||||
sprintf(verbose_str, "GC cleanup");
|
||||
VM_CGC_Operation op(&cl_cl, verbose_str);
|
||||
VM_CGC_Operation op(&cl_cl, verbose_str, false /* needs_pll */);
|
||||
VMThread::execute(&op);
|
||||
} else {
|
||||
// We don't want to update the marking status if a GC pause
|
||||
|
||||
@ -993,7 +993,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
|
||||
// iteration (after taking the Heap_lock).
|
||||
result = _mutator_alloc_region.attempt_allocation(word_size,
|
||||
false /* bot_updates */);
|
||||
if (result != NULL ){
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2437,20 +2437,22 @@ void G1CollectedHeap::collect(GCCause::Cause cause) {
|
||||
true, /* should_initiate_conc_mark */
|
||||
g1_policy()->max_pause_time_ms(),
|
||||
cause);
|
||||
|
||||
VMThread::execute(&op);
|
||||
if (!op.pause_succeeded()) {
|
||||
// Another GC got scheduled and prevented us from scheduling
|
||||
// the initial-mark GC. It's unlikely that the GC that
|
||||
// pre-empted us was also an initial-mark GC. So, we'll retry
|
||||
// the initial-mark GC.
|
||||
|
||||
if (full_gc_count_before == total_full_collections()) {
|
||||
retry_gc = true;
|
||||
retry_gc = op.should_retry_gc();
|
||||
} else {
|
||||
// A Full GC happened while we were trying to schedule the
|
||||
// initial-mark GC. No point in starting a new cycle given
|
||||
// that the whole heap was collected anyway.
|
||||
}
|
||||
|
||||
if (retry_gc) {
|
||||
if (GC_locker::is_active_and_needs_gc()) {
|
||||
GC_locker::stall_until_clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cause == GCCause::_gc_locker
|
||||
|
||||
@ -2608,7 +2608,7 @@ bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
|
||||
size_t reclaimable_bytes = cset_chooser->remainingReclaimableBytes();
|
||||
size_t capacity_bytes = _g1->capacity();
|
||||
double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
|
||||
double threshold = (double) G1OldReclaimableThresholdPercent;
|
||||
double threshold = (double) G1HeapWastePercent;
|
||||
if (perc < threshold) {
|
||||
ergo_verbose4(ErgoMixedGCs,
|
||||
false_action_str,
|
||||
|
||||
@ -940,10 +940,9 @@ public:
|
||||
return _bytes_copied_during_gc;
|
||||
}
|
||||
|
||||
// Determine whether the next GC should be mixed. Called to determine
|
||||
// whether to start mixed GCs or whether to carry on doing mixed
|
||||
// GCs. The two action strings are used in the ergo output when the
|
||||
// method returns true or false.
|
||||
// Determine whether there are candidate regions so that the
|
||||
// next GC should be mixed. The two action strings are used
|
||||
// in the ergo output when the method returns true or false.
|
||||
bool next_gc_should_be_mixed(const char* true_action_str,
|
||||
const char* false_action_str);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2012 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
|
||||
@ -44,7 +44,9 @@ G1YoungGenerationCounters::G1YoungGenerationCounters(G1MonitoringSupport* g1mm,
|
||||
G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
|
||||
G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
|
||||
G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
|
||||
update_all();
|
||||
if (UsePerfData) {
|
||||
update_all();
|
||||
}
|
||||
}
|
||||
|
||||
G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
|
||||
@ -53,7 +55,9 @@ G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
|
||||
G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
|
||||
G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
|
||||
G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
|
||||
update_all();
|
||||
if (UsePerfData) {
|
||||
update_all();
|
||||
}
|
||||
}
|
||||
|
||||
void G1YoungGenerationCounters::update_all() {
|
||||
@ -149,10 +153,6 @@ G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
|
||||
pad_capacity(0) /* max_capacity */,
|
||||
pad_capacity(0) /* init_capacity */,
|
||||
_young_collection_counters);
|
||||
// Given that this survivor space is not used, we update it here
|
||||
// once to reflect that its used space is 0 so that we don't have to
|
||||
// worry about updating it again later.
|
||||
_from_counters->update_used(0);
|
||||
|
||||
// name "generation.0.space.2"
|
||||
// See _old_space_counters for additional counters
|
||||
@ -160,6 +160,13 @@ G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
|
||||
pad_capacity(overall_reserved()) /* max_capacity */,
|
||||
pad_capacity(survivor_space_committed()) /* init_capacity */,
|
||||
_young_collection_counters);
|
||||
|
||||
if (UsePerfData) {
|
||||
// Given that this survivor space is not used, we update it here
|
||||
// once to reflect that its used space is 0 so that we don't have to
|
||||
// worry about updating it again later.
|
||||
_from_counters->update_used(0);
|
||||
}
|
||||
}
|
||||
|
||||
void G1MonitoringSupport::recalculate_sizes() {
|
||||
|
||||
@ -299,17 +299,16 @@
|
||||
"Percentage (0-100) of the heap size to use as maximum " \
|
||||
"young gen size.") \
|
||||
\
|
||||
develop(uintx, G1OldCSetRegionLiveThresholdPercent, 95, \
|
||||
develop(uintx, G1OldCSetRegionLiveThresholdPercent, 90, \
|
||||
"Threshold for regions to be added to the collection set. " \
|
||||
"Regions with more live bytes that this will not be collected.") \
|
||||
\
|
||||
develop(uintx, G1OldReclaimableThresholdPercent, 1, \
|
||||
"Threshold for the remaining old reclaimable bytes, expressed " \
|
||||
"as a percentage of the heap size. If the old reclaimable bytes " \
|
||||
"are under this we will not collect them with more mixed GCs.") \
|
||||
product(uintx, G1HeapWastePercent, 5, \
|
||||
"Amount of space, expressed as a percentage of the heap size, " \
|
||||
"that G1 is willing not to collect to avoid expensive GCs.") \
|
||||
\
|
||||
develop(uintx, G1MaxMixedGCNum, 4, \
|
||||
"The maximum desired number of mixed GCs after a marking cycle.") \
|
||||
product(uintx, G1MixedGCCountTarget, 4, \
|
||||
"The target number of mixed GCs after a marking cycle.") \
|
||||
\
|
||||
develop(uintx, G1OldCSetRegionThresholdPercent, 10, \
|
||||
"An upper bound for the number of old CSet regions expressed " \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,33 +38,36 @@ SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p,
|
||||
_summary_surv_rates(NULL),
|
||||
_surv_rate(NULL),
|
||||
_accum_surv_rate_pred(NULL),
|
||||
_surv_rate_pred(NULL)
|
||||
{
|
||||
_surv_rate_pred(NULL),
|
||||
_stats_arrays_length(0) {
|
||||
reset();
|
||||
if (summary_surv_rates_len > 0) {
|
||||
size_t length = summary_surv_rates_len;
|
||||
_summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
|
||||
if (_summary_surv_rates == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(NumberSeq*) * length,
|
||||
"Not enough space for surv rate summary");
|
||||
}
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
_summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
_summary_surv_rates[i] = new NumberSeq();
|
||||
}
|
||||
}
|
||||
|
||||
start_adding_regions();
|
||||
}
|
||||
|
||||
|
||||
void SurvRateGroup::reset()
|
||||
{
|
||||
void SurvRateGroup::reset() {
|
||||
_all_regions_allocated = 0;
|
||||
_setup_seq_num = 0;
|
||||
_stats_arrays_length = 0;
|
||||
_accum_surv_rate = 0.0;
|
||||
_last_pred = 0.0;
|
||||
// the following will set up the arrays with length 1
|
||||
_region_num = 1;
|
||||
|
||||
// The call to stop_adding_regions() will use "new" to refill
|
||||
// the _surv_rate_pred array, so we need to make sure to call
|
||||
// "delete".
|
||||
for (size_t i = 0; i < _stats_arrays_length; ++i) {
|
||||
delete _surv_rate_pred[i];
|
||||
}
|
||||
_stats_arrays_length = 0;
|
||||
|
||||
stop_adding_regions();
|
||||
guarantee( _stats_arrays_length == 1, "invariant" );
|
||||
guarantee( _surv_rate_pred[0] != NULL, "invariant" );
|
||||
@ -73,72 +76,47 @@ void SurvRateGroup::reset()
|
||||
_region_num = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SurvRateGroup::start_adding_regions() {
|
||||
_setup_seq_num = _stats_arrays_length;
|
||||
_region_num = 0;
|
||||
_accum_surv_rate = 0.0;
|
||||
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
|
||||
_name, _setup_seq_num, _region_num);
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
void
|
||||
SurvRateGroup::stop_adding_regions() {
|
||||
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
|
||||
#endif // 0
|
||||
|
||||
if (_region_num > _stats_arrays_length) {
|
||||
double* old_surv_rate = _surv_rate;
|
||||
double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
|
||||
TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
|
||||
|
||||
_surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
|
||||
if (_surv_rate == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(double) * _region_num,
|
||||
"Not enough space for surv rate array.");
|
||||
}
|
||||
_accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
|
||||
if (_accum_surv_rate_pred == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(double) * _region_num,
|
||||
"Not enough space for accum surv rate pred array.");
|
||||
}
|
||||
_surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
|
||||
if (_surv_rate == NULL) {
|
||||
vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
|
||||
"Not enough space for surv rate pred array.");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _stats_arrays_length; ++i)
|
||||
for (size_t i = 0; i < _stats_arrays_length; ++i) {
|
||||
_surv_rate_pred[i] = old_surv_rate_pred[i];
|
||||
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
|
||||
_name, _array_length, _region_num - 1);
|
||||
#endif // 0
|
||||
|
||||
}
|
||||
for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
|
||||
_surv_rate_pred[i] = new TruncatedSeq(10);
|
||||
// _surv_rate_pred[i]->add(last_pred);
|
||||
}
|
||||
|
||||
_stats_arrays_length = _region_num;
|
||||
|
||||
if (old_surv_rate != NULL)
|
||||
if (old_surv_rate != NULL) {
|
||||
FREE_C_HEAP_ARRAY(double, old_surv_rate);
|
||||
if (old_accum_surv_rate_pred != NULL)
|
||||
}
|
||||
if (old_accum_surv_rate_pred != NULL) {
|
||||
FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
|
||||
if (old_surv_rate_pred != NULL)
|
||||
FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
|
||||
}
|
||||
if (old_surv_rate_pred != NULL) {
|
||||
FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _stats_arrays_length; ++i)
|
||||
for (size_t i = 0; i < _stats_arrays_length; ++i) {
|
||||
_surv_rate[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
@ -187,12 +165,6 @@ void
|
||||
SurvRateGroup::all_surviving_words_recorded(bool propagate) {
|
||||
if (propagate && _region_num > 0) { // conservative
|
||||
double surv_rate = _surv_rate_pred[_region_num-1]->last();
|
||||
|
||||
#if 0
|
||||
gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
|
||||
surv_rate, _curr_length, _array_length - 1);
|
||||
#endif // 0
|
||||
|
||||
for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
|
||||
guarantee( _surv_rate[i] <= 0.00001,
|
||||
"the slot should not have been updated" );
|
||||
|
||||
@ -34,7 +34,8 @@
|
||||
VM_G1CollectForAllocation::VM_G1CollectForAllocation(
|
||||
unsigned int gc_count_before,
|
||||
size_t word_size)
|
||||
: VM_G1OperationWithAllocRequest(gc_count_before, word_size) {
|
||||
: VM_G1OperationWithAllocRequest(gc_count_before, word_size,
|
||||
GCCause::_allocation_failure) {
|
||||
guarantee(word_size > 0, "an allocation should always be requested");
|
||||
}
|
||||
|
||||
@ -57,9 +58,10 @@ VM_G1IncCollectionPause::VM_G1IncCollectionPause(
|
||||
bool should_initiate_conc_mark,
|
||||
double target_pause_time_ms,
|
||||
GCCause::Cause gc_cause)
|
||||
: VM_G1OperationWithAllocRequest(gc_count_before, word_size),
|
||||
: VM_G1OperationWithAllocRequest(gc_count_before, word_size, gc_cause),
|
||||
_should_initiate_conc_mark(should_initiate_conc_mark),
|
||||
_target_pause_time_ms(target_pause_time_ms),
|
||||
_should_retry_gc(false),
|
||||
_full_collections_completed_before(0) {
|
||||
guarantee(target_pause_time_ms > 0.0,
|
||||
err_msg("target_pause_time_ms = %1.6lf should be positive",
|
||||
@ -70,6 +72,22 @@ VM_G1IncCollectionPause::VM_G1IncCollectionPause(
|
||||
_gc_cause = gc_cause;
|
||||
}
|
||||
|
||||
bool VM_G1IncCollectionPause::doit_prologue() {
|
||||
bool res = VM_GC_Operation::doit_prologue();
|
||||
if (!res) {
|
||||
if (_should_initiate_conc_mark) {
|
||||
// The prologue can fail for a couple of reasons. The first is that another GC
|
||||
// got scheduled and prevented the scheduling of the initial mark GC. The
|
||||
// second is that the GC locker may be active and the heap can't be expanded.
|
||||
// In both cases we want to retry the GC so that the initial mark pause is
|
||||
// actually scheduled. In the second case, however, we should stall until
|
||||
// until the GC locker is no longer active and then retry the initial mark GC.
|
||||
_should_retry_gc = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void VM_G1IncCollectionPause::doit() {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
assert(!_should_initiate_conc_mark ||
|
||||
@ -106,11 +124,25 @@ void VM_G1IncCollectionPause::doit() {
|
||||
// next GC pause to be an initial mark; it returns false if a
|
||||
// marking cycle is already in progress.
|
||||
//
|
||||
// If a marking cycle is already in progress just return and skip
|
||||
// the pause - the requesting thread should block in doit_epilogue
|
||||
// until the marking cycle is complete.
|
||||
// If a marking cycle is already in progress just return and skip the
|
||||
// pause below - if the reason for requesting this initial mark pause
|
||||
// was due to a System.gc() then the requesting thread should block in
|
||||
// doit_epilogue() until the marking cycle is complete.
|
||||
//
|
||||
// If this initial mark pause was requested as part of a humongous
|
||||
// allocation then we know that the marking cycle must just have
|
||||
// been started by another thread (possibly also allocating a humongous
|
||||
// object) as there was no active marking cycle when the requesting
|
||||
// thread checked before calling collect() in
|
||||
// attempt_allocation_humongous(). Retrying the GC, in this case,
|
||||
// will cause the requesting thread to spin inside collect() until the
|
||||
// just started marking cycle is complete - which may be a while. So
|
||||
// we do NOT retry the GC.
|
||||
if (!res) {
|
||||
assert(_word_size == 0, "ExplicitGCInvokesConcurrent shouldn't be allocating");
|
||||
assert(_word_size == 0, "Concurrent Full GC/Humongous Object IM shouldn't be allocating");
|
||||
if (_gc_cause != GCCause::_g1_humongous_allocation) {
|
||||
_should_retry_gc = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -123,6 +155,13 @@ void VM_G1IncCollectionPause::doit() {
|
||||
true /* expect_null_cur_alloc_region */);
|
||||
} else {
|
||||
assert(_result == NULL, "invariant");
|
||||
if (!_pause_succeeded) {
|
||||
// Another possible reason reason for the pause to not be successful
|
||||
// is that, again, the GC locker is active (and has become active
|
||||
// since the prologue was executed). In this case we should retry
|
||||
// the pause after waiting for the GC locker to become inactive.
|
||||
_should_retry_gc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +207,7 @@ void VM_G1IncCollectionPause::doit_epilogue() {
|
||||
}
|
||||
|
||||
void VM_CGC_Operation::acquire_pending_list_lock() {
|
||||
assert(_needs_pll, "don't call this otherwise");
|
||||
// The caller may block while communicating
|
||||
// with the SLT thread in order to acquire/release the PLL.
|
||||
ConcurrentMarkThread::slt()->
|
||||
@ -175,6 +215,7 @@ void VM_CGC_Operation::acquire_pending_list_lock() {
|
||||
}
|
||||
|
||||
void VM_CGC_Operation::release_and_notify_pending_list_lock() {
|
||||
assert(_needs_pll, "don't call this otherwise");
|
||||
// The caller may block while communicating
|
||||
// with the SLT thread in order to acquire/release the PLL.
|
||||
ConcurrentMarkThread::slt()->
|
||||
@ -198,7 +239,9 @@ void VM_CGC_Operation::doit() {
|
||||
bool VM_CGC_Operation::doit_prologue() {
|
||||
// Note the relative order of the locks must match that in
|
||||
// VM_GC_Operation::doit_prologue() or deadlocks can occur
|
||||
acquire_pending_list_lock();
|
||||
if (_needs_pll) {
|
||||
acquire_pending_list_lock();
|
||||
}
|
||||
|
||||
Heap_lock->lock();
|
||||
SharedHeap::heap()->_thread_holds_heap_lock_for_gc = true;
|
||||
@ -210,5 +253,7 @@ void VM_CGC_Operation::doit_epilogue() {
|
||||
// VM_GC_Operation::doit_epilogue()
|
||||
SharedHeap::heap()->_thread_holds_heap_lock_for_gc = false;
|
||||
Heap_lock->unlock();
|
||||
release_and_notify_pending_list_lock();
|
||||
if (_needs_pll) {
|
||||
release_and_notify_pending_list_lock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, 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
|
||||
@ -43,8 +43,9 @@ protected:
|
||||
|
||||
public:
|
||||
VM_G1OperationWithAllocRequest(unsigned int gc_count_before,
|
||||
size_t word_size)
|
||||
: VM_GC_Operation(gc_count_before, GCCause::_allocation_failure),
|
||||
size_t word_size,
|
||||
GCCause::Cause gc_cause)
|
||||
: VM_GC_Operation(gc_count_before, gc_cause),
|
||||
_word_size(word_size), _result(NULL), _pause_succeeded(false) { }
|
||||
HeapWord* result() { return _result; }
|
||||
bool pause_succeeded() { return _pause_succeeded; }
|
||||
@ -77,6 +78,7 @@ public:
|
||||
class VM_G1IncCollectionPause: public VM_G1OperationWithAllocRequest {
|
||||
private:
|
||||
bool _should_initiate_conc_mark;
|
||||
bool _should_retry_gc;
|
||||
double _target_pause_time_ms;
|
||||
unsigned int _full_collections_completed_before;
|
||||
public:
|
||||
@ -86,11 +88,13 @@ public:
|
||||
double target_pause_time_ms,
|
||||
GCCause::Cause gc_cause);
|
||||
virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; }
|
||||
virtual bool doit_prologue();
|
||||
virtual void doit();
|
||||
virtual void doit_epilogue();
|
||||
virtual const char* name() const {
|
||||
return "garbage-first incremental collection pause";
|
||||
}
|
||||
bool should_retry_gc() const { return _should_retry_gc; }
|
||||
};
|
||||
|
||||
// Concurrent GC stop-the-world operations such as remark and cleanup;
|
||||
@ -98,6 +102,7 @@ public:
|
||||
class VM_CGC_Operation: public VM_Operation {
|
||||
VoidClosure* _cl;
|
||||
const char* _printGCMessage;
|
||||
bool _needs_pll;
|
||||
|
||||
protected:
|
||||
// java.lang.ref.Reference support
|
||||
@ -105,8 +110,8 @@ protected:
|
||||
void release_and_notify_pending_list_lock();
|
||||
|
||||
public:
|
||||
VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg)
|
||||
: _cl(cl), _printGCMessage(printGCMsg) { }
|
||||
VM_CGC_Operation(VoidClosure* cl, const char *printGCMsg, bool needs_pll)
|
||||
: _cl(cl), _printGCMessage(printGCMsg), _needs_pll(needs_pll) { }
|
||||
virtual VMOp_Type type() const { return VMOp_CGC_Operation; }
|
||||
virtual void doit();
|
||||
virtual bool doit_prologue();
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
|
||||
|
||||
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
|
||||
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2012, 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
|
||||
@ -91,29 +91,37 @@ void MutableNUMASpace::ensure_parsability() {
|
||||
MutableSpace *s = ls->space();
|
||||
if (s->top() < top()) { // For all spaces preceding the one containing top()
|
||||
if (s->free_in_words() > 0) {
|
||||
size_t area_touched_words = pointer_delta(s->end(), s->top());
|
||||
CollectedHeap::fill_with_object(s->top(), area_touched_words);
|
||||
intptr_t cur_top = (intptr_t)s->top();
|
||||
size_t words_left_to_fill = pointer_delta(s->end(), s->top());;
|
||||
while (words_left_to_fill > 0) {
|
||||
size_t words_to_fill = MIN2(words_left_to_fill, CollectedHeap::filler_array_max_size());
|
||||
assert(words_to_fill >= CollectedHeap::min_fill_size(),
|
||||
err_msg("Remaining size ("SIZE_FORMAT ") is too small to fill (based on " SIZE_FORMAT " and " SIZE_FORMAT ")",
|
||||
words_to_fill, words_left_to_fill, CollectedHeap::filler_array_max_size()));
|
||||
CollectedHeap::fill_with_object((HeapWord*)cur_top, words_to_fill);
|
||||
if (!os::numa_has_static_binding()) {
|
||||
size_t touched_words = words_to_fill;
|
||||
#ifndef ASSERT
|
||||
if (!ZapUnusedHeapArea) {
|
||||
area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
|
||||
area_touched_words);
|
||||
}
|
||||
if (!ZapUnusedHeapArea) {
|
||||
touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
|
||||
touched_words);
|
||||
}
|
||||
#endif
|
||||
if (!os::numa_has_static_binding()) {
|
||||
MemRegion invalid;
|
||||
HeapWord *crossing_start = (HeapWord*)round_to((intptr_t)s->top(), os::vm_page_size());
|
||||
HeapWord *crossing_end = (HeapWord*)round_to((intptr_t)(s->top() + area_touched_words),
|
||||
os::vm_page_size());
|
||||
if (crossing_start != crossing_end) {
|
||||
// If object header crossed a small page boundary we mark the area
|
||||
// as invalid rounding it to a page_size().
|
||||
HeapWord *start = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom());
|
||||
HeapWord *end = MIN2((HeapWord*)round_to((intptr_t)(s->top() + area_touched_words), page_size()),
|
||||
s->end());
|
||||
invalid = MemRegion(start, end);
|
||||
}
|
||||
MemRegion invalid;
|
||||
HeapWord *crossing_start = (HeapWord*)round_to(cur_top, os::vm_page_size());
|
||||
HeapWord *crossing_end = (HeapWord*)round_to(cur_top + touched_words, os::vm_page_size());
|
||||
if (crossing_start != crossing_end) {
|
||||
// If object header crossed a small page boundary we mark the area
|
||||
// as invalid rounding it to a page_size().
|
||||
HeapWord *start = MAX2((HeapWord*)round_down(cur_top, page_size()), s->bottom());
|
||||
HeapWord *end = MIN2((HeapWord*)round_to(cur_top + touched_words, page_size()), s->end());
|
||||
invalid = MemRegion(start, end);
|
||||
}
|
||||
|
||||
ls->add_invalid_region(invalid);
|
||||
ls->add_invalid_region(invalid);
|
||||
}
|
||||
cur_top = cur_top + (words_to_fill * HeapWordSize);
|
||||
words_left_to_fill -= words_to_fill;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -85,7 +85,7 @@ CollectedHeap::CollectedHeap() : _n_par_threads(0)
|
||||
const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
|
||||
const size_t elements_per_word = HeapWordSize / sizeof(jint);
|
||||
_filler_array_max_size = align_object_size(filler_array_hdr_size() +
|
||||
max_len * elements_per_word);
|
||||
max_len / elements_per_word);
|
||||
|
||||
_barrier_set = NULL;
|
||||
_is_gc_active = false;
|
||||
@ -303,10 +303,6 @@ size_t CollectedHeap::filler_array_min_size() {
|
||||
return align_object_size(filler_array_hdr_size()); // align to MinObjAlignment
|
||||
}
|
||||
|
||||
size_t CollectedHeap::filler_array_max_size() {
|
||||
return _filler_array_max_size;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void CollectedHeap::fill_args_check(HeapWord* start, size_t words)
|
||||
{
|
||||
@ -333,10 +329,11 @@ CollectedHeap::fill_with_array(HeapWord* start, size_t words, bool zap)
|
||||
|
||||
const size_t payload_size = words - filler_array_hdr_size();
|
||||
const size_t len = payload_size * HeapWordSize / sizeof(jint);
|
||||
assert((int)len >= 0, err_msg("size too large " SIZE_FORMAT " becomes %d", words, (int)len));
|
||||
|
||||
// Set the length first for concurrent GC.
|
||||
((arrayOop)start)->set_length((int)len);
|
||||
post_allocation_setup_common(Universe::intArrayKlassObj(), start, words);
|
||||
post_allocation_setup_common(Universe::intArrayKlassObj(), start);
|
||||
DEBUG_ONLY(zap_filler_array(start, words, zap);)
|
||||
}
|
||||
|
||||
@ -349,8 +346,7 @@ CollectedHeap::fill_with_object_impl(HeapWord* start, size_t words, bool zap)
|
||||
fill_with_array(start, words, zap);
|
||||
} else if (words > 0) {
|
||||
assert(words == min_fill_size(), "unaligned size");
|
||||
post_allocation_setup_common(SystemDictionary::Object_klass(), start,
|
||||
words);
|
||||
post_allocation_setup_common(SystemDictionary::Object_klass(), start);
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,7 +476,7 @@ oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle r
|
||||
assert(ScavengeRootsInCode > 0, "must be");
|
||||
obj = common_mem_allocate_init(size, CHECK_NULL);
|
||||
}
|
||||
post_allocation_setup_common(klass, obj, size);
|
||||
post_allocation_setup_common(klass, obj);
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
|
||||
@ -128,7 +128,6 @@ class CollectedHeap : public CHeapObj {
|
||||
// Reinitialize tlabs before resuming mutators.
|
||||
virtual void resize_all_tlabs();
|
||||
|
||||
protected:
|
||||
// Allocate from the current thread's TLAB, with broken-out slow path.
|
||||
inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
|
||||
static HeapWord* allocate_from_tlab_slow(Thread* thread, size_t size);
|
||||
@ -150,18 +149,14 @@ class CollectedHeap : public CHeapObj {
|
||||
inline static HeapWord* common_permanent_mem_allocate_init(size_t size, TRAPS);
|
||||
|
||||
// Helper functions for (VM) allocation.
|
||||
inline static void post_allocation_setup_common(KlassHandle klass,
|
||||
HeapWord* obj, size_t size);
|
||||
inline static void post_allocation_setup_common(KlassHandle klass, HeapWord* obj);
|
||||
inline static void post_allocation_setup_no_klass_install(KlassHandle klass,
|
||||
HeapWord* objPtr,
|
||||
size_t size);
|
||||
HeapWord* objPtr);
|
||||
|
||||
inline static void post_allocation_setup_obj(KlassHandle klass,
|
||||
HeapWord* obj, size_t size);
|
||||
inline static void post_allocation_setup_obj(KlassHandle klass, HeapWord* obj);
|
||||
|
||||
inline static void post_allocation_setup_array(KlassHandle klass,
|
||||
HeapWord* obj, size_t size,
|
||||
int length);
|
||||
HeapWord* obj, int length);
|
||||
|
||||
// Clears an allocated object.
|
||||
inline static void init_obj(HeapWord* obj, size_t size);
|
||||
@ -169,7 +164,6 @@ class CollectedHeap : public CHeapObj {
|
||||
// Filler object utilities.
|
||||
static inline size_t filler_array_hdr_size();
|
||||
static inline size_t filler_array_min_size();
|
||||
static inline size_t filler_array_max_size();
|
||||
|
||||
DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);)
|
||||
DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words, bool zap = true);)
|
||||
@ -197,6 +191,10 @@ class CollectedHeap : public CHeapObj {
|
||||
G1CollectedHeap
|
||||
};
|
||||
|
||||
static inline size_t filler_array_max_size() {
|
||||
return _filler_array_max_size;
|
||||
}
|
||||
|
||||
virtual CollectedHeap::Name kind() const { return CollectedHeap::Abstract; }
|
||||
|
||||
/**
|
||||
@ -366,9 +364,7 @@ class CollectedHeap : public CHeapObj {
|
||||
inline static oop permanent_obj_allocate_no_klass_install(KlassHandle klass,
|
||||
int size,
|
||||
TRAPS);
|
||||
inline static void post_allocation_install_obj_klass(KlassHandle klass,
|
||||
oop obj,
|
||||
int size);
|
||||
inline static void post_allocation_install_obj_klass(KlassHandle klass, oop obj);
|
||||
inline static oop permanent_array_allocate(KlassHandle klass, int size, int length, TRAPS);
|
||||
|
||||
// Raw memory allocation facilities
|
||||
@ -662,9 +658,6 @@ class CollectedHeap : public CHeapObj {
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate GCHeapLog during VM startup
|
||||
static void initialize_heap_log();
|
||||
|
||||
// Heap verification
|
||||
virtual void verify(bool allow_dirty, bool silent, VerifyOption option) = 0;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, 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
|
||||
@ -50,15 +50,13 @@
|
||||
// Inline allocation implementations.
|
||||
|
||||
void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
size_t size) {
|
||||
post_allocation_setup_no_klass_install(klass, obj, size);
|
||||
post_allocation_install_obj_klass(klass, oop(obj), (int) size);
|
||||
HeapWord* obj) {
|
||||
post_allocation_setup_no_klass_install(klass, obj);
|
||||
post_allocation_install_obj_klass(klass, oop(obj));
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
|
||||
HeapWord* objPtr,
|
||||
size_t size) {
|
||||
HeapWord* objPtr) {
|
||||
oop obj = (oop)objPtr;
|
||||
|
||||
assert(obj != NULL, "NULL object pointer");
|
||||
@ -71,8 +69,7 @@ void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
|
||||
oop obj,
|
||||
int size) {
|
||||
oop obj) {
|
||||
// These asserts are kind of complicated because of klassKlass
|
||||
// and the beginning of the world.
|
||||
assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
|
||||
@ -101,9 +98,8 @@ inline void post_allocation_notify(KlassHandle klass, oop obj) {
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
size_t size) {
|
||||
post_allocation_setup_common(klass, obj, size);
|
||||
HeapWord* obj) {
|
||||
post_allocation_setup_common(klass, obj);
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
|
||||
// notify jvmti and dtrace
|
||||
@ -112,14 +108,13 @@ void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
|
||||
|
||||
void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
size_t size,
|
||||
int length) {
|
||||
// Set array length before setting the _klass field
|
||||
// in post_allocation_setup_common() because the klass field
|
||||
// indicates that the object is parsable by concurrent GC.
|
||||
assert(length >= 0, "length should be non-negative");
|
||||
((arrayOop)obj)->set_length(length);
|
||||
post_allocation_setup_common(klass, obj, size);
|
||||
post_allocation_setup_common(klass, obj);
|
||||
assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
|
||||
// notify jvmti and dtrace (must be after length is set for dtrace)
|
||||
post_allocation_notify(klass, (oop)obj);
|
||||
@ -256,7 +251,7 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
|
||||
post_allocation_setup_obj(klass, obj, size);
|
||||
post_allocation_setup_obj(klass, obj);
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
return (oop)obj;
|
||||
}
|
||||
@ -269,7 +264,7 @@ oop CollectedHeap::array_allocate(KlassHandle klass,
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
|
||||
post_allocation_setup_array(klass, obj, size, length);
|
||||
post_allocation_setup_array(klass, obj, length);
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
return (oop)obj;
|
||||
}
|
||||
@ -283,7 +278,7 @@ oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
|
||||
((oop)obj)->set_klass_gap(0);
|
||||
post_allocation_setup_array(klass, obj, size, length);
|
||||
post_allocation_setup_array(klass, obj, length);
|
||||
#ifndef PRODUCT
|
||||
const size_t hs = oopDesc::header_size()+1;
|
||||
Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
|
||||
@ -293,7 +288,7 @@ oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
|
||||
|
||||
oop CollectedHeap::permanent_obj_allocate(KlassHandle klass, int size, TRAPS) {
|
||||
oop obj = permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
|
||||
post_allocation_install_obj_klass(klass, obj, size);
|
||||
post_allocation_install_obj_klass(klass, obj);
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
|
||||
size));
|
||||
return obj;
|
||||
@ -306,7 +301,7 @@ oop CollectedHeap::permanent_obj_allocate_no_klass_install(KlassHandle klass,
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
|
||||
post_allocation_setup_no_klass_install(klass, obj, size);
|
||||
post_allocation_setup_no_klass_install(klass, obj);
|
||||
#ifndef PRODUCT
|
||||
const size_t hs = oopDesc::header_size();
|
||||
Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs);
|
||||
@ -322,7 +317,7 @@ oop CollectedHeap::permanent_array_allocate(KlassHandle klass,
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
|
||||
post_allocation_setup_array(klass, obj, size, length);
|
||||
post_allocation_setup_array(klass, obj, length);
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
return (oop)obj;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -72,6 +72,9 @@ class CardTableModRefBS: public ModRefBarrierSet {
|
||||
CT_MR_BS_last_reserved = 16
|
||||
};
|
||||
|
||||
// a word's worth (row) of clean card values
|
||||
static const intptr_t clean_card_row = (intptr_t)(-1);
|
||||
|
||||
// dirty and precleaned are equivalent wrt younger_refs_iter.
|
||||
static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
|
||||
return cv == dirty_card || cv == precleaned_card;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, 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
|
||||
@ -173,6 +173,10 @@ ClearNoncleanCardWrapper::ClearNoncleanCardWrapper(
|
||||
SharedHeap::heap()->workers()->active_workers()), "Mismatch");
|
||||
}
|
||||
|
||||
bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
|
||||
return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
|
||||
}
|
||||
|
||||
void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
|
||||
assert(mr.word_size() > 0, "Error");
|
||||
assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
|
||||
@ -194,6 +198,17 @@ void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
|
||||
const MemRegion mrd(start_of_non_clean, end_of_non_clean);
|
||||
_dirty_card_closure->do_MemRegion(mrd);
|
||||
}
|
||||
|
||||
// fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
|
||||
if (is_word_aligned(cur_entry)) {
|
||||
jbyte* cur_row = cur_entry - BytesPerWord;
|
||||
while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row()) {
|
||||
cur_row -= BytesPerWord;
|
||||
}
|
||||
cur_entry = cur_row + BytesPerWord;
|
||||
cur_hw = _ct->addr_for(cur_entry);
|
||||
}
|
||||
|
||||
// Reset the dirty window, while continuing to look
|
||||
// for the next dirty card that will start a
|
||||
// new dirty window.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, 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
|
||||
@ -45,6 +45,10 @@ class CardTableRS: public GenRemSet {
|
||||
return CardTableModRefBS::clean_card;
|
||||
}
|
||||
|
||||
static intptr_t clean_card_row() {
|
||||
return CardTableModRefBS::clean_card_row;
|
||||
}
|
||||
|
||||
static bool
|
||||
card_is_dirty_wrt_gen_iter(jbyte cv) {
|
||||
return CardTableModRefBS::card_is_dirty_wrt_gen_iter(cv);
|
||||
@ -176,6 +180,8 @@ private:
|
||||
// Work methods called by the clear_card()
|
||||
inline bool clear_card_serial(jbyte* entry);
|
||||
inline bool clear_card_parallel(jbyte* entry);
|
||||
// check alignment of pointer
|
||||
bool is_word_aligned(jbyte* entry);
|
||||
|
||||
public:
|
||||
ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct);
|
||||
|
||||
@ -297,16 +297,14 @@ public:
|
||||
|
||||
if (obj->blueprint()->oop_is_instanceKlass()) {
|
||||
instanceKlass* ik = instanceKlass::cast((klassOop)obj);
|
||||
typeArrayOop inner_classes = ik->inner_classes();
|
||||
if (inner_classes != NULL) {
|
||||
constantPoolOop constants = ik->constants();
|
||||
int n = inner_classes->length();
|
||||
for (int i = 0; i < n; i += instanceKlass::inner_class_next_offset) {
|
||||
int ioff = i + instanceKlass::inner_class_inner_name_offset;
|
||||
int index = inner_classes->ushort_at(ioff);
|
||||
if (index != 0) {
|
||||
_closure->do_symbol(constants->symbol_at_addr(index));
|
||||
}
|
||||
instanceKlassHandle ik_h((klassOop)obj);
|
||||
InnerClassesIterator iter(ik_h);
|
||||
constantPoolOop constants = ik->constants();
|
||||
for (; !iter.done(); iter.next()) {
|
||||
int index = iter.inner_name_index();
|
||||
|
||||
if (index != 0) {
|
||||
_closure->do_symbol(constants->symbol_at_addr(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -153,6 +153,7 @@ objArrayOop arrayKlass::allocate_arrayArray(int n, int length, TRAPS) {
|
||||
}
|
||||
if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
|
||||
report_java_out_of_memory("Requested array size exceeds VM limit");
|
||||
JvmtiExport::post_array_size_exhausted();
|
||||
THROW_OOP_0(Universe::out_of_memory_error_array_size());
|
||||
}
|
||||
int size = objArrayOopDesc::object_size(length);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -669,6 +669,7 @@ objArrayOop instanceKlass::allocate_objArray(int n, int length, TRAPS) {
|
||||
if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
|
||||
if (length > arrayOopDesc::max_array_length(T_OBJECT)) {
|
||||
report_java_out_of_memory("Requested array size exceeds VM limit");
|
||||
JvmtiExport::post_array_size_exhausted();
|
||||
THROW_OOP_0(Universe::out_of_memory_error_array_size());
|
||||
}
|
||||
int size = objArrayOopDesc::object_size(length);
|
||||
@ -1132,6 +1133,36 @@ JNIid* instanceKlass::jni_id_for(int offset) {
|
||||
return probe;
|
||||
}
|
||||
|
||||
u2 instanceKlass::enclosing_method_data(int offset) {
|
||||
typeArrayOop inner_class_list = inner_classes();
|
||||
if (inner_class_list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
int length = inner_class_list->length();
|
||||
if (length % inner_class_next_offset == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
int index = length - enclosing_method_attribute_size;
|
||||
typeArrayHandle inner_class_list_h(inner_class_list);
|
||||
assert(offset < enclosing_method_attribute_size, "invalid offset");
|
||||
return inner_class_list_h->ushort_at(index + offset);
|
||||
}
|
||||
}
|
||||
|
||||
void instanceKlass::set_enclosing_method_indices(u2 class_index,
|
||||
u2 method_index) {
|
||||
typeArrayOop inner_class_list = inner_classes();
|
||||
assert (inner_class_list != NULL, "_inner_classes list is not set up");
|
||||
int length = inner_class_list->length();
|
||||
if (length % inner_class_next_offset == enclosing_method_attribute_size) {
|
||||
int index = length - enclosing_method_attribute_size;
|
||||
typeArrayHandle inner_class_list_h(inner_class_list);
|
||||
inner_class_list_h->ushort_at_put(
|
||||
index + enclosing_method_class_index_offset, class_index);
|
||||
inner_class_list_h->ushort_at_put(
|
||||
index + enclosing_method_method_index_offset, method_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup or create a jmethodID.
|
||||
// This code is called by the VMThread and JavaThreads so the
|
||||
@ -2106,28 +2137,21 @@ jint instanceKlass::compute_modifier_flags(TRAPS) const {
|
||||
jint access = access_flags().as_int();
|
||||
|
||||
// But check if it happens to be member class.
|
||||
typeArrayOop inner_class_list = inner_classes();
|
||||
int length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
|
||||
assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
|
||||
if (length > 0) {
|
||||
typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
|
||||
instanceKlassHandle ik(THREAD, k);
|
||||
for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
|
||||
int ioff = inner_class_list_h->ushort_at(
|
||||
i + instanceKlass::inner_class_inner_class_info_offset);
|
||||
instanceKlassHandle ik(THREAD, k);
|
||||
InnerClassesIterator iter(ik);
|
||||
for (; !iter.done(); iter.next()) {
|
||||
int ioff = iter.inner_class_info_index();
|
||||
// Inner class attribute can be zero, skip it.
|
||||
// Strange but true: JVM spec. allows null inner class refs.
|
||||
if (ioff == 0) continue;
|
||||
|
||||
// Inner class attribute can be zero, skip it.
|
||||
// Strange but true: JVM spec. allows null inner class refs.
|
||||
if (ioff == 0) continue;
|
||||
|
||||
// only look at classes that are already loaded
|
||||
// since we are looking for the flags for our self.
|
||||
Symbol* inner_name = ik->constants()->klass_name_at(ioff);
|
||||
if ((ik->name() == inner_name)) {
|
||||
// This is really a member class.
|
||||
access = inner_class_list_h->ushort_at(i + instanceKlass::inner_class_access_flags_offset);
|
||||
break;
|
||||
}
|
||||
// only look at classes that are already loaded
|
||||
// since we are looking for the flags for our self.
|
||||
Symbol* inner_name = ik->constants()->klass_name_at(ioff);
|
||||
if ((ik->name() == inner_name)) {
|
||||
// This is really a member class.
|
||||
access = iter.inner_access_flags();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Remember to strip ACC_SUPER bit
|
||||
|
||||
@ -188,7 +188,17 @@ class instanceKlass: public Klass {
|
||||
klassOop _host_klass;
|
||||
// Class signers.
|
||||
objArrayOop _signers;
|
||||
// inner_classes attribute.
|
||||
// The InnerClasses attribute and EnclosingMethod attribute. The
|
||||
// _inner_classes is an array of shorts. If the class has InnerClasses
|
||||
// attribute, then the _inner_classes array begins with 4-tuples of shorts
|
||||
// [inner_class_info_index, outer_class_info_index,
|
||||
// inner_name_index, inner_class_access_flags] for the InnerClasses
|
||||
// attribute. If the EnclosingMethod attribute exists, it occupies the
|
||||
// last two shorts [class_index, method_index] of the array. If only
|
||||
// the InnerClasses attribute exists, the _inner_classes array length is
|
||||
// number_of_inner_classes * 4. If the class has both InnerClasses
|
||||
// and EnclosingMethod attributes the _inner_classes array length is
|
||||
// number_of_inner_classes * 4 + enclosing_method_attribute_size.
|
||||
typeArrayOop _inner_classes;
|
||||
// Implementors of this interface (not valid if it overflows)
|
||||
klassOop _implementors[implementors_limit];
|
||||
@ -251,8 +261,6 @@ class instanceKlass: public Klass {
|
||||
// Array of interesting part(s) of the previous version(s) of this
|
||||
// instanceKlass. See PreviousVersionWalker below.
|
||||
GrowableArray<PreviousVersionNode *>* _previous_versions;
|
||||
u2 _enclosing_method_class_index; // Constant pool index for class of enclosing method, or 0 if none
|
||||
u2 _enclosing_method_method_index; // Constant pool index for name and type of enclosing method, or 0 if none
|
||||
// JVMTI fields can be moved to their own structure - see 6315920
|
||||
unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
|
||||
jint _cached_class_file_len; // JVMTI: length of above
|
||||
@ -351,6 +359,12 @@ class instanceKlass: public Klass {
|
||||
inner_class_next_offset = 4
|
||||
};
|
||||
|
||||
enum EnclosingMethodAttributeOffset {
|
||||
enclosing_method_class_index_offset = 0,
|
||||
enclosing_method_method_index_offset = 1,
|
||||
enclosing_method_attribute_size = 2
|
||||
};
|
||||
|
||||
// method override check
|
||||
bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
|
||||
|
||||
@ -533,11 +547,15 @@ class instanceKlass: public Klass {
|
||||
Symbol* generic_signature() const { return _generic_signature; }
|
||||
void set_generic_signature(Symbol* sig) { _generic_signature = sig; }
|
||||
|
||||
u2 enclosing_method_class_index() const { return _enclosing_method_class_index; }
|
||||
u2 enclosing_method_method_index() const { return _enclosing_method_method_index; }
|
||||
u2 enclosing_method_data(int offset);
|
||||
u2 enclosing_method_class_index() {
|
||||
return enclosing_method_data(enclosing_method_class_index_offset);
|
||||
}
|
||||
u2 enclosing_method_method_index() {
|
||||
return enclosing_method_data(enclosing_method_method_index_offset);
|
||||
}
|
||||
void set_enclosing_method_indices(u2 class_index,
|
||||
u2 method_index) { _enclosing_method_class_index = class_index;
|
||||
_enclosing_method_method_index = method_index; }
|
||||
u2 method_index);
|
||||
|
||||
// jmethodID support
|
||||
static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
|
||||
@ -1053,4 +1071,83 @@ class nmethodBucket: public CHeapObj {
|
||||
nmethod* get_nmethod() { return _nmethod; }
|
||||
};
|
||||
|
||||
// An iterator that's used to access the inner classes indices in the
|
||||
// instanceKlass::_inner_classes array.
|
||||
class InnerClassesIterator : public StackObj {
|
||||
private:
|
||||
typeArrayHandle _inner_classes;
|
||||
int _length;
|
||||
int _idx;
|
||||
public:
|
||||
|
||||
InnerClassesIterator(instanceKlassHandle k) {
|
||||
_inner_classes = k->inner_classes();
|
||||
if (k->inner_classes() != NULL) {
|
||||
_length = _inner_classes->length();
|
||||
// The inner class array's length should be the multiple of
|
||||
// inner_class_next_offset if it only contains the InnerClasses
|
||||
// attribute data, or it should be
|
||||
// n*inner_class_next_offset+enclosing_method_attribute_size
|
||||
// if it also contains the EnclosingMethod data.
|
||||
assert((_length % instanceKlass::inner_class_next_offset == 0 ||
|
||||
_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size),
|
||||
"just checking");
|
||||
// Remove the enclosing_method portion if exists.
|
||||
if (_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size) {
|
||||
_length -= instanceKlass::enclosing_method_attribute_size;
|
||||
}
|
||||
} else {
|
||||
_length = 0;
|
||||
}
|
||||
_idx = 0;
|
||||
}
|
||||
|
||||
int length() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
void next() {
|
||||
_idx += instanceKlass::inner_class_next_offset;
|
||||
}
|
||||
|
||||
bool done() const {
|
||||
return (_idx >= _length);
|
||||
}
|
||||
|
||||
u2 inner_class_info_index() const {
|
||||
return _inner_classes->ushort_at(
|
||||
_idx + instanceKlass::inner_class_inner_class_info_offset);
|
||||
}
|
||||
|
||||
void set_inner_class_info_index(u2 index) {
|
||||
_inner_classes->ushort_at_put(
|
||||
_idx + instanceKlass::inner_class_inner_class_info_offset, index);
|
||||
}
|
||||
|
||||
u2 outer_class_info_index() const {
|
||||
return _inner_classes->ushort_at(
|
||||
_idx + instanceKlass::inner_class_outer_class_info_offset);
|
||||
}
|
||||
|
||||
void set_outer_class_info_index(u2 index) {
|
||||
_inner_classes->ushort_at_put(
|
||||
_idx + instanceKlass::inner_class_outer_class_info_offset, index);
|
||||
}
|
||||
|
||||
u2 inner_name_index() const {
|
||||
return _inner_classes->ushort_at(
|
||||
_idx + instanceKlass::inner_class_inner_name_offset);
|
||||
}
|
||||
|
||||
void set_inner_name_index(u2 index) {
|
||||
_inner_classes->ushort_at_put(
|
||||
_idx + instanceKlass::inner_class_inner_name_offset, index);
|
||||
}
|
||||
|
||||
u2 inner_access_flags() const {
|
||||
return _inner_classes->ushort_at(
|
||||
_idx + instanceKlass::inner_class_access_flags_offset);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP
|
||||
|
||||
@ -416,7 +416,6 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it
|
||||
ik->set_methods_annotations(NULL);
|
||||
ik->set_methods_parameter_annotations(NULL);
|
||||
ik->set_methods_default_annotations(NULL);
|
||||
ik->set_enclosing_method_indices(0, 0);
|
||||
ik->set_jvmti_cached_class_field_map(NULL);
|
||||
ik->set_initial_method_idnum(0);
|
||||
assert(k()->is_parsable(), "should be parsable here.");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -174,10 +174,9 @@ KlassHandle Klass::base_create_klass(KlassHandle& klass, int size,
|
||||
}
|
||||
|
||||
void Klass_vtbl::post_new_init_klass(KlassHandle& klass,
|
||||
klassOop new_klass,
|
||||
int size) const {
|
||||
klassOop new_klass) const {
|
||||
assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass");
|
||||
CollectedHeap::post_allocation_install_obj_klass(klass, new_klass, size);
|
||||
CollectedHeap::post_allocation_install_obj_klass(klass, new_klass);
|
||||
}
|
||||
|
||||
void* Klass_vtbl::operator new(size_t ignored, KlassHandle& klass,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -149,7 +149,7 @@ class Klass_vtbl {
|
||||
// by the shared "base_create" subroutines.
|
||||
//
|
||||
virtual void* allocate_permanent(KlassHandle& klass, int size, TRAPS) const = 0;
|
||||
void post_new_init_klass(KlassHandle& klass, klassOop obj, int size) const;
|
||||
void post_new_init_klass(KlassHandle& klass, klassOop obj) const;
|
||||
|
||||
// Every subclass on which vtbl_value is called must include this macro.
|
||||
// Delay the installation of the klassKlass pointer until after the
|
||||
@ -160,7 +160,7 @@ class Klass_vtbl {
|
||||
if (HAS_PENDING_EXCEPTION) return NULL; \
|
||||
klassOop new_klass = ((Klass*) result)->as_klassOop(); \
|
||||
OrderAccess::storestore(); \
|
||||
post_new_init_klass(klass_klass, new_klass, size); \
|
||||
post_new_init_klass(klass_klass, new_klass); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -68,6 +68,7 @@ objArrayOop objArrayKlass::allocate(int length, TRAPS) {
|
||||
return a;
|
||||
} else {
|
||||
report_java_out_of_memory("Requested array size exceeds VM limit");
|
||||
JvmtiExport::post_array_size_exhausted();
|
||||
THROW_OOP_0(Universe::out_of_memory_error_array_size());
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -93,6 +93,7 @@ typeArrayOop typeArrayKlass::allocate_common(int length, bool do_zero, TRAPS) {
|
||||
return t;
|
||||
} else {
|
||||
report_java_out_of_memory("Requested array size exceeds VM limit");
|
||||
JvmtiExport::post_array_size_exhausted();
|
||||
THROW_OOP_0(Universe::out_of_memory_error_array_size());
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -257,6 +257,18 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
|
||||
return "exception method";
|
||||
}
|
||||
|
||||
if (callee_method->should_not_inline()) {
|
||||
return "disallowed by CompilerOracle";
|
||||
}
|
||||
|
||||
if (UseStringCache) {
|
||||
// Do not inline StringCache::profile() method used only at the beginning.
|
||||
if (callee_method->name() == ciSymbol::profile_name() &&
|
||||
callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
|
||||
return "profiling method";
|
||||
}
|
||||
}
|
||||
|
||||
// use frequency-based objections only for non-trivial methods
|
||||
if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
|
||||
|
||||
@ -278,18 +290,6 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal
|
||||
}
|
||||
}
|
||||
|
||||
if (callee_method->should_not_inline()) {
|
||||
return "disallowed by CompilerOracle";
|
||||
}
|
||||
|
||||
if (UseStringCache) {
|
||||
// Do not inline StringCache::profile() method used only at the beginning.
|
||||
if (callee_method->name() == ciSymbol::profile_name() &&
|
||||
callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
|
||||
return "profiling method";
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -465,6 +465,9 @@
|
||||
notproduct(bool, PrintOptimizePtrCompare, false, \
|
||||
"Print information about optimized pointers compare") \
|
||||
\
|
||||
notproduct(bool, VerifyConnectionGraph , true, \
|
||||
"Verify Connection Graph construction in Escape Analysis") \
|
||||
\
|
||||
product(bool, UseOptoBiasInlining, true, \
|
||||
"Generate biased locking code in C2 ideal graph") \
|
||||
\
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -1538,10 +1538,7 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// If we are locking an unescaped object, the lock/unlock is unnecessary
|
||||
//
|
||||
ConnectionGraph *cgr = phase->C->congraph();
|
||||
PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
|
||||
if (cgr != NULL)
|
||||
es = cgr->escape_state(obj_node());
|
||||
if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
|
||||
if (cgr != NULL && cgr->not_global_escape(obj_node())) {
|
||||
assert(!is_eliminated() || is_coarsened(), "sanity");
|
||||
// The lock could be marked eliminated by lock coarsening
|
||||
// code during first IGVN before EA. Replace coarsened flag
|
||||
@ -1680,10 +1677,7 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// If we are unlocking an unescaped object, the lock/unlock is unnecessary.
|
||||
//
|
||||
ConnectionGraph *cgr = phase->C->congraph();
|
||||
PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
|
||||
if (cgr != NULL)
|
||||
es = cgr->escape_state(obj_node());
|
||||
if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
|
||||
if (cgr != NULL && cgr->not_global_escape(obj_node())) {
|
||||
assert(!is_eliminated() || is_coarsened(), "sanity");
|
||||
// The lock could be marked eliminated by lock coarsening
|
||||
// code during first IGVN before EA. Replace coarsened flag
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -546,6 +546,12 @@ public:
|
||||
// or result projection is there are several CheckCastPP
|
||||
// or returns NULL if there is no one.
|
||||
Node *result_cast();
|
||||
// Does this node returns pointer?
|
||||
bool returns_pointer() const {
|
||||
const TypeTuple *r = tf()->range();
|
||||
return (r->cnt() > TypeFunc::Parms &&
|
||||
r->field_at(TypeFunc::Parms)->isa_ptr());
|
||||
}
|
||||
|
||||
// Collect all the interesting edges from a call for use in
|
||||
// replacing the call by something else. Used by macro expansion
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -1707,7 +1707,6 @@ void Compile::Optimize() {
|
||||
if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
|
||||
if (failing()) return;
|
||||
}
|
||||
TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
|
||||
ConnectionGraph::do_analysis(this, &igvn);
|
||||
|
||||
if (failing()) return;
|
||||
@ -1719,6 +1718,7 @@ void Compile::Optimize() {
|
||||
if (failing()) return;
|
||||
|
||||
if (congraph() != NULL && macro_count() > 0) {
|
||||
NOT_PRODUCT( TracePhase t2("macroEliminate", &_t_macroEliminate, TimeCompiler); )
|
||||
PhaseMacroExpand mexp(igvn);
|
||||
mexp.eliminate_macro_nodes();
|
||||
igvn.set_delay_transform(false);
|
||||
@ -1875,10 +1875,10 @@ void Compile::Code_Gen() {
|
||||
|
||||
cfg.Estimate_Block_Frequency();
|
||||
cfg.GlobalCodeMotion(m,unique(),proj_list);
|
||||
if (failing()) return;
|
||||
|
||||
print_method("Global code motion", 2);
|
||||
|
||||
if (failing()) return;
|
||||
NOT_PRODUCT( verify_graph_edges(); )
|
||||
|
||||
debug_only( cfg.verify(); )
|
||||
|
||||
@ -631,7 +631,7 @@ class Compile : public Phase {
|
||||
|
||||
// Decide how to build a call.
|
||||
// The profile factor is a discount to apply to this site's interp. profile.
|
||||
CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor);
|
||||
CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true);
|
||||
bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
|
||||
|
||||
// Report if there were too many traps at a current method and bci.
|
||||
|
||||
@ -61,7 +61,7 @@ void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_met
|
||||
|
||||
CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
|
||||
JVMState* jvms, bool allow_inline,
|
||||
float prof_factor) {
|
||||
float prof_factor, bool allow_intrinsics) {
|
||||
ciMethod* caller = jvms->method();
|
||||
int bci = jvms->bci();
|
||||
Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
|
||||
@ -108,7 +108,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||
// then we return it as the inlined version of the call.
|
||||
// We do this before the strict f.p. check below because the
|
||||
// intrinsics handle strict f.p. correctly.
|
||||
if (allow_inline) {
|
||||
if (allow_inline && allow_intrinsics) {
|
||||
CallGenerator* cg = find_intrinsic(call_method, call_is_virtual);
|
||||
if (cg != NULL) return cg;
|
||||
}
|
||||
@ -455,21 +455,12 @@ void Parse::do_call() {
|
||||
// cg->generate(), we are committed. If it fails, the whole
|
||||
// compilation task is compromised.
|
||||
if (failing()) return;
|
||||
#ifndef PRODUCT
|
||||
if (PrintOpto || PrintOptoInlining || PrintInlining) {
|
||||
// Only one fall-back, so if an intrinsic fails, ignore any bytecodes.
|
||||
if (cg->is_intrinsic() && call_method->code_size() > 0) {
|
||||
tty->print("Bailed out of intrinsic, will not inline: ");
|
||||
call_method->print_name(); tty->cr();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// This can happen if a library intrinsic is available, but refuses
|
||||
// the call site, perhaps because it did not match a pattern the
|
||||
// intrinsic was expecting to optimize. The fallback position is
|
||||
// to call out-of-line.
|
||||
try_inline = false; // Inline tactic bailed out.
|
||||
cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
|
||||
// intrinsic was expecting to optimize. Should always be possible to
|
||||
// get a normal java call that may inline in that case
|
||||
cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false);
|
||||
if ((new_jvms = cg->generate(jvms)) == NULL) {
|
||||
guarantee(failing(), "call failed to generate: calls should work");
|
||||
return;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2012, 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
|
||||
@ -115,18 +115,36 @@ class Node;
|
||||
class CallNode;
|
||||
class PhiNode;
|
||||
class PhaseTransform;
|
||||
class PointsToNode;
|
||||
class Type;
|
||||
class TypePtr;
|
||||
class VectorSet;
|
||||
|
||||
class PointsToNode {
|
||||
friend class ConnectionGraph;
|
||||
class JavaObjectNode;
|
||||
class LocalVarNode;
|
||||
class FieldNode;
|
||||
class ArraycopyNode;
|
||||
|
||||
// ConnectionGraph nodes
|
||||
class PointsToNode : public ResourceObj {
|
||||
GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
|
||||
GrowableArray<PointsToNode*> _uses; // List of nodes which point to this node
|
||||
|
||||
const u1 _type; // NodeType
|
||||
u1 _flags; // NodeFlags
|
||||
u1 _escape; // EscapeState of object
|
||||
u1 _fields_escape; // EscapeState of object's fields
|
||||
|
||||
Node* const _node; // Ideal node corresponding to this PointsTo node.
|
||||
const int _idx; // Cached ideal node's _idx
|
||||
|
||||
public:
|
||||
typedef enum {
|
||||
UnknownType = 0,
|
||||
JavaObject = 1,
|
||||
LocalVar = 2,
|
||||
Field = 3
|
||||
Field = 3,
|
||||
Arraycopy = 4
|
||||
} NodeType;
|
||||
|
||||
typedef enum {
|
||||
@ -140,178 +158,387 @@ public:
|
||||
} EscapeState;
|
||||
|
||||
typedef enum {
|
||||
UnknownEdge = 0,
|
||||
PointsToEdge = 1,
|
||||
DeferredEdge = 2,
|
||||
FieldEdge = 3
|
||||
} EdgeType;
|
||||
|
||||
private:
|
||||
enum {
|
||||
EdgeMask = 3,
|
||||
EdgeShift = 2,
|
||||
|
||||
INITIAL_EDGE_COUNT = 4
|
||||
};
|
||||
|
||||
NodeType _type;
|
||||
EscapeState _escape;
|
||||
GrowableArray<uint>* _edges; // outgoing edges
|
||||
Node* _node; // Ideal node corresponding to this PointsTo node.
|
||||
int _offset; // Object fields offsets.
|
||||
bool _scalar_replaceable; // Not escaped object could be replaced with scalar
|
||||
bool _has_unknown_ptr; // Has edge to phantom_object
|
||||
|
||||
public:
|
||||
PointsToNode():
|
||||
_type(UnknownType),
|
||||
_escape(UnknownEscape),
|
||||
_edges(NULL),
|
||||
_node(NULL),
|
||||
_offset(-1),
|
||||
_has_unknown_ptr(false),
|
||||
_scalar_replaceable(true) {}
|
||||
ScalarReplaceable = 1, // Not escaped object could be replaced with scalar
|
||||
PointsToUnknown = 2, // Has edge to phantom_object
|
||||
ArraycopySrc = 4, // Has edge from Arraycopy node
|
||||
ArraycopyDst = 8 // Has edge to Arraycopy node
|
||||
} NodeFlags;
|
||||
|
||||
|
||||
EscapeState escape_state() const { return _escape; }
|
||||
NodeType node_type() const { return _type;}
|
||||
int offset() { return _offset;}
|
||||
bool scalar_replaceable() { return _scalar_replaceable;}
|
||||
bool has_unknown_ptr() { return _has_unknown_ptr;}
|
||||
|
||||
void set_offset(int offs) { _offset = offs;}
|
||||
void set_escape_state(EscapeState state) { _escape = state; }
|
||||
void set_node_type(NodeType ntype) {
|
||||
assert(_type == UnknownType || _type == ntype, "Can't change node type");
|
||||
_type = ntype;
|
||||
}
|
||||
void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
|
||||
void set_has_unknown_ptr() { _has_unknown_ptr = true; }
|
||||
|
||||
// count of outgoing edges
|
||||
uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
|
||||
|
||||
// node index of target of outgoing edge "e"
|
||||
uint edge_target(uint e) const {
|
||||
assert(_edges != NULL, "valid edge index");
|
||||
return (_edges->at(e) >> EdgeShift);
|
||||
}
|
||||
// type of outgoing edge "e"
|
||||
EdgeType edge_type(uint e) const {
|
||||
assert(_edges != NULL, "valid edge index");
|
||||
return (EdgeType) (_edges->at(e) & EdgeMask);
|
||||
PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
|
||||
_edges(C->comp_arena(), 2, 0, NULL),
|
||||
_uses (C->comp_arena(), 2, 0, NULL),
|
||||
_node(n),
|
||||
_idx(n->_idx),
|
||||
_type((u1)type),
|
||||
_escape((u1)es),
|
||||
_fields_escape((u1)es),
|
||||
_flags(ScalarReplaceable) {
|
||||
assert(n != NULL && es != UnknownEscape, "sanity");
|
||||
}
|
||||
|
||||
// add a edge of the specified type pointing to the specified target
|
||||
void add_edge(uint targIdx, EdgeType et);
|
||||
Node* ideal_node() const { return _node; }
|
||||
int idx() const { return _idx; }
|
||||
|
||||
// remove an edge of the specified type pointing to the specified target
|
||||
void remove_edge(uint targIdx, EdgeType et);
|
||||
bool is_JavaObject() const { return _type == (u1)JavaObject; }
|
||||
bool is_LocalVar() const { return _type == (u1)LocalVar; }
|
||||
bool is_Field() const { return _type == (u1)Field; }
|
||||
bool is_Arraycopy() const { return _type == (u1)Arraycopy; }
|
||||
|
||||
JavaObjectNode* as_JavaObject() { assert(is_JavaObject(),""); return (JavaObjectNode*)this; }
|
||||
LocalVarNode* as_LocalVar() { assert(is_LocalVar(),""); return (LocalVarNode*)this; }
|
||||
FieldNode* as_Field() { assert(is_Field(),""); return (FieldNode*)this; }
|
||||
ArraycopyNode* as_Arraycopy() { assert(is_Arraycopy(),""); return (ArraycopyNode*)this; }
|
||||
|
||||
EscapeState escape_state() const { return (EscapeState)_escape; }
|
||||
void set_escape_state(EscapeState state) { _escape = (u1)state; }
|
||||
|
||||
EscapeState fields_escape_state() const { return (EscapeState)_fields_escape; }
|
||||
void set_fields_escape_state(EscapeState state) { _fields_escape = (u1)state; }
|
||||
|
||||
bool has_unknown_ptr() const { return (_flags & PointsToUnknown) != 0; }
|
||||
void set_has_unknown_ptr() { _flags |= PointsToUnknown; }
|
||||
|
||||
bool arraycopy_src() const { return (_flags & ArraycopySrc) != 0; }
|
||||
void set_arraycopy_src() { _flags |= ArraycopySrc; }
|
||||
bool arraycopy_dst() const { return (_flags & ArraycopyDst) != 0; }
|
||||
void set_arraycopy_dst() { _flags |= ArraycopyDst; }
|
||||
|
||||
bool scalar_replaceable() const { return (_flags & ScalarReplaceable) != 0;}
|
||||
void set_scalar_replaceable(bool v) {
|
||||
if (v)
|
||||
_flags |= ScalarReplaceable;
|
||||
else
|
||||
_flags &= ~ScalarReplaceable;
|
||||
}
|
||||
|
||||
int edge_count() const { return _edges.length(); }
|
||||
PointsToNode* edge(int e) const { return _edges.at(e); }
|
||||
bool add_edge(PointsToNode* edge) { return _edges.append_if_missing(edge); }
|
||||
|
||||
int use_count() const { return _uses.length(); }
|
||||
PointsToNode* use(int e) const { return _uses.at(e); }
|
||||
bool add_use(PointsToNode* use) { return _uses.append_if_missing(use); }
|
||||
|
||||
// Mark base edge use to distinguish from stored value edge.
|
||||
bool add_base_use(FieldNode* use) { return _uses.append_if_missing((PointsToNode*)((intptr_t)use + 1)); }
|
||||
static bool is_base_use(PointsToNode* use) { return (((intptr_t)use) & 1); }
|
||||
static PointsToNode* get_use_node(PointsToNode* use) { return (PointsToNode*)(((intptr_t)use) & ~1); }
|
||||
|
||||
// Return true if this node points to specified node or nodes it points to.
|
||||
bool points_to(JavaObjectNode* ptn) const;
|
||||
|
||||
// Return true if this node points only to non-escaping allocations.
|
||||
bool non_escaping_allocation();
|
||||
|
||||
// Return true if one node points to an other.
|
||||
bool meet(PointsToNode* ptn);
|
||||
|
||||
#ifndef PRODUCT
|
||||
NodeType node_type() const { return (NodeType)_type;}
|
||||
void dump(bool print_state=true) const;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class LocalVarNode: public PointsToNode {
|
||||
public:
|
||||
LocalVarNode(Compile *C, Node* n, EscapeState es):
|
||||
PointsToNode(C, n, es, LocalVar) {}
|
||||
};
|
||||
|
||||
class JavaObjectNode: public PointsToNode {
|
||||
public:
|
||||
JavaObjectNode(Compile *C, Node* n, EscapeState es):
|
||||
PointsToNode(C, n, es, JavaObject) {
|
||||
if (es > NoEscape)
|
||||
set_scalar_replaceable(false);
|
||||
}
|
||||
};
|
||||
|
||||
class FieldNode: public PointsToNode {
|
||||
GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node
|
||||
const int _offset; // Field's offset.
|
||||
const bool _is_oop; // Field points to object
|
||||
bool _has_unknown_base; // Has phantom_object base
|
||||
public:
|
||||
FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
|
||||
PointsToNode(C, n, es, Field),
|
||||
_offset(offs), _is_oop(is_oop),
|
||||
_has_unknown_base(false) {}
|
||||
|
||||
int offset() const { return _offset;}
|
||||
bool is_oop() const { return _is_oop;}
|
||||
bool has_unknown_base() const { return _has_unknown_base; }
|
||||
void set_has_unknown_base() { _has_unknown_base = true; }
|
||||
|
||||
int base_count() const { return _bases.length(); }
|
||||
PointsToNode* base(int e) const { return _bases.at(e); }
|
||||
bool add_base(PointsToNode* base) { return _bases.append_if_missing(base); }
|
||||
#ifdef ASSERT
|
||||
// Return true if bases points to this java object.
|
||||
bool has_base(JavaObjectNode* ptn) const;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class ArraycopyNode: public PointsToNode {
|
||||
public:
|
||||
ArraycopyNode(Compile *C, Node* n, EscapeState es):
|
||||
PointsToNode(C, n, es, Arraycopy) {}
|
||||
};
|
||||
|
||||
// Iterators for PointsTo node's edges:
|
||||
// for (EdgeIterator i(n); i.has_next(); i.next()) {
|
||||
// PointsToNode* u = i.get();
|
||||
class PointsToIterator: public StackObj {
|
||||
protected:
|
||||
const PointsToNode* node;
|
||||
const int cnt;
|
||||
int i;
|
||||
public:
|
||||
inline PointsToIterator(const PointsToNode* n, int cnt) : node(n), cnt(cnt), i(0) { }
|
||||
inline bool has_next() const { return i < cnt; }
|
||||
inline void next() { i++; }
|
||||
PointsToNode* get() const { ShouldNotCallThis(); return NULL; }
|
||||
};
|
||||
|
||||
class EdgeIterator: public PointsToIterator {
|
||||
public:
|
||||
inline EdgeIterator(const PointsToNode* n) : PointsToIterator(n, n->edge_count()) { }
|
||||
inline PointsToNode* get() const { return node->edge(i); }
|
||||
};
|
||||
|
||||
class UseIterator: public PointsToIterator {
|
||||
public:
|
||||
inline UseIterator(const PointsToNode* n) : PointsToIterator(n, n->use_count()) { }
|
||||
inline PointsToNode* get() const { return node->use(i); }
|
||||
};
|
||||
|
||||
class BaseIterator: public PointsToIterator {
|
||||
public:
|
||||
inline BaseIterator(const FieldNode* n) : PointsToIterator(n, n->base_count()) { }
|
||||
inline PointsToNode* get() const { return ((PointsToNode*)node)->as_Field()->base(i); }
|
||||
};
|
||||
|
||||
|
||||
class ConnectionGraph: public ResourceObj {
|
||||
private:
|
||||
GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed
|
||||
// by ideal node index.
|
||||
GrowableArray<PointsToNode*> _nodes; // Map from ideal nodes to
|
||||
// ConnectionGraph nodes.
|
||||
|
||||
Unique_Node_List _delayed_worklist; // Nodes to be processed before
|
||||
// the call build_connection_graph().
|
||||
GrowableArray<PointsToNode*> _worklist; // Nodes to be processed
|
||||
|
||||
GrowableArray<MergeMemNode *> _mergemem_worklist; // List of all MergeMem nodes
|
||||
bool _collecting; // Indicates whether escape information
|
||||
// is still being collected. If false,
|
||||
// no new nodes will be processed.
|
||||
|
||||
VectorSet _processed; // Records which nodes have been
|
||||
// processed.
|
||||
bool _verify; // verify graph
|
||||
|
||||
bool _collecting; // Indicates whether escape information
|
||||
// is still being collected. If false,
|
||||
// no new nodes will be processed.
|
||||
JavaObjectNode* phantom_obj; // Unknown object
|
||||
JavaObjectNode* null_obj;
|
||||
Node* _pcmp_neq; // ConI(#CC_GT)
|
||||
Node* _pcmp_eq; // ConI(#CC_EQ)
|
||||
|
||||
bool _progress; // Indicates whether new Graph's edges
|
||||
// were created.
|
||||
Compile* _compile; // Compile object for current compilation
|
||||
PhaseIterGVN* _igvn; // Value numbering
|
||||
|
||||
uint _phantom_object; // Index of globally escaping object
|
||||
// that pointer values loaded from
|
||||
// a field which has not been set
|
||||
// are assumed to point to.
|
||||
uint _oop_null; // ConP(#NULL)->_idx
|
||||
uint _noop_null; // ConN(#NULL)->_idx
|
||||
Node* _pcmp_neq; // ConI(#CC_GT)
|
||||
Node* _pcmp_eq; // ConI(#CC_EQ)
|
||||
|
||||
Compile * _compile; // Compile object for current compilation
|
||||
PhaseIterGVN * _igvn; // Value numbering
|
||||
Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
|
||||
|
||||
// Address of an element in _nodes. Used when the element is to be modified
|
||||
PointsToNode *ptnode_adr(uint idx) const {
|
||||
PointsToNode* ptnode_adr(int idx) const {
|
||||
// There should be no new ideal nodes during ConnectionGraph build,
|
||||
// growableArray::adr_at() will throw assert otherwise.
|
||||
return _nodes.adr_at(idx);
|
||||
// growableArray::at() will throw assert otherwise.
|
||||
return _nodes.at(idx);
|
||||
}
|
||||
uint nodes_size() const { return _nodes.length(); }
|
||||
|
||||
bool is_null_ptr(uint idx) const { return (idx == _noop_null || idx == _oop_null); }
|
||||
// Add nodes to ConnectionGraph.
|
||||
void add_local_var(Node* n, PointsToNode::EscapeState es);
|
||||
void add_java_object(Node* n, PointsToNode::EscapeState es);
|
||||
void add_field(Node* n, PointsToNode::EscapeState es, int offset);
|
||||
void add_arraycopy(Node* n, PointsToNode::EscapeState es, PointsToNode* src, PointsToNode* dst);
|
||||
|
||||
// Add node to ConnectionGraph.
|
||||
void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
|
||||
// Compute the escape state for arguments to a call.
|
||||
void process_call_arguments(CallNode *call);
|
||||
|
||||
// Add PointsToNode node corresponding to a call
|
||||
void add_call_node(CallNode* call);
|
||||
|
||||
// Map ideal node to existing PointsTo node (usually phantom_object).
|
||||
void map_ideal_node(Node *n, PointsToNode* ptn) {
|
||||
assert(ptn != NULL, "only existing PointsTo node");
|
||||
_nodes.at_put(n->_idx, ptn);
|
||||
}
|
||||
|
||||
// Create PointsToNode node and add it to Connection Graph.
|
||||
void add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist);
|
||||
|
||||
// Add final simple edges to graph.
|
||||
void add_final_edges(Node *n);
|
||||
|
||||
// Finish Graph construction.
|
||||
bool complete_connection_graph(GrowableArray<PointsToNode*>& ptnodes_worklist,
|
||||
GrowableArray<JavaObjectNode*>& non_escaped_worklist,
|
||||
GrowableArray<JavaObjectNode*>& java_objects_worklist,
|
||||
GrowableArray<FieldNode*>& oop_fields_worklist);
|
||||
|
||||
#ifdef ASSERT
|
||||
void verify_connection_graph(GrowableArray<PointsToNode*>& ptnodes_worklist,
|
||||
GrowableArray<JavaObjectNode*>& non_escaped_worklist,
|
||||
GrowableArray<JavaObjectNode*>& java_objects_worklist,
|
||||
GrowableArray<Node*>& addp_worklist);
|
||||
#endif
|
||||
|
||||
// Add all references to this JavaObject node.
|
||||
int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
|
||||
|
||||
// Put node on worklist if it is (or was) not there.
|
||||
void add_to_worklist(PointsToNode* pt) {
|
||||
_worklist.push(pt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Put on worklist all uses of this node.
|
||||
void add_uses_to_worklist(PointsToNode* pt) {
|
||||
for (UseIterator i(pt); i.has_next(); i.next())
|
||||
_worklist.push(i.get());
|
||||
}
|
||||
|
||||
// Put on worklist all field's uses and related field nodes.
|
||||
void add_field_uses_to_worklist(FieldNode* field);
|
||||
|
||||
// Put on worklist all related field nodes.
|
||||
void add_fields_to_worklist(FieldNode* field, PointsToNode* base);
|
||||
|
||||
// Find fields which have unknown value.
|
||||
int find_field_value(FieldNode* field);
|
||||
|
||||
// Find fields initializing values for allocations.
|
||||
int find_init_values(JavaObjectNode* ptn, PointsToNode* init_val, PhaseTransform* phase);
|
||||
|
||||
// Set the escape state of an object and its fields.
|
||||
void set_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
|
||||
// Don't change non-escaping state of NULL pointer.
|
||||
if (ptn != null_obj) {
|
||||
if (ptn->escape_state() < esc)
|
||||
ptn->set_escape_state(esc);
|
||||
if (ptn->fields_escape_state() < esc)
|
||||
ptn->set_fields_escape_state(esc);
|
||||
}
|
||||
}
|
||||
void set_fields_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
|
||||
// Don't change non-escaping state of NULL pointer.
|
||||
if (ptn != null_obj) {
|
||||
if (ptn->fields_escape_state() < esc)
|
||||
ptn->set_fields_escape_state(esc);
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate GlobalEscape and ArgEscape escape states to all nodes
|
||||
// and check that we still have non-escaping java objects.
|
||||
bool find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
|
||||
GrowableArray<JavaObjectNode*>& non_escaped_worklist);
|
||||
|
||||
// Adjust scalar_replaceable state after Connection Graph is built.
|
||||
void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
|
||||
|
||||
// Optimize ideal graph.
|
||||
void optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
|
||||
GrowableArray<Node*>& storestore_worklist);
|
||||
// Optimize objects compare.
|
||||
Node* optimize_ptr_compare(Node* n);
|
||||
|
||||
// Returns unique corresponding java object or NULL.
|
||||
JavaObjectNode* unique_java_object(Node *n);
|
||||
|
||||
// Add an edge of the specified type pointing to the specified target.
|
||||
bool add_edge(PointsToNode* from, PointsToNode* to) {
|
||||
assert(!from->is_Field() || from->as_Field()->is_oop(), "sanity");
|
||||
|
||||
if (to == phantom_obj) {
|
||||
if (from->has_unknown_ptr()) {
|
||||
return false; // already points to phantom_obj
|
||||
}
|
||||
from->set_has_unknown_ptr();
|
||||
}
|
||||
|
||||
bool is_new = from->add_edge(to);
|
||||
assert(to != phantom_obj || is_new, "sanity");
|
||||
if (is_new) { // New edge?
|
||||
assert(!_verify, "graph is incomplete");
|
||||
is_new = to->add_use(from);
|
||||
assert(is_new, "use should be also new");
|
||||
}
|
||||
return is_new;
|
||||
}
|
||||
|
||||
// Add an edge from Field node to its base and back.
|
||||
bool add_base(FieldNode* from, PointsToNode* to) {
|
||||
assert(!to->is_Arraycopy(), "sanity");
|
||||
if (to == phantom_obj) {
|
||||
if (from->has_unknown_base()) {
|
||||
return false; // already has phantom_obj base
|
||||
}
|
||||
from->set_has_unknown_base();
|
||||
}
|
||||
bool is_new = from->add_base(to);
|
||||
assert(to != phantom_obj || is_new, "sanity");
|
||||
if (is_new) { // New edge?
|
||||
assert(!_verify, "graph is incomplete");
|
||||
if (to == null_obj)
|
||||
return is_new; // Don't add fields to NULL pointer.
|
||||
if (to->is_JavaObject()) {
|
||||
is_new = to->add_edge(from);
|
||||
} else {
|
||||
is_new = to->add_base_use(from);
|
||||
}
|
||||
assert(is_new, "use should be also new");
|
||||
}
|
||||
return is_new;
|
||||
}
|
||||
|
||||
// Add LocalVar node and edge if possible
|
||||
void add_local_var_and_edge(Node* n, PointsToNode::EscapeState es, Node* to,
|
||||
Unique_Node_List *delayed_worklist) {
|
||||
PointsToNode* ptn = ptnode_adr(to->_idx);
|
||||
if (delayed_worklist != NULL) { // First iteration of CG construction
|
||||
add_local_var(n, es);
|
||||
if (ptn == NULL) {
|
||||
delayed_worklist->push(n);
|
||||
return; // Process it later.
|
||||
}
|
||||
} else {
|
||||
assert(ptn != NULL, "node should be registered");
|
||||
}
|
||||
add_edge(ptnode_adr(n->_idx), ptn);
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
bool is_oop_field(Node* n, int offset);
|
||||
static Node* get_addp_base(Node *addp);
|
||||
static Node* find_second_addp(Node* addp, Node* n);
|
||||
|
||||
// offset of a field reference
|
||||
int address_offset(Node* adr, PhaseTransform *phase);
|
||||
|
||||
// compute the escape state for arguments to a call
|
||||
void process_call_arguments(CallNode *call, PhaseTransform *phase);
|
||||
|
||||
// compute the escape state for the return value of a call
|
||||
void process_call_result(ProjNode *resproj, PhaseTransform *phase);
|
||||
// Propagate unique types created for unescaped allocated objects
|
||||
// through the graph
|
||||
void split_unique_types(GrowableArray<Node *> &alloc_worklist);
|
||||
|
||||
// Populate Connection Graph with Ideal nodes.
|
||||
void record_for_escape_analysis(Node *n, PhaseTransform *phase);
|
||||
// Helper methods for unique types split.
|
||||
bool split_AddP(Node *addp, Node *base);
|
||||
|
||||
// Build Connection Graph and set nodes escape state.
|
||||
void build_connection_graph(Node *n, PhaseTransform *phase);
|
||||
PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, bool &new_created);
|
||||
PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist);
|
||||
|
||||
// walk the connection graph starting at the node corresponding to "n" and
|
||||
// add the index of everything it could point to, to "ptset". This may cause
|
||||
// Phi's encountered to get (re)processed (which requires "phase".)
|
||||
VectorSet* PointsTo(Node * n);
|
||||
|
||||
// Reused structures for PointsTo().
|
||||
VectorSet pt_ptset;
|
||||
VectorSet pt_visited;
|
||||
GrowableArray<uint> pt_worklist;
|
||||
|
||||
// Edge manipulation. The "from_i" and "to_i" arguments are the
|
||||
// node indices of the source and destination of the edge
|
||||
void add_pointsto_edge(uint from_i, uint to_i);
|
||||
void add_deferred_edge(uint from_i, uint to_i);
|
||||
void add_field_edge(uint from_i, uint to_i, int offs);
|
||||
|
||||
// Add an edge of the specified type pointing to the specified target.
|
||||
// Set _progress if new edge is added.
|
||||
void add_edge(PointsToNode *f, uint to_i, PointsToNode::EdgeType et) {
|
||||
uint e_cnt = f->edge_count();
|
||||
f->add_edge(to_i, et);
|
||||
_progress |= (f->edge_count() != e_cnt);
|
||||
}
|
||||
|
||||
// Add an edge to node given by "to_i" from any field of adr_i whose offset
|
||||
// matches "offset" A deferred edge is added if to_i is a LocalVar, and
|
||||
// a pointsto edge is added if it is a JavaObject
|
||||
void add_edge_from_fields(uint adr, uint to_i, int offs);
|
||||
|
||||
// Add a deferred edge from node given by "from_i" to any field
|
||||
// of adr_i whose offset matches "offset"
|
||||
void add_deferred_edge_to_fields(uint from_i, uint adr, int offs);
|
||||
void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis);
|
||||
Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist);
|
||||
Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop);
|
||||
|
||||
|
||||
// Remove outgoing deferred edges from the node referenced by "ni".
|
||||
// Any outgoing edges from the target of the deferred edge are copied
|
||||
// to "ni".
|
||||
void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited);
|
||||
GrowableArray<MergeMemNode*> _mergemem_worklist; // List of all MergeMem nodes
|
||||
|
||||
Node_Array _node_map; // used for bookeeping during type splitting
|
||||
// Used for the following purposes:
|
||||
@ -320,21 +547,18 @@ private:
|
||||
// MemNode - new memory input for this node
|
||||
// ChecCastPP - allocation that this is a cast of
|
||||
// allocation - CheckCastPP of the allocation
|
||||
bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
|
||||
PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
|
||||
PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
|
||||
void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn);
|
||||
Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
|
||||
|
||||
// Propagate unique types created for unescaped allocated objects
|
||||
// through the graph
|
||||
void split_unique_types(GrowableArray<Node *> &alloc_worklist);
|
||||
|
||||
// manage entries in _node_map
|
||||
void set_map(int idx, Node *n) { _node_map.map(idx, n); }
|
||||
Node *get_map(int idx) { return _node_map[idx]; }
|
||||
PhiNode *get_map_phi(int idx) {
|
||||
Node *phi = _node_map[idx];
|
||||
|
||||
void set_map(Node* from, Node* to) {
|
||||
ideal_nodes.push(from);
|
||||
_node_map.map(from->_idx, to);
|
||||
}
|
||||
|
||||
Node* get_map(int idx) { return _node_map[idx]; }
|
||||
|
||||
PhiNode* get_map_phi(int idx) {
|
||||
Node* phi = _node_map[idx];
|
||||
return (phi == NULL) ? NULL : phi->as_Phi();
|
||||
}
|
||||
|
||||
@ -344,23 +568,6 @@ private:
|
||||
_igvn->add_users_to_worklist(n);
|
||||
}
|
||||
|
||||
// Set the escape state of a node
|
||||
void set_escape_state(uint ni, PointsToNode::EscapeState es);
|
||||
|
||||
// Find fields initializing values for allocations.
|
||||
void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
|
||||
|
||||
// Adjust escape state after Connection Graph is built.
|
||||
void adjust_escape_state(Node* n);
|
||||
|
||||
// Propagate escape states to referenced nodes.
|
||||
bool propagate_escape_state(GrowableArray<int>* cg_worklist,
|
||||
GrowableArray<uint>* worklist,
|
||||
PointsToNode::EscapeState esc_state);
|
||||
|
||||
// Optimize objects compare.
|
||||
Node* optimize_ptr_compare(Node* n);
|
||||
|
||||
// Compute the escape information
|
||||
bool compute_escape();
|
||||
|
||||
@ -373,11 +580,10 @@ public:
|
||||
// Perform escape analysis
|
||||
static void do_analysis(Compile *C, PhaseIterGVN *igvn);
|
||||
|
||||
// escape state of a node
|
||||
PointsToNode::EscapeState escape_state(Node *n);
|
||||
bool not_global_escape(Node *n);
|
||||
|
||||
#ifndef PRODUCT
|
||||
void dump();
|
||||
void dump(GrowableArray<PointsToNode*>& ptnodes_worklist);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -338,8 +338,27 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_bitCount_i:
|
||||
if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_bitCount_l:
|
||||
if (!UsePopCountInstruction) return NULL;
|
||||
if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_numberOfLeadingZeros_i:
|
||||
if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_numberOfLeadingZeros_l:
|
||||
if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_numberOfTrailingZeros_i:
|
||||
if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_numberOfTrailingZeros_l:
|
||||
if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL;
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_Reference_get:
|
||||
@ -416,14 +435,12 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
return kit.transfer_exceptions_into_jvms();
|
||||
}
|
||||
|
||||
if (PrintIntrinsics) {
|
||||
// The intrinsic bailed out
|
||||
if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
|
||||
if (jvms->has_method()) {
|
||||
// Not a root compile.
|
||||
tty->print("Did not inline intrinsic %s%s at bci:%d in",
|
||||
vmIntrinsics::name_at(intrinsic_id()),
|
||||
(is_virtual() ? " (virtual)" : ""), kit.bci());
|
||||
kit.caller()->print_short_name(tty);
|
||||
tty->print_cr(" (%d bytes)", kit.caller()->code_size());
|
||||
const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
|
||||
CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), msg);
|
||||
} else {
|
||||
// Root compile
|
||||
tty->print("Did not generate intrinsic %s%s at bci:%d in",
|
||||
@ -5453,4 +5470,3 @@ bool LibraryCallKit::inline_reference_get() {
|
||||
push(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -39,8 +39,9 @@ elapsedTimer Phase::_t_stubCompilation;
|
||||
|
||||
// The next timers used for LogCompilation
|
||||
elapsedTimer Phase::_t_parser;
|
||||
elapsedTimer Phase::_t_escapeAnalysis;
|
||||
elapsedTimer Phase::_t_optimizer;
|
||||
elapsedTimer Phase::_t_escapeAnalysis;
|
||||
elapsedTimer Phase::_t_connectionGraph;
|
||||
elapsedTimer Phase::_t_idealLoop;
|
||||
elapsedTimer Phase::_t_ccp;
|
||||
elapsedTimer Phase::_t_matcher;
|
||||
@ -51,6 +52,7 @@ elapsedTimer Phase::_t_output;
|
||||
elapsedTimer Phase::_t_graphReshaping;
|
||||
elapsedTimer Phase::_t_scheduler;
|
||||
elapsedTimer Phase::_t_blockOrdering;
|
||||
elapsedTimer Phase::_t_macroEliminate;
|
||||
elapsedTimer Phase::_t_macroExpand;
|
||||
elapsedTimer Phase::_t_peephole;
|
||||
elapsedTimer Phase::_t_codeGeneration;
|
||||
@ -104,6 +106,8 @@ void Phase::print_timers() {
|
||||
if (DoEscapeAnalysis) {
|
||||
// EA is part of Optimizer.
|
||||
tty->print_cr (" escape analysis: %3.3f sec", Phase::_t_escapeAnalysis.seconds());
|
||||
tty->print_cr (" connection graph: %3.3f sec", Phase::_t_connectionGraph.seconds());
|
||||
tty->print_cr (" macroEliminate : %3.3f sec", Phase::_t_macroEliminate.seconds());
|
||||
}
|
||||
tty->print_cr (" iterGVN : %3.3f sec", Phase::_t_iterGVN.seconds());
|
||||
tty->print_cr (" idealLoop : %3.3f sec", Phase::_t_idealLoop.seconds());
|
||||
@ -112,9 +116,10 @@ void Phase::print_timers() {
|
||||
tty->print_cr (" iterGVN2 : %3.3f sec", Phase::_t_iterGVN2.seconds());
|
||||
tty->print_cr (" macroExpand : %3.3f sec", Phase::_t_macroExpand.seconds());
|
||||
tty->print_cr (" graphReshape : %3.3f sec", Phase::_t_graphReshaping.seconds());
|
||||
double optimizer_subtotal = Phase::_t_iterGVN.seconds() +
|
||||
double optimizer_subtotal = Phase::_t_iterGVN.seconds() + Phase::_t_iterGVN2.seconds() +
|
||||
Phase::_t_escapeAnalysis.seconds() + Phase::_t_macroEliminate.seconds() +
|
||||
Phase::_t_idealLoop.seconds() + Phase::_t_ccp.seconds() +
|
||||
Phase::_t_graphReshaping.seconds();
|
||||
Phase::_t_macroExpand.seconds() + Phase::_t_graphReshaping.seconds();
|
||||
double percent_of_optimizer = ((optimizer_subtotal == 0.0) ? 0.0 : (optimizer_subtotal / Phase::_t_optimizer.seconds() * 100.0));
|
||||
tty->print_cr (" subtotal : %3.3f sec, %3.2f %%", optimizer_subtotal, percent_of_optimizer);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -72,8 +72,12 @@ protected:
|
||||
|
||||
// The next timers used for LogCompilation
|
||||
static elapsedTimer _t_parser;
|
||||
static elapsedTimer _t_escapeAnalysis;
|
||||
static elapsedTimer _t_optimizer;
|
||||
public:
|
||||
// ConnectionGraph can't be Phase since it is used after EA done.
|
||||
static elapsedTimer _t_escapeAnalysis;
|
||||
static elapsedTimer _t_connectionGraph;
|
||||
protected:
|
||||
static elapsedTimer _t_idealLoop;
|
||||
static elapsedTimer _t_ccp;
|
||||
static elapsedTimer _t_matcher;
|
||||
@ -84,6 +88,7 @@ protected:
|
||||
static elapsedTimer _t_graphReshaping;
|
||||
static elapsedTimer _t_scheduler;
|
||||
static elapsedTimer _t_blockOrdering;
|
||||
static elapsedTimer _t_macroEliminate;
|
||||
static elapsedTimer _t_macroExpand;
|
||||
static elapsedTimer _t_peephole;
|
||||
static elapsedTimer _t_codeGeneration;
|
||||
|
||||
@ -1301,9 +1301,6 @@ JVM_END
|
||||
// Inner class reflection ///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
|
||||
const int inner_class_info_index = 0;
|
||||
const int outer_class_info_index = 1;
|
||||
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
// ofClass is a reference to a java_lang_Class object. The mirror object
|
||||
// of an instanceKlass
|
||||
@ -1315,26 +1312,26 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
|
||||
}
|
||||
|
||||
instanceKlassHandle k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)));
|
||||
InnerClassesIterator iter(k);
|
||||
|
||||
if (k->inner_classes()->length() == 0) {
|
||||
if (iter.length() == 0) {
|
||||
// Neither an inner nor outer class
|
||||
oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray)JNIHandles::make_local(env, result);
|
||||
}
|
||||
|
||||
// find inner class info
|
||||
typeArrayHandle icls(thread, k->inner_classes());
|
||||
constantPoolHandle cp(thread, k->constants());
|
||||
int length = icls->length();
|
||||
int length = iter.length();
|
||||
|
||||
// Allocate temp. result array
|
||||
objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length/4, CHECK_NULL);
|
||||
objArrayHandle result (THREAD, r);
|
||||
int members = 0;
|
||||
|
||||
for(int i = 0; i < length; i += 4) {
|
||||
int ioff = icls->ushort_at(i + inner_class_info_index);
|
||||
int ooff = icls->ushort_at(i + outer_class_info_index);
|
||||
for (; !iter.done(); iter.next()) {
|
||||
int ioff = iter.inner_class_info_index();
|
||||
int ooff = iter.outer_class_info_index();
|
||||
|
||||
if (ioff != 0 && ooff != 0) {
|
||||
// Check to see if the name matches the class we're looking for
|
||||
@ -1392,17 +1389,13 @@ klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k,
|
||||
bool* inner_is_member,
|
||||
TRAPS) {
|
||||
Thread* thread = THREAD;
|
||||
const int inner_class_info_index = inner_class_inner_class_info_offset;
|
||||
const int outer_class_info_index = inner_class_outer_class_info_offset;
|
||||
|
||||
if (k->inner_classes()->length() == 0) {
|
||||
InnerClassesIterator iter(k);
|
||||
if (iter.length() == 0) {
|
||||
// No inner class info => no declaring class
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typeArrayHandle i_icls(thread, k->inner_classes());
|
||||
constantPoolHandle i_cp(thread, k->constants());
|
||||
int i_length = i_icls->length();
|
||||
|
||||
bool found = false;
|
||||
klassOop ok;
|
||||
@ -1410,10 +1403,10 @@ klassOop instanceKlass::compute_enclosing_class_impl(instanceKlassHandle k,
|
||||
*inner_is_member = false;
|
||||
|
||||
// Find inner_klass attribute
|
||||
for (int i = 0; i < i_length && !found; i += inner_class_next_offset) {
|
||||
int ioff = i_icls->ushort_at(i + inner_class_info_index);
|
||||
int ooff = i_icls->ushort_at(i + outer_class_info_index);
|
||||
int noff = i_icls->ushort_at(i + inner_class_inner_name_offset);
|
||||
for (; !iter.done() && !found; iter.next()) {
|
||||
int ioff = iter.inner_class_info_index();
|
||||
int ooff = iter.outer_class_info_index();
|
||||
int noff = iter.inner_name_index();
|
||||
if (ioff != 0) {
|
||||
// Check to see if the name matches the class we're looking for
|
||||
// before attempting to find the class.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2012, 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
|
||||
@ -292,8 +292,8 @@ void JvmtiClassFileReconstituter::write_signature_attribute(u2 generic_signature
|
||||
|
||||
// Compute the number of entries in the InnerClasses attribute
|
||||
u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
|
||||
typeArrayOop inner_class_list = ikh()->inner_classes();
|
||||
return (inner_class_list == NULL) ? 0 : inner_class_list->length();
|
||||
InnerClassesIterator iter(ikh());
|
||||
return iter.length();
|
||||
}
|
||||
|
||||
// Write an annotation attribute. The VM stores them in raw form, so all we need
|
||||
@ -324,26 +324,20 @@ void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_n
|
||||
// JVMSpec| } classes[number_of_classes];
|
||||
// JVMSpec| }
|
||||
void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
|
||||
typeArrayOop inner_class_list = ikh()->inner_classes();
|
||||
guarantee(inner_class_list != NULL && inner_class_list->length() == length,
|
||||
InnerClassesIterator iter(ikh());
|
||||
guarantee(iter.length() != 0 && iter.length() == length,
|
||||
"caller must check");
|
||||
typeArrayHandle inner_class_list_h(thread(), inner_class_list);
|
||||
assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
|
||||
u2 entry_count = length / instanceKlass::inner_class_next_offset;
|
||||
u4 size = 2 + entry_count * (2+2+2+2);
|
||||
|
||||
write_attribute_name_index("InnerClasses");
|
||||
write_u4(size);
|
||||
write_u2(entry_count);
|
||||
for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
|
||||
write_u2(inner_class_list_h->ushort_at(
|
||||
i + instanceKlass::inner_class_inner_class_info_offset));
|
||||
write_u2(inner_class_list_h->ushort_at(
|
||||
i + instanceKlass::inner_class_outer_class_info_offset));
|
||||
write_u2(inner_class_list_h->ushort_at(
|
||||
i + instanceKlass::inner_class_inner_name_offset));
|
||||
write_u2(inner_class_list_h->ushort_at(
|
||||
i + instanceKlass::inner_class_access_flags_offset));
|
||||
for (; !iter.done(); iter.next()) {
|
||||
write_u2(iter.inner_class_info_index());
|
||||
write_u2(iter.outer_class_info_index());
|
||||
write_u2(iter.inner_name_index());
|
||||
write_u2(iter.inner_access_flags());
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,8 +721,11 @@ void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
|
||||
case Bytecodes::_invokestatic : // fall through
|
||||
case Bytecodes::_invokedynamic : // fall through
|
||||
case Bytecodes::_invokeinterface :
|
||||
assert(len == 3 || (code == Bytecodes::_invokeinterface && len ==5),
|
||||
assert(len == 3 ||
|
||||
(code == Bytecodes::_invokeinterface && len == 5) ||
|
||||
(code == Bytecodes::_invokedynamic && len == 5),
|
||||
"sanity check");
|
||||
|
||||
int cpci = Bytes::get_native_u2(bcp+1);
|
||||
bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);
|
||||
if (is_invokedynamic)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2012, 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
|
||||
@ -324,6 +324,12 @@ class JvmtiExport : public AllStatic {
|
||||
record_vm_internal_object_allocation(object);
|
||||
}
|
||||
}
|
||||
inline static void post_array_size_exhausted() {
|
||||
if (should_post_resource_exhausted()) {
|
||||
post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
|
||||
"Requested array size exceeds VM limit");
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup_thread (JavaThread* thread) KERNEL_RETURN;
|
||||
|
||||
|
||||
@ -2400,44 +2400,33 @@ void VM_RedefineClasses::set_new_constant_pool(
|
||||
// new constant indices as needed. The inner classes info is a
|
||||
// quadruple:
|
||||
// (inner_class_info, outer_class_info, inner_name, inner_access_flags)
|
||||
typeArrayOop inner_class_list = scratch_class->inner_classes();
|
||||
int icl_length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
|
||||
if (icl_length > 0) {
|
||||
typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
|
||||
for (int i = 0; i < icl_length;
|
||||
i += instanceKlass::inner_class_next_offset) {
|
||||
int cur_index = inner_class_list_h->ushort_at(i
|
||||
+ instanceKlass::inner_class_inner_class_info_offset);
|
||||
if (cur_index == 0) {
|
||||
continue; // JVM spec. allows null inner class refs so skip it
|
||||
}
|
||||
int new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("inner_class_info change: %d to %d", cur_index, new_index));
|
||||
inner_class_list_h->ushort_at_put(i
|
||||
+ instanceKlass::inner_class_inner_class_info_offset, new_index);
|
||||
}
|
||||
cur_index = inner_class_list_h->ushort_at(i
|
||||
+ instanceKlass::inner_class_outer_class_info_offset);
|
||||
new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("outer_class_info change: %d to %d", cur_index, new_index));
|
||||
inner_class_list_h->ushort_at_put(i
|
||||
+ instanceKlass::inner_class_outer_class_info_offset, new_index);
|
||||
}
|
||||
cur_index = inner_class_list_h->ushort_at(i
|
||||
+ instanceKlass::inner_class_inner_name_offset);
|
||||
new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("inner_name change: %d to %d", cur_index, new_index));
|
||||
inner_class_list_h->ushort_at_put(i
|
||||
+ instanceKlass::inner_class_inner_name_offset, new_index);
|
||||
}
|
||||
} // end for each inner class
|
||||
} // end if we have inner classes
|
||||
InnerClassesIterator iter(scratch_class);
|
||||
for (; !iter.done(); iter.next()) {
|
||||
int cur_index = iter.inner_class_info_index();
|
||||
if (cur_index == 0) {
|
||||
continue; // JVM spec. allows null inner class refs so skip it
|
||||
}
|
||||
int new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("inner_class_info change: %d to %d", cur_index, new_index));
|
||||
iter.set_inner_class_info_index(new_index);
|
||||
}
|
||||
cur_index = iter.outer_class_info_index();
|
||||
new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("outer_class_info change: %d to %d", cur_index, new_index));
|
||||
iter.set_outer_class_info_index(new_index);
|
||||
}
|
||||
cur_index = iter.inner_name_index();
|
||||
new_index = find_new_index(cur_index);
|
||||
if (new_index != 0) {
|
||||
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
|
||||
("inner_name change: %d to %d", cur_index, new_index));
|
||||
iter.set_inner_name_index(new_index);
|
||||
}
|
||||
} // end for each inner class
|
||||
|
||||
// Attach each method in klass to the new constant pool and update
|
||||
// to use new constant pool indices as needed:
|
||||
|
||||
@ -121,6 +121,7 @@ extern "C" {
|
||||
void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
|
||||
void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
|
||||
void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
|
||||
void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
|
||||
}
|
||||
|
||||
#define CC (char*) /* cast a literal from (const char*) */
|
||||
@ -133,7 +134,8 @@ static JNINativeMethod lookup_special_native_methods[] = {
|
||||
|
||||
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
|
||||
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }
|
||||
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
|
||||
{ CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) },
|
||||
};
|
||||
|
||||
static address lookup_special_native(char* jni_name) {
|
||||
|
||||
114
hotspot/src/share/vm/prims/whitebox.cpp
Normal file
114
hotspot/src/share/vm/prims/whitebox.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/whitebox.hpp"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#ifndef SERIALGC
|
||||
#include "gc_implementation/g1/concurrentMark.hpp"
|
||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc_implementation/g1/heapRegionRemSet.hpp"
|
||||
#endif // !SERIALGC
|
||||
|
||||
bool WhiteBox::_used = false;
|
||||
|
||||
// Entry macro to transition from JNI to VM state.
|
||||
|
||||
#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
|
||||
#define WB_END JNI_END
|
||||
|
||||
// Definitions of functions exposed via Whitebox API
|
||||
|
||||
WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
|
||||
return (jlong)(void*)JNIHandles::resolve(obj);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
|
||||
return heapOopSize;
|
||||
WB_END
|
||||
|
||||
#ifndef SERIALGC
|
||||
WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
|
||||
G1CollectedHeap* g1 = G1CollectedHeap::heap();
|
||||
oop result = JNIHandles::resolve(obj);
|
||||
const HeapRegion* hr = g1->heap_region_containing(result);
|
||||
return hr->isHumongous();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
|
||||
G1CollectedHeap* g1 = G1CollectedHeap::heap();
|
||||
size_t nr = g1->free_regions();
|
||||
return (jlong)nr;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
|
||||
G1CollectedHeap* g1 = G1CollectedHeap::heap();
|
||||
ConcurrentMark* cm = g1->concurrent_mark();
|
||||
return cm->concurrent_marking_in_progress();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
|
||||
return (jint)HeapRegion::GrainBytes;
|
||||
WB_END
|
||||
#endif // !SERIALGC
|
||||
|
||||
#define CC (char*)
|
||||
|
||||
static JNINativeMethod methods[] = {
|
||||
{CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress },
|
||||
{CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
|
||||
#ifndef SERIALGC
|
||||
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
|
||||
{CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
|
||||
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
|
||||
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
|
||||
#endif // !SERIALGC
|
||||
};
|
||||
|
||||
#undef CC
|
||||
|
||||
JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
|
||||
{
|
||||
if (WhiteBoxAPI) {
|
||||
// Make sure that wbclass is loaded by the null classloader
|
||||
instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
|
||||
Handle loader(ikh->class_loader());
|
||||
if (loader.is_null()) {
|
||||
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
|
||||
jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
|
||||
if (result == 0) {
|
||||
WhiteBox::set_used();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JVM_END
|
||||
36
hotspot/src/share/vm/prims/whitebox.hpp
Normal file
36
hotspot/src/share/vm/prims/whitebox.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
|
||||
#define SHARE_VM_PRIMS_WHITEBOX_HPP
|
||||
|
||||
class WhiteBox : public AllStatic {
|
||||
private:
|
||||
static bool _used;
|
||||
public:
|
||||
static bool used() { return _used; }
|
||||
static void set_used() { _used = true; }
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
|
||||
@ -816,8 +816,21 @@ bool Arguments::process_argument(const char* arg,
|
||||
return true;
|
||||
}
|
||||
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Unrecognized VM option '%s'\n", argname);
|
||||
// For locked flags, report a custom error message if available.
|
||||
// Otherwise, report the standard unrecognized VM option.
|
||||
|
||||
Flag* locked_flag = Flag::find_flag((char*)argname, strlen(argname), true);
|
||||
if (locked_flag != NULL) {
|
||||
char locked_message_buf[BUFLEN];
|
||||
locked_flag->get_locked_message(locked_message_buf, BUFLEN);
|
||||
if (strlen(locked_message_buf) == 0) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Unrecognized VM option '%s'\n", argname);
|
||||
} else {
|
||||
jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
|
||||
}
|
||||
}
|
||||
|
||||
// allow for commandline "commenting out" options like -XX:#+Verbose
|
||||
return arg[0] == '#';
|
||||
}
|
||||
@ -2050,6 +2063,19 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
|
||||
FREE_C_HEAP_ARRAY(char, altclasses_path);
|
||||
}
|
||||
|
||||
if (WhiteBoxAPI) {
|
||||
// Append wb.jar to bootclasspath if enabled
|
||||
const char* wb_jar = "wb.jar";
|
||||
size_t wb_path_len = strlen(get_meta_index_dir()) + 1 +
|
||||
strlen(wb_jar);
|
||||
char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len);
|
||||
strcpy(wb_path, get_meta_index_dir());
|
||||
strcat(wb_path, wb_jar);
|
||||
scp.add_suffix(wb_path);
|
||||
scp_assembly_required = true;
|
||||
FREE_C_HEAP_ARRAY(char, wb_path);
|
||||
}
|
||||
|
||||
// Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
|
||||
result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
|
||||
if (result != JNI_OK) {
|
||||
@ -2510,15 +2536,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
||||
// was arrived at by experimenting with specjbb.
|
||||
FLAG_SET_CMDLINE(uintx, OldPLABSize, 8*K); // Note: this is in words
|
||||
|
||||
// CompilationPolicyChoice=0 causes the server compiler to adopt
|
||||
// a more conservative which-method-do-I-compile policy when one
|
||||
// of the counters maintained by the interpreter trips. The
|
||||
// result is reduced startup time and improved specjbb and
|
||||
// alacrity performance. Zero is the default, but we set it
|
||||
// explicitly here in case the default changes.
|
||||
// See runtime/compilationPolicy.*.
|
||||
FLAG_SET_CMDLINE(intx, CompilationPolicyChoice, 0);
|
||||
|
||||
// Enable parallel GC and adaptive generation sizing
|
||||
FLAG_SET_CMDLINE(bool, UseParallelGC, true);
|
||||
FLAG_SET_DEFAULT(ParallelGCThreads,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -81,6 +81,12 @@ bool Flag::is_unlocked() const {
|
||||
}
|
||||
}
|
||||
|
||||
// Get custom message for this locked flag, or return NULL if
|
||||
// none is available.
|
||||
void Flag::get_locked_message(char* buf, int buflen) const {
|
||||
get_locked_message_ext(buf, buflen);
|
||||
}
|
||||
|
||||
bool Flag::is_writeable() const {
|
||||
return strcmp(kind, "{manageable}") == 0 ||
|
||||
strcmp(kind, "{product rw}") == 0 ||
|
||||
@ -260,17 +266,22 @@ inline bool str_equal(const char* s, char* q, size_t len) {
|
||||
return strncmp(s, q, len) == 0;
|
||||
}
|
||||
|
||||
Flag* Flag::find_flag(char* name, size_t length) {
|
||||
for (Flag* current = &flagTable[0]; current->name; current++) {
|
||||
// Search the flag table for a named flag
|
||||
Flag* Flag::find_flag(char* name, size_t length, bool allow_locked) {
|
||||
for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
|
||||
if (str_equal(current->name, name, length)) {
|
||||
// Found a matching entry. Report locked flags only if allowed.
|
||||
if (!(current->is_unlocked() || current->is_unlocker())) {
|
||||
// disable use of diagnostic or experimental flags until they
|
||||
// are explicitly unlocked
|
||||
return NULL;
|
||||
if (!allow_locked) {
|
||||
// disable use of locked flags, e.g. diagnostic, experimental,
|
||||
// commercial... until they are explicitly unlocked
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
}
|
||||
// Flag name is not in the flag table
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -222,7 +222,7 @@ struct Flag {
|
||||
// number of flags
|
||||
static size_t numFlags;
|
||||
|
||||
static Flag* find_flag(char* name, size_t length);
|
||||
static Flag* find_flag(char* name, size_t length, bool allow_locked = false);
|
||||
|
||||
bool is_bool() const { return strcmp(type, "bool") == 0; }
|
||||
bool get_bool() const { return *((bool*) addr); }
|
||||
@ -259,6 +259,9 @@ struct Flag {
|
||||
bool is_writeable_ext() const;
|
||||
bool is_external_ext() const;
|
||||
|
||||
void get_locked_message(char*, int) const;
|
||||
void get_locked_message_ext(char*, int) const;
|
||||
|
||||
void print_on(outputStream* st, bool withComments = false );
|
||||
void print_as_flag(outputStream* st);
|
||||
};
|
||||
@ -3896,7 +3899,10 @@ class CommandLineFlags {
|
||||
product(bool, UseVMInterruptibleIO, false, \
|
||||
"(Unstable, Solaris-specific) Thread interrupt before or with " \
|
||||
"EINTR for I/O operations results in OS_INTRPT. The default value"\
|
||||
" of this flag is true for JDK 6 and earlier")
|
||||
" of this flag is true for JDK 6 and earlier") \
|
||||
\
|
||||
diagnostic(bool, WhiteBoxAPI, false, \
|
||||
"Enable internal testing APIs")
|
||||
|
||||
/*
|
||||
* Macros for factoring of globals
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2012, 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
|
||||
@ -61,4 +61,9 @@ inline bool Flag::is_external_ext() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void Flag::get_locked_message_ext(char* buf, int buflen) const {
|
||||
assert(buf != NULL, "Buffer cannot be NULL");
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
#endif // SHARE_VM_RUNTIME_GLOBALS_EXT_HPP
|
||||
|
||||
@ -591,14 +591,11 @@ bool Reflection::is_same_package_member(klassOop class1, klassOop class2, TRAPS)
|
||||
// Caller is responsible for figuring out in advance which case must be true.
|
||||
void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
|
||||
bool inner_is_member, TRAPS) {
|
||||
const int inner_class_info_index = 0;
|
||||
const int outer_class_info_index = 1;
|
||||
|
||||
typeArrayHandle icls (THREAD, outer->inner_classes());
|
||||
InnerClassesIterator iter(outer);
|
||||
constantPoolHandle cp (THREAD, outer->constants());
|
||||
for(int i = 0; i < icls->length(); i += 4) {
|
||||
int ioff = icls->ushort_at(i + inner_class_info_index);
|
||||
int ooff = icls->ushort_at(i + outer_class_info_index);
|
||||
for (; !iter.done(); iter.next()) {
|
||||
int ioff = iter.inner_class_info_index();
|
||||
int ooff = iter.outer_class_info_index();
|
||||
|
||||
if (inner_is_member && ioff != 0 && ooff != 0) {
|
||||
klassOop o = cp->klass_at(ooff, CHECK);
|
||||
|
||||
@ -219,6 +219,8 @@ void SafepointSynchronize::begin() {
|
||||
#ifdef ASSERT
|
||||
for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
|
||||
assert(cur->safepoint_state()->is_running(), "Illegal initial state");
|
||||
// Clear the visited flag to ensure that the critical counts are collected properly.
|
||||
cur->set_visited_for_critical_count(false);
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
@ -378,6 +380,13 @@ void SafepointSynchronize::begin() {
|
||||
|
||||
OrderAccess::fence();
|
||||
|
||||
#ifdef ASSERT
|
||||
for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
|
||||
// make sure all the threads were visited
|
||||
assert(cur->was_visited_for_critical_count(), "missed a thread");
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
// Update the count of active JNI critical regions
|
||||
GC_locker::set_jni_lock_count(_current_jni_active_count);
|
||||
|
||||
@ -626,6 +635,7 @@ void SafepointSynchronize::block(JavaThread *thread) {
|
||||
_waiting_to_block--;
|
||||
thread->safepoint_state()->set_has_called_back(true);
|
||||
|
||||
DEBUG_ONLY(thread->set_visited_for_critical_count(true));
|
||||
if (thread->in_critical()) {
|
||||
// Notice that this thread is in a critical section
|
||||
increment_jni_active_count();
|
||||
@ -907,12 +917,8 @@ void ThreadSafepointState::examine_state_of_thread() {
|
||||
// running, but are actually at a safepoint. We will happily
|
||||
// agree and update the safepoint state here.
|
||||
if (SafepointSynchronize::safepoint_safe(_thread, state)) {
|
||||
roll_forward(_at_safepoint);
|
||||
SafepointSynchronize::check_for_lazy_critical_native(_thread, state);
|
||||
if (_thread->in_critical()) {
|
||||
// Notice that this thread is in a critical section
|
||||
SafepointSynchronize::increment_jni_active_count();
|
||||
}
|
||||
roll_forward(_at_safepoint);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -937,6 +943,11 @@ void ThreadSafepointState::roll_forward(suspend_type type) {
|
||||
switch(_type) {
|
||||
case _at_safepoint:
|
||||
SafepointSynchronize::signal_thread_at_safepoint();
|
||||
DEBUG_ONLY(_thread->set_visited_for_critical_count(true));
|
||||
if (_thread->in_critical()) {
|
||||
// Notice that this thread is in a critical section
|
||||
SafepointSynchronize::increment_jni_active_count();
|
||||
}
|
||||
break;
|
||||
|
||||
case _call_back:
|
||||
|
||||
@ -247,6 +247,10 @@ Thread::Thread() {
|
||||
omInUseList = NULL ;
|
||||
omInUseCount = 0 ;
|
||||
|
||||
#ifdef ASSERT
|
||||
_visited_for_critical_count = false;
|
||||
#endif
|
||||
|
||||
_SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
|
||||
_suspend_flags = 0;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user