aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramurillo <none@none>2012-11-30 16:45:26 -0800
committeramurillo <none@none>2012-11-30 16:45:26 -0800
commite3fcd6e771be423016fc43cb090f6c3eed467233 (patch)
tree0c65ff3f5f7ac920e13a3bd8f466613c8b103ddb
parentf8254912057b9bd2a86aa87c2ae7b32a8284649b (diff)
parent041e533ce201cbd047d48ca32a001b8fc1c640ab (diff)
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java36
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/oops/Method.java5
-rw-r--r--make/hotspot_version2
-rw-r--r--src/cpu/sparc/vm/cppInterpreter_sparc.cpp10
-rw-r--r--src/cpu/sparc/vm/frame_sparc.cpp2
-rw-r--r--src/cpu/sparc/vm/interp_masm_sparc.cpp10
-rw-r--r--src/cpu/sparc/vm/stubGenerator_sparc.cpp7
-rw-r--r--src/cpu/sparc/vm/stubRoutines_sparc.cpp7
-rw-r--r--src/cpu/sparc/vm/templateInterpreter_sparc.cpp5
-rw-r--r--src/cpu/x86/vm/cppInterpreter_x86.cpp16
-rw-r--r--src/cpu/x86/vm/frame_x86.cpp2
-rw-r--r--src/cpu/x86/vm/interp_masm_x86_32.cpp13
-rw-r--r--src/cpu/x86/vm/interp_masm_x86_64.cpp13
-rw-r--r--src/cpu/x86/vm/stubGenerator_x86_32.cpp13
-rw-r--r--src/cpu/x86/vm/stubGenerator_x86_64.cpp13
-rw-r--r--src/cpu/x86/vm/stubRoutines_x86_32.cpp13
-rw-r--r--src/cpu/x86/vm/stubRoutines_x86_64.cpp13
-rw-r--r--src/cpu/zero/vm/interp_masm_zero.cpp7
-rw-r--r--src/cpu/zero/vm/stubGenerator_zero.cpp7
-rw-r--r--src/cpu/zero/vm/stubRoutines_zero.cpp7
-rw-r--r--src/os/bsd/vm/mutex_bsd.cpp2
-rw-r--r--src/os/bsd/vm/mutex_bsd.inline.hpp2
-rw-r--r--src/os/bsd/vm/os_bsd.cpp2
-rw-r--r--src/os/bsd/vm/threadCritical_bsd.cpp2
-rw-r--r--src/os/bsd/vm/thread_bsd.inline.hpp4
-rw-r--r--src/os/linux/vm/mutex_linux.cpp2
-rw-r--r--src/os/linux/vm/mutex_linux.inline.hpp2
-rw-r--r--src/os/linux/vm/os_linux.cpp2
-rw-r--r--src/os/linux/vm/threadCritical_linux.cpp2
-rw-r--r--src/os/linux/vm/thread_linux.inline.hpp4
-rw-r--r--src/os/solaris/vm/mutex_solaris.cpp2
-rw-r--r--src/os/solaris/vm/mutex_solaris.inline.hpp2
-rw-r--r--src/os/solaris/vm/os_solaris.cpp2
-rw-r--r--src/os/solaris/vm/threadCritical_solaris.cpp2
-rw-r--r--src/os/solaris/vm/thread_solaris.inline.hpp4
-rw-r--r--src/os/windows/vm/mutex_windows.cpp2
-rw-r--r--src/os/windows/vm/mutex_windows.inline.hpp2
-rw-r--r--src/os/windows/vm/os_windows.cpp2
-rw-r--r--src/os/windows/vm/threadCritical_windows.cpp2
-rw-r--r--src/os/windows/vm/thread_windows.inline.hpp4
-rw-r--r--src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp2
-rw-r--r--src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp2
-rw-r--r--src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp2
-rw-r--r--src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp2
-rw-r--r--src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp2
-rw-r--r--src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp2
-rw-r--r--src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp2
-rw-r--r--src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp2
-rw-r--r--src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp2
-rw-r--r--src/os_cpu/linux_x86/vm/os_linux_x86.cpp2
-rw-r--r--src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp2
-rw-r--r--src/os_cpu/linux_x86/vm/thread_linux_x86.cpp2
-rw-r--r--src/os_cpu/linux_zero/vm/os_linux_zero.cpp2
-rw-r--r--src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp2
-rw-r--r--src/os_cpu/linux_zero/vm/thread_linux_zero.cpp2
-rw-r--r--src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp2
-rw-r--r--src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp2
-rw-r--r--src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp2
-rw-r--r--src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp2
-rw-r--r--src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp2
-rw-r--r--src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp2
-rw-r--r--src/os_cpu/windows_x86/vm/os_windows_x86.cpp2
-rw-r--r--src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp2
-rw-r--r--src/os_cpu/windows_x86/vm/thread_windows_x86.cpp2
-rw-r--r--src/share/vm/asm/codeBuffer.cpp37
-rw-r--r--src/share/vm/ci/ciReplay.cpp4
-rw-r--r--src/share/vm/ci/ciReplay.hpp2
-rw-r--r--src/share/vm/classfile/classFileParser.cpp12
-rw-r--r--src/share/vm/classfile/classFileParser.hpp6
-rw-r--r--src/share/vm/classfile/classLoader.cpp5
-rw-r--r--src/share/vm/classfile/classLoaderData.cpp251
-rw-r--r--src/share/vm/classfile/classLoaderData.hpp24
-rw-r--r--src/share/vm/classfile/classLoaderData.inline.hpp4
-rw-r--r--src/share/vm/classfile/defaultMethods.cpp3
-rw-r--r--src/share/vm/classfile/dictionary.cpp2
-rw-r--r--src/share/vm/classfile/javaClasses.cpp47
-rw-r--r--src/share/vm/classfile/javaClasses.hpp7
-rw-r--r--src/share/vm/classfile/loaderConstraints.cpp8
-rw-r--r--src/share/vm/classfile/systemDictionary.cpp46
-rw-r--r--src/share/vm/classfile/systemDictionary.hpp4
-rw-r--r--src/share/vm/compiler/compileBroker.cpp16
-rw-r--r--src/share/vm/compiler/compileBroker.hpp4
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp13
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp13
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp3
-rw-r--r--src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp14
-rw-r--r--src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp34
-rw-r--r--src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp41
-rw-r--r--src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp7
-rw-r--r--src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp14
-rw-r--r--src/share/vm/gc_implementation/g1/ptrQueue.cpp13
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp15
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp6
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp3
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp8
-rw-r--r--src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp14
-rw-r--r--src/share/vm/gc_interface/collectedHeap.cpp13
-rw-r--r--src/share/vm/gc_interface/collectedHeap.hpp5
-rw-r--r--src/share/vm/gc_interface/collectedHeap.inline.hpp44
-rw-r--r--src/share/vm/interpreter/abstractInterpreter.hpp13
-rw-r--r--src/share/vm/interpreter/interpreterRuntime.hpp13
-rw-r--r--src/share/vm/interpreter/linkResolver.cpp13
-rw-r--r--src/share/vm/memory/allocation.cpp9
-rw-r--r--src/share/vm/memory/allocation.hpp1
-rw-r--r--src/share/vm/memory/binaryTreeDictionary.cpp8
-rw-r--r--src/share/vm/memory/collectorPolicy.cpp13
-rw-r--r--src/share/vm/memory/defNewGeneration.cpp13
-rw-r--r--src/share/vm/memory/filemap.cpp45
-rw-r--r--src/share/vm/memory/freeBlockDictionary.cpp13
-rw-r--r--src/share/vm/memory/gcLocker.hpp5
-rw-r--r--src/share/vm/memory/genMarkSweep.cpp13
-rw-r--r--src/share/vm/memory/iterator.cpp4
-rw-r--r--src/share/vm/memory/iterator.hpp14
-rw-r--r--src/share/vm/memory/metachunk.hpp4
-rw-r--r--src/share/vm/memory/metaspace.cpp53
-rw-r--r--src/share/vm/memory/metaspace.hpp21
-rw-r--r--src/share/vm/memory/resourceArea.cpp13
-rw-r--r--src/share/vm/memory/resourceArea.hpp13
-rw-r--r--src/share/vm/memory/sharedHeap.cpp6
-rw-r--r--src/share/vm/memory/space.cpp24
-rw-r--r--src/share/vm/memory/threadLocalAllocBuffer.cpp13
-rw-r--r--src/share/vm/memory/universe.cpp25
-rw-r--r--src/share/vm/oops/compiledICHolder.cpp4
-rw-r--r--src/share/vm/oops/constMethod.cpp55
-rw-r--r--src/share/vm/oops/constMethod.hpp51
-rw-r--r--src/share/vm/oops/constantPool.cpp4
-rw-r--r--src/share/vm/oops/instanceKlass.cpp13
-rw-r--r--src/share/vm/oops/klass.cpp51
-rw-r--r--src/share/vm/oops/klass.hpp5
-rw-r--r--src/share/vm/oops/markOop.cpp14
-rw-r--r--src/share/vm/oops/method.cpp25
-rw-r--r--src/share/vm/oops/method.hpp23
-rw-r--r--src/share/vm/oops/objArrayKlass.cpp5
-rw-r--r--src/share/vm/oops/oop.cpp13
-rw-r--r--src/share/vm/oops/oopsHierarchy.cpp14
-rw-r--r--src/share/vm/prims/forte.cpp25
-rw-r--r--src/share/vm/prims/jni.cpp11
-rw-r--r--src/share/vm/prims/jvmti.xml4
-rw-r--r--src/share/vm/prims/jvmtiEnv.cpp14
-rw-r--r--src/share/vm/prims/jvmtiImpl.cpp13
-rw-r--r--src/share/vm/prims/unsafe.cpp29
-rw-r--r--src/share/vm/runtime/arguments.cpp24
-rw-r--r--src/share/vm/runtime/arguments.hpp2
-rw-r--r--src/share/vm/runtime/deoptimization.cpp2
-rw-r--r--src/share/vm/runtime/fprofiler.hpp12
-rw-r--r--src/share/vm/runtime/frame.cpp19
-rw-r--r--src/share/vm/runtime/frame.hpp6
-rw-r--r--src/share/vm/runtime/handles.cpp5
-rw-r--r--src/share/vm/runtime/handles.inline.hpp13
-rw-r--r--src/share/vm/runtime/interfaceSupport.hpp13
-rw-r--r--src/share/vm/runtime/java.cpp13
-rw-r--r--src/share/vm/runtime/javaCalls.cpp13
-rw-r--r--src/share/vm/runtime/javaCalls.hpp13
-rw-r--r--src/share/vm/runtime/jniHandles.cpp13
-rw-r--r--src/share/vm/runtime/memprofiler.cpp13
-rw-r--r--src/share/vm/runtime/mutex.cpp5
-rw-r--r--src/share/vm/runtime/mutexLocker.cpp13
-rw-r--r--src/share/vm/runtime/objectMonitor.cpp6
-rw-r--r--src/share/vm/runtime/os.cpp5
-rw-r--r--src/share/vm/runtime/safepoint.cpp13
-rw-r--r--src/share/vm/runtime/synchronizer.cpp5
-rw-r--r--src/share/vm/runtime/task.cpp5
-rw-r--r--src/share/vm/runtime/thread.cpp36
-rw-r--r--src/share/vm/runtime/thread.hpp12
-rw-r--r--src/share/vm/runtime/thread.inline.hpp46
-rw-r--r--src/share/vm/runtime/threadLocalStorage.cpp5
-rw-r--r--src/share/vm/runtime/vmStructs.cpp34
-rw-r--r--src/share/vm/runtime/vmStructs.hpp5
-rw-r--r--src/share/vm/runtime/vmThread.cpp19
-rw-r--r--src/share/vm/runtime/vmThread.hpp15
-rw-r--r--src/share/vm/runtime/vm_operations.cpp13
-rw-r--r--src/share/vm/runtime/vm_version.cpp14
-rw-r--r--src/share/vm/services/memSnapshot.cpp18
-rw-r--r--src/share/vm/services/memSnapshot.hpp17
-rw-r--r--src/share/vm/services/memTracker.cpp11
-rw-r--r--src/share/vm/services/memTracker.hpp4
-rw-r--r--src/share/vm/utilities/array.cpp13
-rw-r--r--src/share/vm/utilities/debug.cpp5
-rw-r--r--src/share/vm/utilities/events.cpp13
-rw-r--r--src/share/vm/utilities/exceptions.cpp13
-rw-r--r--src/share/vm/utilities/globalDefinitions.hpp8
-rw-r--r--src/share/vm/utilities/growableArray.cpp14
-rw-r--r--src/share/vm/utilities/preserveException.hpp13
-rw-r--r--src/share/vm/utilities/taskqueue.cpp13
-rw-r--r--src/share/vm/utilities/workgroup.hpp13
-rw-r--r--test/runtime/8003720/Asmator.java56
-rw-r--r--test/runtime/8003720/Test8003720.java71
-rw-r--r--test/runtime/8003720/Victim.java50
-rw-r--r--test/runtime/8003720/VictimClassLoader.java86
189 files changed, 1302 insertions, 1289 deletions
diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
index 2bfe8c326..3e3082020 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
@@ -48,6 +48,7 @@ public class ConstMethod extends VMObject {
private static int HAS_CHECKED_EXCEPTIONS;
private static int HAS_LOCALVARIABLE_TABLE;
private static int HAS_EXCEPTION_TABLE;
+ private static int HAS_GENERIC_SIGNATURE;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("ConstMethod");
@@ -60,13 +61,14 @@ public class ConstMethod extends VMObject {
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethod::_has_checked_exceptions").intValue();
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue();
HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue();
+ HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue();
// Size of Java bytecodes allocated immediately after ConstMethod*.
codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0);
signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0);
- genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
idnum = new CIntField(type.getCIntegerField("_method_idnum"), 0);
+ maxStack = new CIntField(type.getCIntegerField("_max_stack"), 0);
// start of byte code
bytecodeOffset = type.getSize();
@@ -92,8 +94,8 @@ public class ConstMethod extends VMObject {
private static CIntField codeSize;
private static CIntField nameIndex;
private static CIntField signatureIndex;
- private static CIntField genericSignatureIndex;
private static CIntField idnum;
+ private static CIntField maxStack;
// start of bytecode
private static long bytecodeOffset;
@@ -134,13 +136,21 @@ public class ConstMethod extends VMObject {
}
public long getGenericSignatureIndex() {
- return genericSignatureIndex.getValue(this);
+ if (hasGenericSignature()) {
+ return getAddress().getCIntegerAt(offsetOfGenericSignatureIndex(), 2, true);
+ } else {
+ return 0;
+ }
}
public long getIdNum() {
return idnum.getValue(this);
}
+ public long getMaxStack() {
+ return maxStack.getValue(this);
+ }
+
public Symbol getName() {
return getMethod().getName();
}
@@ -235,8 +245,8 @@ public class ConstMethod extends VMObject {
visitor.doCInt(codeSize, true);
visitor.doCInt(nameIndex, true);
visitor.doCInt(signatureIndex, true);
- visitor.doCInt(genericSignatureIndex, true);
visitor.doCInt(codeSize, true);
+ visitor.doCInt(maxStack, true);
}
// Accessors
@@ -353,6 +363,10 @@ public class ConstMethod extends VMObject {
return ret;
}
+ private boolean hasGenericSignature() {
+ return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
+ }
+
//---------------------------------------------------------------------------
// Internals only below this point
@@ -377,10 +391,16 @@ public class ConstMethod extends VMObject {
return getSize() * VM.getVM().getObjectHeap().getOopSize() - 2;
}
- private long offsetOfCheckedExceptionsLength() {
+ // Offset of the generic signature index
+ private long offsetOfGenericSignatureIndex() {
return offsetOfLastU2Element();
}
+ private long offsetOfCheckedExceptionsLength() {
+ return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+ offsetOfLastU2Element();
+ }
+
private int getCheckedExceptionsLength() {
if (hasCheckedExceptions()) {
return (int) getAddress().getCIntegerAt(offsetOfCheckedExceptionsLength(), 2, true);
@@ -431,7 +451,8 @@ public class ConstMethod extends VMObject {
} else if (hasCheckedExceptions()) {
return offsetOfCheckedExceptions() - 2;
} else {
- return offsetOfLastU2Element();
+ return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+ offsetOfLastU2Element();
}
}
@@ -460,7 +481,8 @@ public class ConstMethod extends VMObject {
if (hasCheckedExceptions()) {
return offsetOfCheckedExceptions() - 2;
} else {
- return offsetOfLastU2Element();
+ return hasGenericSignature() ? offsetOfLastU2Element() - 2 :
+ offsetOfLastU2Element();
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
index 2fd57fd97..a12d0b1e8 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
@@ -50,7 +50,6 @@ public class Method extends Metadata {
constMethod = type.getAddressField("_constMethod");
methodData = type.getAddressField("_method_data");
methodSize = new CIntField(type.getCIntegerField("_method_size"), 0);
- maxStack = new CIntField(type.getCIntegerField("_max_stack"), 0);
maxLocals = new CIntField(type.getCIntegerField("_max_locals"), 0);
sizeOfParameters = new CIntField(type.getCIntegerField("_size_of_parameters"), 0);
accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0);
@@ -84,7 +83,6 @@ public class Method extends Metadata {
private static AddressField constMethod;
private static AddressField methodData;
private static CIntField methodSize;
- private static CIntField maxStack;
private static CIntField maxLocals;
private static CIntField sizeOfParameters;
private static CIntField accessFlags;
@@ -135,7 +133,7 @@ public class Method extends Metadata {
}
/** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
public long getMethodSize() { return methodSize.getValue(this); }
- public long getMaxStack() { return maxStack.getValue(this); }
+ public long getMaxStack() { return getConstMethod().getMaxStack(); }
public long getMaxLocals() { return maxLocals.getValue(this); }
public long getSizeOfParameters() { return sizeOfParameters.getValue(this); }
public long getNameIndex() { return getConstMethod().getNameIndex(); }
@@ -284,7 +282,6 @@ public class Method extends Metadata {
public void iterateFields(MetadataVisitor visitor) {
visitor.doCInt(methodSize, true);
- visitor.doCInt(maxStack, true);
visitor.doCInt(maxLocals, true);
visitor.doCInt(sizeOfParameters, true);
visitor.doCInt(accessFlags, true);
diff --git a/make/hotspot_version b/make/hotspot_version
index 8556a1f8b..b49a5266c 100644
--- a/make/hotspot_version
+++ b/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=10
+HS_BUILD_NUMBER=11
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff --git a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
index c62d6a536..eacb4d3fd 100644
--- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
+++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
@@ -1048,7 +1048,6 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
const Address constMethod (G5_method, 0, in_bytes(Method::const_offset()));
const Address access_flags (G5_method, 0, in_bytes(Method::access_flags_offset()));
const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
- const Address max_stack (G5_method, 0, in_bytes(Method::max_stack_offset()));
const Address size_of_locals (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
// slop factor is two extra slots on the expression stack so that
@@ -1070,7 +1069,9 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
__ lduh( size_of_parameters, Gtmp );
__ calc_mem_param_words(Gtmp, Gtmp); // space for native call parameters passed on the stack in words
} else {
- __ lduh(max_stack, Gtmp); // Full size expression stack
+ // Full size expression stack
+ __ ld_ptr(constMethod, Gtmp);
+ __ lduh(Gtmp, in_bytes(ConstMethod::max_stack_offset()), Gtmp);
}
__ add(Gtmp, fixed_size, Gtmp); // plus the fixed portion
@@ -1206,7 +1207,9 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
__ sub(O2, wordSize, O2); // prepush
__ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH
- __ lduh(max_stack, O3); // Full size expression stack
+ // Full size expression stack
+ __ ld_ptr(constMethod, O3);
+ __ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
//6815692//if (EnableInvokeDynamic)
//6815692// __ inc(O3, Method::extra_stack_entries());
@@ -1539,7 +1542,6 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
const Address constMethod (G5_method, 0, in_bytes(Method::const_offset()));
const Address access_flags (G5_method, 0, in_bytes(Method::access_flags_offset()));
const Address size_of_parameters(G5_method, 0, in_bytes(Method::size_of_parameters_offset()));
- const Address max_stack (G5_method, 0, in_bytes(Method::max_stack_offset()));
const Address size_of_locals (G5_method, 0, in_bytes(Method::size_of_locals_offset()));
address entry_point = __ pc();
diff --git a/src/cpu/sparc/vm/frame_sparc.cpp b/src/cpu/sparc/vm/frame_sparc.cpp
index 3beb64471..93ae06e0f 100644
--- a/src/cpu/sparc/vm/frame_sparc.cpp
+++ b/src/cpu/sparc/vm/frame_sparc.cpp
@@ -648,7 +648,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
Method* m = *interpreter_frame_method_addr();
// validate the method we'd find in this potential sender
- if (!Universe::heap()->is_valid_method(m)) return false;
+ if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
diff --git a/src/cpu/sparc/vm/interp_masm_sparc.cpp b/src/cpu/sparc/vm/interp_masm_sparc.cpp
index 2e2040efc..6060f003b 100644
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp
@@ -36,12 +36,7 @@
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/sharedRuntime.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
#ifndef CC_INTERP
#ifndef FAST_DISPATCH
@@ -523,7 +518,8 @@ void InterpreterMacroAssembler::empty_expression_stack() {
delayed()->nop();
// Compute max expression stack+register save area
- lduh(Lmethod, in_bytes(Method::max_stack_offset()), Gframe_size); // Load max stack.
+ ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
+ lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size); // Load max stack.
add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
//
diff --git a/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/src/cpu/sparc/vm/stubGenerator_sparc.cpp
index 8faea5119..e8e7499b5 100644
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp
@@ -37,13 +37,8 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
diff --git a/src/cpu/sparc/vm/stubRoutines_sparc.cpp b/src/cpu/sparc/vm/stubRoutines_sparc.cpp
index 68785abfc..3a544be2e 100644
--- a/src/cpu/sparc/vm/stubRoutines_sparc.cpp
+++ b/src/cpu/sparc/vm/stubRoutines_sparc.cpp
@@ -26,12 +26,7 @@
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/stubRoutines.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// Implementation of the platform-specific part of StubRoutines - for
// a description of how to extend it, see the stubRoutines.hpp file.
diff --git a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index a6df245d2..d51b9e5bb 100644
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -496,7 +496,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
const Address size_of_parameters(G5_method, Method::size_of_parameters_offset());
const Address size_of_locals (G5_method, Method::size_of_locals_offset());
- const Address max_stack (G5_method, Method::max_stack_offset());
+ const Address constMethod (G5_method, Method::const_offset());
int rounded_vm_local_words = round_to( frame::interpreter_frame_vm_local_words, WordsPerLong );
const int extra_space =
@@ -538,7 +538,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
// see if the frame is greater than one page in size. If so,
// then we need to verify there is enough stack space remaining
// Frame_size = (max_stack + extra_space) * BytesPerWord;
- __ lduh( max_stack, Gframe_size );
+ __ ld_ptr( constMethod, Gframe_size );
+ __ lduh( Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size );
__ add( Gframe_size, extra_space, Gframe_size );
__ round_to( Gframe_size, WordsPerLong );
__ sll( Gframe_size, Interpreter::logStackElementSize, Gframe_size);
diff --git a/src/cpu/x86/vm/cppInterpreter_x86.cpp b/src/cpu/x86/vm/cppInterpreter_x86.cpp
index 7161b2bc8..64a9463f8 100644
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp
@@ -538,9 +538,9 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
// compute full expression stack limit
- const Address size_of_stack (rbx, Method::max_stack_offset());
const int extra_stack = 0; //6815692//Method::extra_stack_words();
- __ load_unsigned_short(rdx, size_of_stack); // get size of expression stack in words
+ __ movptr(rdx, Address(rbx, Method::const_offset()));
+ __ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
__ negptr(rdx); // so we can subtract in next step
// Allocate expression stack
__ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
@@ -682,12 +682,12 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
const Address stack_size(thread, Thread::stack_size_offset());
// locals + overhead, in bytes
- const Address size_of_stack (rbx, Method::max_stack_offset());
- // Always give one monitor to allow us to start interp if sync method.
- // Any additional monitors need a check when moving the expression stack
- const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
- const int extra_stack = 0; //6815692//Method::extra_stack_entries();
- __ load_unsigned_short(rax, size_of_stack); // get size of expression stack in words
+ // Always give one monitor to allow us to start interp if sync method.
+ // Any additional monitors need a check when moving the expression stack
+ const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
+ const int extra_stack = 0; //6815692//Method::extra_stack_entries();
+ __ movptr(rax, Address(rbx, Method::const_offset()));
+ __ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
__ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
diff --git a/src/cpu/x86/vm/frame_x86.cpp b/src/cpu/x86/vm/frame_x86.cpp
index b8ec9afa5..0718f592a 100644
--- a/src/cpu/x86/vm/frame_x86.cpp
+++ b/src/cpu/x86/vm/frame_x86.cpp
@@ -534,7 +534,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
Method* m = *interpreter_frame_method_addr();
// validate the method we'd find in this potential sender
- if (!Universe::heap()->is_valid_method(m)) return false;
+ if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
diff --git a/src/cpu/x86/vm/interp_masm_x86_32.cpp b/src/cpu/x86/vm/interp_masm_x86_32.cpp
index 9a54ac1ae..78d97a975 100644
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp
@@ -36,18 +36,7 @@
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/sharedRuntime.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// Implementation of InterpreterMacroAssembler
diff --git a/src/cpu/x86/vm/interp_masm_x86_64.cpp b/src/cpu/x86/vm/interp_masm_x86_64.cpp
index 856f017f7..890826310 100644
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp
@@ -36,18 +36,7 @@
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/sharedRuntime.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// Implementation of InterpreterMacroAssembler
diff --git a/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index d8b61e0b2..bcb408b5b 100644
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -37,19 +37,8 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index 3e223387c..d205f9639 100644
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -37,19 +37,8 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
diff --git a/src/cpu/x86/vm/stubRoutines_x86_32.cpp b/src/cpu/x86/vm/stubRoutines_x86_32.cpp
index cfd4f33a6..65e773ed5 100644
--- a/src/cpu/x86/vm/stubRoutines_x86_32.cpp
+++ b/src/cpu/x86/vm/stubRoutines_x86_32.cpp
@@ -26,18 +26,7 @@
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/stubRoutines.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// Implementation of the platform-specific part of StubRoutines - for
// a description of how to extend it, see the stubRoutines.hpp file.
diff --git a/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/src/cpu/x86/vm/stubRoutines_x86_64.cpp
index cf8ec5d7b..9f0a94200 100644
--- a/src/cpu/x86/vm/stubRoutines_x86_64.cpp
+++ b/src/cpu/x86/vm/stubRoutines_x86_64.cpp
@@ -26,18 +26,7 @@
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/stubRoutines.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// Implementation of the platform-specific part of StubRoutines - for
// a description of how to extend it, see the stubRoutines.hpp file.
diff --git a/src/cpu/zero/vm/interp_masm_zero.cpp b/src/cpu/zero/vm/interp_masm_zero.cpp
index 52cfeacdd..a2e85ede0 100644
--- a/src/cpu/zero/vm/interp_masm_zero.cpp
+++ b/src/cpu/zero/vm/interp_masm_zero.cpp
@@ -37,11 +37,6 @@
#include "runtime/basicLock.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/sharedRuntime.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// This file is intentionally empty
diff --git a/src/cpu/zero/vm/stubGenerator_zero.cpp b/src/cpu/zero/vm/stubGenerator_zero.cpp
index 2dd5de6a0..f1a280bb4 100644
--- a/src/cpu/zero/vm/stubGenerator_zero.cpp
+++ b/src/cpu/zero/vm/stubGenerator_zero.cpp
@@ -38,14 +38,9 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "stack_zero.inline.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
diff --git a/src/cpu/zero/vm/stubRoutines_zero.cpp b/src/cpu/zero/vm/stubRoutines_zero.cpp
index 8b21dde68..98bd6c2a7 100644
--- a/src/cpu/zero/vm/stubRoutines_zero.cpp
+++ b/src/cpu/zero/vm/stubRoutines_zero.cpp
@@ -27,9 +27,4 @@
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/stubRoutines.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
diff --git a/src/os/bsd/vm/mutex_bsd.cpp b/src/os/bsd/vm/mutex_bsd.cpp
index f39482ea6..3a1b5ebc0 100644
--- a/src/os/bsd/vm/mutex_bsd.cpp
+++ b/src/os/bsd/vm/mutex_bsd.cpp
@@ -26,7 +26,7 @@
#include "mutex_bsd.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutex.hpp"
-#include "thread_bsd.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
// put OS-includes here
diff --git a/src/os/bsd/vm/mutex_bsd.inline.hpp b/src/os/bsd/vm/mutex_bsd.inline.hpp
index f75267fb5..63c63f0e5 100644
--- a/src/os/bsd/vm/mutex_bsd.inline.hpp
+++ b/src/os/bsd/vm/mutex_bsd.inline.hpp
@@ -27,7 +27,7 @@
#include "os_bsd.inline.hpp"
#include "runtime/interfaceSupport.hpp"
-#include "thread_bsd.inline.hpp"
+#include "runtime/thread.inline.hpp"
// Reconciliation History
diff --git a/src/os/bsd/vm/os_bsd.cpp b/src/os/bsd/vm/os_bsd.cpp
index 83b8b19f9..b77f2f0d7 100644
--- a/src/os/bsd/vm/os_bsd.cpp
+++ b/src/os/bsd/vm/os_bsd.cpp
@@ -52,11 +52,11 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
-#include "thread_bsd.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
diff --git a/src/os/bsd/vm/threadCritical_bsd.cpp b/src/os/bsd/vm/threadCritical_bsd.cpp
index e337a5bd5..7cac3ca22 100644
--- a/src/os/bsd/vm/threadCritical_bsd.cpp
+++ b/src/os/bsd/vm/threadCritical_bsd.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
-#include "thread_bsd.inline.hpp"
// put OS-includes here
# include <pthread.h>
diff --git a/src/os/bsd/vm/thread_bsd.inline.hpp b/src/os/bsd/vm/thread_bsd.inline.hpp
index 290f47786..ba8baaf3d 100644
--- a/src/os/bsd/vm/thread_bsd.inline.hpp
+++ b/src/os/bsd/vm/thread_bsd.inline.hpp
@@ -25,6 +25,10 @@
#ifndef OS_BSD_VM_THREAD_BSD_INLINE_HPP
#define OS_BSD_VM_THREAD_BSD_INLINE_HPP
+#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+#error "This file should only be included from thread.inline.hpp"
+#endif
+
#include "runtime/atomic.hpp"
#include "runtime/prefetch.hpp"
#include "runtime/thread.hpp"
diff --git a/src/os/linux/vm/mutex_linux.cpp b/src/os/linux/vm/mutex_linux.cpp
index 864aca7e8..a54ec992f 100644
--- a/src/os/linux/vm/mutex_linux.cpp
+++ b/src/os/linux/vm/mutex_linux.cpp
@@ -26,7 +26,7 @@
#include "mutex_linux.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutex.hpp"
-#include "thread_linux.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
// put OS-includes here
diff --git a/src/os/linux/vm/mutex_linux.inline.hpp b/src/os/linux/vm/mutex_linux.inline.hpp
index cde6dfe42..ff3ac285e 100644
--- a/src/os/linux/vm/mutex_linux.inline.hpp
+++ b/src/os/linux/vm/mutex_linux.inline.hpp
@@ -27,7 +27,7 @@
#include "os_linux.inline.hpp"
#include "runtime/interfaceSupport.hpp"
-#include "thread_linux.inline.hpp"
+#include "runtime/thread.inline.hpp"
// Reconciliation History
diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp
index cbb48d5b1..09d821423 100644
--- a/src/os/linux/vm/os_linux.cpp
+++ b/src/os/linux/vm/os_linux.cpp
@@ -52,11 +52,11 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
-#include "thread_linux.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
diff --git a/src/os/linux/vm/threadCritical_linux.cpp b/src/os/linux/vm/threadCritical_linux.cpp
index b1d9ab2aa..7cac3ca22 100644
--- a/src/os/linux/vm/threadCritical_linux.cpp
+++ b/src/os/linux/vm/threadCritical_linux.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
-#include "thread_linux.inline.hpp"
// put OS-includes here
# include <pthread.h>
diff --git a/src/os/linux/vm/thread_linux.inline.hpp b/src/os/linux/vm/thread_linux.inline.hpp
index 2a5dcddb7..f5c9e9c4b 100644
--- a/src/os/linux/vm/thread_linux.inline.hpp
+++ b/src/os/linux/vm/thread_linux.inline.hpp
@@ -25,6 +25,10 @@
#ifndef OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
#define OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
+#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+#error "This file should only be included from thread.inline.hpp"
+#endif
+
#include "runtime/atomic.hpp"
#include "runtime/prefetch.hpp"
#include "runtime/thread.hpp"
diff --git a/src/os/solaris/vm/mutex_solaris.cpp b/src/os/solaris/vm/mutex_solaris.cpp
index 30be73721..4d8166f65 100644
--- a/src/os/solaris/vm/mutex_solaris.cpp
+++ b/src/os/solaris/vm/mutex_solaris.cpp
@@ -26,7 +26,7 @@
#include "mutex_solaris.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutex.hpp"
-#include "thread_solaris.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
// Solaris-specific include, therefore not in includeDB_*
diff --git a/src/os/solaris/vm/mutex_solaris.inline.hpp b/src/os/solaris/vm/mutex_solaris.inline.hpp
index 00e91a794..b683a3be9 100644
--- a/src/os/solaris/vm/mutex_solaris.inline.hpp
+++ b/src/os/solaris/vm/mutex_solaris.inline.hpp
@@ -27,6 +27,6 @@
#include "os_solaris.inline.hpp"
#include "runtime/interfaceSupport.hpp"
-#include "thread_solaris.inline.hpp"
+#include "runtime/thread.inline.hpp"
#endif // OS_SOLARIS_VM_MUTEX_SOLARIS_INLINE_HPP
diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp
index dfa4ef1bf..d25c2714b 100644
--- a/src/os/solaris/vm/os_solaris.cpp
+++ b/src/os/solaris/vm/os_solaris.cpp
@@ -52,12 +52,12 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
-#include "thread_solaris.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
diff --git a/src/os/solaris/vm/threadCritical_solaris.cpp b/src/os/solaris/vm/threadCritical_solaris.cpp
index b658183c2..b87e7b45c 100644
--- a/src/os/solaris/vm/threadCritical_solaris.cpp
+++ b/src/os/solaris/vm/threadCritical_solaris.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
-#include "thread_solaris.inline.hpp"
// OS-includes here
#include <thread.h>
diff --git a/src/os/solaris/vm/thread_solaris.inline.hpp b/src/os/solaris/vm/thread_solaris.inline.hpp
index 903be9ddc..a76ddeb20 100644
--- a/src/os/solaris/vm/thread_solaris.inline.hpp
+++ b/src/os/solaris/vm/thread_solaris.inline.hpp
@@ -25,6 +25,10 @@
#ifndef OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
#define OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
+#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+#error "This file should only be included from thread.inline.hpp"
+#endif
+
#include "runtime/atomic.hpp"
#include "runtime/prefetch.hpp"
#include "runtime/thread.hpp"
diff --git a/src/os/windows/vm/mutex_windows.cpp b/src/os/windows/vm/mutex_windows.cpp
index 66f018dd4..f8e06332c 100644
--- a/src/os/windows/vm/mutex_windows.cpp
+++ b/src/os/windows/vm/mutex_windows.cpp
@@ -26,7 +26,7 @@
#include "mutex_windows.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutex.hpp"
-#include "thread_windows.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
// put OS-includes here
diff --git a/src/os/windows/vm/mutex_windows.inline.hpp b/src/os/windows/vm/mutex_windows.inline.hpp
index ddc082279..fbfe7ac84 100644
--- a/src/os/windows/vm/mutex_windows.inline.hpp
+++ b/src/os/windows/vm/mutex_windows.inline.hpp
@@ -27,6 +27,6 @@
#include "os_windows.inline.hpp"
#include "runtime/interfaceSupport.hpp"
-#include "thread_windows.inline.hpp"
+#include "runtime/thread.inline.hpp"
#endif // OS_WINDOWS_VM_MUTEX_WINDOWS_INLINE_HPP
diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp
index e2c36ee12..8e1685ae9 100644
--- a/src/os/windows/vm/os_windows.cpp
+++ b/src/os/windows/vm/os_windows.cpp
@@ -55,11 +55,11 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/timer.hpp"
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
-#include "thread_windows.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
diff --git a/src/os/windows/vm/threadCritical_windows.cpp b/src/os/windows/vm/threadCritical_windows.cpp
index 4a498e07e..c61a29617 100644
--- a/src/os/windows/vm/threadCritical_windows.cpp
+++ b/src/os/windows/vm/threadCritical_windows.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
-#include "thread_windows.inline.hpp"
// OS-includes here
# include <windows.h>
diff --git a/src/os/windows/vm/thread_windows.inline.hpp b/src/os/windows/vm/thread_windows.inline.hpp
index 9fe391574..d73fabff2 100644
--- a/src/os/windows/vm/thread_windows.inline.hpp
+++ b/src/os/windows/vm/thread_windows.inline.hpp
@@ -25,6 +25,10 @@
#ifndef OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
#define OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
+#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+#error "This file should only be included from thread.inline.hpp"
+#endif
+
#include "runtime/atomic.hpp"
#include "runtime/prefetch.hpp"
#include "runtime/thread.hpp"
diff --git a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index 49ea265ba..4b67b60c7 100644
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_bsd.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp
index 3c76437cc..0515fbc3f 100644
--- a/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp
+++ b/src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_bsd.inline.hpp"
// Map stack pointer (%esp) to thread pointer for faster TLS access
//
diff --git a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
index e63c46e97..f508ab9ec 100644
--- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
+++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_bsd.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
index 2262ee207..d2a8c247f 100644
--- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
+++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
@@ -54,8 +54,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_bsd.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp b/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp
index cd6e0f797..73e5e829f 100644
--- a/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp
+++ b/src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp
@@ -24,8 +24,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_bsd.inline.hpp"
void ThreadLocalStorage::generate_code_for_get_thread() {
// nothing to do
diff --git a/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp b/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp
index eb0abaa72..a3cdee54d 100644
--- a/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp
+++ b/src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_bsd.inline.hpp"
+#include "runtime/thread.inline.hpp"
void JavaThread::cache_global_variables() {
// nothing to do
diff --git a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
index 894aec588..97aeaa334 100644
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_linux.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp b/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp
index d2ae5ca9f..3f291a06a 100644
--- a/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp
+++ b/src/os_cpu/linux_sparc/vm/threadLS_linux_sparc.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_linux.inline.hpp"
void ThreadLocalStorage::generate_code_for_get_thread() {
}
diff --git a/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp b/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp
index 8f3eaa3e5..dac85519a 100644
--- a/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp
+++ b/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_linux.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index 126b2ab2a..eabe91205 100644
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_linux.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp b/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp
index 45fcea9e0..ffc89af98 100644
--- a/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp
+++ b/src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_linux.inline.hpp"
// Map stack pointer (%esp) to thread pointer for faster TLS access
//
diff --git a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
index 3f04c7730..69414cf7f 100644
--- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
+++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_linux.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
index 86cb2b4ee..74ec81369 100644
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
@@ -49,8 +49,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_linux.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp
index 0981ea5dd..73e5e829f 100644
--- a/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp
+++ b/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp
@@ -24,8 +24,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_linux.inline.hpp"
void ThreadLocalStorage::generate_code_for_get_thread() {
// nothing to do
diff --git a/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp b/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp
index 9c1b7336c..a3cdee54d 100644
--- a/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp
+++ b/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_linux.inline.hpp"
+#include "runtime/thread.inline.hpp"
void JavaThread::cache_global_variables() {
// nothing to do
diff --git a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
index 0c8116166..dc75ff06f 100644
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_solaris.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp
index 178808ffb..d07db6a5c 100644
--- a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp
+++ b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_solaris.inline.hpp"
// Provides an entry point we can link against and
// a buffer we can emit code into. The buffer is
diff --git a/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
index f622943fe..f0fbc6699 100644
--- a/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
+++ b/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_solaris.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
index 3491bbed1..e51bae179 100644
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_solaris.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp
index 439a09c95..e2ce144a3 100644
--- a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp
+++ b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_solaris.inline.hpp"
#ifdef AMD64
extern "C" Thread* fs_load(ptrdiff_t tlsOffset);
diff --git a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
index b1f785ada..7c04d0272 100644
--- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
+++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_solaris.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
index d0fad7da7..4caf927cf 100644
--- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -48,8 +48,8 @@
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
-#include "thread_windows.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
diff --git a/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
index 9bb8b4ad7..f363816d9 100644
--- a/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
+++ b/src/os_cpu/windows_x86/vm/threadLS_windows_x86.cpp
@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_windows.inline.hpp"
// Provides an entry point we can link against and
// a buffer we can emit code into. The buffer is
diff --git a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
index 6f8c4b84a..308bd9476 100644
--- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
+++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_windows.inline.hpp"
+#include "runtime/thread.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
diff --git a/src/share/vm/asm/codeBuffer.cpp b/src/share/vm/asm/codeBuffer.cpp
index a3fc112f5..3fb1f179b 100644
--- a/src/share/vm/asm/codeBuffer.cpp
+++ b/src/share/vm/asm/codeBuffer.cpp
@@ -492,6 +492,26 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
dest->verify_section_allocation();
}
+// Anonymous classes need mirror to keep the metadata alive but
+// for regular classes, the class_loader is sufficient.
+static void append_oop_references(GrowableArray<oop>* oops, Klass* k) {
+ if (k->oop_is_instance()) {
+ InstanceKlass* ik = InstanceKlass::cast(k);
+ if (ik->is_anonymous()) {
+ oop o = ik->java_mirror();
+ assert (o != NULL, "should have a mirror");
+ if (!oops->contains(o)) {
+ oops->append(o);
+ }
+ return; // only need the mirror
+ }
+ }
+ oop cl = k->class_loader();
+ if (cl != NULL && !oops->contains(cl)) {
+ oops->append(cl);
+ }
+}
+
void CodeBuffer::finalize_oop_references(methodHandle mh) {
No_Safepoint_Verifier nsv;
@@ -509,7 +529,6 @@ void CodeBuffer::finalize_oop_references(methodHandle mh) {
if (md->metadata_is_immediate()) {
Metadata* m = md->metadata_value();
if (oop_recorder()->is_real(m)) {
- oop o = NULL;
if (m->is_methodData()) {
m = ((MethodData*)m)->method();
}
@@ -517,16 +536,13 @@ void CodeBuffer::finalize_oop_references(methodHandle mh) {
m = ((Method*)m)->method_holder();
}
if (m->is_klass()) {
- o = ((Klass*)m)->class_loader();
+ append_oop_references(&oops, (Klass*)m);
} else {
// XXX This will currently occur for MDO which don't
// have a backpointer. This has to be fixed later.
m->print();
ShouldNotReachHere();
}
- if (o != NULL && oops.find(o) == -1) {
- oops.append(o);
- }
}
}
}
@@ -537,7 +553,6 @@ void CodeBuffer::finalize_oop_references(methodHandle mh) {
for (int i = 0; i < oop_recorder()->metadata_count(); i++) {
Metadata* m = oop_recorder()->metadata_at(i);
if (oop_recorder()->is_real(m)) {
- oop o = NULL;
if (m->is_methodData()) {
m = ((MethodData*)m)->method();
}
@@ -545,24 +560,18 @@ void CodeBuffer::finalize_oop_references(methodHandle mh) {
m = ((Method*)m)->method_holder();
}
if (m->is_klass()) {
- o = ((Klass*)m)->class_loader();
+ append_oop_references(&oops, (Klass*)m);
} else {
m->print();
ShouldNotReachHere();
}
- if (o != NULL && oops.find(o) == -1) {
- oops.append(o);
- }
}
}
}
// Add the class loader of Method* for the nmethod itself
- oop cl = mh->method_holder()->class_loader();
- if (cl != NULL) {
- oops.append(cl);
- }
+ append_oop_references(&oops, mh->method_holder());
// Add any oops that we've found
Thread* thread = Thread::current();
diff --git a/src/share/vm/ci/ciReplay.cpp b/src/share/vm/ci/ciReplay.cpp
index 726d84b1b..f2e772419 100644
--- a/src/share/vm/ci/ciReplay.cpp
+++ b/src/share/vm/ci/ciReplay.cpp
@@ -31,7 +31,7 @@
#include "memory/resourceArea.hpp"
#include "utilities/copy.hpp"
-#ifdef ASSERT
+#ifndef PRODUCT
// ciReplay
@@ -939,4 +939,4 @@ bool ciReplay::is_loaded(Method* method) {
ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
return rec != NULL;
}
-#endif
+#endif // PRODUCT
diff --git a/src/share/vm/ci/ciReplay.hpp b/src/share/vm/ci/ciReplay.hpp
index 5966d3ece..8fff3454d 100644
--- a/src/share/vm/ci/ciReplay.hpp
+++ b/src/share/vm/ci/ciReplay.hpp
@@ -32,7 +32,7 @@
class ciReplay {
CI_PACKAGE_ACCESS
-#ifdef ASSERT
+#ifndef PRODUCT
private:
static int replay_impl(TRAPS);
diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
index f53fff63d..a13bdab00 100644
--- a/src/share/vm/classfile/classFileParser.cpp
+++ b/src/share/vm/classfile/classFileParser.cpp
@@ -2184,7 +2184,7 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
Method* m = Method::allocate(
loader_data, code_length, access_flags, linenumber_table_length,
total_lvt_length, exception_table_length, checked_exceptions_length,
- ConstMethod::NORMAL, CHECK_(nullHandle));
+ generic_signature_index, ConstMethod::NORMAL, CHECK_(nullHandle));
ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
@@ -2192,7 +2192,6 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
m->set_constants(cp());
m->set_name_index(name_index);
m->set_signature_index(signature_index);
- m->set_generic_signature_index(generic_signature_index);
#ifdef CC_INTERP
// hmm is there a gc issue here??
ResultTypeFinder rtf(cp->symbol_at(signature_index));
@@ -2950,7 +2949,7 @@ static void parseAndPrintGenericSignatures(
instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
- Handle class_loader,
+ ClassLoaderData* loader_data,
Handle protection_domain,
KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
@@ -2964,7 +2963,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// original class bytes.
unsigned char *cached_class_file_bytes = NULL;
jint cached_class_file_length;
- ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+ Handle class_loader(THREAD, loader_data->class_loader());
bool has_default_methods = false;
ResourceMark rm(THREAD);
@@ -3005,7 +3004,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
unsigned char* ptr = cfs->buffer();
unsigned char* end_ptr = cfs->buffer() + cfs->length();
- JvmtiExport::post_class_file_load_hook(name, class_loader, protection_domain,
+ JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain,
&ptr, &end_ptr,
&cached_class_file_bytes,
&cached_class_file_length);
@@ -4004,8 +4003,7 @@ void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
assert(k->size_helper() > 0, "layout_helper is initialized");
if ((!RegisterFinalizersAtInit && k->has_finalizer())
|| k->is_abstract() || k->is_interface()
- || (k->name() == vmSymbols::java_lang_Class()
- && k->class_loader_data()->is_the_null_class_loader_data())
+ || (k->name() == vmSymbols::java_lang_Class() && k->class_loader() == NULL)
|| k->size_helper() >= FastAllocateSizeLimit) {
// Forbid fast-path allocation.
jint lh = Klass::instance_layout_helper(k->size_helper(), true);
diff --git a/src/share/vm/classfile/classFileParser.hpp b/src/share/vm/classfile/classFileParser.hpp
index 8fa1404cf..c5b470183 100644
--- a/src/share/vm/classfile/classFileParser.hpp
+++ b/src/share/vm/classfile/classFileParser.hpp
@@ -363,16 +363,16 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// "parsed_name" is updated by this method, and is the name found
// while parsing the stream.
instanceKlassHandle parseClassFile(Symbol* name,
- Handle class_loader,
+ ClassLoaderData* loader_data,
Handle protection_domain,
TempNewSymbol& parsed_name,
bool verify,
TRAPS) {
KlassHandle no_host_klass;
- return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
+ return parseClassFile(name, loader_data, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
}
instanceKlassHandle parseClassFile(Symbol* name,
- Handle class_loader,
+ ClassLoaderData* loader_data,
Handle protection_domain,
KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
diff --git a/src/share/vm/classfile/classLoader.cpp b/src/share/vm/classfile/classLoader.cpp
index b5e858a33..7e92f0661 100644
--- a/src/share/vm/classfile/classLoader.cpp
+++ b/src/share/vm/classfile/classLoader.cpp
@@ -26,6 +26,7 @@
#include "classfile/classFileParser.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
@@ -910,11 +911,11 @@ instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
// class file found, parse it
ClassFileParser parser(stream);
- Handle class_loader;
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
Handle protection_domain;
TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name,
- class_loader,
+ loader_data,
protection_domain,
parsed_name,
false,
diff --git a/src/share/vm/classfile/classLoaderData.cpp b/src/share/vm/classfile/classLoaderData.cpp
index 4f2b5f041..c4479bfcf 100644
--- a/src/share/vm/classfile/classLoaderData.cpp
+++ b/src/share/vm/classfile/classLoaderData.cpp
@@ -65,13 +65,19 @@
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
ClassLoaderData::ClassLoaderData(Handle h_class_loader) : _class_loader(h_class_loader()),
- _metaspace(NULL), _unloading(false), _klasses(NULL),
- _claimed(0), _jmethod_ids(NULL), _handles(NULL),
- _deallocate_list(NULL), _next(NULL),
+ _metaspace(NULL), _unloading(false), _keep_alive(false), _klasses(NULL),
+ _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
+ _next(NULL), _dependencies(NULL),
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) {
// empty
}
+void ClassLoaderData::init_dependencies(TRAPS) {
+ // Create empty dependencies array to add to. CMS requires this to be
+ // an oop so that it can track additions via card marks. We think.
+ _dependencies = (oop)oopFactory::new_objectArray(2, CHECK);
+}
+
bool ClassLoaderData::claim() {
if (_claimed == 1) {
return false;
@@ -86,6 +92,7 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m
}
f->do_oop(&_class_loader);
+ f->do_oop(&_dependencies);
_handles->oops_do(f);
if (klass_closure != NULL) {
classes_do(klass_closure);
@@ -110,70 +117,100 @@ void ClassLoaderData::record_dependency(Klass* k, TRAPS) {
ClassLoaderData * const from_cld = this;
ClassLoaderData * const to_cld = k->class_loader_data();
- // Records dependency between non-null class loaders only.
- if (to_cld->is_the_null_class_loader_data() || from_cld->is_the_null_class_loader_data()) {
+ // Dependency to the null class loader data doesn't need to be recorded
+ // because the null class loader data never goes away.
+ if (to_cld->is_the_null_class_loader_data()) {
return;
}
- // Check that this dependency isn't from the same or parent class_loader
- oop to = to_cld->class_loader();
- oop from = from_cld->class_loader();
-
- oop curr = from;
- while (curr != NULL) {
- if (curr == to) {
- return; // this class loader is in the parent list, no need to add it.
+ oop to;
+ if (to_cld->is_anonymous()) {
+ // Anonymous class dependencies are through the mirror.
+ to = k->java_mirror();
+ } else {
+ to = to_cld->class_loader();
+
+ // If from_cld is anonymous, even if it's class_loader is a parent of 'to'
+ // we still have to add it. The class_loader won't keep from_cld alive.
+ if (!from_cld->is_anonymous()) {
+ // Check that this dependency isn't from the same or parent class_loader
+ oop from = from_cld->class_loader();
+
+ oop curr = from;
+ while (curr != NULL) {
+ if (curr == to) {
+ return; // this class loader is in the parent list, no need to add it.
+ }
+ curr = java_lang_ClassLoader::parent(curr);
+ }
}
- curr = java_lang_ClassLoader::parent(curr);
}
// It's a dependency we won't find through GC, add it. This is relatively rare
- from_cld->add_dependency(to_cld, CHECK);
+ // Must handle over GC point.
+ Handle dependency(THREAD, to);
+ from_cld->add_dependency(dependency, CHECK);
}
-bool ClassLoaderData::has_dependency(ClassLoaderData* dependency) {
- oop loader = dependency->class_loader();
- // Get objArrayOop out of the class_loader oop and see if this dependency
- // is there. Don't safepoint! These are all oops.
- // Dependency list is (oop class_loader, objArrayOop next)
- objArrayOop ok = (objArrayOop)java_lang_ClassLoader::dependencies(class_loader());
+void ClassLoaderData::add_dependency(Handle dependency, TRAPS) {
+ // Check first if this dependency is already in the list.
+ // Save a pointer to the last to add to under the lock.
+ objArrayOop ok = (objArrayOop)_dependencies;
+ objArrayOop last = NULL;
while (ok != NULL) {
- if (ok->obj_at(0) == loader) {
- return true;
+ last = ok;
+ if (ok->obj_at(0) == dependency()) {
+ // Don't need to add it
+ return;
}
ok = (objArrayOop)ok->obj_at(1);
}
- return false;
+
+ // Create a new dependency node with fields for (class_loader or mirror, next)
+ objArrayOop deps = oopFactory::new_objectArray(2, CHECK);
+ deps->obj_at_put(0, dependency());
+
+ // Must handle over more GC points
+ objArrayHandle new_dependency(THREAD, deps);
+
+ // Add the dependency under lock
+ assert (last != NULL, "dependencies should be initialized");
+ objArrayHandle last_handle(THREAD, last);
+ locked_add_dependency(last_handle, new_dependency);
}
-void ClassLoaderData::add_dependency(ClassLoaderData* dependency, TRAPS) {
- // Minimize the number of duplicates in the list.
- if (has_dependency(dependency)) {
- return;
- }
+void ClassLoaderData::locked_add_dependency(objArrayHandle last_handle,
+ objArrayHandle new_dependency) {
- // Create a new dependency node with fields for (class_loader, next)
- objArrayOop deps = oopFactory::new_objectArray(2, CHECK);
- deps->obj_at_put(0, dependency->class_loader());
-
- // Add this lock free, using compare and exchange, need barriers for GC
- // Do the barrier first.
- HeapWord* addr = java_lang_ClassLoader::dependencies_addr(class_loader());
- while (true) {
- oop old_dependency = java_lang_ClassLoader::dependencies(class_loader());
- deps->obj_at_put(1, old_dependency);
-
- oop newold = oopDesc::atomic_compare_exchange_oop((oop)deps, addr, old_dependency, true);
- if (newold == old_dependency) {
- update_barrier_set((void*)addr, (oop)deps);
- // we won the race to add this dependency
- break;
+ // Have to lock and put the new dependency on the end of the dependency
+ // array so the card mark for CMS sees that this dependency is new.
+ // Can probably do this lock free with some effort.
+ MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
+
+ oop loader_or_mirror = new_dependency->obj_at(0);
+
+ // Since the dependencies are only added, add to the end.
+ objArrayOop end = last_handle();
+ objArrayOop last = NULL;
+ while (end != NULL) {
+ last = end;
+ // check again if another thread added it to the end.
+ if (end->obj_at(0) == loader_or_mirror) {
+ // Don't need to add it
+ return;
}
+ end = (objArrayOop)end->obj_at(1);
+ }
+ assert (last != NULL, "dependencies should be initialized");
+ // fill in the first element with the oop in new_dependency.
+ if (last->obj_at(0) == NULL) {
+ last->obj_at_put(0, new_dependency->obj_at(0));
+ } else {
+ last->obj_at_put(1, new_dependency());
}
}
-
void ClassLoaderDataGraph::clear_claimed_marks() {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
cld->clear_claimed();
@@ -187,7 +224,7 @@ void ClassLoaderData::add_class(Klass* k) {
// link the new item into the list
_klasses = k;
- if (TraceClassLoaderData && k->class_loader_data() != NULL) {
+ if (TraceClassLoaderData && Verbose && k->class_loader_data() != NULL) {
ResourceMark rm;
tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: "
PTR_FORMAT " loader: " PTR_FORMAT " %s",
@@ -195,8 +232,7 @@ void ClassLoaderData::add_class(Klass* k) {
k->external_name(),
k->class_loader_data(),
k->class_loader(),
- k->class_loader() != NULL ? k->class_loader()->klass()->external_name() : "NULL"
- );
+ loader_name());
}
}
@@ -221,6 +257,38 @@ void ClassLoaderData::remove_class(Klass* scratch_class) {
ShouldNotReachHere(); // should have found this class!!
}
+
+bool ClassLoaderData::is_anonymous() const {
+ Klass* k = _klasses;
+ return (_keep_alive || (k != NULL && k->oop_is_instance() &&
+ InstanceKlass::cast(k)->is_anonymous()));
+}
+
+void ClassLoaderData::unload() {
+ _unloading = true;
+
+ if (TraceClassLoaderData) {
+ ResourceMark rm;
+ tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this);
+ tty->print(" for instance "PTR_FORMAT" of %s", class_loader(),
+ loader_name());
+ if (is_anonymous()) {
+ tty->print(" for anonymous class "PTR_FORMAT " ", _klasses);
+ }
+ tty->print_cr("]");
+ }
+}
+
+bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const {
+ bool alive =
+ is_anonymous() ?
+ is_alive_closure->do_object_b(_klasses->java_mirror()) :
+ class_loader() == NULL || is_alive_closure->do_object_b(class_loader());
+ assert(!alive || claimed(), "must be claimed");
+ return alive;
+}
+
+
ClassLoaderData::~ClassLoaderData() {
Metaspace *m = _metaspace;
if (m != NULL) {
@@ -263,8 +331,8 @@ Metaspace* ClassLoaderData::metaspace_non_null() {
if (_metaspace != NULL) {
return _metaspace;
}
- if (class_loader() == NULL) {
- assert(this == the_null_class_loader_data(), "Must be");
+ if (this == the_null_class_loader_data()) {
+ assert (class_loader() == NULL, "Must be");
size_t word_size = Metaspace::first_chunk_word_size();
set_metaspace(new Metaspace(_metaspace_lock, word_size));
} else {
@@ -325,12 +393,19 @@ void ClassLoaderData::free_deallocate_list() {
}
}
-#ifndef PRODUCT
-void ClassLoaderData::print_loader(ClassLoaderData *loader_data, outputStream* out) {
- oop class_loader = loader_data->class_loader();
- out->print("%s", SystemDictionary::loader_name(class_loader));
+// These anonymous class loaders are to contain classes used for JSR292
+ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
+ // Add a new class loader data to the graph.
+ ClassLoaderData* cld = ClassLoaderDataGraph::add(NULL, loader, CHECK_NULL);
+ return cld;
}
+const char* ClassLoaderData::loader_name() {
+ // Handles null class loader
+ return SystemDictionary::loader_name(class_loader());
+}
+
+#ifndef PRODUCT
// Define to dump klasses
#undef CLD_DUMP_KLASSES
@@ -338,8 +413,7 @@ void ClassLoaderData::dump(outputStream * const out) {
ResourceMark rm;
out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {",
this, class_loader(),
- class_loader() != NULL ? class_loader()->klass() : NULL,
- class_loader() != NULL ? class_loader()->klass()->external_name() : "NULL");
+ class_loader() != NULL ? class_loader()->klass() : NULL, loader_name());
if (claimed()) out->print(" claimed ");
if (is_unloading()) out->print(" unloading ");
out->print(" handles " INTPTR_FORMAT, handles());
@@ -373,8 +447,8 @@ void ClassLoaderData::dump(outputStream * const out) {
void ClassLoaderData::verify() {
oop cl = class_loader();
- guarantee(this == class_loader_data(cl), "Must be the same");
- guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data(), "must be");
+ guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same");
+ guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_anonymous(), "must be");
// Verify the integrity of the allocated space.
if (metaspace_or_null() != NULL) {
@@ -387,6 +461,7 @@ void ClassLoaderData::verify() {
}
}
+
// GC root of class loader data created.
ClassLoaderData* ClassLoaderDataGraph::_head = NULL;
ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
@@ -395,19 +470,25 @@ ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
// Add a new class loader data node to the list. Assign the newly created
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
-ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader_data) {
+ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader, TRAPS) {
// Not assigned a class loader data yet.
// Create one.
ClassLoaderData* *list_head = &_head;
ClassLoaderData* next = _head;
- ClassLoaderData* cld = new ClassLoaderData(loader_data);
-
- // First, Atomically set it.
- ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
- if (old != NULL) {
- delete cld;
- // Returns the data.
- return old;
+ ClassLoaderData* cld = new ClassLoaderData(loader);
+
+ if (cld_addr != NULL) {
+ // First, Atomically set it
+ ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL);
+ if (old != NULL) {
+ delete cld;
+ // Returns the data.
+ return old;
+ }
+ } else {
+ // Disallow unloading for this CLD during initialization if there is no
+ // class_loader oop to link this to.
+ cld->set_keep_alive(true);
}
// We won the race, and therefore the task of adding the data to the list of
@@ -417,16 +498,22 @@ ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle lo
ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next);
if (exchanged == next) {
if (TraceClassLoaderData) {
+ ResourceMark rm;
tty->print("[ClassLoaderData: ");
tty->print("create class loader data "PTR_FORMAT, cld);
- tty->print(" for instance "PTR_FORMAT" of ", cld->class_loader());
- loader_data->klass()->name()->print_symbol_on(tty);
+ tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(),
+ cld->loader_name());
tty->print_cr("]");
}
+ // Create dependencies after the CLD is added to the list. Otherwise,
+ // the GC GC will not find the CLD and the _class_loader field will
+ // not be updated.
+ cld->init_dependencies(CHECK_NULL);
return cld;
}
next = exchanged;
} while (true);
+
}
void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
@@ -435,9 +522,19 @@ void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, b
}
}
+void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ if (cld->keep_alive()) {
+ cld->oops_do(f, klass_closure, must_claim);
+ }
+ }
+}
+
void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
if (ClassUnloading) {
ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim);
+ // keep any special CLDs alive.
+ ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim);
} else {
ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim);
}
@@ -516,9 +613,10 @@ bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
}
#endif // PRODUCT
+
// Move class loader data from main list to the unloaded list for unloading
// and deallocation later.
-bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive) {
+bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
ClassLoaderData* data = _head;
ClassLoaderData* prev = NULL;
bool seen_dead_loader = false;
@@ -527,8 +625,7 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive) {
bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
MetadataOnStackMark md_on_stack;
while (data != NULL) {
- if (data->class_loader() == NULL || is_alive->do_object_b(data->class_loader())) {
- assert(data->claimed(), "class loader data must have been claimed");
+ if (data->keep_alive() || data->is_alive(is_alive_closure)) {
if (has_redefined_a_class) {
data->classes_do(InstanceKlass::purge_previous_versions);
}
@@ -539,13 +636,7 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive) {
}
seen_dead_loader = true;
ClassLoaderData* dead = data;
- dead->mark_for_unload();
- if (TraceClassLoaderData) {
- tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, dead);
- tty->print(" for instance "PTR_FORMAT" of ", dead->class_loader());
- dead->class_loader()->klass()->name()->print_symbol_on(tty);
- tty->print_cr("]");
- }
+ dead->unload();
data = data->next();
// Remove from loader list.
if (prev != NULL) {
diff --git a/src/share/vm/classfile/classLoaderData.hpp b/src/share/vm/classfile/classLoaderData.hpp
index 999f48dbd..71cd7b2a4 100644
--- a/src/share/vm/classfile/classLoaderData.hpp
+++ b/src/share/vm/classfile/classLoaderData.hpp
@@ -62,13 +62,14 @@ class ClassLoaderDataGraph : public AllStatic {
// CMS support.
static ClassLoaderData* _saved_head;
- static ClassLoaderData* add(ClassLoaderData** loader_data_addr, Handle class_loader);
+ static ClassLoaderData* add(ClassLoaderData** loader_data_addr, Handle class_loader, TRAPS);
public:
- static ClassLoaderData* find_or_create(Handle class_loader);
+ static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
static void purge();
static void clear_claimed_marks();
static void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
+ static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
static void classes_do(KlassClosure* klass_closure);
static bool do_unloading(BoolObjectClosure* is_alive);
@@ -101,10 +102,13 @@ class ClassLoaderData : public CHeapObj<mtClass> {
oop _class_loader; // oop used to uniquely identify a class loader
// class loader or a canonical class path
+ oop _dependencies; // oop to hold dependencies from this class loader
+ // data to others.
Metaspace * _metaspace; // Meta-space where meta-data defined by the
// classes in the class loader are allocated.
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away
+ bool _keep_alive; // if this CLD can be unloaded for anonymous loaders
volatile int _claimed; // true if claimed, for example during GC traces.
// To avoid applying oop closure more than once.
// Has to be an int because we cas it.
@@ -129,8 +133,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
static Metaspace* _ro_metaspace;
static Metaspace* _rw_metaspace;
- bool has_dependency(ClassLoaderData* cld);
- void add_dependency(ClassLoaderData* to_loader_data, TRAPS);
+ void add_dependency(Handle dependency, TRAPS);
+ void locked_add_dependency(objArrayHandle last, objArrayHandle new_dependency);
void set_next(ClassLoaderData* next) { _next = next; }
ClassLoaderData* next() const { return _next; }
@@ -150,7 +154,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
bool claimed() const { return _claimed == 1; }
bool claim();
- void mark_for_unload() { _unloading = true; }
+ void unload();
+ bool keep_alive() const { return _keep_alive; }
+ bool is_alive(BoolObjectClosure* is_alive_closure) const;
void classes_do(void f(InstanceKlass*));
@@ -168,6 +174,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
return _the_null_class_loader_data;
}
+ bool is_anonymous() const;
+
static void init_null_class_loader_data() {
assert(_the_null_class_loader_data == NULL, "cannot initialize twice");
assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice");
@@ -194,6 +202,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
assert(!(is_the_null_class_loader_data() && _unloading), "The null class loader can never be unloaded");
return _unloading;
}
+ // Anonymous class loader data doesn't have anything to keep them from
+ // being unloaded during parsing the anonymous class.
+ void set_keep_alive(bool value) { _keep_alive = value; }
unsigned int identity_hash() {
return _class_loader == NULL ? 0 : _class_loader->identity_hash();
@@ -211,15 +222,18 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void print_value_on(outputStream* out) const PRODUCT_RETURN;
void dump(outputStream * const out) PRODUCT_RETURN;
void verify();
+ const char* loader_name();
jobject add_handle(Handle h);
void add_class(Klass* k);
void remove_class(Klass* k);
void record_dependency(Klass* to, TRAPS);
+ void init_dependencies(TRAPS);
void add_to_deallocate_list(Metadata* m);
static ClassLoaderData* class_loader_data(oop loader);
+ static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS);
static void print_loader(ClassLoaderData *loader_data, outputStream *out);
// CDS support
diff --git a/src/share/vm/classfile/classLoaderData.inline.hpp b/src/share/vm/classfile/classLoaderData.inline.hpp
index c2d01e632..770856fe8 100644
--- a/src/share/vm/classfile/classLoaderData.inline.hpp
+++ b/src/share/vm/classfile/classLoaderData.inline.hpp
@@ -33,7 +33,7 @@ inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
}
-inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) {
+inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader, TRAPS) {
assert(loader() != NULL,"Must be a class loader");
// Gets the class loader data out of the java/lang/ClassLoader object, if non-null
// it's already in the loader_data, so no need to add
@@ -42,5 +42,5 @@ inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) {
if (loader_data_id) {
return loader_data_id;
}
- return ClassLoaderDataGraph::add(loader_data_addr, loader);
+ return ClassLoaderDataGraph::add(loader_data_addr, loader, THREAD);
}
diff --git a/src/share/vm/classfile/defaultMethods.cpp b/src/share/vm/classfile/defaultMethods.cpp
index 9ac1bef7a..1f4eefa79 100644
--- a/src/share/vm/classfile/defaultMethods.cpp
+++ b/src/share/vm/classfile/defaultMethods.cpp
@@ -1148,12 +1148,11 @@ static Method* new_method(
int code_length = bytecodes->length();
Method* m = Method::allocate(cp->pool_holder()->class_loader_data(),
- code_length, flags, 0, 0, 0, 0, mt, CHECK_NULL);
+ code_length, flags, 0, 0, 0, 0, 0, mt, CHECK_NULL);
m->set_constants(NULL); // This will get filled in later
m->set_name_index(cp->utf8(name));
m->set_signature_index(cp->utf8(sig));
- m->set_generic_signature_index(0);
#ifdef CC_INTERP
ResultTypeFinder rtf(sig);
m->set_result_index(rtf.type());
diff --git a/src/share/vm/classfile/dictionary.cpp b/src/share/vm/classfile/dictionary.cpp
index 33470303f..32ebb2710 100644
--- a/src/share/vm/classfile/dictionary.cpp
+++ b/src/share/vm/classfile/dictionary.cpp
@@ -580,7 +580,7 @@ void Dictionary::verify() {
// class loader must be present; a null class loader is the
// boostrap loader
guarantee(loader_data != NULL || DumpSharedSpaces ||
- loader_data->is_the_null_class_loader_data() ||
+ loader_data->class_loader() == NULL ||
loader_data->class_loader()->is_instance(),
"checking type of class_loader");
e->verify();
diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp
index c5fad6487..80b15fbd2 100644
--- a/src/share/vm/classfile/javaClasses.cpp
+++ b/src/share/vm/classfile/javaClasses.cpp
@@ -47,20 +47,9 @@
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "utilities/preserveException.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \
klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);
@@ -2555,8 +2544,8 @@ Metadata* java_lang_invoke_MemberName::vmtarget(oop mname) {
void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
assert(is_instance(mname), "wrong type");
-#ifdef ASSERT
// check the type of the vmtarget
+ oop dependency = NULL;
if (ref != NULL) {
switch (flags(mname) & (MN_IS_METHOD |
MN_IS_CONSTRUCTOR |
@@ -2564,28 +2553,21 @@ void java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) {
case MN_IS_METHOD:
case MN_IS_CONSTRUCTOR:
assert(ref->is_method(), "should be a method");
+ dependency = ((Method*)ref)->method_holder()->java_mirror();
break;
case MN_IS_FIELD:
assert(ref->is_klass(), "should be a class");
+ dependency = ((Klass*)ref)->java_mirror();
break;
default:
ShouldNotReachHere();
}
}
-#endif //ASSERT
mname->address_field_put(_vmtarget_offset, (address)ref);
- oop loader = NULL;
- if (ref != NULL) {
- if (ref->is_klass()) {
- loader = ((Klass*)ref)->class_loader();
- } else if (ref->is_method()) {
- loader = ((Method*)ref)->method_holder()->class_loader();
- } else {
- ShouldNotReachHere();
- }
- }
- // Add a reference to the loader to ensure the metadata is kept alive
- mname->obj_field_put(_vmloader_offset, loader);
+ // Add a reference to the loader (actually mirror because anonymous classes will not have
+ // distinct loaders) to ensure the metadata is kept alive
+ // This mirror may be different than the one in clazz field.
+ mname->obj_field_put(_vmloader_offset, dependency);
}
intptr_t java_lang_invoke_MemberName::vmindex(oop mname) {
@@ -2750,7 +2732,6 @@ oop java_security_AccessControlContext::create(objArrayHandle context, bool isPr
bool java_lang_ClassLoader::offsets_computed = false;
int java_lang_ClassLoader::_loader_data_offset = -1;
-int java_lang_ClassLoader::_dependencies_offset = -1;
int java_lang_ClassLoader::parallelCapable_offset = -1;
ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
@@ -2762,18 +2743,6 @@ ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
return *java_lang_ClassLoader::loader_data_addr(loader);
}
-oop java_lang_ClassLoader::dependencies(oop loader) {
- return loader->obj_field(_dependencies_offset);
-}
-
-HeapWord* java_lang_ClassLoader::dependencies_addr(oop loader) {
- if (UseCompressedOops) {
- return (HeapWord*)loader->obj_field_addr<narrowOop>(_dependencies_offset);
- } else {
- return (HeapWord*)loader->obj_field_addr<oop>(_dependencies_offset);
- }
-}
-
void java_lang_ClassLoader::compute_offsets() {
assert(!offsets_computed, "offsets should be initialized only once");
offsets_computed = true;
diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp
index 74442df1d..9359d5b3c 100644
--- a/src/share/vm/classfile/javaClasses.hpp
+++ b/src/share/vm/classfile/javaClasses.hpp
@@ -1125,8 +1125,7 @@ class java_security_AccessControlContext: AllStatic {
// Interface to java.lang.ClassLoader objects
#define CLASSLOADER_INJECTED_FIELDS(macro) \
- macro(java_lang_ClassLoader, loader_data, intptr_signature, false) \
- macro(java_lang_ClassLoader, dependencies, object_signature, false)
+ macro(java_lang_ClassLoader, loader_data, intptr_signature, false)
class java_lang_ClassLoader : AllStatic {
private:
@@ -1135,7 +1134,6 @@ class java_lang_ClassLoader : AllStatic {
hc_parent_offset = 0
};
static int _loader_data_offset;
- static int _dependencies_offset;
static bool offsets_computed;
static int parent_offset;
static int parallelCapable_offset;
@@ -1146,9 +1144,6 @@ class java_lang_ClassLoader : AllStatic {
static ClassLoaderData** loader_data_addr(oop loader);
static ClassLoaderData* loader_data(oop loader);
- static oop dependencies(oop loader);
- static HeapWord* dependencies_addr(oop loader);
-
static oop parent(oop loader);
static bool isAncestor(oop loader, oop cl);
diff --git a/src/share/vm/classfile/loaderConstraints.cpp b/src/share/vm/classfile/loaderConstraints.cpp
index 135eb59e8..8d59c00e7 100644
--- a/src/share/vm/classfile/loaderConstraints.cpp
+++ b/src/share/vm/classfile/loaderConstraints.cpp
@@ -118,7 +118,7 @@ void LoaderConstraintTable::purge_loader_constraints() {
probe->name()->as_C_string());
for (int i = 0; i < probe->num_loaders(); i++) {
tty->print_cr("[ [%d]: %s", i,
- SystemDictionary::loader_name(probe->loader_data(i)));
+ probe->loader_data(i)->loader_name());
}
}
}
@@ -129,7 +129,7 @@ void LoaderConstraintTable::purge_loader_constraints() {
if (TraceLoaderConstraints) {
ResourceMark rm;
tty->print_cr("[Purging loader %s from constraint for name %s",
- SystemDictionary::loader_name(probe->loader_data(n)),
+ probe->loader_data(n)->loader_name(),
probe->name()->as_C_string()
);
}
@@ -145,7 +145,7 @@ void LoaderConstraintTable::purge_loader_constraints() {
tty->print_cr("[New loader list:");
for (int i = 0; i < probe->num_loaders(); i++) {
tty->print_cr("[ [%d]: %s", i,
- SystemDictionary::loader_name(probe->loader_data(i)));
+ probe->loader_data(i)->loader_name());
}
}
@@ -400,7 +400,7 @@ void LoaderConstraintTable::merge_loader_constraints(
for (int i = 0; i < p1->num_loaders(); i++) {
tty->print_cr("[ [%d]: %s", i,
- SystemDictionary::loader_name(p1->loader_data(i)));
+ p1->loader_data(i)->loader_name());
}
if (p1->klass() == NULL) {
tty->print_cr("[... and setting class object]");
diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp
index 7a997ebb4..a493e73d8 100644
--- a/src/share/vm/classfile/systemDictionary.cpp
+++ b/src/share/vm/classfile/systemDictionary.cpp
@@ -106,9 +106,9 @@ void SystemDictionary::compute_java_system_loader(TRAPS) {
}
-ClassLoaderData* SystemDictionary::register_loader(Handle class_loader) {
+ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) {
if (class_loader() == NULL) return ClassLoaderData::the_null_class_loader_data();
- return ClassLoaderDataGraph::find_or_create(class_loader);
+ return ClassLoaderDataGraph::find_or_create(class_loader, CHECK_NULL);
}
// ----------------------------------------------------------------------------
@@ -591,7 +591,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// UseNewReflection
// Fix for 4474172; see evaluation for more details
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
- ClassLoaderData *loader_data = register_loader(class_loader);
+ ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
// Do lookup to see if class already exist and the protection domain
// has the right access
@@ -888,7 +888,7 @@ Klass* SystemDictionary::find(Symbol* class_name,
// of the call to resolve_instance_class_or_null().
// See evaluation 6790209 and 4474172 for more details.
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
- ClassLoaderData* loader_data = register_loader(class_loader);
+ ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL);
unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);
@@ -948,6 +948,18 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
TRAPS) {
TempNewSymbol parsed_name = NULL;
+ ClassLoaderData* loader_data;
+ if (host_klass.not_null()) {
+ // Create a new CLD for anonymous class, that uses the same class loader
+ // as the host_klass
+ assert(EnableInvokeDynamic, "");
+ guarantee(host_klass->class_loader() == class_loader(), "should be the same");
+ loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
+ loader_data->record_dependency(host_klass(), CHECK_NULL);
+ } else {
+ loader_data = ClassLoaderData::class_loader_data(class_loader());
+ }
+
// Parse the stream. Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
@@ -959,7 +971,7 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
- class_loader,
+ loader_data,
protection_domain,
host_klass,
cp_patches,
@@ -973,8 +985,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
// Parsed name could be null if we threw an error before we got far
// enough along to parse it -- in that case, there is nothing to clean up.
if (parsed_name != NULL) {
- ClassLoaderData* loader_data = class_loader_data(class_loader);
-
unsigned int p_hash = placeholders()->compute_hash(parsed_name,
loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
@@ -987,9 +997,8 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
if (host_klass.not_null() && k.not_null()) {
assert(EnableInvokeDynamic, "");
- // If it's anonymous, initialize it now, since nobody else will.
- k->class_loader_data()->record_dependency(host_klass(), CHECK_NULL);
k->set_host_klass(host_klass());
+ // If it's anonymous, initialize it now, since nobody else will.
{
MutexLocker mu_r(Compile_lock, THREAD);
@@ -1002,11 +1011,11 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
}
// Rewrite and patch constant pool here.
- k->link_class(THREAD);
+ k->link_class(CHECK_NULL);
if (cp_patches != NULL) {
k->constants()->patch_resolved_references(cp_patches);
}
- k->eager_initialize(THREAD);
+ k->eager_initialize(CHECK_NULL);
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
@@ -1039,7 +1048,7 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
DoObjectLock = false;
}
- ClassLoaderData* loader_data = register_loader(class_loader);
+ ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL);
// Make sure we are synchronized on the class loader before we proceed
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
@@ -1059,7 +1068,7 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
- class_loader,
+ loader_data,
protection_domain,
parsed_name,
verify,
@@ -2343,6 +2352,7 @@ methodHandle SystemDictionary::find_method_handle_intrinsic(vmIntrinsics::ID iid
// Helper for unpacking the return value from linkMethod and linkCallSite.
static methodHandle unpack_method_and_appendix(Handle mname,
+ KlassHandle accessing_klass,
objArrayHandle appendix_box,
Handle* appendix_result,
TRAPS) {
@@ -2361,6 +2371,12 @@ static methodHandle unpack_method_and_appendix(Handle mname,
#endif //PRODUCT
}
(*appendix_result) = Handle(THREAD, appendix);
+ // the target is stored in the cpCache and if a reference to this
+ // MethodName is dropped we need a way to make sure the
+ // class_loader containing this method is kept alive.
+ // FIXME: the appendix might also preserve this dependency.
+ ClassLoaderData* this_key = InstanceKlass::cast(accessing_klass())->class_loader_data();
+ this_key->record_dependency(m->method_holder(), CHECK_NULL); // Can throw OOM
return methodHandle(THREAD, m);
}
}
@@ -2405,7 +2421,7 @@ methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
&args, CHECK_(empty));
Handle mname(THREAD, (oop) result.get_jobject());
(*method_type_result) = method_type;
- return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
+ return unpack_method_and_appendix(mname, accessing_klass, appendix_box, appendix_result, THREAD);
}
@@ -2596,7 +2612,7 @@ methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller
&args, CHECK_(empty));
Handle mname(THREAD, (oop) result.get_jobject());
(*method_type_result) = method_type;
- return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
+ return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD);
}
// Since the identity hash code for symbols changes when the symbols are
diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp
index 21967f6d8..c757d3409 100644
--- a/src/share/vm/classfile/systemDictionary.hpp
+++ b/src/share/vm/classfile/systemDictionary.hpp
@@ -471,7 +471,7 @@ public:
static void compute_java_system_loader(TRAPS);
// Register a new class loader
- static ClassLoaderData* register_loader(Handle class_loader);
+ static ClassLoaderData* register_loader(Handle class_loader, TRAPS);
private:
// Mirrors for primitive classes (created eagerly)
static oop check_mirror(oop m) {
@@ -531,7 +531,7 @@ public:
InstanceKlass::cast((loader)->klass())->name()->as_C_string() );
}
static const char* loader_name(ClassLoaderData* loader_data) {
- return (loader_data->is_the_null_class_loader_data() ? "<bootloader>" :
+ return (loader_data->class_loader() == NULL ? "<bootloader>" :
InstanceKlass::cast((loader_data->class_loader())->klass())->name()->as_C_string() );
}
diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp
index d4d09e0c6..bd76850ee 100644
--- a/src/share/vm/compiler/compileBroker.cpp
+++ b/src/share/vm/compiler/compileBroker.cpp
@@ -269,10 +269,12 @@ void CompileTask::initialize(int compile_id,
const char* comment,
bool is_blocking) {
assert(!_lock->is_locked(), "bad locking");
+ InstanceKlass* holder = method->method_holder();
_compile_id = compile_id;
_method = method();
- _method_loader = JNIHandles::make_global(_method->method_holder()->class_loader());
+ _method_holder = JNIHandles::make_global(
+ holder->is_anonymous() ? holder->java_mirror(): holder->class_loader());
_osr_bci = osr_bci;
_is_blocking = is_blocking;
_comp_level = comp_level;
@@ -283,7 +285,7 @@ void CompileTask::initialize(int compile_id,
_code_handle = NULL;
_hot_method = NULL;
- _hot_method_loader = NULL;
+ _hot_method_holder = NULL;
_hot_count = hot_count;
_time_queued = 0; // tidy
_comment = comment;
@@ -295,8 +297,12 @@ void CompileTask::initialize(int compile_id,
_hot_method = _method;
} else {
_hot_method = hot_method();
+ // only add loader or mirror if different from _method_holder
+ InstanceKlass* hot_holder = hot_method->method_holder();
+ _hot_method_holder = JNIHandles::make_global(
+ hot_holder->is_anonymous() ? hot_holder->java_mirror() :
+ hot_holder->class_loader());
}
- _hot_method_loader = JNIHandles::make_global(_hot_method->method_holder()->class_loader());
}
}
@@ -321,8 +327,8 @@ void CompileTask::set_code(nmethod* nm) {
void CompileTask::free() {
set_code(NULL);
assert(!_lock->is_locked(), "Should not be locked when freed");
- JNIHandles::destroy_global(_method_loader);
- JNIHandles::destroy_global(_hot_method_loader);
+ JNIHandles::destroy_global(_method_holder);
+ JNIHandles::destroy_global(_hot_method_holder);
}
diff --git a/src/share/vm/compiler/compileBroker.hpp b/src/share/vm/compiler/compileBroker.hpp
index 5169cbe35..7ba448b80 100644
--- a/src/share/vm/compiler/compileBroker.hpp
+++ b/src/share/vm/compiler/compileBroker.hpp
@@ -43,7 +43,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
Monitor* _lock;
uint _compile_id;
Method* _method;
- jobject _method_loader;
+ jobject _method_holder;
int _osr_bci;
bool _is_complete;
bool _is_success;
@@ -56,7 +56,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
// Fields used for logging why the compilation was initiated:
jlong _time_queued; // in units of os::elapsed_counter()
Method* _hot_method; // which method actually triggered this task
- jobject _hot_method_loader;
+ jobject _hot_method_holder;
int _hot_count; // information about its invocation counter
const char* _comment; // more info about the task
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
index 9c10aaa0e..5123d460c 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp
@@ -40,19 +40,8 @@
#include "runtime/globals_extension.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
//
// ConcurrentMarkSweepPolicy methods
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
index 63e5cb457..f59ce4598 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
@@ -27,18 +27,7 @@
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/shared/concurrentGCThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
class ConcurrentMarkSweepGeneration;
class CMSCollector;
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
index b722779b8..a67e19d89 100644
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
@@ -65,8 +65,7 @@ typedef BinaryTreeDictionary<FreeChunk, AdaptiveFreeList> AFLBinaryTreeDictionar
declare_toplevel_type(AFLBinaryTreeDictionary*) \
declare_toplevel_type(LinearAllocBlock) \
declare_toplevel_type(FreeBlockDictionary<FreeChunk>) \
- declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>) \
- declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>) \
+ declare_type(AFLBinaryTreeDictionary, FreeBlockDictionary<FreeChunk>)
#define VM_INT_CONSTANTS_CMS(declare_constant) \
declare_constant(Generation::ConcurrentMarkSweep) \
diff --git a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
index 915ee25ef..7bdb98f16 100644
--- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
+++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
@@ -28,20 +28,8 @@
#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/workgroup.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
bool consume,
diff --git a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
index 3b9646aae..9152e7010 100644
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
+++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
@@ -302,16 +302,28 @@ void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) con
for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
u_char entry = _array->offset_array(c);
if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
- guarantee(entry > N_words, "Should be in logarithmic region");
+ guarantee(entry > N_words,
+ err_msg("Should be in logarithmic region - "
+ "entry: " UINT32_FORMAT ", "
+ "_array->offset_array(c): " UINT32_FORMAT ", "
+ "N_words: " UINT32_FORMAT,
+ entry, _array->offset_array(c), N_words));
}
size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
size_t landing_card = c - backskip;
guarantee(landing_card >= (start_card - 1), "Inv");
if (landing_card >= start_card) {
- guarantee(_array->offset_array(landing_card) <= entry, "monotonicity");
+ guarantee(_array->offset_array(landing_card) <= entry,
+ err_msg("Monotonicity - landing_card offset: " UINT32_FORMAT ", "
+ "entry: " UINT32_FORMAT,
+ _array->offset_array(landing_card), entry));
} else {
guarantee(landing_card == start_card - 1, "Tautology");
- guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
+ // Note that N_words is the maximum offset value
+ guarantee(_array->offset_array(landing_card) <= N_words,
+ err_msg("landing card offset: " UINT32_FORMAT ", "
+ "N_words: " UINT32_FORMAT,
+ _array->offset_array(landing_card), N_words));
}
}
}
@@ -536,17 +548,27 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_
// The offset can be 0 if the block starts on a boundary. That
// is checked by an assertion above.
size_t start_index = _array->index_for(blk_start);
- HeapWord* boundary = _array->address_for_index(start_index);
+ HeapWord* boundary = _array->address_for_index(start_index);
assert((_array->offset_array(orig_index) == 0 &&
blk_start == boundary) ||
(_array->offset_array(orig_index) > 0 &&
_array->offset_array(orig_index) <= N_words),
- "offset array should have been set");
+ err_msg("offset array should have been set - "
+ "orig_index offset: " UINT32_FORMAT ", "
+ "blk_start: " PTR_FORMAT ", "
+ "boundary: " PTR_FORMAT,
+ _array->offset_array(orig_index),
+ blk_start, boundary));
for (size_t j = orig_index + 1; j <= end_index; j++) {
assert(_array->offset_array(j) > 0 &&
_array->offset_array(j) <=
(u_char) (N_words+BlockOffsetArray::N_powers-1),
- "offset array should have been set");
+ err_msg("offset array should have been set - "
+ UINT32_FORMAT " not > 0 OR "
+ UINT32_FORMAT " not <= " UINT32_FORMAT,
+ _array->offset_array(j),
+ _array->offset_array(j),
+ (u_char) (N_words+BlockOffsetArray::N_powers-1)));
}
#endif
}
diff --git a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
index e04ff7108..655ab698d 100644
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
+++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
@@ -78,7 +78,9 @@ public:
virtual void resize(size_t new_word_size) = 0;
virtual void set_bottom(HeapWord* new_bottom) {
- assert(new_bottom <= _end, "new_bottom > _end");
+ assert(new_bottom <= _end,
+ err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")",
+ new_bottom, _end));
_bottom = new_bottom;
resize(pointer_delta(_end, _bottom));
}
@@ -134,29 +136,42 @@ private:
VirtualSpace _vs;
u_char* _offset_array; // byte array keeping backwards offsets
+ void check_index(size_t index, const char* msg) const {
+ assert(index < _vs.committed_size(),
+ err_msg("%s - "
+ "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
+ msg, index, _vs.committed_size()));
+ }
+
+ void check_offset(size_t offset, const char* msg) const {
+ assert(offset <= N_words,
+ err_msg("%s - "
+ "offset: " UINT32_FORMAT", N_words: " UINT32_FORMAT,
+ msg, offset, N_words));
+ }
+
// Bounds checking accessors:
// For performance these have to devolve to array accesses in product builds.
u_char offset_array(size_t index) const {
- assert(index < _vs.committed_size(), "index out of range");
+ check_index(index, "index out of range");
return _offset_array[index];
}
void set_offset_array(size_t index, u_char offset) {
- assert(index < _vs.committed_size(), "index out of range");
- assert(offset <= N_words, "offset too large");
+ check_index(index, "index out of range");
+ check_offset(offset, "offset too large");
_offset_array[index] = offset;
}
void set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
- assert(index < _vs.committed_size(), "index out of range");
+ check_index(index, "index out of range");
assert(high >= low, "addresses out of order");
- assert(pointer_delta(high, low) <= N_words, "offset too large");
+ check_offset(pointer_delta(high, low), "offset too large");
_offset_array[index] = (u_char) pointer_delta(high, low);
}
void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
- assert(index_for(right - 1) < _vs.committed_size(),
- "right address out of range");
+ check_index(index_for(right - 1), "right address out of range");
assert(left < right, "Heap addresses out of order");
size_t num_cards = pointer_delta(right, left) >> LogN_words;
if (UseMemSetInBOT) {
@@ -171,7 +186,7 @@ private:
}
void set_offset_array(size_t left, size_t right, u_char offset) {
- assert(right < _vs.committed_size(), "right address out of range");
+ check_index(right, "right index out of range");
assert(left <= right, "indexes out of order");
size_t num_cards = right - left + 1;
if (UseMemSetInBOT) {
@@ -186,11 +201,10 @@ private:
}
void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
- assert(index < _vs.committed_size(), "index out of range");
+ check_index(index, "index out of range");
assert(high >= low, "addresses out of order");
- assert(pointer_delta(high, low) <= N_words, "offset too large");
- assert(_offset_array[index] == pointer_delta(high, low),
- "Wrong offset");
+ check_offset(pointer_delta(high, low), "offset too large");
+ assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
}
bool is_card_boundary(HeapWord* p) const;
@@ -481,7 +495,6 @@ class G1BlockOffsetArrayContigSpace: public G1BlockOffsetArray {
blk_start, blk_end);
}
-
public:
G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);
diff --git a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
index 2f8868185..d300f5625 100644
--- a/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
+++ b/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
@@ -49,16 +49,17 @@ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const {
char* pc = (char*)p;
assert(pc >= (char*)_reserved.start() &&
pc < (char*)_reserved.end(),
- "p not in range.");
+ err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
+ p, (char*)_reserved.start(), (char*)_reserved.end()));
size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char));
size_t result = delta >> LogN;
- assert(result < _vs.committed_size(), "bad index from address");
+ check_index(result, "bad index from address");
return result;
}
inline HeapWord*
G1BlockOffsetSharedArray::address_for_index(size_t index) const {
- assert(index < _vs.committed_size(), "bad index");
+ check_index(index, "index out of range");
HeapWord* result = _reserved.start() + (index << LogN_words);
assert(result >= _reserved.start() && result < _reserved.end(),
err_msg("bad address from index result " PTR_FORMAT
diff --git a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
index e54956c75..9cee1eb1b 100644
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
@@ -27,19 +27,7 @@
#include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/satbQueue.hpp"
#include "runtime/mutexLocker.hpp"
-#include "runtime/thread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap,
int max_covered_regions) :
diff --git a/src/share/vm/gc_implementation/g1/ptrQueue.cpp b/src/share/vm/gc_implementation/g1/ptrQueue.cpp
index b780b2d52..2193c17e3 100644
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp
@@ -28,18 +28,7 @@
#include "memory/allocation.inline.hpp"
#include "runtime/mutex.hpp"
#include "runtime/mutexLocker.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) :
_qset(qset), _buf(NULL), _index(0), _active(active),
diff --git a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
index 7b9ff1650..3834722fa 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
@@ -52,14 +52,22 @@ void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
+
PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
+ CLDToOopClosure mark_and_push_from_clds(&mark_and_push_closure, true);
CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true);
if (_java_thread != NULL)
- _java_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
+ _java_thread->oops_do(
+ &mark_and_push_closure,
+ &mark_and_push_from_clds,
+ &mark_and_push_in_blobs);
if (_vm_thread != NULL)
- _vm_thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
+ _vm_thread->oops_do(
+ &mark_and_push_closure,
+ &mark_and_push_from_clds,
+ &mark_and_push_in_blobs);
// Do the real work
cm->follow_marking_stacks();
@@ -89,7 +97,8 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
{
ResourceMark rm;
CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true);
- Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
+ CLDToOopClosure mark_and_push_from_cld(&mark_and_push_closure);
+ Threads::oops_do(&mark_and_push_closure, &mark_and_push_from_cld, &each_active_code_blob);
}
break;
diff --git a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index a37555d2c..63cd37602 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -495,8 +495,9 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
ParallelScavengeHeap::ParStrongRootsScope psrs;
Universe::oops_do(mark_and_push_closure());
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
+ CLDToOopClosure mark_and_push_from_cld(mark_and_push_closure());
CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
- Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
+ Threads::oops_do(mark_and_push_closure(), &mark_and_push_from_cld, &each_active_code_blob);
ObjectSynchronizer::oops_do(mark_and_push_closure());
FlatProfiler::oops_do(mark_and_push_closure());
Management::oops_do(mark_and_push_closure());
@@ -584,7 +585,8 @@ void PSMarkSweep::mark_sweep_phase3() {
// General strong roots.
Universe::oops_do(adjust_root_pointer_closure());
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
- Threads::oops_do(adjust_root_pointer_closure(), NULL);
+ CLDToOopClosure adjust_from_cld(adjust_root_pointer_closure());
+ Threads::oops_do(adjust_root_pointer_closure(), &adjust_from_cld, NULL);
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
FlatProfiler::oops_do(adjust_root_pointer_closure());
Management::oops_do(adjust_root_pointer_closure());
diff --git a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index fc6d5ef59..9fbf01169 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -2436,7 +2436,8 @@ void PSParallelCompact::adjust_roots() {
// General strong roots.
Universe::oops_do(adjust_root_pointer_closure());
JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
- Threads::oops_do(adjust_root_pointer_closure(), NULL);
+ CLDToOopClosure adjust_from_cld(adjust_root_pointer_closure());
+ Threads::oops_do(adjust_root_pointer_closure(), &adjust_from_cld, NULL);
ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
FlatProfiler::oops_do(adjust_root_pointer_closure());
Management::oops_do(adjust_root_pointer_closure());
diff --git a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
index 605792671..ccad48f35 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
@@ -65,7 +65,8 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
case threads:
{
ResourceMark rm;
- Threads::oops_do(&roots_closure, NULL);
+ CLDToOopClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
+ Threads::oops_do(&roots_closure, cld_closure, NULL);
}
break;
@@ -120,13 +121,14 @@ void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
PSScavengeRootsClosure roots_closure(pm);
+ CLDToOopClosure* roots_from_clds = NULL; // Not needed. All CLDs are already visited.
CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
if (_java_thread != NULL)
- _java_thread->oops_do(&roots_closure, &roots_in_blobs);
+ _java_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
if (_vm_thread != NULL)
- _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
+ _vm_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
// Do the real work
pm->drain_stacks(false);
diff --git a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
index d930b0067..8de8b3a29 100644
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
@@ -28,19 +28,7 @@
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/sharedHeap.hpp"
#include "oops/oop.inline.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
-
+#include "runtime/thread.inline.hpp"
MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) {
_lgrp_spaces = new (ResourceObj::C_HEAP, mtGC) GrowableArray<LGRPSpace*>(0, true);
diff --git a/src/share/vm/gc_interface/collectedHeap.cpp b/src/share/vm/gc_interface/collectedHeap.cpp
index 99c0f18dc..f6555979d 100644
--- a/src/share/vm/gc_interface/collectedHeap.cpp
+++ b/src/share/vm/gc_interface/collectedHeap.cpp
@@ -30,19 +30,8 @@
#include "oops/oop.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "runtime/init.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/heapDumper.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef ASSERT
diff --git a/src/share/vm/gc_interface/collectedHeap.hpp b/src/share/vm/gc_interface/collectedHeap.hpp
index 06369dc1b..7c63f8916 100644
--- a/src/share/vm/gc_interface/collectedHeap.hpp
+++ b/src/share/vm/gc_interface/collectedHeap.hpp
@@ -289,11 +289,6 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// (A scavenge is a GC which is not a full GC.)
virtual bool is_scavengable(const void *p) = 0;
- // Returns "TRUE" if "p" is a method oop in the
- // current heap, with high probability. This predicate
- // is not stable, in general.
- bool is_valid_method(Method* p) const;
-
void set_gc_cause(GCCause::Cause v) {
if (UsePerfData) {
_gc_lastcause = _gc_cause;
diff --git a/src/share/vm/gc_interface/collectedHeap.inline.hpp b/src/share/vm/gc_interface/collectedHeap.inline.hpp
index d06ade797..c57b057c6 100644
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp
@@ -31,21 +31,9 @@
#include "oops/arrayOop.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/sharedRuntime.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/lowMemoryDetector.hpp"
#include "utilities/copy.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Inline allocation implementations.
@@ -242,36 +230,6 @@ oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
return (oop)obj;
}
-// Returns "TRUE" if "p" is a method oop in the
-// current heap with high probability. NOTE: The main
-// current consumers of this interface are Forte::
-// and ThreadProfiler::. In these cases, the
-// interpreter frame from which "p" came, may be
-// under construction when sampled asynchronously, so
-// the clients want to check that it represents a
-// valid method before using it. Nonetheless since
-// the clients do not typically lock out GC, the
-// predicate is_valid_method() is not stable, so
-// it is possible that by the time "p" is used, it
-// is no longer valid.
-inline bool CollectedHeap::is_valid_method(Method* p) const {
- return
- p != NULL &&
-
- // Check whether "method" is metadata
- p->is_metadata() &&
-
- // See if GC is active; however, there is still an
- // apparently unavoidable window after this call
- // and before the client of this interface uses "p".
- // If the client chooses not to lock out GC, then
- // it's a risk the client must accept.
- !is_gc_active() &&
-
- // Check that p is a Method*.
- p->is_method();
-}
-
inline void CollectedHeap::oop_iterate_no_header(OopClosure* cl) {
NoHeaderExtendedOopClosure no_header_cl(cl);
oop_iterate(&no_header_cl);
diff --git a/src/share/vm/interpreter/abstractInterpreter.hpp b/src/share/vm/interpreter/abstractInterpreter.hpp
index 4dc2ef451..7cd621318 100644
--- a/src/share/vm/interpreter/abstractInterpreter.hpp
+++ b/src/share/vm/interpreter/abstractInterpreter.hpp
@@ -27,6 +27,7 @@
#include "code/stubs.hpp"
#include "interpreter/bytecodes.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/top.hpp"
#ifdef TARGET_ARCH_MODEL_x86_32
@@ -47,18 +48,6 @@
#ifdef TARGET_ARCH_MODEL_ppc
# include "interp_masm_ppc.hpp"
#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// This file contains the platform-independent parts
// of the abstract interpreter and the abstract interpreter generator.
diff --git a/src/share/vm/interpreter/interpreterRuntime.hpp b/src/share/vm/interpreter/interpreterRuntime.hpp
index aa199a4bd..3aa2c8348 100644
--- a/src/share/vm/interpreter/interpreterRuntime.hpp
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp
@@ -31,19 +31,8 @@
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// The InterpreterRuntime is called by the interpreter for everything
// that cannot/should not be dealt with in assembly and needs C support.
diff --git a/src/share/vm/interpreter/linkResolver.cpp b/src/share/vm/interpreter/linkResolver.cpp
index 81607cc25..959388fc6 100644
--- a/src/share/vm/interpreter/linkResolver.cpp
+++ b/src/share/vm/interpreter/linkResolver.cpp
@@ -43,19 +43,8 @@
#include "runtime/handles.inline.hpp"
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
//------------------------------------------------------------------------------------------------------------------------
// Implementation of FieldAccessInfo
diff --git a/src/share/vm/memory/allocation.cpp b/src/share/vm/memory/allocation.cpp
index 92b335b10..f83eada81 100644
--- a/src/share/vm/memory/allocation.cpp
+++ b/src/share/vm/memory/allocation.cpp
@@ -66,10 +66,17 @@ bool MetaspaceObj::is_shared() const {
}
bool MetaspaceObj::is_metadata() const {
- // ClassLoaderDataGraph::contains((address)this); has lock inversion problems
+ // GC Verify checks use this in guarantees.
+ // TODO: either replace them with is_metaspace_object() or remove them.
+ // is_metaspace_object() is slower than this test. This test doesn't
+ // seem very useful for metaspace objects anymore though.
return !Universe::heap()->is_in_reserved(this);
}
+bool MetaspaceObj::is_metaspace_object() const {
+ return Metaspace::contains((void*)this);
+}
+
void MetaspaceObj::print_address_on(outputStream* st) const {
st->print(" {"INTPTR_FORMAT"}", this);
}
diff --git a/src/share/vm/memory/allocation.hpp b/src/share/vm/memory/allocation.hpp
index 892e50ddc..8bf63ac72 100644
--- a/src/share/vm/memory/allocation.hpp
+++ b/src/share/vm/memory/allocation.hpp
@@ -245,6 +245,7 @@ class ClassLoaderData;
class MetaspaceObj {
public:
bool is_metadata() const;
+ bool is_metaspace_object() const; // more specific test but slower
bool is_shared() const;
void print_address_on(outputStream* st) const; // nonvirtual address printing
diff --git a/src/share/vm/memory/binaryTreeDictionary.cpp b/src/share/vm/memory/binaryTreeDictionary.cpp
index e0fde430b..a08a389f8 100644
--- a/src/share/vm/memory/binaryTreeDictionary.cpp
+++ b/src/share/vm/memory/binaryTreeDictionary.cpp
@@ -290,7 +290,7 @@ void TreeList<Chunk_t, FreeList_t>::return_chunk_at_tail(TreeChunk<Chunk_t, Free
assert(chunk->list() == this, "list should be set for chunk");
assert(tail() != NULL, "The tree list is embedded in the first chunk");
// which means that the list can never be empty.
- assert(!verify_chunk_in_free_list(chunk), "Double entry");
+ assert(!this->verify_chunk_in_free_list(chunk), "Double entry");
assert(head() == NULL || head()->prev() == NULL, "list invariant");
assert(tail() == NULL || tail()->next() == NULL, "list invariant");
@@ -300,7 +300,7 @@ void TreeList<Chunk_t, FreeList_t>::return_chunk_at_tail(TreeChunk<Chunk_t, Free
assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
FreeList_t<Chunk_t>::increment_count();
- debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
+ debug_only(this->increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
assert(head() == NULL || head()->prev() == NULL, "list invariant");
assert(tail() == NULL || tail()->next() == NULL, "list invariant");
}
@@ -314,7 +314,7 @@ void TreeList<Chunk_t, FreeList_t>::return_chunk_at_head(TreeChunk<Chunk_t, Free
assert(chunk->list() == this, "list should be set for chunk");
assert(head() != NULL, "The tree list is embedded in the first chunk");
assert(chunk != NULL, "returning NULL chunk");
- assert(!verify_chunk_in_free_list(chunk), "Double entry");
+ assert(!this->verify_chunk_in_free_list(chunk), "Double entry");
assert(head() == NULL || head()->prev() == NULL, "list invariant");
assert(tail() == NULL || tail()->next() == NULL, "list invariant");
@@ -328,7 +328,7 @@ void TreeList<Chunk_t, FreeList_t>::return_chunk_at_head(TreeChunk<Chunk_t, Free
head()->link_after(chunk);
assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
FreeList_t<Chunk_t>::increment_count();
- debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
+ debug_only(this->increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
assert(head() == NULL || head()->prev() == NULL, "list invariant");
assert(tail() == NULL || tail()->next() == NULL, "list invariant");
}
diff --git a/src/share/vm/memory/collectorPolicy.cpp b/src/share/vm/memory/collectorPolicy.cpp
index 6c0b1bd82..c6eee674d 100644
--- a/src/share/vm/memory/collectorPolicy.cpp
+++ b/src/share/vm/memory/collectorPolicy.cpp
@@ -37,19 +37,8 @@
#include "runtime/globals_extension.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
#include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
diff --git a/src/share/vm/memory/defNewGeneration.cpp b/src/share/vm/memory/defNewGeneration.cpp
index dbf9ca70b..cca7cd0e7 100644
--- a/src/share/vm/memory/defNewGeneration.cpp
+++ b/src/share/vm/memory/defNewGeneration.cpp
@@ -38,20 +38,9 @@
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/copy.hpp"
#include "utilities/stack.inline.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
//
// DefNewGeneration functions.
diff --git a/src/share/vm/memory/filemap.cpp b/src/share/vm/memory/filemap.cpp
index c3d1bf5f9..11b395776 100644
--- a/src/share/vm/memory/filemap.cpp
+++ b/src/share/vm/memory/filemap.cpp
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/symbolTable.hpp"
+#include "classfile/altHashing.hpp"
#include "memory/filemap.hpp"
#include "runtime/arguments.hpp"
#include "runtime/java.hpp"
@@ -82,9 +83,38 @@ void FileMapInfo::fail_continue(const char *msg, ...) {
close();
}
-
// Fill in the fileMapInfo structure with data about this VM instance.
+// This method copies the vm version info into header_version. If the version is too
+// long then a truncated version, which has a hash code appended to it, is copied.
+//
+// Using a template enables this method to verify that header_version is an array of
+// length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and
+// the code that reads the CDS file will both use the same size buffer. Hence, will
+// use identical truncation. This is necessary for matching of truncated versions.
+template <int N> static void get_header_version(char (&header_version) [N]) {
+ assert(N == JVM_IDENT_MAX, "Bad header_version size");
+
+ const char *vm_version = VM_Version::internal_vm_info_string();
+ const int version_len = (int)strlen(vm_version);
+
+ if (version_len < (JVM_IDENT_MAX-1)) {
+ strcpy(header_version, vm_version);
+
+ } else {
+ // Get the hash value. Use a static seed because the hash needs to return the same
+ // value over multiple jvm invocations.
+ unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len);
+
+ // Truncate the ident, saving room for the 8 hex character hash value.
+ strncpy(header_version, vm_version, JVM_IDENT_MAX-9);
+
+ // Append the hash code as eight hex digits.
+ sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash);
+ header_version[JVM_IDENT_MAX-1] = 0; // Null terminate.
+ }
+}
+
void FileMapInfo::populate_header(size_t alignment) {
_header._magic = 0xf00baba2;
_header._version = _current_version;
@@ -95,13 +125,7 @@ void FileMapInfo::populate_header(size_t alignment) {
// invoked with.
// JVM version string ... changes on each build.
- const char *vm_version = VM_Version::internal_vm_info_string();
- if (strlen(vm_version) < (JVM_IDENT_MAX-1)) {
- strcpy(_header._jvm_ident, vm_version);
- } else {
- fail_stop("JVM Ident field for shared archive is too long"
- " - truncated to <%s>", _header._jvm_ident);
- }
+ get_header_version(_header._jvm_ident);
// Build checks on classpath and jar files
_header._num_jars = 0;
@@ -434,8 +458,9 @@ bool FileMapInfo::validate() {
fail_continue("The shared archive file has a bad magic number.");
return false;
}
- if (strncmp(_header._jvm_ident, VM_Version::internal_vm_info_string(),
- JVM_IDENT_MAX-1) != 0) {
+ char header_version[JVM_IDENT_MAX];
+ get_header_version(header_version);
+ if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
fail_continue("The shared archive file was created by a different"
" version or build of HotSpot.");
return false;
diff --git a/src/share/vm/memory/freeBlockDictionary.cpp b/src/share/vm/memory/freeBlockDictionary.cpp
index 9b2221281..918a80f1f 100644
--- a/src/share/vm/memory/freeBlockDictionary.cpp
+++ b/src/share/vm/memory/freeBlockDictionary.cpp
@@ -29,18 +29,7 @@
#include "memory/freeBlockDictionary.hpp"
#include "memory/metablock.hpp"
#include "memory/metachunk.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
#ifndef PRODUCT
template <class Chunk> Mutex* FreeBlockDictionary<Chunk>::par_lock() const {
diff --git a/src/share/vm/memory/gcLocker.hpp b/src/share/vm/memory/gcLocker.hpp
index f8ce732ff..8ede8fb27 100644
--- a/src/share/vm/memory/gcLocker.hpp
+++ b/src/share/vm/memory/gcLocker.hpp
@@ -29,21 +29,18 @@
#include "memory/genCollectedHeap.hpp"
#include "memory/universe.hpp"
#include "oops/oop.hpp"
+#include "runtime/thread.inline.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
// The direct lock/unlock calls do not force a collection if an unlock
diff --git a/src/share/vm/memory/genMarkSweep.cpp b/src/share/vm/memory/genMarkSweep.cpp
index 91fe3957c..5ae799472 100644
--- a/src/share/vm/memory/genMarkSweep.cpp
+++ b/src/share/vm/memory/genMarkSweep.cpp
@@ -43,21 +43,10 @@
#include "runtime/fprofiler.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/synchronizer.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/copy.hpp"
#include "utilities/events.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
bool clear_all_softrefs) {
diff --git a/src/share/vm/memory/iterator.cpp b/src/share/vm/memory/iterator.cpp
index af5720335..e33a5614d 100644
--- a/src/share/vm/memory/iterator.cpp
+++ b/src/share/vm/memory/iterator.cpp
@@ -30,6 +30,10 @@ void KlassToOopClosure::do_klass(Klass* k) {
k->oops_do(_oop_closure);
}
+void CLDToOopClosure::do_cld(ClassLoaderData* cld) {
+ cld->oops_do(_oop_closure, &_klass_closure, _must_claim_cld);
+}
+
void ObjectToOopClosure::do_object(oop obj) {
obj->oop_iterate(_cl);
}
diff --git a/src/share/vm/memory/iterator.hpp b/src/share/vm/memory/iterator.hpp
index 825bc23ee..736efdd61 100644
--- a/src/share/vm/memory/iterator.hpp
+++ b/src/share/vm/memory/iterator.hpp
@@ -135,6 +135,20 @@ class KlassToOopClosure : public KlassClosure {
virtual void do_klass(Klass* k);
};
+class CLDToOopClosure {
+ OopClosure* _oop_closure;
+ KlassToOopClosure _klass_closure;
+ bool _must_claim_cld;
+
+ public:
+ CLDToOopClosure(OopClosure* oop_closure, bool must_claim_cld = true) :
+ _oop_closure(oop_closure),
+ _klass_closure(oop_closure),
+ _must_claim_cld(must_claim_cld) {}
+
+ void do_cld(ClassLoaderData* cld);
+};
+
// ObjectClosure is used for iterating through an object space
class ObjectClosure : public Closure {
diff --git a/src/share/vm/memory/metachunk.hpp b/src/share/vm/memory/metachunk.hpp
index dd461972a..693532d9d 100644
--- a/src/share/vm/memory/metachunk.hpp
+++ b/src/share/vm/memory/metachunk.hpp
@@ -123,9 +123,7 @@ class Metachunk VALUE_OBJ_CLASS_SPEC {
void assert_is_mangled() const {/* Don't check "\*/}
-#ifdef ASSERT
- void mangle();
-#endif // ASSERT
+ NOT_PRODUCT(void mangle();)
void print_on(outputStream* st) const;
void verify();
diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp
index 7245e4f28..1e83247ad 100644
--- a/src/share/vm/memory/metaspace.cpp
+++ b/src/share/vm/memory/metaspace.cpp
@@ -36,6 +36,7 @@
#include "memory/universe.hpp"
#include "runtime/globals.hpp"
#include "runtime/mutex.hpp"
+#include "runtime/orderAccess.hpp"
#include "services/memTracker.hpp"
#include "utilities/copy.hpp"
#include "utilities/debug.hpp"
@@ -108,7 +109,6 @@ size_t Metablock::_min_block_byte_size = sizeof(Metablock);
size_t Metablock::_overhead = 0;
#endif
-
// Pointer to list of Metachunks.
class ChunkList VALUE_OBJ_CLASS_SPEC {
// List of free chunks
@@ -325,10 +325,12 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
bool expand_by(size_t words, bool pre_touch = false);
bool shrink_by(size_t words);
+#ifdef ASSERT
// Debug support
static void verify_virtual_space_total();
static void verify_virtual_space_count();
void mangle();
+#endif
void print_on(outputStream* st) const;
};
@@ -621,8 +623,8 @@ class SpaceManager : public CHeapObj<mtClass> {
void locked_print_chunks_in_use_on(outputStream* st) const;
void verify();
+ NOT_PRODUCT(void mangle_freed_chunks();)
#ifdef ASSERT
- void mangle_freed_chunks();
void verify_allocation_total();
#endif
};
@@ -711,7 +713,7 @@ void Metachunk::print_on(outputStream* st) const {
bottom(), top(), end(), word_size());
}
-#ifdef ASSERT
+#ifndef PRODUCT
void Metachunk::mangle() {
// Mangle the payload of the chunk and not the links that
// maintain list of chunks.
@@ -719,7 +721,7 @@ void Metachunk::mangle() {
size_t word_size = capacity_word_size() - overhead();
Copy::fill_to_words(start, word_size, metadata_chunk_initialize);
}
-#endif // ASSERT
+#endif // PRODUCT
void Metachunk::verify() {
#ifdef ASSERT
@@ -917,10 +919,12 @@ void VirtualSpaceNode::print_on(outputStream* st) const {
vs->high_boundary());
}
+#ifdef ASSERT
void VirtualSpaceNode::mangle() {
size_t word_size = capacity_words_in_vs();
Copy::fill_to_words((HeapWord*) low(), word_size, 0xf1f1f1f1);
}
+#endif // ASSERT
// VirtualSpaceList methods
// Space allocated from the VirtualSpace
@@ -1007,6 +1011,8 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
delete new_entry;
return false;
} else {
+ // ensure lock-free iteration sees fully initialized node
+ OrderAccess::storestore();
link_vs(new_entry, vs_word_size);
return true;
}
@@ -1096,7 +1102,6 @@ void VirtualSpaceList::print_on(outputStream* st) const {
}
}
-#ifndef PRODUCT
bool VirtualSpaceList::contains(const void *ptr) {
VirtualSpaceNode* list = virtual_space_list();
VirtualSpaceListIterator iter(list);
@@ -1108,7 +1113,6 @@ bool VirtualSpaceList::contains(const void *ptr) {
}
return false;
}
-#endif // PRODUCT
// MetaspaceGC methods
@@ -1985,16 +1989,14 @@ SpaceManager::~SpaceManager() {
locked_print_chunks_in_use_on(gclog_or_tty);
}
+ // Mangle freed memory.
+ NOT_PRODUCT(mangle_freed_chunks();)
+
// Have to update before the chunks_in_use lists are emptied
// below.
chunk_manager->inc_free_chunks_total(sum_capacity_in_chunks_in_use(),
sum_count_in_chunks_in_use());
-#ifdef ASSERT
- // Mangle freed memory.
- mangle_freed_chunks();
-#endif // ASSERT
-
// Add all the chunks in use by this space manager
// to the global list of free chunks.
@@ -2273,7 +2275,7 @@ void SpaceManager::dump(outputStream* const out) const {
" waste " SIZE_FORMAT, curr_total, used, free, capacity, waste);
}
-#ifdef ASSERT
+#ifndef PRODUCT
void SpaceManager::mangle_freed_chunks() {
for (ChunkIndex index = SmallIndex;
index < NumberOfInUseLists;
@@ -2291,11 +2293,16 @@ void SpaceManager::mangle_freed_chunks() {
}
}
}
-#endif // ASSERT
+#endif // PRODUCT
// MetaspaceAux
+size_t MetaspaceAux::used_in_bytes() {
+ return (Metaspace::class_space_list()->used_words_sum() +
+ Metaspace::space_list()->used_words_sum()) * BytesPerWord;
+}
+
size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) {
size_t used = 0;
ClassLoaderDataGraphMetaspaceIterator iter;
@@ -2324,6 +2331,11 @@ size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) {
// The total words available for metadata allocation. This
// uses Metaspace capacity_words() which is the total words
// in chunks allocated for a Metaspace.
+size_t MetaspaceAux::capacity_in_bytes() {
+ return (Metaspace::class_space_list()->capacity_words_sum() +
+ Metaspace::space_list()->capacity_words_sum()) * BytesPerWord;
+}
+
size_t MetaspaceAux::capacity_in_bytes(Metaspace::MetadataType mdtype) {
size_t capacity = free_chunks_total(mdtype);
ClassLoaderDataGraphMetaspaceIterator iter;
@@ -2336,6 +2348,11 @@ size_t MetaspaceAux::capacity_in_bytes(Metaspace::MetadataType mdtype) {
return capacity * BytesPerWord;
}
+size_t MetaspaceAux::reserved_in_bytes() {
+ return (Metaspace::class_space_list()->virtual_space_total() +
+ Metaspace::space_list()->virtual_space_total()) * BytesPerWord;
+}
+
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
size_t reserved = (mdtype == Metaspace::ClassType) ?
Metaspace::class_space_list()->virtual_space_total() :
@@ -2739,15 +2756,17 @@ void Metaspace::print_on(outputStream* out) const {
}
}
-#ifndef PRODUCT
-bool Metaspace::contains(const void * ptr) const {
+bool Metaspace::contains(const void * ptr) {
if (MetaspaceShared::is_in_shared_space(ptr)) {
return true;
}
- MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
+ // This is checked while unlocked. As long as the virtualspaces are added
+ // at the end, the pointer will be in one of them. The virtual spaces
+ // aren't deleted presently. When they are, some sort of locking might
+ // be needed. Note, locking this can cause inversion problems with the
+ // caller in MetaspaceObj::is_metadata() function.
return space_list()->contains(ptr) || class_space_list()->contains(ptr);
}
-#endif
void Metaspace::verify() {
vsm()->verify();
diff --git a/src/share/vm/memory/metaspace.hpp b/src/share/vm/memory/metaspace.hpp
index 743fed130..993419436 100644
--- a/src/share/vm/memory/metaspace.hpp
+++ b/src/share/vm/memory/metaspace.hpp
@@ -135,11 +135,7 @@ class Metaspace : public CHeapObj<mtClass> {
static bool is_initialized() { return _class_space_list != NULL; }
-#ifndef PRODUCT
- bool contains(const void *ptr) const;
- bool contains_class(const void *ptr) const;
-#endif
-
+ static bool contains(const void *ptr);
void dump(outputStream* const out) const;
void print_on(outputStream* st) const;
@@ -160,25 +156,16 @@ class MetaspaceAux : AllStatic {
public:
// Total of space allocated to metadata in all Metaspaces
- static size_t used_in_bytes() {
- return used_in_bytes(Metaspace::ClassType) +
- used_in_bytes(Metaspace::NonClassType);
- }
+ static size_t used_in_bytes();
// Total of available space in all Metaspaces
// Total of capacity allocated to all Metaspaces. This includes
// space in Metachunks not yet allocated and in the Metachunk
// freelist.
- static size_t capacity_in_bytes() {
- return capacity_in_bytes(Metaspace::ClassType) +
- capacity_in_bytes(Metaspace::NonClassType);
- }
+ static size_t capacity_in_bytes();
// Total space reserved in all Metaspaces
- static size_t reserved_in_bytes() {
- return reserved_in_bytes(Metaspace::ClassType) +
- reserved_in_bytes(Metaspace::NonClassType);
- }
+ static size_t reserved_in_bytes();
static size_t min_chunk_size();
diff --git a/src/share/vm/memory/resourceArea.cpp b/src/share/vm/memory/resourceArea.cpp
index 12a56d0f4..767e45ec1 100644
--- a/src/share/vm/memory/resourceArea.cpp
+++ b/src/share/vm/memory/resourceArea.cpp
@@ -26,18 +26,7 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
//------------------------------ResourceMark-----------------------------------
debug_only(int ResourceArea::_warned;) // to suppress multiple warnings
diff --git a/src/share/vm/memory/resourceArea.hpp b/src/share/vm/memory/resourceArea.hpp
index f1418ce19..0699334a5 100644
--- a/src/share/vm/memory/resourceArea.hpp
+++ b/src/share/vm/memory/resourceArea.hpp
@@ -26,18 +26,7 @@
#define SHARE_VM_MEMORY_RESOURCEAREA_HPP
#include "memory/allocation.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// The resource area holds temporary data structures in the VM.
// The actual allocation areas are thread local. Typical usage:
diff --git a/src/share/vm/memory/sharedHeap.cpp b/src/share/vm/memory/sharedHeap.cpp
index 773be4c65..be641d304 100644
--- a/src/share/vm/memory/sharedHeap.cpp
+++ b/src/share/vm/memory/sharedHeap.cpp
@@ -154,10 +154,12 @@ void SharedHeap::process_strong_roots(bool activate_scope,
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
JNIHandles::oops_do(roots);
// All threads execute this; the individual threads are task groups.
+ CLDToOopClosure roots_from_clds(roots);
+ CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
if (ParallelGCThreads > 0) {
- Threads::possibly_parallel_oops_do(roots, code_roots);
+ Threads::possibly_parallel_oops_do(roots, roots_from_clds_p ,code_roots);
} else {
- Threads::oops_do(roots, code_roots);
+ Threads::oops_do(roots, roots_from_clds_p, code_roots);
}
if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
ObjectSynchronizer::oops_do(roots);
diff --git a/src/share/vm/memory/space.cpp b/src/share/vm/memory/space.cpp
index b4fe565fd..7f9647f2e 100644
--- a/src/share/vm/memory/space.cpp
+++ b/src/share/vm/memory/space.cpp
@@ -790,7 +790,9 @@ ALL_SINCE_SAVE_MARKS_CLOSURES(ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN)
// Very general, slow implementation.
HeapWord* ContiguousSpace::block_start_const(const void* p) const {
- assert(MemRegion(bottom(), end()).contains(p), "p not in space");
+ assert(MemRegion(bottom(), end()).contains(p),
+ err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+ p, bottom(), end()));
if (p >= top()) {
return top();
} else {
@@ -800,19 +802,27 @@ HeapWord* ContiguousSpace::block_start_const(const void* p) const {
last = cur;
cur += oop(cur)->size();
}
- assert(oop(last)->is_oop(), "Should be an object start");
+ assert(oop(last)->is_oop(),
+ err_msg(PTR_FORMAT " should be an object start", last));
return last;
}
}
size_t ContiguousSpace::block_size(const HeapWord* p) const {
- assert(MemRegion(bottom(), end()).contains(p), "p not in space");
+ assert(MemRegion(bottom(), end()).contains(p),
+ err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+ p, bottom(), end()));
HeapWord* current_top = top();
- assert(p <= current_top, "p is not a block start");
- assert(p == current_top || oop(p)->is_oop(), "p is not a block start");
- if (p < current_top)
+ assert(p <= current_top,
+ err_msg("p > current top - p: " PTR_FORMAT ", current top: " PTR_FORMAT,
+ p, current_top));
+ assert(p == current_top || oop(p)->is_oop(),
+ err_msg("p (" PTR_FORMAT ") is not a block start - "
+ "current_top: " PTR_FORMAT ", is_oop: %s",
+ p, current_top, BOOL_TO_STR(oop(p)->is_oop())));
+ if (p < current_top) {
return oop(p)->size();
- else {
+ } else {
assert(p == current_top, "just checking");
return pointer_delta(end(), (HeapWord*) p);
}
diff --git a/src/share/vm/memory/threadLocalAllocBuffer.cpp b/src/share/vm/memory/threadLocalAllocBuffer.cpp
index 03d6e6b83..9006398eb 100644
--- a/src/share/vm/memory/threadLocalAllocBuffer.cpp
+++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp
@@ -28,19 +28,8 @@
#include "memory/threadLocalAllocBuffer.inline.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/copy.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Thread-Local Edens support
diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp
index 7cad19270..c528d270c 100644
--- a/src/share/vm/memory/universe.cpp
+++ b/src/share/vm/memory/universe.cpp
@@ -62,6 +62,7 @@
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/synchronizer.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memoryService.hpp"
@@ -69,18 +70,6 @@
#include "utilities/events.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/preserveException.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
#include "gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp"
@@ -418,6 +407,10 @@ void Universe::genesis(TRAPS) {
assert(i == _fullgc_alot_dummy_array->length(), "just checking");
}
#endif
+
+ // Initialize dependency array for null class loader
+ ClassLoaderData::the_null_class_loader_data()->init_dependencies(CHECK);
+
}
// CDS support for patching vtables in metadata in the shared archive.
@@ -425,14 +418,10 @@ void Universe::genesis(TRAPS) {
// from MetaspaceObj, because the latter does not have virtual functions.
// If the metadata type has a vtable, it cannot be shared in the read-only
// section of the CDS archive, because the vtable pointer is patched.
-static inline void* dereference(void* addr) {
- return *(void**)addr;
-}
-
static inline void add_vtable(void** list, int* n, void* o, int count) {
guarantee((*n) < count, "vtable list too small");
- void* vtable = dereference(o);
- assert(dereference(vtable) != NULL, "invalid vtable");
+ void* vtable = dereference_vptr(o);
+ assert(*(void**)(vtable) != NULL, "invalid vtable");
list[(*n)++] = vtable;
}
diff --git a/src/share/vm/oops/compiledICHolder.cpp b/src/share/vm/oops/compiledICHolder.cpp
index cdb6df280..c13b7559a 100644
--- a/src/share/vm/oops/compiledICHolder.cpp
+++ b/src/share/vm/oops/compiledICHolder.cpp
@@ -48,8 +48,8 @@ void CompiledICHolder::print_value_on(outputStream* st) const {
// Verification
void CompiledICHolder::verify_on(outputStream* st) {
- guarantee(holder_method()->is_metadata(), "should be in permspace");
+ guarantee(holder_method()->is_metadata(), "should be in metaspace");
guarantee(holder_method()->is_method(), "should be method");
- guarantee(holder_klass()->is_metadata(), "should be in permspace");
+ guarantee(holder_klass()->is_metadata(), "should be in metaspace");
guarantee(holder_klass()->is_klass(), "should be klass");
}
diff --git a/src/share/vm/oops/constMethod.cpp b/src/share/vm/oops/constMethod.cpp
index 7f89d61ee..10b057b4f 100644
--- a/src/share/vm/oops/constMethod.cpp
+++ b/src/share/vm/oops/constMethod.cpp
@@ -39,16 +39,19 @@ ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
MethodType method_type,
TRAPS) {
int size = ConstMethod::size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
exception_table_length,
- checked_exceptions_length);
+ checked_exceptions_length,
+ generic_signature_index);
return new (loader_data, size, true, THREAD) ConstMethod(
byte_code_size, compressed_line_number_size, localvariable_table_length,
- exception_table_length, checked_exceptions_length, method_type, size);
+ exception_table_length, checked_exceptions_length, generic_signature_index,
+ method_type, size);
}
ConstMethod::ConstMethod(int byte_code_size,
@@ -56,6 +59,7 @@ ConstMethod::ConstMethod(int byte_code_size,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
MethodType method_type,
int size) {
@@ -66,7 +70,8 @@ ConstMethod::ConstMethod(int byte_code_size,
set_stackmap_data(NULL);
set_code_size(byte_code_size);
set_constMethod_size(size);
- set_inlined_tables_length(checked_exceptions_length,
+ set_inlined_tables_length(generic_signature_index,
+ checked_exceptions_length,
compressed_line_number_size,
localvariable_table_length,
exception_table_length);
@@ -90,7 +95,8 @@ int ConstMethod::size(int code_size,
int compressed_line_number_size,
int local_variable_table_length,
int exception_table_length,
- int checked_exceptions_length) {
+ int checked_exceptions_length,
+ u2 generic_signature_index) {
int extra_bytes = code_size;
if (compressed_line_number_size > 0) {
extra_bytes += compressed_line_number_size;
@@ -108,6 +114,9 @@ int ConstMethod::size(int code_size,
extra_bytes += sizeof(u2);
extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
}
+ if (generic_signature_index != 0) {
+ extra_bytes += sizeof(u2);
+ }
int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
return align_object_size(header_size() + extra_words);
}
@@ -125,20 +134,29 @@ u_char* ConstMethod::compressed_linenumber_table() const {
return code_end();
}
-u2* ConstMethod::checked_exceptions_length_addr() const {
+u2* ConstMethod::generic_signature_index_addr() const {
// Located at the end of the constMethod.
- assert(has_checked_exceptions(), "called only if table is present");
+ assert(has_generic_signature(), "called only if generic signature exists");
return last_u2_element();
}
+u2* ConstMethod::checked_exceptions_length_addr() const {
+ // Located immediately before the generic signature index.
+ assert(has_checked_exceptions(), "called only if table is present");
+ return has_generic_signature() ? (last_u2_element() - 1) :
+ last_u2_element();
+}
+
u2* ConstMethod::exception_table_length_addr() const {
assert(has_exception_handler(), "called only if table is present");
if (has_checked_exceptions()) {
// If checked_exception present, locate immediately before them.
return (u2*) checked_exceptions_start() - 1;
} else {
- // Else, the exception table is at the end of the constMethod.
- return last_u2_element();
+ // Else, the exception table is at the end of the constMethod or
+ // immediately before the generic signature index.
+ return has_generic_signature() ? (last_u2_element() - 1) :
+ last_u2_element();
}
}
@@ -152,25 +170,30 @@ u2* ConstMethod::localvariable_table_length_addr() const {
// If checked_exception present, locate immediately before them.
return (u2*) checked_exceptions_start() - 1;
} else {
- // Else, the linenumber table is at the end of the constMethod.
- return last_u2_element();
+ // Else, the linenumber table is at the end of the constMethod or
+ // immediately before the generic signature index.
+ return has_generic_signature() ? (last_u2_element() - 1) :
+ last_u2_element();
}
}
}
-
// Update the flags to indicate the presence of these optional fields.
-void ConstMethod::set_inlined_tables_length(
- int checked_exceptions_len,
- int compressed_line_number_size,
- int localvariable_table_len,
- int exception_table_len) {
+void ConstMethod::set_inlined_tables_length(u2 generic_signature_index,
+ int checked_exceptions_len,
+ int compressed_line_number_size,
+ int localvariable_table_len,
+ int exception_table_len) {
// Must be done in the order below, otherwise length_addr accessors
// will not work. Only set bit in header if length is positive.
assert(_flags == 0, "Error");
if (compressed_line_number_size > 0) {
_flags |= _has_linenumber_table;
}
+ if (generic_signature_index != 0) {
+ _flags |= _has_generic_signature;
+ *(generic_signature_index_addr()) = generic_signature_index;
+ }
if (checked_exceptions_len > 0) {
_flags |= _has_checked_exceptions;
*(checked_exceptions_length_addr()) = checked_exceptions_len;
diff --git a/src/share/vm/oops/constMethod.hpp b/src/share/vm/oops/constMethod.hpp
index 9712eee57..771bf7b16 100644
--- a/src/share/vm/oops/constMethod.hpp
+++ b/src/share/vm/oops/constMethod.hpp
@@ -45,7 +45,7 @@
// | constMethod_size |
// | interp_kind | flags | code_size |
// | name index | signature index |
-// | method_idnum | generic_signature_index |
+// | method_idnum | max_stack |
// |------------------------------------------------------|
// | |
// | byte codes |
@@ -55,26 +55,29 @@
// | (see class CompressedLineNumberReadStream) |
// | (note that length is unknown until decompressed) |
// | (access flags bit tells whether table is present) |
-// | (indexed from start of ConstMethod*) |
+// | (indexed from start of ConstMethod*) |
// | (elements not necessarily sorted!) |
// |------------------------------------------------------|
// | localvariable table elements + length (length last) |
// | (length is u2, elements are 6-tuples of u2) |
// | (see class LocalVariableTableElement) |
// | (access flags bit tells whether table is present) |
-// | (indexed from end of ConstMethod*) |
+// | (indexed from end of ConstMethod*) |
// |------------------------------------------------------|
// | exception table + length (length last) |
// | (length is u2, elements are 4-tuples of u2) |
// | (see class ExceptionTableElement) |
// | (access flags bit tells whether table is present) |
-// | (indexed from end of ConstMethod*) |
+// | (indexed from end of ConstMethod*) |
// |------------------------------------------------------|
// | checked exceptions elements + length (length last) |
// | (length is u2, elements are u2) |
// | (see class CheckedExceptionElement) |
// | (access flags bit tells whether table is present) |
-// | (indexed from end of ConstMethod*) |
+// | (indexed from end of ConstMethod*) |
+// |------------------------------------------------------|
+// | generic signature index (u2) |
+// | (indexed from start of constMethodOop) |
// |------------------------------------------------------|
@@ -118,7 +121,8 @@ private:
_has_checked_exceptions = 2,
_has_localvariable_table = 4,
_has_exception_table = 8,
- _is_overpass = 16
+ _has_generic_signature = 16,
+ _is_overpass = 32
};
// Bit vector of signature
@@ -145,7 +149,7 @@ private:
u2 _method_idnum; // unique identification number for the method within the class
// initially corresponds to the index into the methods array.
// but this may change with redefinition
- u2 _generic_signature_index; // Generic signature (index in constant pool, 0 if absent)
+ u2 _max_stack; // Maximum number of entries on the expression stack
// Constructor
@@ -154,6 +158,7 @@ private:
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
MethodType is_overpass,
int size);
public:
@@ -164,17 +169,22 @@ public:
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
MethodType mt,
TRAPS);
bool is_constMethod() const { return true; }
// Inlined tables
- void set_inlined_tables_length(int checked_exceptions_len,
+ void set_inlined_tables_length(u2 generic_signature_index,
+ int checked_exceptions_len,
int compressed_line_number_size,
int localvariable_table_len,
int exception_table_len);
+ bool has_generic_signature() const
+ { return (_flags & _has_generic_signature) != 0; }
+
bool has_linenumber_table() const
{ return (_flags & _has_linenumber_table) != 0; }
@@ -252,8 +262,18 @@ public:
void set_signature_index(int index) { _signature_index = index; }
// generics support
- int generic_signature_index() const { return _generic_signature_index; }
- void set_generic_signature_index(int index) { _generic_signature_index = index; }
+ int generic_signature_index() const {
+ if (has_generic_signature()) {
+ return *generic_signature_index_addr();
+ } else {
+ return 0;
+ }
+ }
+ void set_generic_signature_index(u2 index) {
+ assert(has_generic_signature(), "");
+ u2* addr = generic_signature_index_addr();
+ *addr = index;
+ }
// Sizing
static int header_size() {
@@ -264,7 +284,8 @@ public:
static int size(int code_size, int compressed_line_number_size,
int local_variable_table_length,
int exception_table_length,
- int checked_exceptions_length);
+ int checked_exceptions_length,
+ u2 generic_signature_index);
int size() const { return _constMethod_size;}
void set_constMethod_size(int size) { _constMethod_size = size; }
@@ -281,6 +302,7 @@ public:
// linenumber table - note that length is unknown until decompression,
// see class CompressedLineNumberReadStream.
u_char* compressed_linenumber_table() const; // not preserved by gc
+ u2* generic_signature_index_addr() const;
u2* checked_exceptions_length_addr() const;
u2* localvariable_table_length_addr() const;
u2* exception_table_length_addr() const;
@@ -314,12 +336,19 @@ public:
static ByteSize constants_offset()
{ return byte_offset_of(ConstMethod, _constants); }
+ static ByteSize max_stack_offset()
+ { return byte_offset_of(ConstMethod, _max_stack); }
+
// Unique id for the method
static const u2 MAX_IDNUM;
static const u2 UNSET_IDNUM;
u2 method_idnum() const { return _method_idnum; }
void set_method_idnum(u2 idnum) { _method_idnum = idnum; }
+ // max stack
+ int max_stack() const { return _max_stack; }
+ void set_max_stack(int size) { _max_stack = size; }
+
// Deallocation for RedefineClasses
void deallocate_contents(ClassLoaderData* loader_data);
bool is_klass() const { return false; }
diff --git a/src/share/vm/oops/constantPool.cpp b/src/share/vm/oops/constantPool.cpp
index 09730aeeb..ff8472d3d 100644
--- a/src/share/vm/oops/constantPool.cpp
+++ b/src/share/vm/oops/constantPool.cpp
@@ -340,9 +340,7 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
do_resolve = this_oop->tag_at(which).is_unresolved_klass();
if (do_resolve) {
ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data();
- if (!this_key->is_the_null_class_loader_data()) {
- this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
- }
+ this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
this_oop->klass_at_put(which, k());
}
}
diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp
index 7ffdf41c5..69d1910f2 100644
--- a/src/share/vm/oops/instanceKlass.cpp
+++ b/src/share/vm/oops/instanceKlass.cpp
@@ -51,20 +51,9 @@
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
index 6980e0e51..21bfb6bda 100644
--- a/src/share/vm/oops/klass.cpp
+++ b/src/share/vm/oops/klass.cpp
@@ -373,29 +373,22 @@ void Klass::append_to_sibling_list() {
debug_only(verify();)
}
-void Klass::remove_from_sibling_list() {
- // remove receiver from sibling list
- InstanceKlass* super = superklass();
- assert(super != NULL || this == SystemDictionary::Object_klass(), "should have super");
- if (super == NULL) return; // special case: class Object
- if (super->subklass() == this) {
- // first subklass
- super->set_subklass(_next_sibling);
- } else {
- Klass* sib = super->subklass();
- while (sib->next_sibling() != this) {
- sib = sib->next_sibling();
- };
- sib->set_next_sibling(_next_sibling);
- }
-}
-
bool Klass::is_loader_alive(BoolObjectClosure* is_alive) {
assert(is_metadata(), "p is not meta-data");
assert(ClassLoaderDataGraph::contains((address)this), "is in the metaspace");
+
+#ifdef ASSERT
// The class is alive iff the class loader is alive.
oop loader = class_loader();
- return (loader == NULL) || is_alive->do_object_b(loader);
+ bool loader_alive = (loader == NULL) || is_alive->do_object_b(loader);
+#endif // ASSERT
+
+ // The class is alive if it's mirror is alive (which should be marked if the
+ // loader is alive) unless it's an anoymous class.
+ bool mirror_alive = is_alive->do_object_b(java_mirror());
+ assert(!mirror_alive || loader_alive, "loader must be alive if the mirror is"
+ " but not the other way around with anonymous classes");
+ return mirror_alive;
}
void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive) {
@@ -416,10 +409,10 @@ void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive) {
Klass* sub = current->subklass_oop();
while (sub != NULL && !sub->is_loader_alive(is_alive)) {
#ifndef PRODUCT
- if (TraceClassUnloading && WizardMode) {
- ResourceMark rm;
+ if (TraceClassUnloading && WizardMode) {
+ ResourceMark rm;
tty->print_cr("[Unlinking class (subclass) %s]", sub->external_name());
- }
+ }
#endif
sub = sub->next_sibling_oop();
}
@@ -431,16 +424,16 @@ void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive) {
// Find and set the first alive sibling
Klass* sibling = current->next_sibling_oop();
while (sibling != NULL && !sibling->is_loader_alive(is_alive)) {
- if (TraceClassUnloading && WizardMode) {
- ResourceMark rm;
+ if (TraceClassUnloading && WizardMode) {
+ ResourceMark rm;
tty->print_cr("[Unlinking class (sibling) %s]", sibling->external_name());
- }
- sibling = sibling->next_sibling_oop();
}
+ sibling = sibling->next_sibling_oop();
+ }
current->set_next_sibling(sibling);
if (sibling != NULL) {
stack.push(sibling);
-}
+ }
// Clean the implementors list and method data.
if (current->oop_is_instance()) {
@@ -554,7 +547,11 @@ const char* Klass::external_name() const {
InstanceKlass* ik = (InstanceKlass*) this;
if (ik->is_anonymous()) {
assert(EnableInvokeDynamic, "");
- intptr_t hash = ik->java_mirror()->identity_hash();
+ intptr_t hash = 0;
+ if (ik->java_mirror() != NULL) {
+ // java_mirror might not be created yet, return 0 as hash.
+ hash = ik->java_mirror()->identity_hash();
+ }
char hash_buf[40];
sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
size_t hash_len = strlen(hash_buf);
diff --git a/src/share/vm/oops/klass.hpp b/src/share/vm/oops/klass.hpp
index 58c94b20b..3e8c84699 100644
--- a/src/share/vm/oops/klass.hpp
+++ b/src/share/vm/oops/klass.hpp
@@ -267,7 +267,6 @@ class Klass : public Metadata {
Klass* subklass() const;
Klass* next_sibling() const;
void append_to_sibling_list(); // add newly created receiver to superklass' subklass list
- void remove_from_sibling_list(); // remove receiver from sibling list
void set_next_link(Klass* k) { _next_link = k; }
Klass* next_link() const { return _next_link; } // The next klass defined by the class loader.
@@ -581,8 +580,8 @@ class Klass : public Metadata {
// garbage collection support
virtual void oops_do(OopClosure* cl);
- // Checks if the class loader is alive.
- // Iff the class loader is alive the Klass is considered alive.
+ // Iff the class loader (or mirror for anonymous classes) is alive the
+ // Klass is considered alive.
// The is_alive closure passed in depends on the Garbage Collector used.
bool is_loader_alive(BoolObjectClosure* is_alive);
diff --git a/src/share/vm/oops/markOop.cpp b/src/share/vm/oops/markOop.cpp
index 4fbd7ac00..af722e7cf 100644
--- a/src/share/vm/oops/markOop.cpp
+++ b/src/share/vm/oops/markOop.cpp
@@ -24,19 +24,7 @@
#include "precompiled.hpp"
#include "oops/markOop.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
-
+#include "runtime/thread.inline.hpp"
void markOopDesc::print_on(outputStream* st) const {
if (is_locked()) {
diff --git a/src/share/vm/oops/method.cpp b/src/share/vm/oops/method.cpp
index 93e4532b0..5818d58c2 100644
--- a/src/share/vm/oops/method.cpp
+++ b/src/share/vm/oops/method.cpp
@@ -64,6 +64,7 @@ Method* Method::allocate(ClassLoaderData* loader_data,
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
ConstMethod::MethodType method_type,
TRAPS) {
assert(!access_flags.is_native() || byte_code_size == 0,
@@ -74,6 +75,7 @@ Method* Method::allocate(ClassLoaderData* loader_data,
localvariable_table_length,
exception_table_length,
checked_exceptions_length,
+ generic_signature_index,
method_type,
CHECK_NULL);
@@ -1034,7 +1036,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
methodHandle m;
{
Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits),
- 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty));
+ 0, 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
m->set_constants(cp());
@@ -1082,6 +1084,7 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n
assert(!m->is_native(), "cannot rewrite native methods");
// Allocate new Method*
AccessFlags flags = m->access_flags();
+ u2 generic_signature_index = m->generic_signature_index();
int checked_exceptions_len = m->checked_exceptions_length();
int localvariable_len = m->localvariable_table_length();
int exception_table_len = m->exception_table_length();
@@ -1094,6 +1097,7 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n
localvariable_len,
exception_table_len,
checked_exceptions_len,
+ generic_signature_index,
m->method_type(),
CHECK_(methodHandle()));
methodHandle newm (THREAD, newm_oop);
@@ -1814,6 +1818,23 @@ void Method::clear_jmethod_ids(ClassLoaderData* loader_data) {
loader_data->jmethod_ids()->clear_all_methods();
}
+
+// Check that this pointer is valid by checking that the vtbl pointer matches
+bool Method::is_valid_method() const {
+ if (this == NULL) {
+ return false;
+ } else if (!is_metaspace_object()) {
+ return false;
+ } else {
+ Method m;
+ // This assumes that the vtbl pointer is the first word of a C++ object.
+ // This assumption is also in universe.cpp patch_klass_vtble
+ void* vtbl2 = dereference_vptr((void*)&m);
+ void* this_vtbl = dereference_vptr((void*)this);
+ return vtbl2 == this_vtbl;
+ }
+}
+
#ifndef PRODUCT
void Method::print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) {
out->print_cr("jni_method_id count = %d", loader_data->jmethod_ids()->count_methods());
@@ -1935,7 +1956,7 @@ void Method::verify_on(outputStream* st) {
guarantee(constMethod()->is_metadata(), "should be metadata");
MethodData* md = method_data();
guarantee(md == NULL ||
- md->is_metadata(), "should be in permspace");
+ md->is_metadata(), "should be metadata");
guarantee(md == NULL ||
md->is_methodData(), "should be method data");
}
diff --git a/src/share/vm/oops/method.hpp b/src/share/vm/oops/method.hpp
index 0b6b6b676..ff7bc0ee5 100644
--- a/src/share/vm/oops/method.hpp
+++ b/src/share/vm/oops/method.hpp
@@ -73,12 +73,10 @@
// |------------------------------------------------------|
// | result_index (C++ interpreter only) |
// |------------------------------------------------------|
-// | method_size | max_stack |
-// | max_locals | size_of_parameters |
+// | method_size | max_locals |
+// | size_of_parameters | intrinsic_id| flags |
// |------------------------------------------------------|
-// |intrinsic_id| flags | throwout_count |
-// |------------------------------------------------------|
-// | num_breakpoints | (unused) |
+// | throwout_count | num_breakpoints |
// |------------------------------------------------------|
// | invocation_counter |
// | backedge_counter |
@@ -118,7 +116,6 @@ class Method : public Metadata {
int _result_index; // C++ interpreter needs for converting results to/from stack
#endif
u2 _method_size; // size of this object
- u2 _max_stack; // Maximum number of entries on the expression stack
u2 _max_locals; // Number of local variables used by this method
u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words
u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
@@ -166,10 +163,12 @@ class Method : public Metadata {
int localvariable_table_length,
int exception_table_length,
int checked_exceptions_length,
+ u2 generic_signature_index,
ConstMethod::MethodType method_type,
TRAPS);
- Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
+ // CDS and vtbl checking can create an empty Method to get vtbl pointer.
+ Method(){}
// The Method vtable is restored by this call when the Method is in the
// shared archive. See patch_klass_vtables() in metaspaceShared.cpp for
@@ -288,9 +287,9 @@ class Method : public Metadata {
// max stack
// return original max stack size for method verification
- int verifier_max_stack() const { return _max_stack; }
- int max_stack() const { return _max_stack + extra_stack_entries(); }
- void set_max_stack(int size) { _max_stack = size; }
+ int verifier_max_stack() const { return constMethod()->max_stack(); }
+ int max_stack() const { return constMethod()->max_stack() + extra_stack_entries(); }
+ void set_max_stack(int size) { constMethod()->set_max_stack(size); }
// max locals
int max_locals() const { return _max_locals; }
@@ -606,7 +605,6 @@ class Method : public Metadata {
static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); }
static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); }
static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); }
- static ByteSize max_stack_offset() { return byte_offset_of(Method, _max_stack ); }
// for code generation
static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); }
@@ -812,6 +810,9 @@ class Method : public Metadata {
const char* internal_name() const { return "{method}"; }
+ // Check for valid method pointer
+ bool is_valid_method() const;
+
// Verify
void verify() { verify_on(tty); }
void verify_on(outputStream* st);
diff --git a/src/share/vm/oops/objArrayKlass.cpp b/src/share/vm/oops/objArrayKlass.cpp
index 6260c05fc..434fb74ab 100644
--- a/src/share/vm/oops/objArrayKlass.cpp
+++ b/src/share/vm/oops/objArrayKlass.cpp
@@ -88,11 +88,6 @@ Klass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_data,
}
if (!supers_exist) {
// Oops. Not allocated yet. Back out, allocate it, and retry.
-#ifndef PRODUCT
- if (WizardMode) {
- tty->print_cr("Must retry array klass creation for depth %d",n);
- }
-#endif
KlassHandle ek;
{
MutexUnlocker mu(MultiArray_lock);
diff --git a/src/share/vm/oops/oop.cpp b/src/share/vm/oops/oop.cpp
index fc360c768..43f227e4d 100644
--- a/src/share/vm/oops/oop.cpp
+++ b/src/share/vm/oops/oop.cpp
@@ -27,19 +27,8 @@
#include "classfile/javaClasses.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/copy.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
bool always_do_update_barrier = false;
diff --git a/src/share/vm/oops/oopsHierarchy.cpp b/src/share/vm/oops/oopsHierarchy.cpp
index b7d2c3599..1b6536194 100644
--- a/src/share/vm/oops/oopsHierarchy.cpp
+++ b/src/share/vm/oops/oopsHierarchy.cpp
@@ -26,20 +26,8 @@
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "oops/oopsHierarchy.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/globalDefinitions.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef CHECK_UNHANDLED_OOPS
diff --git a/src/share/vm/prims/forte.cpp b/src/share/vm/prims/forte.cpp
index 7a15af974..33419f298 100644
--- a/src/share/vm/prims/forte.cpp
+++ b/src/share/vm/prims/forte.cpp
@@ -216,10 +216,7 @@ static bool is_decipherable_interpreted_frame(JavaThread* thread,
// not yet valid.
*method_p = method;
-
- // See if gc may have invalidated method since we validated frame
-
- if (!Universe::heap()->is_valid_method(method)) return false;
+ if (!method->is_valid_method()) return false;
intptr_t bcx = fr->interpreter_frame_bcx();
@@ -394,19 +391,11 @@ static void forte_fill_call_trace_given_top(JavaThread* thd,
bool fully_decipherable = find_initial_Java_frame(thd, &top_frame, &initial_Java_frame, &method, &bci);
// The frame might not be walkable but still recovered a method
- // (e.g. an nmethod with no scope info for the pc
+ // (e.g. an nmethod with no scope info for the pc)
if (method == NULL) return;
- CollectedHeap* ch = Universe::heap();
-
- // The method is not stored GC safe so see if GC became active
- // after we entered AsyncGetCallTrace() and before we try to
- // use the Method*.
- // Yes, there is still a window after this check and before
- // we use Method* below, but we can't lock out GC so that
- // has to be an acceptable risk.
- if (!ch->is_valid_method(method)) {
+ if (!method->is_valid_method()) {
trace->num_frames = ticks_GC_active; // -2
return;
}
@@ -440,13 +429,7 @@ static void forte_fill_call_trace_given_top(JavaThread* thd,
bci = st.bci();
method = st.method();
- // The method is not stored GC safe so see if GC became active
- // after we entered AsyncGetCallTrace() and before we try to
- // use the Method*.
- // Yes, there is still a window after this check and before
- // we use Method* below, but we can't lock out GC so that
- // has to be an acceptable risk.
- if (!ch->is_valid_method(method)) {
+ if (!method->is_valid_method()) {
// we throw away everything we've gathered in this sample since
// none of it is safe
trace->num_frames = ticks_GC_active; // -2
diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp
index 2204c4aba..ddbde753f 100644
--- a/src/share/vm/prims/jni.cpp
+++ b/src/share/vm/prims/jni.cpp
@@ -69,6 +69,7 @@
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vm_operations.hpp"
#include "services/runtimeService.hpp"
#include "trace/tracing.hpp"
@@ -79,19 +80,15 @@
#include "utilities/histogram.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
static jint CurrentVersion = JNI_VERSION_1_6;
@@ -5044,6 +5041,9 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
#include "gc_interface/collectedHeap.hpp"
#include "utilities/quickSort.hpp"
+#if INCLUDE_VM_STRUCTS
+#include "runtime/vmStructs.hpp"
+#endif
#define run_unit_test(unit_test_function_call) \
tty->print_cr("Running test: " #unit_test_function_call); \
@@ -5056,6 +5056,9 @@ void execute_internal_vm_tests() {
run_unit_test(CollectedHeap::test_is_in());
run_unit_test(QuickSort::test_quick_sort());
run_unit_test(AltHashing::test_alt_hash());
+#if INCLUDE_VM_STRUCTS
+ run_unit_test(VMStructs::test());
+#endif
tty->print_cr("All internal VM tests passed");
}
}
diff --git a/src/share/vm/prims/jvmti.xml b/src/share/vm/prims/jvmti.xml
index 517083f20..dbd6735aa 100644
--- a/src/share/vm/prims/jvmti.xml
+++ b/src/share/vm/prims/jvmti.xml
@@ -2370,11 +2370,11 @@ jint count;
jvmtiError err;
err = (*jvmti)-&gt;GetStackTrace(jvmti, aThread, 0, 5,
- &amp;frames, &amp;count);
+ frames, &amp;count);
if (err == JVMTI_ERROR_NONE &amp;&amp; count &gt;= 1) {
char *methodName;
err = (*jvmti)-&gt;GetMethodName(jvmti, frames[0].method,
- &amp;methodName, NULL);
+ &amp;methodName, NULL, NULL);
if (err == JVMTI_ERROR_NONE) {
printf("Executing method: %s", methodName);
}
diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp
index a456cacc6..cb3b3db1e 100644
--- a/src/share/vm/prims/jvmtiEnv.cpp
+++ b/src/share/vm/prims/jvmtiEnv.cpp
@@ -53,24 +53,12 @@
#include "runtime/osThread.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vmThread.hpp"
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/preserveException.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
-
#define FIXLATER 0 // REMOVE this when completed.
diff --git a/src/share/vm/prims/jvmtiImpl.cpp b/src/share/vm/prims/jvmtiImpl.cpp
index 4ff9bf3c5..bb7714d49 100644
--- a/src/share/vm/prims/jvmtiImpl.cpp
+++ b/src/share/vm/prims/jvmtiImpl.cpp
@@ -41,22 +41,11 @@
#include "runtime/os.hpp"
#include "runtime/serviceThread.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframe_hp.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/exceptions.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
//
// class JvmtiAgentThread
diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp
index 8d8b30df0..cb7f0fcf3 100644
--- a/src/share/vm/prims/unsafe.cpp
+++ b/src/share/vm/prims/unsafe.cpp
@@ -996,7 +996,7 @@ UNSAFE_END
// not just a literal string. For such ldc instructions, the verifier uses the
// type Object instead of String, if the loaded constant is not in fact a String.
-static oop
+static instanceKlassHandle
Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
HeapWord* *temp_alloc,
@@ -1073,32 +1073,39 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
anon_klass = instanceKlassHandle(THREAD, anonk);
}
- // let caller initialize it as needed...
-
- return anon_klass->java_mirror();
+ return anon_klass;
}
UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
{
+ instanceKlassHandle anon_klass;
+ jobject res_jh = NULL;
+
UnsafeWrapper("Unsafe_DefineAnonymousClass");
ResourceMark rm(THREAD);
HeapWord* temp_alloc = NULL;
- jobject res_jh = NULL;
-
- { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
- host_class, data, cp_patches_jh,
+ anon_klass = Unsafe_DefineAnonymousClass_impl(env, host_class, data,
+ cp_patches_jh,
&temp_alloc, THREAD);
- if (res_oop != NULL)
- res_jh = JNIHandles::make_local(env, res_oop);
- }
+ if (anon_klass() != NULL)
+ res_jh = JNIHandles::make_local(env, anon_klass->java_mirror());
// try/finally clause:
if (temp_alloc != NULL) {
FREE_C_HEAP_ARRAY(HeapWord, temp_alloc, mtInternal);
}
+ // The anonymous class loader data has been artificially been kept alive to
+ // this point. The mirror and any instances of this class have to keep
+ // it alive afterwards.
+ if (anon_klass() != NULL) {
+ anon_klass->class_loader_data()->set_keep_alive(false);
+ }
+
+ // let caller initialize it as needed...
+
return (jclass) res_jh;
}
UNSAFE_END
diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp
index 24a98be33..f850e05cb 100644
--- a/src/share/vm/runtime/arguments.cpp
+++ b/src/share/vm/runtime/arguments.cpp
@@ -1485,14 +1485,6 @@ void Arguments::set_parallel_gc_flags() {
}
}
}
- if (UseNUMA) {
- if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
- FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
- }
- // For those collectors or operating systems (eg, Windows) that do
- // not support full UseNUMA, we will map to UseNUMAInterleaving for now
- UseNUMAInterleaving = true;
- }
}
void Arguments::set_g1_gc_flags() {
@@ -3332,6 +3324,22 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
return JNI_OK;
}
+jint Arguments::adjust_after_os() {
+#if INCLUDE_ALTERNATE_GCS
+ if (UseParallelGC || UseParallelOldGC) {
+ if (UseNUMA) {
+ if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
+ FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
+ }
+ // For those collectors or operating systems (eg, Windows) that do
+ // not support full UseNUMA, we will map to UseNUMAInterleaving for now
+ UseNUMAInterleaving = true;
+ }
+ }
+#endif
+ return JNI_OK;
+}
+
int Arguments::PropertyList_count(SystemProperty* pl) {
int count = 0;
while(pl != NULL) {
diff --git a/src/share/vm/runtime/arguments.hpp b/src/share/vm/runtime/arguments.hpp
index 1dbb5eb22..5e0f00944 100644
--- a/src/share/vm/runtime/arguments.hpp
+++ b/src/share/vm/runtime/arguments.hpp
@@ -409,6 +409,8 @@ class Arguments : AllStatic {
public:
// Parses the arguments
static jint parse(const JavaVMInitArgs* args);
+ // Adjusts the arguments after the OS have adjusted the arguments
+ static jint adjust_after_os();
// Check for consistency in the selection of the garbage collector.
static bool check_gc_consistency();
// Check consistecy or otherwise of VM argument settings
diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp
index 01f4dc75f..c761c0b33 100644
--- a/src/share/vm/runtime/deoptimization.cpp
+++ b/src/share/vm/runtime/deoptimization.cpp
@@ -721,7 +721,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
guarantee(false, "wrong number of expression stack elements during deopt");
}
VerifyOopClosure verify;
- iframe->oops_interpreted_do(&verify, &rm, false);
+ iframe->oops_interpreted_do(&verify, NULL, &rm, false);
callee_size_of_parameters = mh->size_of_parameters();
callee_max_locals = mh->max_locals();
is_top_frame = false;
diff --git a/src/share/vm/runtime/fprofiler.hpp b/src/share/vm/runtime/fprofiler.hpp
index 725e5fcaf..c06a50563 100644
--- a/src/share/vm/runtime/fprofiler.hpp
+++ b/src/share/vm/runtime/fprofiler.hpp
@@ -26,18 +26,6 @@
#define SHARE_VM_RUNTIME_FPROFILER_HPP
#include "runtime/timer.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// a simple flat profiler for Java
diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp
index f9acadd45..1788d3d0d 100644
--- a/src/share/vm/runtime/frame.cpp
+++ b/src/share/vm/runtime/frame.cpp
@@ -879,7 +879,8 @@ oop* frame::interpreter_callee_receiver_addr(Symbol* signature) {
}
-void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
+void frame::oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f,
+ const RegisterMap* map, bool query_oop_map_cache) {
assert(is_interpreted_frame(), "Not an interpreted frame");
assert(map != NULL, "map must be set");
Thread *thread = Thread::current();
@@ -906,6 +907,16 @@ void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool quer
}
// process fixed part
+ if (cld_f != NULL) {
+ // The method pointer in the frame might be the only path to the method's
+ // klass, and the klass needs to be kept alive while executing. The GCs
+ // don't trace through method pointers, so typically in similar situations
+ // the mirror or the class loader of the klass are installed as a GC root.
+ // To minimze the overhead of doing that here, we ask the GC to pass down a
+ // closure that knows how to keep klasses alive given a ClassLoaderData.
+ cld_f->do_cld(m->method_holder()->class_loader_data());
+ }
+
#if !defined(PPC) || defined(ZERO)
if (m->is_native()) {
#ifdef CC_INTERP
@@ -1108,7 +1119,7 @@ void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) {
}
-void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
+void frame::oops_do_internal(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
#ifndef PRODUCT
// simulate GC crash here to dump java thread in error report
if (CrashGCForDumpingJavaThread) {
@@ -1117,7 +1128,7 @@ void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* ma
}
#endif
if (is_interpreted_frame()) {
- oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
+ oops_interpreted_do(f, cld_f, map, use_interpreter_oop_map_cache);
} else if (is_entry_frame()) {
oops_entry_do(f, map);
} else if (CodeCache::contains(pc())) {
@@ -1278,7 +1289,7 @@ void frame::verify(const RegisterMap* map) {
}
}
COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");)
- oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
+ oops_do_internal(&VerifyOopClosure::verify_oop, NULL, NULL, (RegisterMap*)map, false);
}
diff --git a/src/share/vm/runtime/frame.hpp b/src/share/vm/runtime/frame.hpp
index 8f6d759d6..6e990dce7 100644
--- a/src/share/vm/runtime/frame.hpp
+++ b/src/share/vm/runtime/frame.hpp
@@ -413,19 +413,19 @@ class frame VALUE_OBJ_CLASS_SPEC {
// Oops-do's
void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
- void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
+ void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
private:
void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
// Iteration of oops
- void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
+ void oops_do_internal(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
void oops_entry_do(OopClosure* f, const RegisterMap* map);
void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
int adjust_offset(Method* method, int index); // helper for above fn
public:
// Memory management
- void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
+ void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cld_f, cf, map, true); }
void nmethods_do(CodeBlobClosure* cf);
// RedefineClasses support for finding live interpreted methods on the stack
diff --git a/src/share/vm/runtime/handles.cpp b/src/share/vm/runtime/handles.cpp
index a37e46da1..a62ff177d 100644
--- a/src/share/vm/runtime/handles.cpp
+++ b/src/share/vm/runtime/handles.cpp
@@ -27,21 +27,18 @@
#include "oops/constantPool.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/thread.inline.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
#ifdef ASSERT
diff --git a/src/share/vm/runtime/handles.inline.hpp b/src/share/vm/runtime/handles.inline.hpp
index 51c31ff4b..6565b9793 100644
--- a/src/share/vm/runtime/handles.inline.hpp
+++ b/src/share/vm/runtime/handles.inline.hpp
@@ -26,18 +26,7 @@
#define SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
#include "runtime/handles.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// these inline functions are in a separate file to break an include cycle
// between Thread and Handle
diff --git a/src/share/vm/runtime/interfaceSupport.hpp b/src/share/vm/runtime/interfaceSupport.hpp
index 1f1ffa8eb..0c48e5181 100644
--- a/src/share/vm/runtime/interfaceSupport.hpp
+++ b/src/share/vm/runtime/interfaceSupport.hpp
@@ -31,22 +31,11 @@
#include "runtime/orderAccess.hpp"
#include "runtime/os.hpp"
#include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Wrapper for all entry points to the virtual machine.
// The HandleMarkCleaner is a faster version of HandleMark.
diff --git a/src/share/vm/runtime/java.cpp b/src/share/vm/runtime/java.cpp
index c4d0b1b66..ad6399495 100644
--- a/src/share/vm/runtime/java.cpp
+++ b/src/share/vm/runtime/java.cpp
@@ -54,6 +54,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/task.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memReporter.hpp"
@@ -79,18 +80,6 @@
#ifdef TARGET_ARCH_ppc
# include "vm_version_ppc.hpp"
#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
diff --git a/src/share/vm/runtime/javaCalls.cpp b/src/share/vm/runtime/javaCalls.cpp
index fe965acb9..1dc58e40c 100644
--- a/src/share/vm/runtime/javaCalls.cpp
+++ b/src/share/vm/runtime/javaCalls.cpp
@@ -39,18 +39,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// -----------------------------------------------------
// Implementation of JavaCallWrapper
diff --git a/src/share/vm/runtime/javaCalls.hpp b/src/share/vm/runtime/javaCalls.hpp
index 3b288f0d2..08881fcbb 100644
--- a/src/share/vm/runtime/javaCalls.hpp
+++ b/src/share/vm/runtime/javaCalls.hpp
@@ -29,6 +29,7 @@
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#ifdef TARGET_ARCH_x86
# include "jniTypes_x86.hpp"
@@ -45,18 +46,6 @@
#ifdef TARGET_ARCH_ppc
# include "jniTypes_ppc.hpp"
#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// A JavaCallWrapper is constructed before each JavaCall and destructed after the call.
// Its purpose is to allocate/deallocate a new handle block and to save/restore the last
diff --git a/src/share/vm/runtime/jniHandles.cpp b/src/share/vm/runtime/jniHandles.cpp
index 4c618b049..4dc83d304 100644
--- a/src/share/vm/runtime/jniHandles.cpp
+++ b/src/share/vm/runtime/jniHandles.cpp
@@ -28,18 +28,7 @@
#include "prims/jvmtiExport.hpp"
#include "runtime/jniHandles.hpp"
#include "runtime/mutexLocker.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
JNIHandleBlock* JNIHandles::_global_handles = NULL;
diff --git a/src/share/vm/runtime/memprofiler.cpp b/src/share/vm/runtime/memprofiler.cpp
index 339358b4f..279277ed0 100644
--- a/src/share/vm/runtime/memprofiler.cpp
+++ b/src/share/vm/runtime/memprofiler.cpp
@@ -35,19 +35,8 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/task.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef PRODUCT
diff --git a/src/share/vm/runtime/mutex.cpp b/src/share/vm/runtime/mutex.cpp
index 9fc156089..10d91fa37 100644
--- a/src/share/vm/runtime/mutex.cpp
+++ b/src/share/vm/runtime/mutex.cpp
@@ -26,22 +26,19 @@
#include "precompiled.hpp"
#include "runtime/mutex.hpp"
#include "runtime/osThread.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/events.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "mutex_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "mutex_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "mutex_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "mutex_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
// o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
diff --git a/src/share/vm/runtime/mutexLocker.cpp b/src/share/vm/runtime/mutexLocker.cpp
index 0be262268..31fe66f38 100644
--- a/src/share/vm/runtime/mutexLocker.cpp
+++ b/src/share/vm/runtime/mutexLocker.cpp
@@ -25,20 +25,9 @@
#include "precompiled.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/vmThread.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Mutexes used in the VM (see comment in mutexLocker.hpp):
//
diff --git a/src/share/vm/runtime/objectMonitor.cpp b/src/share/vm/runtime/objectMonitor.cpp
index e02feeeae..2eefe2911 100644
--- a/src/share/vm/runtime/objectMonitor.cpp
+++ b/src/share/vm/runtime/objectMonitor.cpp
@@ -34,25 +34,21 @@
#include "runtime/objectMonitor.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/stubRoutines.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/threadService.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
#if defined(__GNUC__) && !defined(IA64)
diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp
index bc44d0163..649ce4fcc 100644
--- a/src/share/vm/runtime/os.cpp
+++ b/src/share/vm/runtime/os.cpp
@@ -44,6 +44,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
#include "services/threadService.hpp"
@@ -51,19 +52,15 @@
#include "utilities/events.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
# include <signal.h>
diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp
index 31b33e320..bf2d38c20 100644
--- a/src/share/vm/runtime/safepoint.cpp
+++ b/src/share/vm/runtime/safepoint.cpp
@@ -48,6 +48,7 @@
#include "runtime/stubRoutines.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
+#include "runtime/thread.inline.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
#include "utilities/events.hpp"
@@ -71,18 +72,6 @@
# include "nativeInst_ppc.hpp"
# include "vmreg_ppc.inline.hpp"
#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/shared/concurrentGCThread.hpp"
diff --git a/src/share/vm/runtime/synchronizer.cpp b/src/share/vm/runtime/synchronizer.cpp
index 1ffc285b2..13b71cb80 100644
--- a/src/share/vm/runtime/synchronizer.cpp
+++ b/src/share/vm/runtime/synchronizer.cpp
@@ -36,24 +36,21 @@
#include "runtime/osThread.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
#if defined(__GNUC__) && !defined(IA64)
diff --git a/src/share/vm/runtime/task.cpp b/src/share/vm/runtime/task.cpp
index 689f3857c..9d2286f2d 100644
--- a/src/share/vm/runtime/task.cpp
+++ b/src/share/vm/runtime/task.cpp
@@ -26,22 +26,19 @@
#include "memory/allocation.hpp"
#include "runtime/init.hpp"
#include "runtime/task.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/timer.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
int PeriodicTask::_num_tasks = 0;
diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp
index 45c73408b..23b0bbf32 100644
--- a/src/share/vm/runtime/thread.cpp
+++ b/src/share/vm/runtime/thread.cpp
@@ -65,6 +65,7 @@
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/task.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/vframe.hpp"
@@ -83,19 +84,15 @@
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
#ifndef SERIALGC
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
@@ -826,7 +823,7 @@ bool Thread::claim_oops_do_par_case(int strong_roots_parity) {
return false;
}
-void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+void Thread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
active_handles()->oops_do(f);
// Do oop for ThreadShadow
f->do_oop((oop*)&_pending_exception);
@@ -2705,7 +2702,7 @@ public:
}
};
-void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+void JavaThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
// Verify that the deferred card marks have been flushed.
assert(deferred_card_mark().is_empty(), "Should be empty during GC");
@@ -2713,7 +2710,7 @@ void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
// since there may be more than one thread using each ThreadProfiler.
// Traverse the GCHandles
- Thread::oops_do(f, cf);
+ Thread::oops_do(f, cld_f, cf);
assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
(has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
@@ -2741,7 +2738,7 @@ void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
// Traverse the execution stack
for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
- fst.current()->oops_do(f, cf, fst.register_map());
+ fst.current()->oops_do(f, cld_f, cf, fst.register_map());
}
}
@@ -2875,7 +2872,7 @@ static void frame_verify(frame* f, const RegisterMap *map) { f->verify(map); }
void JavaThread::verify() {
// Verify oops in the thread.
- oops_do(&VerifyOopClosure::verify_oop, NULL);
+ oops_do(&VerifyOopClosure::verify_oop, NULL, NULL);
// Verify the stack frames.
frames_do(frame_verify);
@@ -3125,7 +3122,7 @@ class PrintAndVerifyOopClosure: public OopClosure {
static void oops_print(frame* f, const RegisterMap *map) {
PrintAndVerifyOopClosure print;
f->print_value();
- f->oops_do(&print, NULL, (RegisterMap*)map);
+ f->oops_do(&print, NULL, NULL, (RegisterMap*)map);
}
// Print our all the locations that contain oops and whether they are
@@ -3227,8 +3224,8 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
#endif
}
-void CompilerThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
- JavaThread::oops_do(f, cf);
+void CompilerThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
+ JavaThread::oops_do(f, cld_f, cf);
if (_scanned_nmethod != NULL && cf != NULL) {
// Safepoints can occur when the sweeper is scanning an nmethod so
// process it here to make sure it isn't unloaded in the middle of
@@ -3334,6 +3331,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
jint os_init_2_result = os::init_2();
if (os_init_2_result != JNI_OK) return os_init_2_result;
+ jint adjust_after_os_result = Arguments::adjust_after_os();
+ if (adjust_after_os_result != JNI_OK) return adjust_after_os_result;
+
// intialize TLS
ThreadLocalStorage::init();
@@ -4198,14 +4198,14 @@ bool Threads::includes(JavaThread* p) {
// uses the Threads_lock to gurantee this property. It also makes sure that
// all threads gets blocked when exiting or starting).
-void Threads::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+void Threads::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
ALL_JAVA_THREADS(p) {
- p->oops_do(f, cf);
+ p->oops_do(f, cld_f, cf);
}
- VMThread::vm_thread()->oops_do(f, cf);
+ VMThread::vm_thread()->oops_do(f, cld_f, cf);
}
-void Threads::possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf) {
+void Threads::possibly_parallel_oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
// Introduce a mechanism allowing parallel threads to claim threads as
// root groups. Overhead should be small enough to use all the time,
// even in sequential code.
@@ -4222,12 +4222,12 @@ void Threads::possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf) {
int cp = SharedHeap::heap()->strong_roots_parity();
ALL_JAVA_THREADS(p) {
if (p->claim_oops_do(is_par, cp)) {
- p->oops_do(f, cf);
+ p->oops_do(f, cld_f, cf);
}
}
VMThread* vmt = VMThread::vm_thread();
if (vmt->claim_oops_do(is_par, cp)) {
- vmt->oops_do(f, cf);
+ vmt->oops_do(f, cld_f, cf);
}
}
diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp
index 3ccbf487e..627000c72 100644
--- a/src/share/vm/runtime/thread.hpp
+++ b/src/share/vm/runtime/thread.hpp
@@ -480,8 +480,10 @@ class Thread: public ThreadShadow {
// GC support
// Apply "f->do_oop" to all root oops in "this".
+ // Apply "cld_f->do_cld" to CLDs that are otherwise not kept alive.
+ // Used by JavaThread::oops_do.
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
- virtual void oops_do(OopClosure* f, CodeBlobClosure* cf);
+ virtual void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
// Handles the parallel case for the method below.
private:
@@ -1405,7 +1407,7 @@ class JavaThread: public Thread {
void frames_do(void f(frame*, const RegisterMap*));
// Memory operations
- void oops_do(OopClosure* f, CodeBlobClosure* cf);
+ void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
// Sweeper operations
void nmethods_do(CodeBlobClosure* cf);
@@ -1825,7 +1827,7 @@ class CompilerThread : public JavaThread {
// GC support
// Apply "f->do_oop" to all root oops in "this".
// Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
- void oops_do(OopClosure* f, CodeBlobClosure* cf);
+ void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
#ifndef PRODUCT
private:
@@ -1892,9 +1894,9 @@ class Threads: AllStatic {
// Apply "f->do_oop" to all root oops in all threads.
// This version may only be called by sequential code.
- static void oops_do(OopClosure* f, CodeBlobClosure* cf);
+ static void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
// This version may be called by sequential or parallel code.
- static void possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf);
+ static void possibly_parallel_oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
// This creates a list of GCTasks, one per thread.
static void create_thread_roots_tasks(GCTaskQueue* q);
// This creates a list of GCTasks, one per thread, for marking objects.
diff --git a/src/share/vm/runtime/thread.inline.hpp b/src/share/vm/runtime/thread.inline.hpp
new file mode 100644
index 000000000..30b02dbcb
--- /dev/null
+++ b/src/share/vm/runtime/thread.inline.hpp
@@ -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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP
+#define SHARE_VM_RUNTIME_THREAD_INLINE_HPP
+
+#define SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+
+#include "runtime/thread.hpp"
+#ifdef TARGET_OS_FAMILY_linux
+# include "thread_linux.inline.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_solaris
+# include "thread_solaris.inline.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_windows
+# include "thread_windows.inline.hpp"
+#endif
+#ifdef TARGET_OS_FAMILY_bsd
+# include "thread_bsd.inline.hpp"
+#endif
+
+#undef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
+
+#endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP
diff --git a/src/share/vm/runtime/threadLocalStorage.cpp b/src/share/vm/runtime/threadLocalStorage.cpp
index 0cdc48a0a..639118fe4 100644
--- a/src/share/vm/runtime/threadLocalStorage.cpp
+++ b/src/share/vm/runtime/threadLocalStorage.cpp
@@ -23,22 +23,19 @@
*/
#include "precompiled.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
// static member initialization
diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp
index 484566125..9346d6c72 100644
--- a/src/share/vm/runtime/vmStructs.cpp
+++ b/src/share/vm/runtime/vmStructs.cpp
@@ -95,6 +95,7 @@
#include "runtime/serviceThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/virtualspace.hpp"
#include "runtime/vmStructs.hpp"
#include "utilities/array.hpp"
@@ -115,18 +116,6 @@
#ifdef TARGET_ARCH_ppc
# include "vmStructs_ppc.hpp"
#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef TARGET_OS_ARCH_linux_x86
# include "vmStructs_linux_x86.hpp"
#endif
@@ -366,7 +355,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _method_size, u2) \
- nonstatic_field(Method, _max_stack, u2) \
nonstatic_field(Method, _max_locals, u2) \
nonstatic_field(Method, _size_of_parameters, u2) \
nonstatic_field(Method, _interpreter_throwout_count, u2) \
@@ -389,7 +377,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(ConstMethod, _name_index, u2) \
nonstatic_field(ConstMethod, _signature_index, u2) \
nonstatic_field(ConstMethod, _method_idnum, u2) \
- nonstatic_field(ConstMethod, _generic_signature_index, u2) \
+ nonstatic_field(ConstMethod, _max_stack, u2) \
nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \
nonstatic_field(ObjArrayKlass, _bottom_klass, Klass*) \
volatile_nonstatic_field(Symbol, _refcount, int) \
@@ -2107,8 +2095,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_toplevel_type(FreeList<Metablock>*) \
declare_toplevel_type(FreeList<Metablock>) \
declare_toplevel_type(MetablockTreeDictionary*) \
- declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>) \
- declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
+ declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
/* NOTE that we do not use the last_entry() macro here; it is used */
@@ -2292,6 +2279,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_constant(ConstMethod::_has_checked_exceptions) \
declare_constant(ConstMethod::_has_localvariable_table) \
declare_constant(ConstMethod::_has_exception_table) \
+ declare_constant(ConstMethod::_has_generic_signature) \
\
/*************************************/ \
/* InstanceKlass enum */ \
@@ -3215,3 +3203,17 @@ VMStructs::findType(const char* typeName) {
void vmStructs_init() {
debug_only(VMStructs::init());
}
+
+#ifndef PRODUCT
+void VMStructs::test() {
+ // Check for duplicate entries in type array
+ for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
+ for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {
+ if (strcmp(localHotSpotVMTypes[i].typeName, localHotSpotVMTypes[j].typeName) == 0) {
+ tty->print_cr("Duplicate entries for '%s'", localHotSpotVMTypes[i].typeName);
+ assert(false, "Duplicate types in localHotSpotVMTypes array");
+ }
+ }
+ }
+}
+#endif
diff --git a/src/share/vm/runtime/vmStructs.hpp b/src/share/vm/runtime/vmStructs.hpp
index 725399e2c..b1070a406 100644
--- a/src/share/vm/runtime/vmStructs.hpp
+++ b/src/share/vm/runtime/vmStructs.hpp
@@ -123,6 +123,11 @@ public:
// the data structure (debug build only)
static void init();
+#ifndef PRODUCT
+ // Execute unit tests
+ static void test();
+#endif
+
private:
// Look up a type in localHotSpotVMTypes using strcmp() (debug build only).
// Returns 1 if found, 0 if not.
diff --git a/src/share/vm/runtime/vmThread.cpp b/src/share/vm/runtime/vmThread.cpp
index 470d6b1c4..d8d3e4447 100644
--- a/src/share/vm/runtime/vmThread.cpp
+++ b/src/share/vm/runtime/vmThread.cpp
@@ -31,24 +31,13 @@
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "services/runtimeService.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/xmlstream.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifndef USDT2
HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
@@ -668,8 +657,8 @@ void VMThread::execute(VM_Operation* op) {
}
-void VMThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
- Thread::oops_do(f, cf);
+void VMThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
+ Thread::oops_do(f, cld_f, cf);
_vm_queue->oops_do(f);
}
@@ -701,5 +690,5 @@ void VMOperationQueue::verify_queue(int prio) {
#endif
void VMThread::verify() {
- oops_do(&VerifyOopClosure::verify_oop, NULL);
+ oops_do(&VerifyOopClosure::verify_oop, NULL, NULL);
}
diff --git a/src/share/vm/runtime/vmThread.hpp b/src/share/vm/runtime/vmThread.hpp
index 30e45ee26..d7a45b385 100644
--- a/src/share/vm/runtime/vmThread.hpp
+++ b/src/share/vm/runtime/vmThread.hpp
@@ -26,19 +26,8 @@
#define SHARE_VM_RUNTIME_VMTHREAD_HPP
#include "runtime/perfData.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vm_operations.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
//
// Prioritized queue of VM operations.
@@ -137,7 +126,7 @@ class VMThread: public NamedThread {
static VMThread* vm_thread() { return _vm_thread; }
// GC support
- void oops_do(OopClosure* f, CodeBlobClosure* cf);
+ void oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf);
// Debugging
void print_on(outputStream* st) const;
diff --git a/src/share/vm/runtime/vm_operations.cpp b/src/share/vm/runtime/vm_operations.cpp
index b010b9acb..99e367cdf 100644
--- a/src/share/vm/runtime/vm_operations.cpp
+++ b/src/share/vm/runtime/vm_operations.cpp
@@ -34,20 +34,9 @@
#include "runtime/deoptimization.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/sweeper.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vm_operations.hpp"
#include "services/threadService.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#define VM_OP_NAME_INITIALIZE(name) #name,
diff --git a/src/share/vm/runtime/vm_version.cpp b/src/share/vm/runtime/vm_version.cpp
index bb110ee15..2d105a97b 100644
--- a/src/share/vm/runtime/vm_version.cpp
+++ b/src/share/vm/runtime/vm_version.cpp
@@ -243,19 +243,21 @@ const char* Abstract_VM_Version::internal_vm_info_string() {
#ifndef FLOAT_ARCH
#if defined(__SOFTFP__)
- #define FLOAT_ARCH "-sflt"
+ #define FLOAT_ARCH_STR "-sflt"
#elif defined(E500V2)
- #define FLOAT_ARCH "-e500v2"
+ #define FLOAT_ARCH_STR "-e500v2"
#elif defined(ARM)
- #define FLOAT_ARCH "-vfp"
+ #define FLOAT_ARCH_STR "-vfp"
#elif defined(PPC)
- #define FLOAT_ARCH "-hflt"
+ #define FLOAT_ARCH_STR "-hflt"
#else
- #define FLOAT_ARCH ""
+ #define FLOAT_ARCH_STR ""
#endif
+ #else
+ #define FLOAT_ARCH_STR XSTR(FLOAT_ARCH)
#endif
- return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH
+ return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH_STR
" JRE (" JRE_RELEASE_VERSION "), built on " __DATE__ " " __TIME__
" by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER;
}
diff --git a/src/share/vm/services/memSnapshot.cpp b/src/share/vm/services/memSnapshot.cpp
index 92c407615..c293542f7 100644
--- a/src/share/vm/services/memSnapshot.cpp
+++ b/src/share/vm/services/memSnapshot.cpp
@@ -261,17 +261,19 @@ bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
VMMemRegion* cur = (VMMemRegion*)current();
assert(cur->is_reserved_region() && cur->contains_region(rec),
"Sanity check");
+ if (rec->is_same_region(cur)) {
+ // release whole reserved region
#ifdef ASSERT
- VMMemRegion* next_reg = (VMMemRegion*)peek_next();
- // should not have any committed memory in this reserved region
- assert(next_reg == NULL || !next_reg->is_committed_region(), "Sanity check");
+ VMMemRegion* next_region = (VMMemRegion*)peek_next();
+ // should not have any committed memory in this reserved region
+ assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check");
#endif
- if (rec->is_same_region(cur)) {
remove();
} else if (rec->addr() == cur->addr() ||
rec->addr() + rec->size() == cur->addr() + cur->size()) {
// released region is at either end of this region
cur->exclude_region(rec->addr(), rec->size());
+ assert(check_reserved_region(), "Integrity check");
} else { // split the reserved region and release the middle
address high_addr = cur->addr() + cur->size();
size_t sz = high_addr - rec->addr();
@@ -280,10 +282,14 @@ bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
if (MemTracker::track_callsite()) {
MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
((VMMemRegionEx*)cur)->pc());
- return insert_reserved_region(&tmp);
+ bool ret = insert_reserved_region(&tmp);
+ assert(!ret || check_reserved_region(), "Integrity check");
+ return ret;
} else {
MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
- return insert_reserved_region(&tmp);
+ bool ret = insert_reserved_region(&tmp);
+ assert(!ret || check_reserved_region(), "Integrity check");
+ return ret;
}
}
return true;
diff --git a/src/share/vm/services/memSnapshot.hpp b/src/share/vm/services/memSnapshot.hpp
index 1620c5454..5755108c0 100644
--- a/src/share/vm/services/memSnapshot.hpp
+++ b/src/share/vm/services/memSnapshot.hpp
@@ -146,6 +146,23 @@ class VMMemPointerIterator : public MemPointerIterator {
// reset current position
inline void reset() { _pos = 0; }
#ifdef ASSERT
+ // check integrity of records on current reserved memory region.
+ bool check_reserved_region() {
+ VMMemRegion* reserved_region = (VMMemRegion*)current();
+ assert(reserved_region != NULL && reserved_region->is_reserved_region(),
+ "Sanity check");
+ // all committed regions that follow current reserved region, should all
+ // belong to the reserved region.
+ VMMemRegion* next_region = (VMMemRegion*)next();
+ for (; next_region != NULL && next_region->is_committed_region();
+ next_region = (VMMemRegion*)next() ) {
+ if(!reserved_region->contains_region(next_region)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
virtual bool is_dup_pointer(const MemPointer* ptr1,
const MemPointer* ptr2) const {
VMMemRegion* p1 = (VMMemRegion*)ptr1;
diff --git a/src/share/vm/services/memTracker.cpp b/src/share/vm/services/memTracker.cpp
index 3cec67868..ebb690a1b 100644
--- a/src/share/vm/services/memTracker.cpp
+++ b/src/share/vm/services/memTracker.cpp
@@ -69,15 +69,12 @@ NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
void MemTracker::init_tracking_options(const char* option_line) {
_tracking_level = NMT_off;
- if (strncmp(option_line, "=summary", 8) == 0) {
+ if (strcmp(option_line, "=summary") == 0) {
_tracking_level = NMT_summary;
- } else if (strncmp(option_line, "=detail", 7) == 0) {
+ } else if (strcmp(option_line, "=detail") == 0) {
_tracking_level = NMT_detail;
- } else {
- char msg[255];
- //+1 to remove the '=' character
- jio_snprintf(msg, 255, "Unknown option given to XX:NativeMemoryTracking: %s", option_line+1);
- vm_exit_during_initialization(msg, NULL);
+ } else if (strcmp(option_line, "=off") != 0) {
+ vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
}
}
diff --git a/src/share/vm/services/memTracker.hpp b/src/share/vm/services/memTracker.hpp
index 13eb4caf8..bd149efb3 100644
--- a/src/share/vm/services/memTracker.hpp
+++ b/src/share/vm/services/memTracker.hpp
@@ -109,10 +109,6 @@ class MemTracker : AllStatic {
#include "services/memSnapshot.hpp"
#include "services/memTrackWorker.hpp"
-#ifdef SOLARIS
-#include "thread_solaris.inline.hpp"
-#endif
-
extern bool NMT_track_callsite;
#ifdef ASSERT
diff --git a/src/share/vm/utilities/array.cpp b/src/share/vm/utilities/array.cpp
index 5b51a947c..782abd95a 100644
--- a/src/share/vm/utilities/array.cpp
+++ b/src/share/vm/utilities/array.cpp
@@ -24,19 +24,8 @@
#include "precompiled.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/array.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef ASSERT
diff --git a/src/share/vm/utilities/debug.cpp b/src/share/vm/utilities/debug.cpp
index 51d59c445..e7dd8539c 100644
--- a/src/share/vm/utilities/debug.cpp
+++ b/src/share/vm/utilities/debug.cpp
@@ -44,6 +44,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.hpp"
#include "services/heapDumper.hpp"
#include "utilities/defaultStream.hpp"
@@ -52,19 +53,15 @@
#include "utilities/vmError.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
-# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
-# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
-# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
-# include "thread_bsd.inline.hpp"
#endif
#ifndef ASSERT
diff --git a/src/share/vm/utilities/events.cpp b/src/share/vm/utilities/events.cpp
index b2f292f26..8ccd65095 100644
--- a/src/share/vm/utilities/events.cpp
+++ b/src/share/vm/utilities/events.cpp
@@ -26,22 +26,11 @@
#include "memory/allocation.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/osThread.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/threadLocalStorage.hpp"
#include "runtime/timer.hpp"
#include "utilities/events.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
EventLog* Events::_logs = NULL;
diff --git a/src/share/vm/utilities/exceptions.cpp b/src/share/vm/utilities/exceptions.cpp
index 756c537d7..6083c555c 100644
--- a/src/share/vm/utilities/exceptions.cpp
+++ b/src/share/vm/utilities/exceptions.cpp
@@ -30,21 +30,10 @@
#include "runtime/init.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
#include "utilities/events.hpp"
#include "utilities/exceptions.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Implementation of ThreadShadow
diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp
index 9c51c1d58..e00be9032 100644
--- a/src/share/vm/utilities/globalDefinitions.hpp
+++ b/src/share/vm/utilities/globalDefinitions.hpp
@@ -1280,4 +1280,12 @@ inline int build_int_from_shorts( jushort low, jushort high ) {
#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
+// Dereference vptr
+// All C++ compilers that we know of have the vtbl pointer in the first
+// word. If there are exceptions, this function needs to be made compiler
+// specific.
+static inline void* dereference_vptr(void* addr) {
+ return *(void**)addr;
+}
+
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_HPP
diff --git a/src/share/vm/utilities/growableArray.cpp b/src/share/vm/utilities/growableArray.cpp
index d8aa925cb..d6dc256a2 100644
--- a/src/share/vm/utilities/growableArray.cpp
+++ b/src/share/vm/utilities/growableArray.cpp
@@ -24,19 +24,9 @@
#include "precompiled.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/growableArray.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+
#ifdef ASSERT
void GenericGrowableArray::set_nesting() {
if (on_stack()) {
diff --git a/src/share/vm/utilities/preserveException.hpp b/src/share/vm/utilities/preserveException.hpp
index 7737a3761..58f92a876 100644
--- a/src/share/vm/utilities/preserveException.hpp
+++ b/src/share/vm/utilities/preserveException.hpp
@@ -26,18 +26,7 @@
#define SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
#include "runtime/handles.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
+#include "runtime/thread.inline.hpp"
// This file provides more support for exception handling; see also exceptions.hpp
class PreserveExceptionMark {
diff --git a/src/share/vm/utilities/taskqueue.cpp b/src/share/vm/utilities/taskqueue.cpp
index df61a559e..fbb035adf 100644
--- a/src/share/vm/utilities/taskqueue.cpp
+++ b/src/share/vm/utilities/taskqueue.cpp
@@ -25,21 +25,10 @@
#include "precompiled.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/os.hpp"
+#include "runtime/thread.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/stack.inline.hpp"
#include "utilities/taskqueue.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
#ifdef TRACESPINNING
uint ParallelTaskTerminator::_total_yields = 0;
diff --git a/src/share/vm/utilities/workgroup.hpp b/src/share/vm/utilities/workgroup.hpp
index 362640f47..b82478eac 100644
--- a/src/share/vm/utilities/workgroup.hpp
+++ b/src/share/vm/utilities/workgroup.hpp
@@ -25,19 +25,8 @@
#ifndef SHARE_VM_UTILITIES_WORKGROUP_HPP
#define SHARE_VM_UTILITIES_WORKGROUP_HPP
+#include "runtime/thread.inline.hpp"
#include "utilities/taskqueue.hpp"
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_solaris
-# include "thread_solaris.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_windows
-# include "thread_windows.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_bsd
-# include "thread_bsd.inline.hpp"
-#endif
// Task class hierarchy:
// AbstractGangTask
diff --git a/test/runtime/8003720/Asmator.java b/test/runtime/8003720/Asmator.java
new file mode 100644
index 000000000..3d9a5ca13
--- /dev/null
+++ b/test/runtime/8003720/Asmator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ */
+
+import jdk.internal.org.objectweb.asm.*;
+
+class Asmator {
+ static byte[] fixup(byte[] buf) throws java.io.IOException {
+ ClassReader cr = new ClassReader(buf);
+ ClassWriter cw = new ClassWriter(0);
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, cw) {
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ MethodVisitor mv = super.visitMethod(access,
+ name,
+ desc,
+ signature,
+ exceptions);
+ if (mv == null) return null;
+ if (name.equals("callme")) {
+ // make receiver go dead!
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ mv.visitVarInsn(Opcodes.ASTORE, 0);
+ }
+ return mv;
+ }
+ };
+ cr.accept(cv, 0);
+ return cw.toByteArray();
+ }
+}
diff --git a/test/runtime/8003720/Test8003720.java b/test/runtime/8003720/Test8003720.java
new file mode 100644
index 000000000..88682712a
--- /dev/null
+++ b/test/runtime/8003720/Test8003720.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8003720
+ * @summary Method in interpreter stack frame can be deallocated
+ * @compile -XDignore.symbol.file -source 1.7 -target 1.7 Victim.java
+ * @run main/othervm -Xverify:all -Xint Test8003720
+ */
+
+// Attempts to make the JVM unload a class while still executing one of its methods.
+public class Test8003720 {
+ final static String VICTIM_CLASS_NAME = "Victim";
+ final static boolean QUIET = true;
+ final static long DURATION = 30000;
+
+ public interface CallMe { void callme(); }
+
+ public static void main(String... av) throws Throwable {
+ newVictimClassLoader();
+ System.gc();
+
+ newVictimClass();
+ System.gc();
+
+ newVictimInstance();
+ System.gc();
+
+ ((CallMe)newVictimInstance()).callme();
+ }
+
+ public static Object newVictimInstance() throws Throwable {
+ return newVictimClass().newInstance();
+ }
+
+ public static Class<?> newVictimClass() throws Throwable {
+ return Class.forName(VICTIM_CLASS_NAME, true, new VictimClassLoader());
+ }
+
+ public static ClassLoader newVictimClassLoader() throws Throwable {
+ return new VictimClassLoader();
+ }
+
+ public static void println(String line) {
+ if (!QUIET) {
+ System.out.println(line);
+ }
+ }
+}
diff --git a/test/runtime/8003720/Victim.java b/test/runtime/8003720/Victim.java
new file mode 100644
index 000000000..c671e6030
--- /dev/null
+++ b/test/runtime/8003720/Victim.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ *
+ */
+
+public class Victim implements Test8003720.CallMe {
+ public void callme() {
+ // note: Victim.this is dead here
+ Test8003720.println("executing in loader=" + Victim.class.getClassLoader());
+
+ long now = System.currentTimeMillis();
+
+ while ((System.currentTimeMillis() - now) < Test8003720.DURATION) {
+ long count = VictimClassLoader.counter++;
+ if (count % 1000000 == 0) System.gc();
+ if (count % 16180000 == 0) blurb();
+ new Object[1].clone();
+ }
+ }
+ static void blurb() {
+ Test8003720.println("count=" + VictimClassLoader.counter);
+ }
+ static {
+ blather();
+ }
+ static void blather() {
+ new java.util.ArrayList<Object>(1000000);
+ Class<Victim> c = Victim.class;
+ Test8003720.println("initializing " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
+ }
+}
diff --git a/test/runtime/8003720/VictimClassLoader.java b/test/runtime/8003720/VictimClassLoader.java
new file mode 100644
index 000000000..3505f7832
--- /dev/null
+++ b/test/runtime/8003720/VictimClassLoader.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ *
+ */
+
+public class VictimClassLoader extends ClassLoader {
+ public static long counter = 0;
+
+ private int which = (int) ++counter;
+
+ protected VictimClassLoader() {
+ super(VictimClassLoader.class.getClassLoader());
+ }
+
+ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class c;
+ if (!name.endsWith("Victim")) {
+ c = super.loadClass(name, resolve);
+ return c;
+ }
+
+ c = findLoadedClass(name);
+ if (c != null) {
+ return c;
+ }
+
+ byte[] buf = readClassFile(name);
+ c = defineClass(name, buf, 0, buf.length);
+ resolveClass(c);
+
+ if (c.getClassLoader() != this) {
+ throw new AssertionError();
+ }
+
+ Test8003720.println("loaded " + c + "#" + System.identityHashCode(c) + " in " + c.getClassLoader());
+ return c;
+ }
+
+ static byte[] readClassFile(String name) {
+ try {
+ String rname = name.substring(name.lastIndexOf('.') + 1) + ".class";
+ java.net.URL url = VictimClassLoader.class.getResource(rname);
+ Test8003720.println("found " + rname + " = " + url);
+
+ java.net.URLConnection connection = url.openConnection();
+ int contentLength = connection.getContentLength();
+ byte[] buf = readFully(connection.getInputStream(), contentLength);
+
+ return Asmator.fixup(buf);
+ } catch (java.io.IOException ex) {
+ throw new Error(ex);
+ }
+ }
+
+ static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException {
+ // Warning here:
+ return sun.misc.IOUtils.readFully(in, len, true);
+ }
+
+ public void finalize() {
+ Test8003720.println("Goodbye from " + this);
+ }
+
+ public String toString() {
+ return "VictimClassLoader#" + which;
+ }
+}