aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ. Duke <duke@openjdk.org>2017-07-05 20:07:33 +0200
committerJ. Duke <duke@openjdk.org>2017-07-05 20:07:33 +0200
commitc391740612660488f7b90e2250c50255767e59e7 (patch)
tree81052c753fd61314441ac7616a4136ae825bec9b
parentb227f09f2806aa68e4cd482c8694d9997cda3e09 (diff)
parent46d13b99d3caadcc3ef9b4daa8294a30a3fbe321 (diff)
downloadlibcore-c391740612660488f7b90e2250c50255767e59e7.tar.gz
Merge
-rw-r--r--.hgtags-top-repo1
-rw-r--r--hotspot/.hgtags1
-rw-r--r--hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CodeCacheSweeperThread.java41
-rw-r--r--hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java7
-rw-r--r--hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java15
-rw-r--r--hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java5
-rw-r--r--hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js1
-rw-r--r--hotspot/make/solaris/makefiles/vm.make2
-rw-r--r--hotspot/make/windows/makefiles/compile.make2
-rw-r--r--hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp2
-rw-r--r--hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp8
-rw-r--r--hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp2
-rw-r--r--hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp2
-rw-r--r--hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp2
-rw-r--r--hotspot/src/cpu/x86/vm/vm_version_x86.cpp9
-rw-r--r--hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp2
-rw-r--r--hotspot/src/os/aix/vm/os_aix.cpp17
-rw-r--r--hotspot/src/os/aix/vm/os_aix.inline.hpp78
-rw-r--r--hotspot/src/os/aix/vm/perfMemory_aix.cpp4
-rw-r--r--hotspot/src/os/bsd/vm/os_bsd.cpp65
-rw-r--r--hotspot/src/os/bsd/vm/os_bsd.inline.hpp77
-rw-r--r--hotspot/src/os/bsd/vm/perfMemory_bsd.cpp4
-rw-r--r--hotspot/src/os/linux/vm/os_linux.cpp248
-rw-r--r--hotspot/src/os/linux/vm/os_linux.inline.hpp78
-rw-r--r--hotspot/src/os/linux/vm/perfMemory_linux.cpp4
-rw-r--r--hotspot/src/os/posix/vm/os_posix.cpp5
-rw-r--r--hotspot/src/os/solaris/vm/os_solaris.cpp142
-rw-r--r--hotspot/src/os/solaris/vm/os_solaris.inline.hpp28
-rw-r--r--hotspot/src/os/solaris/vm/perfMemory_solaris.cpp4
-rw-r--r--hotspot/src/os/windows/vm/attachListener_windows.cpp5
-rw-r--r--hotspot/src/os/windows/vm/os_windows.cpp471
-rw-r--r--hotspot/src/os/windows/vm/os_windows.hpp1
-rw-r--r--hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp2
-rw-r--r--hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp185
-rw-r--r--hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java2
-rw-r--r--hotspot/src/share/vm/ci/ciEnv.cpp3
-rw-r--r--hotspot/src/share/vm/classfile/classFileParser.cpp20
-rw-r--r--hotspot/src/share/vm/classfile/classFileParser.hpp2
-rw-r--r--hotspot/src/share/vm/classfile/classLoaderData.cpp8
-rw-r--r--hotspot/src/share/vm/classfile/classLoaderData.hpp6
-rw-r--r--hotspot/src/share/vm/classfile/vmSymbols.hpp3
-rw-r--r--hotspot/src/share/vm/code/codeBlob.cpp18
-rw-r--r--hotspot/src/share/vm/code/codeBlob.hpp2
-rw-r--r--hotspot/src/share/vm/code/codeCache.cpp79
-rw-r--r--hotspot/src/share/vm/code/codeCache.hpp23
-rw-r--r--hotspot/src/share/vm/code/nmethod.cpp5
-rw-r--r--hotspot/src/share/vm/code/vtableStubs.cpp1
-rw-r--r--hotspot/src/share/vm/compiler/compileBroker.cpp146
-rw-r--r--hotspot/src/share/vm/compiler/compileBroker.hpp11
-rw-r--r--hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp85
-rw-r--r--hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp3
-rw-r--r--hotspot/src/share/vm/interpreter/interpreterRuntime.cpp1
-rw-r--r--hotspot/src/share/vm/memory/heap.cpp22
-rw-r--r--hotspot/src/share/vm/memory/heap.hpp6
-rw-r--r--hotspot/src/share/vm/memory/metaspace.cpp10
-rw-r--r--hotspot/src/share/vm/memory/metaspaceShared.cpp13
-rw-r--r--hotspot/src/share/vm/memory/metaspaceShared.hpp15
-rw-r--r--hotspot/src/share/vm/oops/constMethod.hpp2
-rw-r--r--hotspot/src/share/vm/oops/constantPool.cpp49
-rw-r--r--hotspot/src/share/vm/oops/constantPool.hpp11
-rw-r--r--hotspot/src/share/vm/oops/instanceKlass.cpp134
-rw-r--r--hotspot/src/share/vm/oops/instanceKlass.hpp29
-rw-r--r--hotspot/src/share/vm/oops/method.cpp184
-rw-r--r--hotspot/src/share/vm/oops/method.hpp9
-rw-r--r--hotspot/src/share/vm/oops/objArrayOop.hpp12
-rw-r--r--hotspot/src/share/vm/oops/typeArrayOop.hpp2
-rw-r--r--hotspot/src/share/vm/opto/c2_globals.hpp3
-rw-r--r--hotspot/src/share/vm/opto/callnode.cpp3
-rw-r--r--hotspot/src/share/vm/opto/coalesce.cpp12
-rw-r--r--hotspot/src/share/vm/opto/compile.cpp1
-rw-r--r--hotspot/src/share/vm/opto/escape.cpp74
-rw-r--r--hotspot/src/share/vm/opto/escape.hpp78
-rw-r--r--hotspot/src/share/vm/opto/lcm.cpp8
-rw-r--r--hotspot/src/share/vm/opto/library_call.cpp91
-rw-r--r--hotspot/src/share/vm/opto/memnode.cpp10
-rw-r--r--hotspot/src/share/vm/opto/mulnode.cpp2
-rw-r--r--hotspot/src/share/vm/opto/output.cpp3
-rw-r--r--hotspot/src/share/vm/prims/jni.cpp10
-rw-r--r--hotspot/src/share/vm/prims/jvm.cpp13
-rw-r--r--hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp22
-rw-r--r--hotspot/src/share/vm/prims/jvmtiEnv.cpp32
-rw-r--r--hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp622
-rw-r--r--hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp17
-rw-r--r--hotspot/src/share/vm/prims/methodHandles.cpp35
-rw-r--r--hotspot/src/share/vm/prims/methodHandles.hpp2
-rw-r--r--hotspot/src/share/vm/prims/unsafe.cpp3
-rw-r--r--hotspot/src/share/vm/prims/whitebox.cpp84
-rw-r--r--hotspot/src/share/vm/runtime/arguments.cpp23
-rw-r--r--hotspot/src/share/vm/runtime/deoptimization.cpp2
-rw-r--r--hotspot/src/share/vm/runtime/globals.cpp39
-rw-r--r--hotspot/src/share/vm/runtime/globals.hpp45
-rw-r--r--hotspot/src/share/vm/runtime/interfaceSupport.cpp24
-rw-r--r--hotspot/src/share/vm/runtime/java.cpp20
-rw-r--r--hotspot/src/share/vm/runtime/mutexLocker.cpp4
-rw-r--r--hotspot/src/share/vm/runtime/mutexLocker.hpp2
-rw-r--r--hotspot/src/share/vm/runtime/os.cpp17
-rw-r--r--hotspot/src/share/vm/runtime/os.hpp19
-rw-r--r--hotspot/src/share/vm/runtime/sharedRuntime.cpp5
-rw-r--r--hotspot/src/share/vm/runtime/signature.cpp2
-rw-r--r--hotspot/src/share/vm/runtime/signature.hpp2
-rw-r--r--hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp13
-rw-r--r--hotspot/src/share/vm/runtime/sweeper.cpp205
-rw-r--r--hotspot/src/share/vm/runtime/sweeper.hpp14
-rw-r--r--hotspot/src/share/vm/runtime/thread.cpp19
-rw-r--r--hotspot/src/share/vm/runtime/thread.hpp42
-rw-r--r--hotspot/src/share/vm/runtime/vmStructs.cpp1
-rw-r--r--hotspot/src/share/vm/runtime/vm_operations.cpp3
-rw-r--r--hotspot/src/share/vm/runtime/vm_operations.hpp8
-rw-r--r--hotspot/src/share/vm/services/jmm.h5
-rw-r--r--hotspot/src/share/vm/services/mallocTracker.cpp30
-rw-r--r--hotspot/src/share/vm/services/mallocTracker.hpp64
-rw-r--r--hotspot/src/share/vm/services/mallocTracker.inline.hpp7
-rw-r--r--hotspot/src/share/vm/services/management.cpp7
-rw-r--r--hotspot/src/share/vm/services/runtimeService.cpp11
-rw-r--r--hotspot/src/share/vm/services/runtimeService.hpp1
-rw-r--r--hotspot/src/share/vm/services/threadService.cpp2
-rw-r--r--hotspot/src/share/vm/trace/trace.xml1
-rw-r--r--hotspot/src/share/vm/utilities/debug.cpp8
-rw-r--r--hotspot/src/share/vm/utilities/debug.hpp3
-rw-r--r--hotspot/src/share/vm/utilities/dtrace_disabled.hpp2
-rw-r--r--hotspot/src/share/vm/utilities/globalDefinitions.hpp2
-rw-r--r--hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp8
-rw-r--r--hotspot/src/share/vm/utilities/ostream.cpp21
-rw-r--r--hotspot/src/share/vm/utilities/vmError.cpp4
-rw-r--r--hotspot/test/TEST.ROOT1
-rw-r--r--hotspot/test/TEST.groups18
-rw-r--r--hotspot/test/compiler/6896617/Test6896617.java17
-rw-r--r--hotspot/test/compiler/7100757/Test7100757.java10
-rw-r--r--hotspot/test/compiler/7177917/Test7177917.java15
-rw-r--r--hotspot/test/compiler/7184394/TestAESBase.java10
-rw-r--r--hotspot/test/compiler/7184394/TestAESMain.java1
-rw-r--r--hotspot/test/compiler/8005956/PolynomialRoot.java15
-rw-r--r--hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java63
-rw-r--r--hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java14
-rw-r--r--hotspot/test/compiler/debug/TraceIterativeGVN.java39
-rw-r--r--hotspot/test/compiler/exceptions/CatchInlineExceptions.java2
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/BMITestRunner.java25
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestAndnI.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestAndnL.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java6
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java5
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java5
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java5
-rw-r--r--hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java5
-rw-r--r--hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java346
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java8
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java8
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java8
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java3
-rw-r--r--hotspot/test/compiler/intrinsics/mathexact/Verify.java17
-rw-r--r--hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java26
-rw-r--r--hotspot/test/compiler/startup/SmallCodeCacheStartup.java12
-rw-r--r--hotspot/test/compiler/types/correctness/OffTest.java13
-rw-r--r--hotspot/test/compiler/unsafe/UnsafeRaw.java2
-rw-r--r--hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java166
-rw-r--r--hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java95
-rw-r--r--hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java7
-rw-r--r--hotspot/test/gc/arguments/TestUseNUMAInterleaving.java60
-rw-r--r--hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java1
-rw-r--r--hotspot/test/runtime/7194254/Test7194254.java1
-rw-r--r--hotspot/test/runtime/NMT/MallocSiteHashOverflow.java39
-rw-r--r--hotspot/test/runtime/RedefineTests/RedefineAnnotations.java410
-rw-r--r--hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java9
-rw-r--r--hotspot/test/runtime/lambda-features/InvokespecialInterface.java4
-rw-r--r--hotspot/test/runtime/lambda-features/TestInterfaceInit.java87
-rw-r--r--hotspot/test/runtime/lambda-features/TestInterfaceOrder.java88
-rw-r--r--hotspot/test/runtime/reflect/ArrayGetIntException.java76
-rw-r--r--hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java5
-rw-r--r--hotspot/test/serviceability/threads/TestFalseDeadLock.java7
-rw-r--r--hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java43
-rw-r--r--hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java4
-rw-r--r--hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java5
-rw-r--r--hotspot/test/testlibrary_tests/RandomGeneratorTest.java154
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java2
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java2
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java2
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java2
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java2
-rw-r--r--hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java49
-rw-r--r--jdk/.hgtags1
-rw-r--r--jdk/src/java.base/share/classes/java/lang/reflect/Executable.java49
-rw-r--r--jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/Label.java8
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java4
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java4
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java6
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java4
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java6
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java4
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java8
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java6
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java2
-rw-r--r--jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java6
-rw-r--r--jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c4
-rw-r--r--jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java2
-rw-r--r--jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m2
-rw-r--r--jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m5
-rw-r--r--jdk/src/java.desktop/share/classes/java/awt/Component.java2
-rw-r--r--jdk/src/java.desktop/share/classes/java/awt/Robot.java23
-rw-r--r--jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java3
-rw-r--r--jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java34
-rw-r--r--jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java60
-rw-r--r--jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java5
-rw-r--r--jdk/src/java.management/share/classes/sun/management/Flag.java3
-rw-r--r--jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java23
-rw-r--r--jdk/src/java.management/share/native/include/jmm.h5
-rw-r--r--jdk/src/java.management/share/native/libmanagement/Flag.c16
-rw-r--r--jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c1584
-rw-r--r--jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c12
-rw-r--r--jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java14
-rw-r--r--jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m5
-rw-r--r--jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java8
-rw-r--r--jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java27
-rw-r--r--jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java65
-rw-r--r--jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java11
-rw-r--r--jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java12
-rw-r--r--jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html21
-rw-r--r--jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java247
-rw-r--r--jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy3
-rw-r--r--jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java307
-rw-r--r--jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java483
-rw-r--r--jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java352
-rw-r--r--jdk/test/java/awt/geom/AffineTransform/TestSerialization.java159
-rw-r--r--jdk/test/java/awt/geom/AffineTransform/serial.1.2bin0 -> 410 bytes
-rw-r--r--jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java68
-rw-r--r--jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java113
-rw-r--r--jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java2
-rw-r--r--jdk/test/java/lang/ProcessBuilder/Basic.java21
-rw-r--r--jdk/test/java/lang/reflect/Generics/ThreadSafety.java129
-rw-r--r--jdk/test/java/lang/reflect/Parameter/InnerClassToString.java95
-rw-r--r--jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java1318
-rw-r--r--jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java211
-rw-r--r--jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java199
-rw-r--r--jdk/test/javax/sql/testng/util/StubBaseRowSet.java1001
-rw-r--r--jdk/test/javax/sql/testng/util/StubNClob.java29
-rw-r--r--jdk/test/javax/sql/testng/util/StubRowId.java (renamed from hotspot/test/runtime/NMT/UnsafeMallocLimit.java)30
-rw-r--r--jdk/test/javax/sql/testng/util/StubSQLXML.java81
-rw-r--r--jdk/test/javax/sql/testng/util/SuperHero.java6
-rw-r--r--jdk/test/javax/sql/testng/util/TestRowSetListener.java64
-rw-r--r--jdk/test/javax/sql/testng/util/TestSQLDataImpl.java125
-rw-r--r--jdk/test/javax/swing/JComboBox/8057893/bug8057893.java84
-rw-r--r--jdk/test/javax/swing/JTable/4222153/bug4222153.html31
-rw-r--r--jdk/test/javax/swing/JTable/4222153/bug4222153.java48
-rw-r--r--jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html43
-rw-r--r--jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java170
-rw-r--r--jdk/test/javax/swing/JTable/TAB/TAB.html43
-rw-r--r--jdk/test/javax/swing/JTable/TAB/TAB.java169
-rw-r--r--jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java52
-rw-r--r--jdk/test/lib/testlibrary/ExtendedRobot.java9
-rw-r--r--jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java1
-rw-r--r--jdk/test/sun/security/pkcs11/Cipher/JNICheck.java (renamed from hotspot/test/runtime/NMT/UnsafeMallocLimit2.java)50
-rw-r--r--jdk/test/sun/security/tools/keytool/ListKeychainStore.sh27
-rw-r--r--make/CompileJavaModules.gmk13
307 files changed, 11453 insertions, 2819 deletions
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 72d6aa0a02b..a5f58b034a6 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -281,3 +281,4 @@ c173ba994245380fb11ef077d1e59823386840eb jdk9-b35
201d4e235d597a25a2d3ee1404394789ba386119 jdk9-b36
723a67b0c442391447b1d8aad8b249d06d1032e8 jdk9-b37
d42c0a90afc3c66ca87543076ec9aafd4b4680de jdk9-b38
+512dbbeb1730edcebfec873fc3f1455660b32000 jdk9-b39
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 4d511d872c6..ec88eae37e7 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -441,3 +441,4 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32
464ab653fbb17eb518d8ef60f8df301de7ef00d0 jdk9-b36
b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37
c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
+9cb75e5e394827ccbaf2e15524108a412dc4ddc5 jdk9-b39
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CodeCacheSweeperThread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CodeCacheSweeperThread.java
new file mode 100644
index 00000000000..72877516b65
--- /dev/null
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CodeCacheSweeperThread.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.runtime;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.types.*;
+
+public class CodeCacheSweeperThread extends JavaThread {
+ public CodeCacheSweeperThread(Address addr) {
+ super(addr);
+ }
+
+ public boolean isJavaThread() { return false; }
+ public boolean isHiddenFromExternalView() { return true; }
+ public boolean isCodeCacheSweeperThread() { return true; }
+
+}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
index 926c11c4bad..a6f04042184 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
@@ -118,9 +118,10 @@ public class JavaThread extends Thread {
return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr);
}
- /** NOTE: for convenience, this differs in definition from the
- underlying VM. Only "pure" JavaThreads return true;
- CompilerThreads and JVMDIDebuggerThreads return false. FIXME:
+ /** NOTE: for convenience, this differs in definition from the underlying VM.
+ Only "pure" JavaThreads return true; CompilerThreads, the CodeCacheSweeperThread,
+ JVMDIDebuggerThreads return false.
+ FIXME:
consider encapsulating platform-specific functionality in an
object instead of using inheritance (which is the primary reason
we can't traverse CompilerThreads, etc; didn't want to have, for
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java
index 03c426ba84a..5b47b2a40e2 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java
@@ -111,14 +111,15 @@ public class Thread extends VMObject {
return allocatedBytesField.getValue(addr);
}
- public boolean isVMThread() { return false; }
- public boolean isJavaThread() { return false; }
- public boolean isCompilerThread() { return false; }
- public boolean isHiddenFromExternalView() { return false; }
- public boolean isJvmtiAgentThread() { return false; }
- public boolean isWatcherThread() { return false; }
+ public boolean isVMThread() { return false; }
+ public boolean isJavaThread() { return false; }
+ public boolean isCompilerThread() { return false; }
+ public boolean isCodeCacheSweeperThread() { return false; }
+ public boolean isHiddenFromExternalView() { return false; }
+ public boolean isJvmtiAgentThread() { return false; }
+ public boolean isWatcherThread() { return false; }
public boolean isConcurrentMarkSweepThread() { return false; }
- public boolean isServiceThread() { return false; }
+ public boolean isServiceThread() { return false; }
/** Memory operations */
public void oopsDo(AddressVisitor oopVisitor) {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
index b4b5903d139..3b6a53c5302 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
@@ -120,6 +120,7 @@ public class Threads {
virtualConstructor.addMapping("JavaThread", JavaThread.class);
if (!VM.getVM().isCore()) {
virtualConstructor.addMapping("CompilerThread", CompilerThread.class);
+ virtualConstructor.addMapping("CodeCacheSweeperThread", CodeCacheSweeperThread.class);
}
// for now, use JavaThread itself. fix it later with appropriate class if needed
virtualConstructor.addMapping("SurrogateLockerThread", JavaThread.class);
@@ -164,7 +165,7 @@ public class Threads {
return thread;
} catch (Exception e) {
throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
- " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, or SurrogateLockerThread)", e);
+ " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, SurrogateLockerThread, or CodeCacheSweeperThread)", e);
}
}
@@ -201,7 +202,7 @@ public class Threads {
public List getPendingThreads(ObjectMonitor monitor) {
List pendingThreads = new ArrayList();
for (JavaThread thread = first(); thread != null; thread = thread.next()) {
- if (thread.isCompilerThread()) {
+ if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
continue;
}
ObjectMonitor pending = thread.getCurrentPendingMonitor();
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
index 14a8e9aa137..58515933a3e 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
@@ -836,6 +836,7 @@ vmType2Class["InterpreterCodelet"] = sapkg.interpreter.InterpreterCodelet;
// Java Threads
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
+vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
vmType2Class["SurrogateLockerThread"] = sapkg.runtime.JavaThread;
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make
index 59f2b575642..da906bcfad8 100644
--- a/hotspot/make/solaris/makefiles/vm.make
+++ b/hotspot/make/solaris/makefiles/vm.make
@@ -143,7 +143,7 @@ else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
endif # sparcWorks
-LIBS += -lkstat -lpicl
+LIBS += -lkstat
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM
diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make
index a4d1c0d4c3e..8523bfd2eb6 100644
--- a/hotspot/make/windows/makefiles/compile.make
+++ b/hotspot/make/windows/makefiles/compile.make
@@ -158,7 +158,7 @@ LD=link.exe
!endif
LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
- uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \
+ uuid.lib Wsock32.lib winmm.lib version.lib /nologo /machine:$(MACHINE) /opt:REF \
/opt:ICF,8
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
LD_FLAGS= $(LD_FLAGS) /map /debug
diff --git a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp
index 8cbe422a4af..0e1d6c992cd 100644
--- a/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interpreterRT_sparc.cpp
@@ -237,7 +237,7 @@ IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(
// handle arguments
// Warning: We use reg arg slot 00 temporarily to return the RegArgSignature
// back to the code that pops the arguments into the CPU registers
- SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate(UCONST64(-1));
+ SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate((uint64_t)CONST64(-1));
// return result handler
return Interpreter::result_handler(m->result_type());
IRT_END
diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
index 62bb56fe97f..6235c90df13 100644
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
@@ -60,10 +60,10 @@ static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
// Static initialization during VM startup.
-static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
-static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
-static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
-static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
+static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
+static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
+static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], (jlong)UCONST64(0x8000000080000000), (jlong)UCONST64(0x8000000080000000));
+static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], (jlong)UCONST64(0x8000000000000000), (jlong)UCONST64(0x8000000000000000));
diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
index 580964a7cd9..a0d54665375 100644
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
@@ -1597,7 +1597,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
__ movl(rdx, 0x80000000);
__ xorl(rax, rax);
#else
- __ mov64(rax, CONST64(0x8000000000000000));
+ __ mov64(rax, UCONST64(0x8000000000000000));
#endif // _LP64
__ jmp(do_return);
diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp
index eb66640c338..0e68dd011d3 100644
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_32.cpp
@@ -135,7 +135,7 @@ IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread
methodHandle m(thread, (Method*)method);
assert(m->is_native(), "sanity check");
// handle arguments
- SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
+ SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
// return result handler
return Interpreter::result_handler(m->result_type());
IRT_END
diff --git a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp
index 959ed6e3208..40cc9d71aa7 100644
--- a/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpp
@@ -487,7 +487,7 @@ IRT_ENTRY(address,
assert(m->is_native(), "sanity check");
// handle arguments
- SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
+ SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
// return result handler
return Interpreter::result_handler(m->result_type());
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
index e73f93c705f..8d575c2d4bd 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
@@ -865,14 +865,19 @@ void VM_Version::get_processor_features() {
if (supports_bmi1()) {
// tzcnt does not require VEX prefix
if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstruction)) {
- UseCountTrailingZerosInstruction = true;
+ if (!UseBMI1Instructions && !FLAG_IS_DEFAULT(UseBMI1Instructions)) {
+ // Don't use tzcnt if BMI1 is switched off on command line.
+ UseCountTrailingZerosInstruction = false;
+ } else {
+ UseCountTrailingZerosInstruction = true;
+ }
}
} else if (UseCountTrailingZerosInstruction) {
warning("tzcnt instruction is not available on this CPU");
FLAG_SET_DEFAULT(UseCountTrailingZerosInstruction, false);
}
- // BMI instructions use an encoding with VEX prefix.
+ // BMI instructions (except tzcnt) use an encoding with VEX prefix.
// VEX prefix is generated only when AVX > 0.
if (supports_bmi1() && supports_avx()) {
if (FLAG_IS_DEFAULT(UseBMI1Instructions)) {
diff --git a/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp b/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp
index e23e3eaa93b..8fb45375262 100644
--- a/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp
@@ -155,7 +155,7 @@ IRT_ENTRY(address,
intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf);
- sshg.generate(UCONST64(-1));
+ sshg.generate((uint64_t)CONST64(-1));
SignatureHandler *handler = sshg.handler();
handler->finalize();
diff --git a/hotspot/src/os/aix/vm/os_aix.cpp b/hotspot/src/os/aix/vm/os_aix.cpp
index bec34838920..d0765c4c1fc 100644
--- a/hotspot/src/os/aix/vm/os_aix.cpp
+++ b/hotspot/src/os/aix/vm/os_aix.cpp
@@ -1641,7 +1641,8 @@ void os::jvm_path(char *buf, jint buflen) {
char* rp = realpath((char *)dlinfo.dli_fname, buf);
assert(rp != NULL, "error in realpath(): maybe the 'path' argument is too long?");
- strcpy(saved_jvm_path, buf);
+ strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path));
+ saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0';
}
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
@@ -3829,11 +3830,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if (!guard_memory((char*)_polling_page, Aix::page_size())) {
@@ -4137,15 +4133,6 @@ int os::available(int fd, jlong *bytes) {
return 1;
}
-int os::socket_available(int fd, jint *pbytes) {
- // Linux doc says EINTR not returned, unlike Solaris
- int ret = ::ioctl(fd, FIONREAD, pbytes);
-
- //%% note ioctl can return 0 when successful, JVM_SocketAvailable
- // is expected to return 0 on failure and 1 on success to the jdk.
- return (ret < 0) ? 0 : 1;
-}
-
// Map a block of memory.
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
char *addr, size_t bytes, bool read_only,
diff --git a/hotspot/src/os/aix/vm/os_aix.inline.hpp b/hotspot/src/os/aix/vm/os_aix.inline.hpp
index bb3232bfbc7..5602342b4ff 100644
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp
+++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp
@@ -178,92 +178,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
return os::send(fd, buf, nBytes, flags);
}
-inline int os::timeout(int fd, long timeout) {
- julong prevtime,newtime;
- struct timeval t;
-
- gettimeofday(&t, NULL);
- prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
-
- for(;;) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN | POLLERR;
-
- int res = ::poll(&pfd, 1, timeout);
-
- if (res == OS_ERR && errno == EINTR) {
-
- // On Linux any value < 0 means "forever"
-
- if(timeout >= 0) {
- gettimeofday(&t, NULL);
- newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if(timeout <= 0)
- return OS_OK;
- prevtime = newtime;
- }
- } else
- return res;
- }
-}
-
-inline int os::listen(int fd, int count) {
- return ::listen(fd, count);
-}
-
inline int os::connect(int fd, struct sockaddr* him, socklen_t len) {
RESTARTABLE_RETURN_INT(::connect(fd, him, len));
}
-inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
- // Linux doc says this can't return EINTR, unlike accept() on Solaris.
- // But see attachListener_linux.cpp, LinuxAttachListener::dequeue().
- return (int)::accept(fd, him, len);
-}
-
-inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags,
- sockaddr* from, socklen_t* fromlen) {
- RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen));
-}
-
-inline int os::sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr* to, socklen_t tolen) {
- RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen));
-}
-
-inline int os::socket_shutdown(int fd, int howto) {
- return ::shutdown(fd, howto);
-}
-
-inline int os::bind(int fd, struct sockaddr* him, socklen_t len) {
- return ::bind(fd, him, len);
-}
-
-inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
- return ::getsockname(fd, him, len);
-}
-
-inline int os::get_host_name(char* name, int namelen) {
- return ::gethostname(name, namelen);
-}
-
inline struct hostent* os::get_host_by_name(char* name) {
return ::gethostbyname(name);
}
-inline int os::get_sock_opt(int fd, int level, int optname,
- char* optval, socklen_t* optlen) {
- return ::getsockopt(fd, level, optname, optval, optlen);
-}
-
-inline int os::set_sock_opt(int fd, int level, int optname,
- const char* optval, socklen_t optlen) {
- return ::setsockopt(fd, level, optname, optval, optlen);
-}
-
inline bool os::supports_monotonic_clock() {
// mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments)
return true;
diff --git a/hotspot/src/os/aix/vm/perfMemory_aix.cpp b/hotspot/src/os/aix/vm/perfMemory_aix.cpp
index 36644f0f679..8850fe705e2 100644
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp
@@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
if (!is_directory_secure(dirname)) {
// the directory is not a secure directory
+ os::closedir(dirp);
return;
}
@@ -853,6 +854,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
//
if (!is_directory_secure(dirname)) {
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ if (luser != user) {
+ FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ }
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
}
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 95e026651ac..a42e3bf19ba 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -1875,6 +1875,7 @@ void os::jvm_path(char *buf, jint buflen) {
}
strncpy(saved_jvm_path, buf, MAXPATHLEN);
+ saved_jvm_path[MAXPATHLEN - 1] = '\0';
}
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
@@ -3635,9 +3636,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) { }
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if (!guard_memory((char*)_polling_page, Bsd::page_size())) {
@@ -3958,21 +3956,6 @@ int os::available(int fd, jlong *bytes) {
return 1;
}
-int os::socket_available(int fd, jint *pbytes) {
- if (fd < 0) {
- return OS_OK;
- }
-
- int ret;
-
- RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
-
- //%% note ioctl can return 0 when successful, JVM_SocketAvailable
- // is expected to return 0 on failure and 1 on success to the jdk.
-
- return (ret == OS_ERR) ? 0 : 1;
-}
-
// Map a block of memory.
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
char *addr, size_t bytes, bool read_only,
@@ -4133,7 +4116,18 @@ void os::pause() {
}
-// Refer to the comments in os_solaris.cpp park-unpark.
+// Refer to the comments in os_solaris.cpp park-unpark. The next two
+// comment paragraphs are worth repeating here:
+//
+// Assumption:
+// Only one parker can exist on an event, which is why we allocate
+// them per-thread. Multiple unparkers can coexist.
+//
+// _Event serves as a restricted-range semaphore.
+// -1 : thread is blocked, i.e. there is a waiter
+// 0 : neutral: thread is running or ready,
+// could have been signaled after a wait started
+// 1 : signaled - thread is running or ready
//
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
@@ -4218,6 +4212,11 @@ static struct timespec* compute_abstime(struct timespec* abstime,
}
void os::PlatformEvent::park() { // AKA "down()"
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
// Invariant: Only the thread associated with the Event/PlatformEvent
// may call park().
// TODO: assert that _Assoc != NULL or _Assoc == Self
@@ -4255,6 +4254,11 @@ void os::PlatformEvent::park() { // AKA "down()"
}
int os::PlatformEvent::park(jlong millis) {
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
guarantee(_nParked == 0, "invariant");
int v;
@@ -4318,11 +4322,11 @@ int os::PlatformEvent::park(jlong millis) {
void os::PlatformEvent::unpark() {
// Transitions for _Event:
- // 0 :=> 1
- // 1 :=> 1
- // -1 :=> either 0 or 1; must signal target thread
- // That is, we can safely transition _Event from -1 to either
- // 0 or 1.
+ // 0 => 1 : just return
+ // 1 => 1 : just return
+ // -1 => either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1.
// See also: "Semaphores in Plan 9" by Mullender & Cox
//
// Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -4345,15 +4349,16 @@ void os::PlatformEvent::unpark() {
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
if (AnyWaiters != 0) {
+ // Note that we signal() *after* dropping the lock for "immortal" Events.
+ // This is safe and avoids a common class of futile wakeups. In rare
+ // circumstances this can cause a thread to return prematurely from
+ // cond_{timed}wait() but the spurious wakeup is benign and the victim
+ // will simply re-test the condition and re-park itself.
+ // This provides particular benefit if the underlying platform does not
+ // provide wait morphing.
status = pthread_cond_signal(_cond);
assert_status(status == 0, status, "cond_signal");
}
-
- // Note that we signal() _after dropping the lock for "immortal" Events.
- // This is safe and avoids a common class of futile wakeups. In rare
- // circumstances this can cause a thread to return prematurely from
- // cond_{timed}wait() but the spurious wakeup is benign and the victim will
- // simply re-test the condition and re-park itself.
}
diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
index 1eafb9c76e9..3afb5c21a83 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
@@ -181,91 +181,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
return os::send(fd, buf, nBytes, flags);
}
-inline int os::timeout(int fd, long timeout) {
- julong prevtime,newtime;
- struct timeval t;
-
- gettimeofday(&t, NULL);
- prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
-
- for(;;) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN | POLLERR;
-
- int res = ::poll(&pfd, 1, timeout);
-
- if (res == OS_ERR && errno == EINTR) {
-
- // On Bsd any value < 0 means "forever"
-
- if(timeout >= 0) {
- gettimeofday(&t, NULL);
- newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if(timeout <= 0)
- return OS_OK;
- prevtime = newtime;
- }
- } else
- return res;
- }
-}
-
-inline int os::listen(int fd, int count) {
- return ::listen(fd, count);
-}
-
inline int os::connect(int fd, struct sockaddr* him, socklen_t len) {
RESTARTABLE_RETURN_INT(::connect(fd, him, len));
}
-inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
- // At least OpenBSD and FreeBSD can return EINTR from accept.
- RESTARTABLE_RETURN_INT(::accept(fd, him, len));
-}
-
-inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags,
- sockaddr* from, socklen_t* fromlen) {
- RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen));
-}
-
-inline int os::sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr *to, socklen_t tolen) {
- RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen));
-}
-
-inline int os::socket_shutdown(int fd, int howto) {
- return ::shutdown(fd, howto);
-}
-
-inline int os::bind(int fd, struct sockaddr* him, socklen_t len) {
- return ::bind(fd, him, len);
-}
-
-inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
- return ::getsockname(fd, him, len);
-}
-
-inline int os::get_host_name(char* name, int namelen) {
- return ::gethostname(name, namelen);
-}
-
inline struct hostent* os::get_host_by_name(char* name) {
return ::gethostbyname(name);
}
-inline int os::get_sock_opt(int fd, int level, int optname,
- char *optval, socklen_t* optlen) {
- return ::getsockopt(fd, level, optname, optval, optlen);
-}
-
-inline int os::set_sock_opt(int fd, int level, int optname,
- const char* optval, socklen_t optlen) {
- return ::setsockopt(fd, level, optname, optval, optlen);
-}
-
inline bool os::supports_monotonic_clock() {
#ifdef __APPLE__
return true;
diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
index 631366e2944..5cd6cf4e3dd 100644
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
@@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
if (!is_directory_secure(dirname)) {
// the directory is not a secure directory
+ os::closedir(dirp);
return;
}
@@ -872,6 +873,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
//
if (!is_directory_secure(dirname)) {
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ if (luser != user) {
+ FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ }
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
}
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 3d82d976f37..202e3612171 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -163,35 +163,6 @@ static pthread_mutex_t dl_mutex;
// Declarations
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
-#ifdef JAVASE_EMBEDDED
-class MemNotifyThread: public Thread {
- friend class VMStructs;
- public:
- virtual void run();
-
- private:
- static MemNotifyThread* _memnotify_thread;
- int _fd;
-
- public:
-
- // Constructor
- MemNotifyThread(int fd);
-
- // Tester
- bool is_memnotify_thread() const { return true; }
-
- // Printing
- char* name() const { return (char*)"Linux MemNotify Thread"; }
-
- // Returns the single instance of the MemNotifyThread
- static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
-
- // Create and start the single instance of MemNotifyThread
- static void start();
-};
-#endif // JAVASE_EMBEDDED
-
// utility functions
static int SR_initialize();
@@ -384,7 +355,10 @@ void os::init_system_properties_values() {
// Found the full path to libjvm.so.
// Now cut the path to <java_home>/jre if we can.
- *(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so.
+ pslash = strrchr(buf, '/');
+ if (pslash != NULL) {
+ *pslash = '\0'; // Get rid of /libjvm.so.
+ }
pslash = strrchr(buf, '/');
if (pslash != NULL) {
*pslash = '\0'; // Get rid of /{client|server|hotspot}.
@@ -1223,7 +1197,7 @@ void os::Linux::capture_initial_stack(size_t max_size) {
i = 0;
if (s) {
// Skip blank chars
- do s++; while (isspace(*s));
+ do { s++; } while (s && isspace(*s));
#define _UFM UINTX_FORMAT
#define _DFM INTX_FORMAT
@@ -2372,6 +2346,9 @@ void os::jvm_path(char *buf, jint buflen) {
// Check the current module name "libjvm.so".
p = strrchr(buf, '/');
+ if (p == NULL) {
+ return;
+ }
assert(strstr(p, "/libjvm") == p, "invalid library name");
rp = realpath(java_home_var, buf);
@@ -2405,6 +2382,7 @@ void os::jvm_path(char *buf, jint buflen) {
}
strncpy(saved_jvm_path, buf, MAXPATHLEN);
+ saved_jvm_path[MAXPATHLEN - 1] = '\0';
}
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
@@ -4866,17 +4844,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-// this is called at the end of vm_initialization
-void os::init_3(void) {
-#ifdef JAVASE_EMBEDDED
- // Start the MemNotifyThread
- if (LowMemoryProtection) {
- MemNotifyThread::start();
- }
- return;
-#endif
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if (!guard_memory((char*)_polling_page, Linux::page_size())) {
@@ -5103,9 +5070,38 @@ int os::open(const char *path, int oflag, int mode) {
errno = ENAMETOOLONG;
return -1;
}
- int fd;
- fd = ::open64(path, oflag, mode);
+ // All file descriptors that are opened in the Java process and not
+ // specifically destined for a subprocess should have the close-on-exec
+ // flag set. If we don't set it, then careless 3rd party native code
+ // might fork and exec without closing all appropriate file descriptors
+ // (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in
+ // turn might:
+ //
+ // - cause end-of-file to fail to be detected on some file
+ // descriptors, resulting in mysterious hangs, or
+ //
+ // - might cause an fopen in the subprocess to fail on a system
+ // suffering from bug 1085341.
+ //
+ // (Yes, the default setting of the close-on-exec flag is a Unix
+ // design flaw)
+ //
+ // See:
+ // 1085341: 32-bit stdio routines should support file descriptors >255
+ // 4843136: (process) pipe file descriptor from Runtime.exec not being closed
+ // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
+ //
+ // Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open().
+ // O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor
+ // because it saves a system call and removes a small window where the flag
+ // is unset. On ancient Linux kernels the O_CLOEXEC flag will be ignored
+ // and we fall back to using FD_CLOEXEC (see below).
+#ifdef O_CLOEXEC
+ oflag |= O_CLOEXEC;
+#endif
+
+ int fd = ::open64(path, oflag, mode);
if (fd == -1) return -1;
//If the open succeeded, the file might still be a directory
@@ -5126,32 +5122,17 @@ int os::open(const char *path, int oflag, int mode) {
}
}
- // All file descriptors that are opened in the JVM and not
- // specifically destined for a subprocess should have the
- // close-on-exec flag set. If we don't set it, then careless 3rd
- // party native code might fork and exec without closing all
- // appropriate file descriptors (e.g. as we do in closeDescriptors in
- // UNIXProcess.c), and this in turn might:
- //
- // - cause end-of-file to fail to be detected on some file
- // descriptors, resulting in mysterious hangs, or
- //
- // - might cause an fopen in the subprocess to fail on a system
- // suffering from bug 1085341.
- //
- // (Yes, the default setting of the close-on-exec flag is a Unix
- // design flaw)
- //
- // See:
- // 1085341: 32-bit stdio routines should support file descriptors >255
- // 4843136: (process) pipe file descriptor from Runtime.exec not being closed
- // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
- //
#ifdef FD_CLOEXEC
- {
+ // Validate that the use of the O_CLOEXEC flag on open above worked.
+ // With recent kernels, we will perform this check exactly once.
+ static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
+ if (!O_CLOEXEC_is_known_to_work) {
int flags = ::fcntl(fd, F_GETFD);
if (flags != -1) {
- ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+ if ((flags & FD_CLOEXEC) != 0)
+ O_CLOEXEC_is_known_to_work = 1;
+ else
+ ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
}
#endif
@@ -5211,15 +5192,6 @@ int os::available(int fd, jlong *bytes) {
return 1;
}
-int os::socket_available(int fd, jint *pbytes) {
- // Linux doc says EINTR not returned, unlike Solaris
- int ret = ::ioctl(fd, FIONREAD, pbytes);
-
- //%% note ioctl can return 0 when successful, JVM_SocketAvailable
- // is expected to return 0 on failure and 1 on success to the jdk.
- return (ret < 0) ? 0 : 1;
-}
-
// Map a block of memory.
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
char *addr, size_t bytes, bool read_only,
@@ -5349,7 +5321,7 @@ static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
if (s == NULL) return -1;
// Skip blank chars
- do s++; while (isspace(*s));
+ do { s++; } while (s && isspace(*s));
count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
&cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
@@ -5410,7 +5382,18 @@ void os::pause() {
}
-// Refer to the comments in os_solaris.cpp park-unpark.
+// Refer to the comments in os_solaris.cpp park-unpark. The next two
+// comment paragraphs are worth repeating here:
+//
+// Assumption:
+// Only one parker can exist on an event, which is why we allocate
+// them per-thread. Multiple unparkers can coexist.
+//
+// _Event serves as a restricted-range semaphore.
+// -1 : thread is blocked, i.e. there is a waiter
+// 0 : neutral: thread is running or ready,
+// could have been signaled after a wait started
+// 1 : signaled - thread is running or ready
//
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
@@ -5509,6 +5492,11 @@ static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
}
void os::PlatformEvent::park() { // AKA "down()"
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
// Invariant: Only the thread associated with the Event/PlatformEvent
// may call park().
// TODO: assert that _Assoc != NULL or _Assoc == Self
@@ -5546,6 +5534,11 @@ void os::PlatformEvent::park() { // AKA "down()"
}
int os::PlatformEvent::park(jlong millis) {
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
guarantee(_nParked == 0, "invariant");
int v;
@@ -5609,11 +5602,11 @@ int os::PlatformEvent::park(jlong millis) {
void os::PlatformEvent::unpark() {
// Transitions for _Event:
- // 0 :=> 1
- // 1 :=> 1
- // -1 :=> either 0 or 1; must signal target thread
- // That is, we can safely transition _Event from -1 to either
- // 0 or 1.
+ // 0 => 1 : just return
+ // 1 => 1 : just return
+ // -1 => either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1.
// See also: "Semaphores in Plan 9" by Mullender & Cox
//
// Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -5636,15 +5629,16 @@ void os::PlatformEvent::unpark() {
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
if (AnyWaiters != 0) {
+ // Note that we signal() *after* dropping the lock for "immortal" Events.
+ // This is safe and avoids a common class of futile wakeups. In rare
+ // circumstances this can cause a thread to return prematurely from
+ // cond_{timed}wait() but the spurious wakeup is benign and the victim
+ // will simply re-test the condition and re-park itself.
+ // This provides particular benefit if the underlying platform does not
+ // provide wait morphing.
status = pthread_cond_signal(_cond);
assert_status(status == 0, status, "cond_signal");
}
-
- // Note that we signal() _after dropping the lock for "immortal" Events.
- // This is safe and avoids a common class of futile wakeups. In rare
- // circumstances this can cause a thread to return prematurely from
- // cond_{timed}wait() but the spurious wakeup is benign and the victim will
- // simply re-test the condition and re-park itself.
}
@@ -6006,82 +6000,6 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
return strlen(buffer);
}
-#ifdef JAVASE_EMBEDDED
-//
-// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
-//
-MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
-
-// ctor
-//
-MemNotifyThread::MemNotifyThread(int fd): Thread() {
- assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
- _fd = fd;
-
- if (os::create_thread(this, os::os_thread)) {
- _memnotify_thread = this;
- os::set_priority(this, NearMaxPriority);
- os::start_thread(this);
- }
-}
-
-// Where all the work gets done
-//
-void MemNotifyThread::run() {
- assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
-
- // Set up the select arguments
- fd_set rfds;
- if (_fd != -1) {
- FD_ZERO(&rfds);
- FD_SET(_fd, &rfds);
- }
-
- // Now wait for the mem_notify device to wake up
- while (1) {
- // Wait for the mem_notify device to signal us..
- int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
- if (rc == -1) {
- perror("select!\n");
- break;
- } else if (rc) {
- //ssize_t free_before = os::available_memory();
- //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
-
- // The kernel is telling us there is not much memory left...
- // try to do something about that
-
- // If we are not already in a GC, try one.
- if (!Universe::heap()->is_gc_active()) {
- Universe::heap()->collect(GCCause::_allocation_failure);
-
- //ssize_t free_after = os::available_memory();
- //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
- //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
- }
- // We might want to do something like the following if we find the GC's are not helping...
- // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
- }
- }
-}
-
-// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
-//
-void MemNotifyThread::start() {
- int fd;
- fd = open("/dev/mem_notify", O_RDONLY, 0);
- if (fd < 0) {
- return;
- }
-
- if (memnotify_thread() == NULL) {
- new MemNotifyThread(fd);
- }
-}
-
-#endif // JAVASE_EMBEDDED
-
-
/////////////// Unit tests ///////////////
#ifndef PRODUCT
diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp
index d83fb5b7930..ba4b777d520 100644
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp
@@ -173,92 +173,14 @@ inline int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
return os::send(fd, buf, nBytes, flags);
}
-inline int os::timeout(int fd, long timeout) {
- julong prevtime,newtime;
- struct timeval t;
-
- gettimeofday(&t, NULL);
- prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
-
- for(;;) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN | POLLERR;
-
- int res = ::poll(&pfd, 1, timeout);
-
- if (res == OS_ERR && errno == EINTR) {
-
- // On Linux any value < 0 means "forever"
-
- if(timeout >= 0) {
- gettimeofday(&t, NULL);
- newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if(timeout <= 0)
- return OS_OK;
- prevtime = newtime;
- }
- } else
- return res;
- }
-}
-
-inline int os::listen(int fd, int count) {
- return ::listen(fd, count);
-}
-
inline int os::connect(int fd, struct sockaddr* him, socklen_t len) {
RESTARTABLE_RETURN_INT(::connect(fd, him, len));
}
-inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
- // Linux doc says this can't return EINTR, unlike accept() on Solaris.
- // But see attachListener_linux.cpp, LinuxAttachListener::dequeue().
- return (int)::accept(fd, him, len);
-}
-
-inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags,
- sockaddr* from, socklen_t* fromlen) {
- RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen));
-}
-
-inline int os::sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr* to, socklen_t tolen) {
- RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen));
-}
-
-inline int os::socket_shutdown(int fd, int howto) {
- return ::shutdown(fd, howto);
-}
-
-inline int os::bind(int fd, struct sockaddr* him, socklen_t len) {
- return ::bind(fd, him, len);
-}
-
-inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
- return ::getsockname(fd, him, len);
-}
-
-inline int os::get_host_name(char* name, int namelen) {
- return ::gethostname(name, namelen);
-}
-
inline struct hostent* os::get_host_by_name(char* name) {
return ::gethostbyname(name);
}
-inline int os::get_sock_opt(int fd, int level, int optname,
- char* optval, socklen_t* optlen) {
- return ::getsockopt(fd, level, optname, optval, optlen);
-}
-
-inline int os::set_sock_opt(int fd, int level, int optname,
- const char* optval, socklen_t optlen) {
- return ::setsockopt(fd, level, optname, optval, optlen);
-}
-
inline bool os::supports_monotonic_clock() {
return Linux::_clock_gettime != NULL;
}
diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
index 6d92575563e..3fad2964ab8 100644
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
@@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
if (!is_directory_secure(dirname)) {
// the directory is not a secure directory
+ os::closedir(dirp);
return;
}
@@ -872,6 +873,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
//
if (!is_directory_secure(dirname)) {
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ if (luser != user) {
+ FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ }
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
}
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index e5c99a8914a..beb8754198f 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -663,7 +663,10 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
}
}
- jio_snprintf(out, outlen, ret);
+ if (out && outlen > 0) {
+ strncpy(out, ret, outlen);
+ out[outlen - 1] = '\0';
+ }
return out;
}
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 109bf44bdc0..8fcc883f0a6 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -2221,6 +2221,7 @@ void os::jvm_path(char *buf, jint buflen) {
}
strncpy(saved_jvm_path, buf, MAXPATHLEN);
+ saved_jvm_path[MAXPATHLEN - 1] = '\0';
}
@@ -4761,10 +4762,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) {
@@ -5372,31 +5369,32 @@ extern "C" {
// to immediately return 0 your code should still work,
// albeit degenerating to a spin loop.
//
-// An interesting optimization for park() is to use a trylock()
-// to attempt to acquire the mutex. If the trylock() fails
-// then we know that a concurrent unpark() operation is in-progress.
-// in that case the park() code could simply set _count to 0
-// and return immediately. The subsequent park() operation *might*
-// return immediately. That's harmless as the caller of park() is
-// expected to loop. By using trylock() we will have avoided a
-// avoided a context switch caused by contention on the per-thread mutex.
+// In a sense, park()-unpark() just provides more polite spinning
+// and polling with the key difference over naive spinning being
+// that a parked thread needs to be explicitly unparked() in order
+// to wake up and to poll the underlying condition.
//
-// TODO-FIXME:
-// 1. Reconcile Doug's JSR166 j.u.c park-unpark with the
-// objectmonitor implementation.
-// 2. Collapse the JSR166 parker event, and the
-// objectmonitor ParkEvent into a single "Event" construct.
-// 3. In park() and unpark() add:
-// assert (Thread::current() == AssociatedWith).
-// 4. add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
-// 1-out-of-N park() operations will return immediately.
+// Assumption:
+// Only one parker can exist on an event, which is why we allocate
+// them per-thread. Multiple unparkers can coexist.
//
// _Event transitions in park()
// -1 => -1 : illegal
// 1 => 0 : pass - return immediately
-// 0 => -1 : block
+// 0 => -1 : block; then set _Event to 0 before returning
+//
+// _Event transitions in unpark()
+// 0 => 1 : just return
+// 1 => 1 : just return
+// -1 => either 0 or 1; must signal target thread
+// That is, we can safely transition _Event from -1 to either
+// 0 or 1.
//
// _Event serves as a restricted-range semaphore.
+// -1 : thread is blocked, i.e. there is a waiter
+// 0 : neutral: thread is running or ready,
+// could have been signaled after a wait started
+// 1 : signaled - thread is running or ready
//
// Another possible encoding of _Event would be with
// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
@@ -5456,6 +5454,11 @@ static timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) {
}
void os::PlatformEvent::park() { // AKA: down()
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
// Invariant: Only the thread associated with the Event/PlatformEvent
// may call park().
assert(_nParked == 0, "invariant");
@@ -5497,6 +5500,11 @@ void os::PlatformEvent::park() { // AKA: down()
}
int os::PlatformEvent::park(jlong millis) {
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
guarantee(_nParked == 0, "invariant");
int v;
for (;;) {
@@ -5542,11 +5550,11 @@ int os::PlatformEvent::park(jlong millis) {
void os::PlatformEvent::unpark() {
// Transitions for _Event:
- // 0 :=> 1
- // 1 :=> 1
- // -1 :=> either 0 or 1; must signal target thread
- // That is, we can safely transition _Event from -1 to either
- // 0 or 1.
+ // 0 => 1 : just return
+ // 1 => 1 : just return
+ // -1 => either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1.
// See also: "Semaphores in Plan 9" by Mullender & Cox
//
// Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -5566,8 +5574,13 @@ void os::PlatformEvent::unpark() {
assert_status(status == 0, status, "mutex_unlock");
guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
if (AnyWaiters != 0) {
- // We intentional signal *after* dropping the lock
- // to avoid a common class of futile wakeups.
+ // Note that we signal() *after* dropping the lock for "immortal" Events.
+ // This is safe and avoids a common class of futile wakeups. In rare
+ // circumstances this can cause a thread to return prematurely from
+ // cond_{timed}wait() but the spurious wakeup is benign and the victim
+ // will simply re-test the condition and re-park itself.
+ // This provides particular benefit if the underlying platform does not
+ // provide wait morphing.
status = os::Solaris::cond_signal(_cond);
assert_status(status == 0, status, "cond_signal");
}
@@ -5912,37 +5925,6 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
// a poll() is done with timeout == -1, in which case we repeat with this
// "wait forever" value.
-int os::timeout(int fd, long timeout) {
- int res;
- struct timeval t;
- julong prevtime, newtime;
- static const char* aNull = 0;
- struct pollfd pfd;
- pfd.fd = fd;
- pfd.events = POLLIN;
-
- assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
- "Assumed _thread_in_native");
-
- gettimeofday(&t, &aNull);
- prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
-
- for (;;) {
- res = ::poll(&pfd, 1, timeout);
- if (res == OS_ERR && errno == EINTR) {
- if (timeout != -1) {
- gettimeofday(&t, &aNull);
- newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000;
- timeout -= newtime - prevtime;
- if (timeout <= 0) {
- return OS_OK;
- }
- prevtime = newtime;
- }
- } else return res;
- }
-}
-
int os::connect(int fd, struct sockaddr *him, socklen_t len) {
int _result;
_result = ::connect(fd, him, len);
@@ -5982,46 +5964,6 @@ int os::connect(int fd, struct sockaddr *him, socklen_t len) {
return _result;
}
-int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
- if (fd < 0) {
- return OS_ERR;
- }
- assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
- "Assumed _thread_in_native");
- RESTARTABLE_RETURN_INT((int)::accept(fd, him, len));
-}
-
-int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags,
- sockaddr* from, socklen_t* fromlen) {
- assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
- "Assumed _thread_in_native");
- RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen));
-}
-
-int os::sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr* to, socklen_t tolen) {
- assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
- "Assumed _thread_in_native");
- RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen));
-}
-
-int os::socket_available(int fd, jint *pbytes) {
- if (fd < 0) {
- return OS_OK;
- }
- int ret;
- RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
- // note: ioctl can return 0 when successful, JVM_SocketAvailable
- // is expected to return 0 on failure and 1 on success to the jdk.
- return (ret == OS_ERR) ? 0 : 1;
-}
-
-int os::bind(int fd, struct sockaddr* him, socklen_t len) {
- assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native,
- "Assumed _thread_in_native");
- return ::bind(fd, him, len);
-}
-
// Get the default path to the core file
// Returns the length of the string
int os::get_core_path(char* buffer, size_t bufferSize) {
diff --git a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
index 7609abac014..3456414f048 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
@@ -120,38 +120,10 @@ inline int os::socket(int domain, int type, int protocol) {
return ::socket(domain, type, protocol);
}
-inline int os::listen(int fd, int count) {
- if (fd < 0) return OS_ERR;
-
- return ::listen(fd, count);
-}
-
-inline int os::socket_shutdown(int fd, int howto){
- return ::shutdown(fd, howto);
-}
-
-inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){
- return ::getsockname(fd, him, len);
-}
-
-inline int os::get_host_name(char* name, int namelen){
- return ::gethostname(name, namelen);
-}
-
inline struct hostent* os::get_host_by_name(char* name) {
return ::gethostbyname(name);
}
-inline int os::get_sock_opt(int fd, int level, int optname,
- char* optval, socklen_t* optlen) {
- return ::getsockopt(fd, level, optname, optval, optlen);
-}
-
-inline int os::set_sock_opt(int fd, int level, int optname,
- const char *optval, socklen_t optlen) {
- return ::setsockopt(fd, level, optname, optval, optlen);
-}
-
inline bool os::supports_monotonic_clock() {
// javaTimeNanos() is monotonic on Solaris, see getTimeNanos() comments
return true;
diff --git a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
index 7f956338e6b..9c348d9b2d1 100644
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
@@ -545,6 +545,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
if (!is_directory_secure(dirname)) {
// the directory is not a secure directory
+ os::closedir(dirp);
return;
}
@@ -890,6 +891,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
//
if (!is_directory_secure(dirname)) {
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+ if (luser != user) {
+ FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+ }
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Process not found");
}
diff --git a/hotspot/src/os/windows/vm/attachListener_windows.cpp b/hotspot/src/os/windows/vm/attachListener_windows.cpp
index 34a454f6363..3b3d0ca9d08 100644
--- a/hotspot/src/os/windows/vm/attachListener_windows.cpp
+++ b/hotspot/src/os/windows/vm/attachListener_windows.cpp
@@ -30,6 +30,7 @@
#include <windows.h>
#include <signal.h> // SIGBREAK
+#include <stdio.h>
// The AttachListener thread services a queue of operations. It blocks in the dequeue
// function until an operation is enqueued. A client enqueues an operation by creating
@@ -269,6 +270,7 @@ HANDLE Win32AttachOperation::open_pipe() {
if (hPipe != INVALID_HANDLE_VALUE) {
// shouldn't happen as there is a pipe created per operation
if (::GetLastError() == ERROR_PIPE_BUSY) {
+ ::CloseHandle(hPipe);
return INVALID_HANDLE_VALUE;
}
}
@@ -313,7 +315,8 @@ void Win32AttachOperation::complete(jint result, bufferedStream* result_stream)
BOOL fSuccess;
char msg[32];
- sprintf(msg, "%d\n", result);
+ _snprintf(msg, sizeof(msg), "%d\n", result);
+ msg[sizeof(msg) - 1] = '\0';
fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
if (fSuccess) {
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 2bde459105b..4a3109bef47 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -96,7 +96,7 @@
#include <vdmdbg.h>
// for timer info max values which include all bits
-#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
+#define ALL_64_BITS CONST64(-1)
// For DLL loading/load error detection
// Values of PE COFF
@@ -211,6 +211,7 @@ void os::init_system_properties_values() {
}
strcpy(home_path, home_dir);
Arguments::set_java_home(home_path);
+ FREE_C_HEAP_ARRAY(char, home_path, mtInternal);
dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1,
mtInternal);
@@ -220,6 +221,7 @@ void os::init_system_properties_values() {
strcpy(dll_path, home_dir);
strcat(dll_path, bin);
Arguments::set_dll_dir(dll_path);
+ FREE_C_HEAP_ARRAY(char, dll_path, mtInternal);
if (!set_boot_path('\\', ';')) {
return;
@@ -297,6 +299,9 @@ void os::init_system_properties_values() {
char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
Arguments::set_endorsed_dirs(buf);
+ // (Arguments::set_endorsed_dirs() calls SystemProperty::set_value(), which
+ // duplicates the input.)
+ FREE_C_HEAP_ARRAY(char, buf, mtInternal);
#undef ENDORSED_DIR
}
@@ -436,9 +441,9 @@ static unsigned __stdcall java_start(Thread* thread) {
}
// Diagnostic code to investigate JDK-6573254
- int res = 90115; // non-java thread
+ int res = 50115; // non-java thread
if (thread->is_Java_thread()) {
- res = 60115; // java thread
+ res = 40115; // java thread
}
// Install a win32 structured exception handler around every thread created
@@ -1610,96 +1615,123 @@ void os::print_os_info(outputStream* st) {
void os::win32::print_windows_version(outputStream* st) {
OSVERSIONINFOEX osvi;
- SYSTEM_INFO si;
+ VS_FIXEDFILEINFO *file_info;
+ TCHAR kernel32_path[MAX_PATH];
+ UINT len, ret;
+ // Use the GetVersionEx information to see if we're on a server or
+ // workstation edition of Windows. Starting with Windows 8.1 we can't
+ // trust the OS version information returned by this API.
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
- st->print_cr("N/A");
+ st->print_cr("Call to GetVersionEx failed");
return;
}
+ bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);
- int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
+ // Get the full path to \Windows\System32\kernel32.dll and use that for
+ // determining what version of Windows we're running on.
+ len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;
+ ret = GetSystemDirectory(kernel32_path, len);
+ if (ret == 0 || ret > len) {
+ st->print_cr("Call to GetSystemDirectory failed");
+ return;
+ }
+ strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);
- ZeroMemory(&si, sizeof(SYSTEM_INFO));
- if (os_vers >= 5002) {
- // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
- // find out whether we are running on 64 bit processor or not.
- if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) {
- os::Kernel32Dll::GetNativeSystemInfo(&si);
- } else {
- GetSystemInfo(&si);
- }
+ DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);
+ if (version_size == 0) {
+ st->print_cr("Call to GetFileVersionInfoSize failed");
+ return;
}
- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- switch (os_vers) {
- case 3051: st->print(" Windows NT 3.51"); break;
- case 4000: st->print(" Windows NT 4.0"); break;
- case 5000: st->print(" Windows 2000"); break;
- case 5001: st->print(" Windows XP"); break;
- case 5002:
- if (osvi.wProductType == VER_NT_WORKSTATION &&
- si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
- st->print(" Windows XP x64 Edition");
- } else {
- st->print(" Windows Server 2003 family");
- }
- break;
+ LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);
+ if (version_info == NULL) {
+ st->print_cr("Failed to allocate version_info");
+ return;
+ }
- case 6000:
- if (osvi.wProductType == VER_NT_WORKSTATION) {
- st->print(" Windows Vista");
- } else {
- st->print(" Windows Server 2008");
- }
- break;
+ if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {
+ os::free(version_info);
+ st->print_cr("Call to GetFileVersionInfo failed");
+ return;
+ }
- case 6001:
- if (osvi.wProductType == VER_NT_WORKSTATION) {
- st->print(" Windows 7");
- } else {
- st->print(" Windows Server 2008 R2");
- }
- break;
+ if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {
+ os::free(version_info);
+ st->print_cr("Call to VerQueryValue failed");
+ return;
+ }
- case 6002:
- if (osvi.wProductType == VER_NT_WORKSTATION) {
- st->print(" Windows 8");
- } else {
- st->print(" Windows Server 2012");
- }
- break;
+ int major_version = HIWORD(file_info->dwProductVersionMS);
+ int minor_version = LOWORD(file_info->dwProductVersionMS);
+ int build_number = HIWORD(file_info->dwProductVersionLS);
+ int build_minor = LOWORD(file_info->dwProductVersionLS);
+ int os_vers = major_version * 1000 + minor_version;
+ os::free(version_info);
- case 6003:
- if (osvi.wProductType == VER_NT_WORKSTATION) {
- st->print(" Windows 8.1");
- } else {
- st->print(" Windows Server 2012 R2");
- }
- break;
+ st->print(" Windows ");
+ switch (os_vers) {
- default: // future os
- // Unrecognized windows, print out its major and minor versions
- st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ case 6000:
+ if (is_workstation) {
+ st->print("Vista");
+ } else {
+ st->print("Server 2008");
}
- } else {
- switch (os_vers) {
- case 4000: st->print(" Windows 95"); break;
- case 4010: st->print(" Windows 98"); break;
- case 4090: st->print(" Windows Me"); break;
- default: // future windows, print out its major and minor versions
- st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ break;
+
+ case 6001:
+ if (is_workstation) {
+ st->print("7");
+ } else {
+ st->print("Server 2008 R2");
+ }
+ break;
+
+ case 6002:
+ if (is_workstation) {
+ st->print("8");
+ } else {
+ st->print("Server 2012");
+ }
+ break;
+
+ case 6003:
+ if (is_workstation) {
+ st->print("8.1");
+ } else {
+ st->print("Server 2012 R2");
+ }
+ break;
+
+ case 6004:
+ if (is_workstation) {
+ st->print("10");
+ } else {
+ // The server version name of Windows 10 is not known at this time
+ st->print("%d.%d", major_version, minor_version);
}
+ break;
+
+ default:
+ // Unrecognized windows, print out its major and minor versions
+ st->print("%d.%d", major_version, minor_version);
+ break;
}
- if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+ // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
+ // find out whether we are running on 64 bit processor or not
+ SYSTEM_INFO si;
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ os::Kernel32Dll::GetNativeSystemInfo(&si);
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
st->print(" , 64 bit");
}
- st->print(" Build %d", osvi.dwBuildNumber);
- st->print(" %s", osvi.szCSDVersion); // service pack
+ st->print(" Build %d", build_number);
+ st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
st->cr();
}
@@ -1807,6 +1839,7 @@ void os::jvm_path(char *buf, jint buflen) {
GetModuleFileName(vm_lib_handle, buf, buflen);
}
strncpy(saved_jvm_path, buf, MAX_PATH);
+ saved_jvm_path[MAX_PATH - 1] = '\0';
}
@@ -3719,8 +3752,12 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
// search system directory
if ((size = GetSystemDirectory(path, pathLen)) > 0) {
- strcat(path, "\\");
- strcat(path, name);
+ if (size >= pathLen) {
+ return NULL; // truncated
+ }
+ if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
+ return NULL; // truncated
+ }
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
return result;
}
@@ -3728,8 +3765,12 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
// try Windows directory
if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
- strcat(path, "\\");
- strcat(path, name);
+ if (size >= pathLen) {
+ return NULL; // truncated
+ }
+ if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
+ return NULL; // truncated
+ }
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
return result;
}
@@ -3740,68 +3781,134 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
return NULL;
}
-#define MIN_EXIT_MUTEXES 1
-#define MAX_EXIT_MUTEXES 16
-
-struct ExitMutexes {
- DWORD count;
- HANDLE handles[MAX_EXIT_MUTEXES];
-};
+#define MAX_EXIT_HANDLES 16
+#define EXIT_TIMEOUT 1000 /* 1 sec */
-static BOOL CALLBACK init_muts_call(PINIT_ONCE, PVOID ppmuts, PVOID*) {
- static ExitMutexes muts;
-
- muts.count = os::processor_count();
- if (muts.count < MIN_EXIT_MUTEXES) {
- muts.count = MIN_EXIT_MUTEXES;
- } else if (muts.count > MAX_EXIT_MUTEXES) {
- muts.count = MAX_EXIT_MUTEXES;
- }
-
- for (DWORD i = 0; i < muts.count; ++i) {
- muts.handles[i] = CreateMutex(NULL, FALSE, NULL);
- if (muts.handles[i] == NULL) {
- return FALSE;
- }
- }
- *((ExitMutexes**)ppmuts) = &muts;
+static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
+ InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
return TRUE;
}
int os::win32::exit_process_or_thread(Ept what, int exit_code) {
+ // Basic approach:
+ // - Each exiting thread registers its intent to exit and then does so.
+ // - A thread trying to terminate the process must wait for all
+ // threads currently exiting to complete their exit.
+
if (os::win32::has_exit_bug()) {
- static INIT_ONCE init_once_muts = INIT_ONCE_STATIC_INIT;
- static ExitMutexes* pmuts;
-
- if (!InitOnceExecuteOnce(&init_once_muts, init_muts_call, &pmuts, NULL)) {
- warning("ExitMutex initialization failed in %s: %d\n", __FILE__, __LINE__);
- } else if (WaitForMultipleObjects(pmuts->count, pmuts->handles,
- (what != EPT_THREAD), // exiting process waits for all mutexes
- INFINITE) == WAIT_FAILED) {
- warning("ExitMutex acquisition failed in %s: %d\n", __FILE__, __LINE__);
+ // The array holds handles of the threads that have started exiting by calling
+ // _endthreadex().
+ // Should be large enough to avoid blocking the exiting thread due to lack of
+ // a free slot.
+ static HANDLE handles[MAX_EXIT_HANDLES];
+ static int handle_count = 0;
+
+ static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
+ static CRITICAL_SECTION crit_sect;
+ int i, j;
+ DWORD res;
+ HANDLE hproc, hthr;
+
+ // The first thread that reached this point, initializes the critical section.
+ if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
+ warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
+ } else {
+ EnterCriticalSection(&crit_sect);
+
+ if (what == EPT_THREAD) {
+ // Remove from the array those handles of the threads that have completed exiting.
+ for (i = 0, j = 0; i < handle_count; ++i) {
+ res = WaitForSingleObject(handles[i], 0 /* don't wait */);
+ if (res == WAIT_TIMEOUT) {
+ handles[j++] = handles[i];
+ } else {
+ if (res != WAIT_OBJECT_0) {
+ warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__);
+ // Don't keep the handle, if we failed waiting for it.
+ }
+ CloseHandle(handles[i]);
+ }
+ }
+
+ // If there's no free slot in the array of the kept handles, we'll have to
+ // wait until at least one thread completes exiting.
+ if ((handle_count = j) == MAX_EXIT_HANDLES) {
+ res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
+ if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
+ i = (res - WAIT_OBJECT_0);
+ handle_count = MAX_EXIT_HANDLES - 1;
+ for (; i < handle_count; ++i) {
+ handles[i] = handles[i + 1];
+ }
+ } else {
+ warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+ // Don't keep handles, if we failed waiting for them.
+ for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
+ CloseHandle(handles[i]);
+ }
+ handle_count = 0;
+ }
+ }
+
+ // Store a duplicate of the current thread handle in the array of handles.
+ hproc = GetCurrentProcess();
+ hthr = GetCurrentThread();
+ if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
+ 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+ warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__);
+ } else {
+ ++handle_count;
+ }
+
+ // The current exiting thread has stored its handle in the array, and now
+ // should leave the critical section before calling _endthreadex().
+
+ } else { // what != EPT_THREAD
+ if (handle_count > 0) {
+ // Before ending the process, make sure all the threads that had called
+ // _endthreadex() completed.
+ res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
+ if (res == WAIT_FAILED) {
+ warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
+ }
+ for (i = 0; i < handle_count; ++i) {
+ CloseHandle(handles[i]);
+ }
+ handle_count = 0;
+ }
+
+ // End the process, not leaving critical section.
+ // This makes sure no other thread executes exit-related code at the same
+ // time, thus a race is avoided.
+ if (what == EPT_PROCESS) {
+ ::exit(exit_code);
+ } else {
+ _exit(exit_code);
+ }
+ }
+
+ LeaveCriticalSection(&crit_sect);
}
}
- switch (what) {
- case EPT_THREAD:
+ // We are here if either
+ // - there's no 'race at exit' bug on this OS release;
+ // - initialization of the critical section failed (unlikely);
+ // - the current thread has stored its handle and left the critical section.
+ if (what == EPT_THREAD) {
_endthreadex((unsigned)exit_code);
- break;
-
- case EPT_PROCESS:
+ } else if (what == EPT_PROCESS) {
::exit(exit_code);
- break;
-
- case EPT_PROCESS_DIE:
+ } else {
_exit(exit_code);
- break;
}
- // should not reach here
+ // Should not reach here
return exit_code;
}
-#undef MIN_EXIT_MUTEXES
-#undef MAX_EXIT_MUTEXES
+#undef MAX_EXIT_HANDLES
+#undef EXIT_TIMEOUT
void os::win32::setmode_streams() {
_setmode(_fileno(stdin), _O_BINARY);
@@ -4047,10 +4154,6 @@ jint os::init_2(void) {
return JNI_OK;
}
-void os::init_3(void) {
- return;
-}
-
// Mark the polling page as unreadable
void os::make_polling_page_unreadable(void) {
DWORD old_status;
@@ -4792,27 +4895,46 @@ bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
// 3. Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent
// into a single win32 CreateEvent() handle.
//
+// Assumption:
+// Only one parker can exist on an event, which is why we allocate
+// them per-thread. Multiple unparkers can coexist.
+//
// _Event transitions in park()
// -1 => -1 : illegal
// 1 => 0 : pass - return immediately
-// 0 => -1 : block
+// 0 => -1 : block; then set _Event to 0 before returning
+//
+// _Event transitions in unpark()
+// 0 => 1 : just return
+// 1 => 1 : just return
+// -1 => either 0 or 1; must signal target thread
+// That is, we can safely transition _Event from -1 to either
+// 0 or 1.
+//
+// _Event serves as a restricted-range semaphore.
+// -1 : thread is blocked, i.e. there is a waiter
+// 0 : neutral: thread is running or ready,
+// could have been signaled after a wait started
+// 1 : signaled - thread is running or ready
//
-// _Event serves as a restricted-range semaphore :
-// -1 : thread is blocked
-// 0 : neutral - thread is running or ready
-// 1 : signaled - thread is running or ready
+// Another possible encoding of _Event would be with
+// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
//
-// Another possible encoding of _Event would be
-// with explicit "PARKED" and "SIGNALED" bits.
int os::PlatformEvent::park(jlong Millis) {
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
guarantee(_ParkHandle != NULL , "Invariant");
guarantee(Millis > 0 , "Invariant");
- int v;
// CONSIDER: defer assigning a CreateEvent() handle to the Event until
// the initial park() operation.
+ // Consider: use atomic decrement instead of CAS-loop
+ int v;
for (;;) {
v = _Event;
if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
@@ -4860,9 +4982,15 @@ int os::PlatformEvent::park(jlong Millis) {
}
void os::PlatformEvent::park() {
+ // Transitions for _Event:
+ // -1 => -1 : illegal
+ // 1 => 0 : pass - return immediately
+ // 0 => -1 : block; then set _Event to 0 before returning
+
guarantee(_ParkHandle != NULL, "Invariant");
// Invariant: Only the thread associated with the Event/PlatformEvent
// may call park().
+ // Consider: use atomic decrement instead of CAS-loop
int v;
for (;;) {
v = _Event;
@@ -4891,11 +5019,11 @@ void os::PlatformEvent::unpark() {
guarantee(_ParkHandle != NULL, "Invariant");
// Transitions for _Event:
- // 0 :=> 1
- // 1 :=> 1
- // -1 :=> either 0 or 1; must signal target thread
- // That is, we can safely transition _Event from -1 to either
- // 0 or 1.
+ // 0 => 1 : just return
+ // 1 => 1 : just return
+ // -1 => either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1.
// See also: "Semaphores in Plan 9" by Mullender & Cox
//
// Note: Forcing a transition from "-1" to "1" on an unpark() means
@@ -5091,39 +5219,14 @@ int os::socket_close(int fd) {
return ::closesocket(fd);
}
-int os::socket_available(int fd, jint *pbytes) {
- int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes);
- return (ret < 0) ? 0 : 1;
-}
-
int os::socket(int domain, int type, int protocol) {
return ::socket(domain, type, protocol);
}
-int os::listen(int fd, int count) {
- return ::listen(fd, count);
-}
-
int os::connect(int fd, struct sockaddr* him, socklen_t len) {
return ::connect(fd, him, len);
}
-int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
- return ::accept(fd, him, len);
-}
-
-int os::sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr* to, socklen_t tolen) {
-
- return ::sendto(fd, buf, (int)len, flags, to, tolen);
-}
-
-int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags,
- sockaddr* from, socklen_t* fromlen) {
-
- return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen);
-}
-
int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
return ::recv(fd, buf, (int)nBytes, flags);
}
@@ -5136,45 +5239,6 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
return ::send(fd, buf, (int)nBytes, flags);
}
-int os::timeout(int fd, long timeout) {
- fd_set tbl;
- struct timeval t;
-
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
-
- tbl.fd_count = 1;
- tbl.fd_array[0] = fd;
-
- return ::select(1, &tbl, 0, 0, &t);
-}
-
-int os::get_host_name(char* name, int namelen) {
- return ::gethostname(name, namelen);
-}
-
-int os::socket_shutdown(int fd, int howto) {
- return ::shutdown(fd, howto);
-}
-
-int os::bind(int fd, struct sockaddr* him, socklen_t len) {
- return ::bind(fd, him, len);
-}
-
-int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
- return ::getsockname(fd, him, len);
-}
-
-int os::get_sock_opt(int fd, int level, int optname,
- char* optval, socklen_t* optlen) {
- return ::getsockopt(fd, level, optname, optval, optlen);
-}
-
-int os::set_sock_opt(int fd, int level, int optname,
- const char* optval, socklen_t optlen) {
- return ::setsockopt(fd, level, optname, optval, optlen);
-}
-
// WINDOWS CONTEXT Flags for THREAD_SAMPLING
#if defined(IA32)
#define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
@@ -5367,11 +5431,6 @@ inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,
return ::Module32Next(hSnapshot, lpme);
}
-
-inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
- return true;
-}
-
inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
::GetNativeSystemInfo(lpSystemInfo);
}
diff --git a/hotspot/src/os/windows/vm/os_windows.hpp b/hotspot/src/os/windows/vm/os_windows.hpp
index eb299ab36c9..9ef4d1d50b4 100644
--- a/hotspot/src/os/windows/vm/os_windows.hpp
+++ b/hotspot/src/os/windows/vm/os_windows.hpp
@@ -210,7 +210,6 @@ public:
static BOOL Module32First(HANDLE,LPMODULEENTRY32);
static BOOL Module32Next(HANDLE,LPMODULEENTRY32);
- static BOOL GetNativeSystemInfoAvailable();
static void GetNativeSystemInfo(LPSYSTEM_INFO);
// NUMA calls
diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index 136d8066dd4..4f69c6ad43a 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -910,7 +910,7 @@ void os::workaround_expand_exec_shield_cs_limit() {
*/
char* hint = (char*) (Linux::initial_thread_stack_bottom() -
((StackYellowPages + StackRedPages + 1) * page_size));
- char* codebuf = os::reserve_memory(page_size, hint);
+ char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
return; // No matter, we tried, best effort.
}
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
index 20bac5061ee..2b1033496d7 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
@@ -33,18 +33,50 @@
#include <sys/systeminfo.h>
#include <kstat.h>
#include <picl.h>
-
-extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
-extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
+#include <dlfcn.h>
+#include <link.h>
+
+extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result);
+
+// Functions from the library we need (signatures should match those in picl.h)
+extern "C" {
+ typedef int (*picl_initialize_func_t)(void);
+ typedef int (*picl_shutdown_func_t)(void);
+ typedef int (*picl_get_root_func_t)(picl_nodehdl_t *nodehandle);
+ typedef int (*picl_walk_tree_by_class_func_t)(picl_nodehdl_t rooth,
+ const char *classname, void *c_args,
+ int (*callback_fn)(picl_nodehdl_t hdl, void *args));
+ typedef int (*picl_get_prop_by_name_func_t)(picl_nodehdl_t nodeh, const char *nm,
+ picl_prophdl_t *ph);
+ typedef int (*picl_get_propval_func_t)(picl_prophdl_t proph, void *valbuf, size_t sz);
+ typedef int (*picl_get_propinfo_func_t)(picl_prophdl_t proph, picl_propinfo_t *pi);
+}
class PICL {
+ // Pointers to functions in the library
+ picl_initialize_func_t _picl_initialize;
+ picl_shutdown_func_t _picl_shutdown;
+ picl_get_root_func_t _picl_get_root;
+ picl_walk_tree_by_class_func_t _picl_walk_tree_by_class;
+ picl_get_prop_by_name_func_t _picl_get_prop_by_name;
+ picl_get_propval_func_t _picl_get_propval;
+ picl_get_propinfo_func_t _picl_get_propinfo;
+ // Handle to the library that is returned by dlopen
+ void *_dl_handle;
+
+ bool open_library();
+ void close_library();
+
+ template<typename FuncType> bool bind(FuncType& func, const char* name);
+ bool bind_library_functions();
+
// Get a value of the integer property. The value in the tree can be either 32 or 64 bit
// depending on the platform. The result is converted to int.
- static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) {
+ int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) {
picl_propinfo_t pinfo;
picl_prophdl_t proph;
- if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS ||
- picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) {
+ if (_picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS ||
+ _picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) {
return PICL_FAILURE;
}
@@ -54,13 +86,13 @@ class PICL {
}
if (pinfo.size == sizeof(int64_t)) {
int64_t val;
- if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) {
+ if (_picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) {
return PICL_FAILURE;
}
*result = static_cast<int>(val);
} else if (pinfo.size == sizeof(int32_t)) {
int32_t val;
- if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) {
+ if (_picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) {
return PICL_FAILURE;
}
*result = static_cast<int>(val);
@@ -74,6 +106,7 @@ class PICL {
// Visitor and a state machine that visits integer properties and verifies that the
// values are the same. Stores the unique value observed.
class UniqueValueVisitor {
+ PICL *_picl;
enum {
INITIAL, // Start state, no assignments happened
ASSIGNED, // Assigned a value
@@ -81,7 +114,7 @@ class PICL {
} _state;
int _value;
public:
- UniqueValueVisitor() : _state(INITIAL) { }
+ UniqueValueVisitor(PICL* picl) : _picl(picl), _state(INITIAL) { }
int value() {
assert(_state == ASSIGNED, "Precondition");
return _value;
@@ -96,71 +129,125 @@ class PICL {
bool is_inconsistent() { return _state == INCONSISTENT; }
void set_inconsistent() { _state = INCONSISTENT; }
- static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) {
- UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg);
- assert(!state->is_inconsistent(), "Precondition");
+ void visit(picl_nodehdl_t nodeh, const char* name) {
+ assert(!is_inconsistent(), "Precondition");
int curr;
- if (PICL::get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
- if (!state->is_assigned()) { // first iteration
- state->set_value(curr);
- } else if (curr != state->value()) { // following iterations
- state->set_inconsistent();
+ if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
+ if (!is_assigned()) { // first iteration
+ set_value(curr);
+ } else if (curr != value()) { // following iterations
+ set_inconsistent();
}
}
- if (state->is_inconsistent()) {
+ }
+ };
+
+ class CPUVisitor {
+ UniqueValueVisitor _l1_visitor;
+ UniqueValueVisitor _l2_visitor;
+ int _limit; // number of times visit() can be run
+ public:
+ CPUVisitor(PICL *picl, int limit) : _l1_visitor(picl), _l2_visitor(picl), _limit(limit) {}
+ static int visit(picl_nodehdl_t nodeh, void *arg) {
+ CPUVisitor *cpu_visitor = static_cast<CPUVisitor*>(arg);
+ UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor();
+ UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor();
+ if (!l1_visitor->is_inconsistent()) {
+ l1_visitor->visit(nodeh, "l1-dcache-line-size");
+ }
+ if (!l2_visitor->is_inconsistent()) {
+ l2_visitor->visit(nodeh, "l2-cache-line-size");
+ }
+
+ if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) {
+ return PICL_WALK_TERMINATE;
+ }
+ cpu_visitor->_limit--;
+ if (cpu_visitor->_limit <= 0) {
return PICL_WALK_TERMINATE;
}
return PICL_WALK_CONTINUE;
}
+ UniqueValueVisitor* l1_visitor() { return &_l1_visitor; }
+ UniqueValueVisitor* l2_visitor() { return &_l2_visitor; }
};
-
int _L1_data_cache_line_size;
int _L2_cache_line_size;
public:
- static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) {
- return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state);
- }
- static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) {
- return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state);
+ static int visit_cpu(picl_nodehdl_t nodeh, void *state) {
+ return CPUVisitor::visit(nodeh, state);
}
- PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) {
- if (picl_initialize() == PICL_SUCCESS) {
+ PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) {
+ if (!open_library()) {
+ return;
+ }
+ if (_picl_initialize() == PICL_SUCCESS) {
picl_nodehdl_t rooth;
- if (picl_get_root(&rooth) == PICL_SUCCESS) {
- UniqueValueVisitor L1_state;
- // Visit all "cpu" class instances
- picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper);
- if (L1_state.is_initial()) { // Still initial, iteration found no values
- // Try walk all "core" class instances, it might be a Fujitsu machine
- picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper);
- }
- if (L1_state.is_assigned()) { // Is there a value?
- _L1_data_cache_line_size = L1_state.value();
+ if (_picl_get_root(&rooth) == PICL_SUCCESS) {
+ const char* cpu_class = "cpu";
+ // If it's a Fujitsu machine, it's a "core"
+ if (is_fujitsu) {
+ cpu_class = "core";
}
-
- UniqueValueVisitor L2_state;
- picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper);
- if (L2_state.is_initial()) {
- picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper);
+ CPUVisitor cpu_visitor(this, os::processor_count());
+ _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
+ if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
+ _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
}
- if (L2_state.is_assigned()) {
- _L2_cache_line_size = L2_state.value();
+ if (cpu_visitor.l2_visitor()->is_assigned()) {
+ _L2_cache_line_size = cpu_visitor.l2_visitor()->value();
}
}
- picl_shutdown();
+ _picl_shutdown();
}
+ close_library();
}
unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
unsigned int L2_cache_line_size() const { return _L2_cache_line_size; }
};
-extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
- return PICL::get_l1_data_cache_line_size(nodeh, result);
+
+extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) {
+ return PICL::visit_cpu(nodeh, result);
}
-extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
- return PICL::get_l2_cache_line_size(nodeh, result);
+
+template<typename FuncType>
+bool PICL::bind(FuncType& func, const char* name) {
+ func = reinterpret_cast<FuncType>(dlsym(_dl_handle, name));
+ return func != NULL;
+}
+
+bool PICL::bind_library_functions() {
+ assert(_dl_handle != NULL, "library should be open");
+ return bind(_picl_initialize, "picl_initialize" ) &&
+ bind(_picl_shutdown, "picl_shutdown" ) &&
+ bind(_picl_get_root, "picl_get_root" ) &&
+ bind(_picl_walk_tree_by_class, "picl_walk_tree_by_class") &&
+ bind(_picl_get_prop_by_name, "picl_get_prop_by_name" ) &&
+ bind(_picl_get_propval, "picl_get_propval" ) &&
+ bind(_picl_get_propinfo, "picl_get_propinfo" );
+}
+
+bool PICL::open_library() {
+ _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
+ if (_dl_handle == NULL) {
+ warning("PICL (libpicl.so.1) is missing. Performance will not be optimal.");
+ return false;
+ }
+ if (!bind_library_functions()) {
+ assert(false, "unexpected PICL API change");
+ close_library();
+ return false;
+ }
+ return true;
+}
+
+void PICL::close_library() {
+ assert(_dl_handle != NULL, "library should be open");
+ dlclose(_dl_handle);
+ _dl_handle = NULL;
}
// We need to keep these here as long as we have to build on Solaris
@@ -342,7 +429,7 @@ int VM_Version::platform_features(int features) {
}
// Figure out cache line sizes using PICL
- PICL picl;
+ PICL picl((features & sparc64_family_m) != 0);
_L1_data_cache_line_size = picl.L1_data_cache_line_size();
_L2_cache_line_size = picl.L2_cache_line_size();
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
index 6d7ef1efcbe..543b0ddc88b 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
@@ -411,7 +411,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
"/export:jio_vsnprintf "+
"/export:JVM_GetVersionInfo "+
"/export:JVM_InitAgentProperties");
- addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib");
+ addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
addAttr(rv, "OutputFile", outDll);
addAttr(rv, "SuppressStartupBanner", "true");
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp
index 98179f46fdf..ec16b8da1ee 100644
--- a/hotspot/src/share/vm/ci/ciEnv.cpp
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp
@@ -1093,9 +1093,8 @@ void ciEnv::register_method(ciMethod* target,
// JVMTI -- compiled method notification (must be done outside lock)
nm->post_compiled_method_load_event();
} else {
- // The CodeCache is full. Print out warning and disable compilation.
+ // The CodeCache is full.
record_failure("code cache is full");
- CompileBroker::handle_full_code_cache(CodeCache::get_code_blob_type(comp_level));
}
}
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 0f2f8d590c4..fe9f2443a80 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -2557,7 +2557,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
AccessFlags* promoted_flags,
bool* has_final_method,
- bool* has_default_methods,
+ bool* declares_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK_NULL); // length
@@ -2576,11 +2576,11 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
if (method->is_final()) {
*has_final_method = true;
}
- if (is_interface && !(*has_default_methods)
- && !method->is_abstract() && !method->is_static()
- && !method->is_private()) {
- // default method
- *has_default_methods = true;
+ // declares_default_methods: declares concrete instance methods, any access flags
+ // used for interface initialization, and default method inheritance analysis
+ if (is_interface && !(*declares_default_methods)
+ && !method->is_abstract() && !method->is_static()) {
+ *declares_default_methods = true;
}
_methods->at_put(index, method());
}
@@ -3739,6 +3739,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
JvmtiCachedClassFileData *cached_class_file = NULL;
Handle class_loader(THREAD, loader_data->class_loader());
bool has_default_methods = false;
+ bool declares_default_methods = false;
ResourceMark rm(THREAD);
ClassFileStream* cfs = stream();
@@ -3976,9 +3977,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Array<Method*>* methods = parse_methods(access_flags.is_interface(),
&promoted_flags,
&has_final_method,
- &has_default_methods,
+ &declares_default_methods,
CHECK_(nullHandle));
+ if (declares_default_methods) {
+ has_default_methods = true;
+ }
+
// Additional attributes
ClassAnnotationCollector parsed_annotations;
parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle));
@@ -4120,6 +4125,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass->set_minor_version(minor_version);
this_klass->set_major_version(major_version);
this_klass->set_has_default_methods(has_default_methods);
+ this_klass->set_declares_default_methods(declares_default_methods);
if (!host_klass.is_null()) {
assert (this_klass->is_anonymous(), "should be the same");
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index 6ce366a21f8..b2efa8ceba3 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -247,7 +247,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array<Method*>* parse_methods(bool is_interface,
AccessFlags* promoted_flags,
bool* has_final_method,
- bool* has_default_method,
+ bool* declares_default_methods,
TRAPS);
intArray* sort_methods(Array<Method*>* methods);
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp
index 380c3dea10c..ff7b3533cba 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp
@@ -553,6 +553,7 @@ ClassLoaderData* ClassLoaderDataGraph::_saved_unloading = NULL;
ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
bool ClassLoaderDataGraph::_should_purge = false;
+bool ClassLoaderDataGraph::_metaspace_oom = false;
// 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
@@ -804,12 +805,17 @@ void ClassLoaderDataGraph::purge() {
ClassLoaderData* list = _unloading;
_unloading = NULL;
ClassLoaderData* next = list;
+ bool classes_unloaded = false;
while (next != NULL) {
ClassLoaderData* purge_me = next;
next = purge_me->next();
delete purge_me;
+ classes_unloaded = true;
+ }
+ if (classes_unloaded) {
+ Metaspace::purge();
+ set_metaspace_oom(false);
}
- Metaspace::purge();
}
void ClassLoaderDataGraph::post_class_unload_events(void) {
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp
index 231c135f435..17eab14b672 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp
@@ -68,6 +68,9 @@ class ClassLoaderDataGraph : public AllStatic {
static ClassLoaderData* _saved_head;
static ClassLoaderData* _saved_unloading;
static bool _should_purge;
+ // OOM has been seen in metaspace allocation. Used to prevent some
+ // allocations until class unloading
+ static bool _metaspace_oom;
static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
static void post_class_unload_events(void);
@@ -107,6 +110,9 @@ class ClassLoaderDataGraph : public AllStatic {
}
}
+ static bool has_metaspace_oom() { return _metaspace_oom; }
+ static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
+
static void free_deallocate_lists();
static void dump_on(outputStream * const out) PRODUCT_RETURN;
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index a4cf130d5c9..d6a84b75af0 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -455,6 +455,7 @@
template(object_void_signature, "(Ljava/lang/Object;)V") \
template(object_int_signature, "(Ljava/lang/Object;)I") \
template(object_boolean_signature, "(Ljava/lang/Object;)Z") \
+ template(object_object_signature, "(Ljava/lang/Object;)Ljava/lang/Object;") \
template(string_void_signature, "(Ljava/lang/String;)V") \
template(string_int_signature, "(Ljava/lang/String;)I") \
template(throwable_void_signature, "(Ljava/lang/Throwable;)V") \
@@ -746,6 +747,8 @@
do_name( isPrimitive_name, "isPrimitive") \
do_intrinsic(_getSuperclass, java_lang_Class, getSuperclass_name, void_class_signature, F_RN) \
do_name( getSuperclass_name, "getSuperclass") \
+ do_intrinsic(_Class_cast, java_lang_Class, Class_cast_name, object_object_signature, F_R) \
+ do_name( Class_cast_name, "cast") \
\
do_intrinsic(_getClassAccessFlags, sun_reflect_Reflection, getClassAccessFlags_name, class_int_signature, F_SN) \
do_name( getClassAccessFlags_name, "getClassAccessFlags") \
diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp
index 780111b0aa7..98b7ec0f23c 100644
--- a/hotspot/src/share/vm/code/codeBlob.cpp
+++ b/hotspot/src/share/vm/code/codeBlob.cpp
@@ -229,8 +229,8 @@ BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {
return blob;
}
-void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() {
- return CodeCache::allocate(size, CodeBlobType::NonNMethod, is_critical);
+void* BufferBlob::operator new(size_t s, unsigned size) throw() {
+ return CodeCache::allocate(size, CodeBlobType::NonNMethod);
}
void BufferBlob::free(BufferBlob *blob) {
@@ -260,10 +260,7 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- // The parameter 'true' indicates a critical memory allocation.
- // This means that CodeCacheMinimumFreeSpace is used, if necessary
- const bool is_critical = true;
- blob = new (size, is_critical) AdapterBlob(size, cb);
+ blob = new (size) AdapterBlob(size, cb);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();
@@ -285,10 +282,7 @@ MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
size += round_to(buffer_size, oopSize);
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- // The parameter 'true' indicates a critical memory allocation.
- // This means that CodeCacheMinimumFreeSpace is used, if necessary
- const bool is_critical = true;
- blob = new (size, is_critical) MethodHandlesAdapterBlob(size);
+ blob = new (size) MethodHandlesAdapterBlob(size);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();
@@ -336,14 +330,14 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
void* RuntimeStub::operator new(size_t s, unsigned size) throw() {
- void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod, true);
+ void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
}
// operator new shared by all singletons:
void* SingletonBlob::operator new(size_t s, unsigned size) throw() {
- void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod, true);
+ void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod);
if (!p) fatal("Initial size of CodeCache is too small");
return p;
}
diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp
index 88d86eb5995..2c066788657 100644
--- a/hotspot/src/share/vm/code/codeBlob.hpp
+++ b/hotspot/src/share/vm/code/codeBlob.hpp
@@ -221,7 +221,7 @@ class BufferBlob: public CodeBlob {
BufferBlob(const char* name, int size);
BufferBlob(const char* name, int size, CodeBuffer* cb);
- void* operator new(size_t s, unsigned size, bool is_critical = false) throw();
+ void* operator new(size_t s, unsigned size) throw();
public:
// Creation
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index b21604f8549..4876a40111d 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -44,6 +44,7 @@
#include "runtime/icache.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
+#include "runtime/sweeper.hpp"
#include "runtime/compilationPolicy.hpp"
#include "services/memoryService.hpp"
#include "trace/tracing.hpp"
@@ -192,16 +193,16 @@ void CodeCache::initialize_heaps() {
}
// Make sure we have enough space for VM internal code
- uint min_code_cache_size = (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3)) + CodeCacheMinimumFreeSpace;
+ uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
if (NonNMethodCodeHeapSize < (min_code_cache_size + code_buffers_size)) {
vm_exit_during_initialization("Not enough space in non-nmethod code heap to run VM.");
}
guarantee(NonProfiledCodeHeapSize + ProfiledCodeHeapSize + NonNMethodCodeHeapSize <= ReservedCodeCacheSize, "Size check");
// Align reserved sizes of CodeHeaps
- size_t non_method_size = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize);
- size_t profiled_size = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize);
- size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize);
+ size_t non_method_size = ReservedCodeSpace::allocation_align_size_up(NonNMethodCodeHeapSize);
+ size_t profiled_size = ReservedCodeSpace::allocation_align_size_up(ProfiledCodeHeapSize);
+ size_t non_profiled_size = ReservedCodeSpace::allocation_align_size_up(NonProfiledCodeHeapSize);
// Compute initial sizes of CodeHeaps
size_t init_non_method_size = MIN2(InitialCodeCacheSize, non_method_size);
@@ -267,6 +268,22 @@ bool CodeCache::heap_available(int code_blob_type) {
}
}
+const char* CodeCache::get_code_heap_flag_name(int code_blob_type) {
+ switch(code_blob_type) {
+ case CodeBlobType::NonNMethod:
+ return "NonNMethodCodeHeapSize";
+ break;
+ case CodeBlobType::MethodNonProfiled:
+ return "NonProfiledCodeHeapSize";
+ break;
+ case CodeBlobType::MethodProfiled:
+ return "ProfiledCodeHeapSize";
+ break;
+ }
+ ShouldNotReachHere();
+ return NULL;
+}
+
void CodeCache::add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type) {
// Check if heap is needed
if (!heap_available(code_blob_type)) {
@@ -332,14 +349,18 @@ CodeBlob* CodeCache::next_blob(CodeBlob* cb) {
return next_blob(get_code_heap(cb), cb);
}
-CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool is_critical) {
- // Do not seize the CodeCache lock here--if the caller has not
- // already done so, we are going to lose bigtime, since the code
- // cache will contain a garbage CodeBlob until the caller can
- // run the constructor for the CodeBlob subclass he is busy
- // instantiating.
+/**
+ * Do not seize the CodeCache lock here--if the caller has not
+ * already done so, we are going to lose bigtime, since the code
+ * cache will contain a garbage CodeBlob until the caller can
+ * run the constructor for the CodeBlob subclass he is busy
+ * instantiating.
+ */
+CodeBlob* CodeCache::allocate(int size, int code_blob_type) {
+ // Possibly wakes up the sweeper thread.
+ NMethodSweeper::notify(code_blob_type);
assert_locked_or_safepoint(CodeCache_lock);
- assert(size > 0, "allocation request must be reasonable");
+ assert(size > 0, err_msg_res("Code cache allocation request must be > 0 but is %d", size));
if (size <= 0) {
return NULL;
}
@@ -350,14 +371,18 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool is_critical) {
assert(heap != NULL, "heap is null");
while (true) {
- cb = (CodeBlob*)heap->allocate(size, is_critical);
+ cb = (CodeBlob*)heap->allocate(size);
if (cb != NULL) break;
if (!heap->expand_by(CodeCacheExpansionSize)) {
// Expansion failed
if (SegmentedCodeCache && (code_blob_type == CodeBlobType::NonNMethod)) {
- // Fallback solution: Store non-nmethod code in the non-profiled code heap
- return allocate(size, CodeBlobType::MethodNonProfiled, is_critical);
+ // Fallback solution: Store non-nmethod code in the non-profiled code heap.
+ // Note that at in the sweeper, we check the reverse_free_ratio of the non-profiled
+ // code heap and force stack scanning if less than 10% if the code heap are free.
+ return allocate(size, CodeBlobType::MethodNonProfiled);
}
+ MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CompileBroker::handle_full_code_cache(code_blob_type);
return NULL;
}
if (PrintCodeCacheExtension) {
@@ -755,19 +780,6 @@ size_t CodeCache::max_capacity() {
}
/**
- * Returns true if a CodeHeap is full and sets code_blob_type accordingly.
- */
-bool CodeCache::is_full(int* code_blob_type) {
- FOR_ALL_HEAPS(heap) {
- if ((*heap)->unallocated_capacity() < CodeCacheMinimumFreeSpace) {
- *code_blob_type = (*heap)->code_blob_type();
- return true;
- }
- }
- return false;
-}
-
-/**
* Returns the reverse free ratio. E.g., if 25% (1/4) of the code heap
* is free, reverse_free_ratio() returns 4.
*/
@@ -776,9 +788,13 @@ double CodeCache::reverse_free_ratio(int code_blob_type) {
if (heap == NULL) {
return 0;
}
- double unallocated_capacity = (double)(heap->unallocated_capacity() - CodeCacheMinimumFreeSpace);
+
+ double unallocated_capacity = MAX2((double)heap->unallocated_capacity(), 1.0); // Avoid division by 0;
double max_capacity = (double)heap->max_capacity();
- return max_capacity / unallocated_capacity;
+ double result = max_capacity / unallocated_capacity;
+ assert (max_capacity >= unallocated_capacity, "Must be");
+ assert (result >= 1.0, err_msg_res("reverse_free_ratio must be at least 1. It is %f", result));
+ return result;
}
size_t CodeCache::bytes_allocated_in_freelists() {
@@ -1011,9 +1027,8 @@ void CodeCache::report_codemem_full(int code_blob_type, bool print) {
// Not yet reported for this heap, report
heap->report_full();
if (SegmentedCodeCache) {
- warning("%s is full. Compiler has been disabled.", CodeCache::get_code_heap_name(code_blob_type));
- warning("Try increasing the code heap size using -XX:%s=",
- (code_blob_type == CodeBlobType::MethodNonProfiled) ? "NonProfiledCodeHeapSize" : "ProfiledCodeHeapSize");
+ warning("%s is full. Compiler has been disabled.", get_code_heap_name(code_blob_type));
+ warning("Try increasing the code heap size using -XX:%s=", get_code_heap_flag_name(code_blob_type));
} else {
warning("CodeCache is full. Compiler has been disabled.");
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp
index 87fc1e8e839..fd7fb286c31 100644
--- a/hotspot/src/share/vm/code/codeCache.hpp
+++ b/hotspot/src/share/vm/code/codeCache.hpp
@@ -100,6 +100,8 @@ class CodeCache : AllStatic {
static void add_heap(ReservedSpace rs, const char* name, size_t size_initial, int code_blob_type);
static CodeHeap* get_code_heap(CodeBlob* cb); // Returns the CodeHeap for the given CodeBlob
static CodeHeap* get_code_heap(int code_blob_type); // Returns the CodeHeap for the given CodeBlobType
+ // Returns the name of the VM option to set the size of the corresponding CodeHeap
+ static const char* get_code_heap_flag_name(int code_blob_type);
static bool heap_available(int code_blob_type); // Returns true if an own CodeHeap for the given CodeBlobType is available
static ReservedCodeSpace reserve_heap_memory(size_t size); // Reserves one continuous chunk of memory for the CodeHeaps
@@ -118,16 +120,16 @@ class CodeCache : AllStatic {
static void initialize();
// Allocation/administration
- static CodeBlob* allocate(int size, int code_blob_type, bool is_critical = false); // allocates a new CodeBlob
- static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
- static int alignment_unit(); // guaranteed alignment of all CodeBlobs
- static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
- static void free(CodeBlob* cb); // frees a CodeBlob
- static bool contains(void *p); // returns whether p is included
- static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs
- static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs
- static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods
- static void alive_nmethods_do(void f(nmethod* nm)); // iterates over all alive nmethods
+ static CodeBlob* allocate(int size, int code_blob_type); // allocates a new CodeBlob
+ static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
+ static int alignment_unit(); // guaranteed alignment of all CodeBlobs
+ static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
+ static void free(CodeBlob* cb); // frees a CodeBlob
+ static bool contains(void *p); // returns whether p is included
+ static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs
+ static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs
+ static void nmethods_do(void f(nmethod* nm)); // iterates over all nmethods
+ static void alive_nmethods_do(void f(nmethod* nm)); // iterates over all alive nmethods
// Lookup
static CodeBlob* find_blob(void* start); // Returns the CodeBlob containing the given address
@@ -180,7 +182,6 @@ class CodeCache : AllStatic {
static size_t unallocated_capacity();
static size_t max_capacity();
- static bool is_full(int* code_blob_type);
static double reverse_free_ratio(int code_blob_type);
static bool needs_cache_clean() { return _needs_cache_clean; }
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 278ba992154..835b3dc831d 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -804,10 +804,7 @@ nmethod::nmethod(
#endif // def HAVE_DTRACE_H
void* nmethod::operator new(size_t size, int nmethod_size, int comp_level) throw () {
- // With a SegmentedCodeCache, nmethods are allocated on separate heaps and therefore do not share memory
- // with critical CodeBlobs. We define the allocation as critical to make sure all code heap memory is used.
- bool is_critical = SegmentedCodeCache;
- return CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(comp_level), is_critical);
+ return CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(comp_level));
}
nmethod::nmethod(
diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp
index f4b0f20652c..c6262988265 100644
--- a/hotspot/src/share/vm/code/vtableStubs.cpp
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp
@@ -63,7 +63,6 @@ void* VtableStub::operator new(size_t size, int code_size) throw() {
// If changing the name, update the other file accordingly.
BufferBlob* blob = BufferBlob::create("vtable chunks", bytes);
if (blob == NULL) {
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return NULL;
}
_chunk = blob->content_begin();
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 1eccfde6fd0..330fa0214ef 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -156,8 +156,6 @@ long CompileBroker::_peak_compilation_time = 0;
CompileQueue* CompileBroker::_c2_compile_queue = NULL;
CompileQueue* CompileBroker::_c1_compile_queue = NULL;
-GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL;
-
class CompilationLog : public StringEventLog {
public:
@@ -187,6 +185,14 @@ class CompilationLog : public StringEventLog {
lm.print("\n");
log(thread, "%s", (const char*)lm);
}
+
+ void log_metaspace_failure(const char* reason) {
+ ResourceMark rm;
+ StringLogMessage lm;
+ lm.print("%4d COMPILE PROFILING SKIPPED: %s", -1, reason);
+ lm.print("\n");
+ log(JavaThread::current(), "%s", (const char*)lm);
+ }
};
static CompilationLog* _compilation_log = NULL;
@@ -649,13 +655,10 @@ void CompileQueue::free_all() {
lock()->notify_all();
}
-// ------------------------------------------------------------------
-// CompileQueue::get
-//
-// Get the next CompileTask from a CompileQueue
+/**
+ * Get the next CompileTask from a CompileQueue
+ */
CompileTask* CompileQueue::get() {
- NMethodSweeper::possibly_sweep();
-
MutexLocker locker(lock());
// If _first is NULL we have no more compile jobs. There are two reasons for
// having no compile jobs: First, we compiled everything we wanted. Second,
@@ -668,35 +671,16 @@ CompileTask* CompileQueue::get() {
return NULL;
}
- if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
- // Wait a certain amount of time to possibly do another sweep.
- // We must wait until stack scanning has happened so that we can
- // transition a method's state from 'not_entrant' to 'zombie'.
- long wait_time = NmethodSweepCheckInterval * 1000;
- if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
- // Only one thread at a time can do sweeping. Scale the
- // wait time according to the number of compiler threads.
- // As a result, the next sweep is likely to happen every 100ms
- // with an arbitrary number of threads that do sweeping.
- wait_time = 100 * CICompilerCount;
- }
- bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
- if (timeout) {
- MutexUnlocker ul(lock());
- NMethodSweeper::possibly_sweep();
- }
- } else {
- // If there are no compilation tasks and we can compile new jobs
- // (i.e., there is enough free space in the code cache) there is
- // no need to invoke the sweeper. As a result, the hotness of methods
- // remains unchanged. This behavior is desired, since we want to keep
- // the stable state, i.e., we do not want to evict methods from the
- // code cache if it is unnecessary.
- // We need a timed wait here, since compiler threads can exit if compilation
- // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
- // is not critical and we do not want idle compiler threads to wake up too often.
- lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
- }
+ // If there are no compilation tasks and we can compile new jobs
+ // (i.e., there is enough free space in the code cache) there is
+ // no need to invoke the sweeper. As a result, the hotness of methods
+ // remains unchanged. This behavior is desired, since we want to keep
+ // the stable state, i.e., we do not want to evict methods from the
+ // code cache if it is unnecessary.
+ // We need a timed wait here, since compiler threads can exit if compilation
+ // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
+ // is not critical and we do not want idle compiler threads to wake up too often.
+ lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
}
if (CompileBroker::is_compilation_disabled_forever()) {
@@ -886,8 +870,8 @@ void CompileBroker::compilation_init() {
_compilers[1] = new SharkCompiler();
#endif // SHARK
- // Start the CompilerThreads
- init_compiler_threads(c1_count, c2_count);
+ // Start the compiler thread(s) and the sweeper thread
+ init_compiler_sweeper_threads(c1_count, c2_count);
// totalTime performance counter is always created as it is required
// by the implementation of java.lang.management.CompilationMBean.
{
@@ -991,13 +975,10 @@ void CompileBroker::compilation_init() {
}
-CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
- AbstractCompiler* comp, TRAPS) {
- CompilerThread* compiler_thread = NULL;
-
- Klass* k =
- SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
- true, CHECK_0);
+JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
+ AbstractCompiler* comp, bool compiler_thread, TRAPS) {
+ JavaThread* thread = NULL;
+ Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0);
instanceKlassHandle klass (THREAD, k);
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
Handle string = java_lang_String::create_from_str(name, CHECK_0);
@@ -1015,7 +996,11 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue
{
MutexLocker mu(Threads_lock, THREAD);
- compiler_thread = new CompilerThread(queue, counters);
+ if (compiler_thread) {
+ thread = new CompilerThread(queue, counters);
+ } else {
+ thread = new CodeCacheSweeperThread();
+ }
// At this point the new CompilerThread data-races with this startup
// thread (which I believe is the primoridal thread and NOT the VM
// thread). This means Java bytecodes being executed at startup can
@@ -1028,12 +1013,12 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue
// in that case. However, since this must work and we do not allow
// exceptions anyway, check and abort if this fails.
- if (compiler_thread == NULL || compiler_thread->osthread() == NULL){
+ if (thread == NULL || thread->osthread() == NULL) {
vm_exit_during_initialization("java.lang.OutOfMemoryError",
os::native_thread_creation_failed_msg());
}
- java_lang_Thread::set_thread(thread_oop(), compiler_thread);
+ java_lang_Thread::set_thread(thread_oop(), thread);
// Note that this only sets the JavaThread _priority field, which by
// definition is limited to Java priorities and not OS priorities.
@@ -1054,24 +1039,26 @@ CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQue
native_prio = os::java_to_os_priority[NearMaxPriority];
}
}
- os::set_native_priority(compiler_thread, native_prio);
+ os::set_native_priority(thread, native_prio);
java_lang_Thread::set_daemon(thread_oop());
- compiler_thread->set_threadObj(thread_oop());
- compiler_thread->set_compiler(comp);
- Threads::add(compiler_thread);
- Thread::start(compiler_thread);
+ thread->set_threadObj(thread_oop());
+ if (compiler_thread) {
+ thread->as_CompilerThread()->set_compiler(comp);
+ }
+ Threads::add(thread);
+ Thread::start(thread);
}
// Let go of Threads_lock before yielding
os::naked_yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)
- return compiler_thread;
+ return thread;
}
-void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
+void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
EXCEPTION_MARK;
#if !defined(ZERO) && !defined(SHARK)
assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
@@ -1088,17 +1075,14 @@ void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler
int compiler_count = c1_compiler_count + c2_compiler_count;
- _compiler_threads =
- new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true);
-
char name_buffer[256];
+ const bool compiler_thread = true;
for (int i = 0; i < c2_compiler_count; i++) {
// Create a name for our thread.
sprintf(name_buffer, "C2 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
// Shark and C2
- CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], CHECK);
- _compiler_threads->append(new_thread);
+ make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
}
for (int i = c2_compiler_count; i < compiler_count; i++) {
@@ -1106,13 +1090,17 @@ void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler
sprintf(name_buffer, "C1 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
// C1
- CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], CHECK);
- _compiler_threads->append(new_thread);
+ make_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], compiler_thread, CHECK);
}
if (UsePerfData) {
PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK);
}
+
+ if (MethodFlushing) {
+ // Initialize the sweeper thread
+ make_thread("Sweeper thread", NULL, NULL, NULL, false, CHECK);
+ }
}
@@ -1759,13 +1747,6 @@ void CompileBroker::compiler_thread_loop() {
// We need this HandleMark to avoid leaking VM handles.
HandleMark hm(thread);
- // Check if the CodeCache is full
- int code_blob_type = 0;
- if (CodeCache::is_full(&code_blob_type)) {
- // The CodeHeap for code_blob_type is really full
- handle_full_code_cache(code_blob_type);
- }
-
CompileTask* task = queue->get();
if (task == NULL) {
continue;
@@ -1773,8 +1754,9 @@ void CompileBroker::compiler_thread_loop() {
// Give compiler threads an extra quanta. They tend to be bursty and
// this helps the compiler to finish up the job.
- if( CompilerThreadHintNoPreempt )
+ if (CompilerThreadHintNoPreempt) {
os::hint_no_preempt();
+ }
// trace per thread time and compile statistics
CompilerCounters* counters = ((CompilerThread*)thread)->counters();
@@ -1843,6 +1825,18 @@ void CompileBroker::init_compiler_thread_log() {
warning("Cannot open log file: %s", file_name);
}
+void CompileBroker::log_metaspace_failure() {
+ const char* message = "some methods may not be compiled because metaspace "
+ "is out of memory";
+ if (_compilation_log != NULL) {
+ _compilation_log->log_metaspace_failure(message);
+ }
+ if (PrintCompilation) {
+ tty->print_cr("COMPILE PROFILING SKIPPED: %s", message);
+ }
+}
+
+
// ------------------------------------------------------------------
// CompileBroker::set_should_block
//
@@ -2074,8 +2068,10 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
}
/**
- * The CodeCache is full. Print out warning and disable compilation
- * or try code cache cleaning so compilation can continue later.
+ * The CodeCache is full. Print warning and disable compilation.
+ * Schedule code cache cleaning so compilation can continue later.
+ * This function needs to be called only from CodeCache::allocate(),
+ * since we currently handle a full code cache uniformly.
*/
void CompileBroker::handle_full_code_cache(int code_blob_type) {
UseInterpreter = true;
@@ -2107,10 +2103,6 @@ void CompileBroker::handle_full_code_cache(int code_blob_type) {
if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
NMethodSweeper::log_sweep("disable_compiler");
}
- // Switch to 'vm_state'. This ensures that possibly_sweep() can be called
- // without having to consider the state in which the current thread is.
- ThreadInVMfromUnknown in_vm;
- NMethodSweeper::possibly_sweep();
} else {
disable_compilation_forever();
}
diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp
index c199cb1480d..e5b0484fc4c 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -290,8 +290,6 @@ class CompileBroker: AllStatic {
static CompileQueue* _c2_compile_queue;
static CompileQueue* _c1_compile_queue;
- static GrowableArray<CompilerThread*>* _compiler_threads;
-
// performance counters
static PerfCounter* _perf_total_compilation;
static PerfCounter* _perf_native_compilation;
@@ -339,8 +337,8 @@ class CompileBroker: AllStatic {
static volatile jint _print_compilation_warning;
- static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS);
- static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
+ static JavaThread* make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, bool compiler_thread, TRAPS);
+ static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count);
static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level);
static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
static bool is_compile_blocking();
@@ -473,6 +471,9 @@ class CompileBroker: AllStatic {
static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }
static long get_peak_compilation_time() { return _peak_compilation_time; }
static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }
+
+ // Log that compilation profiling is skipped because metaspace is full.
+ static void log_metaspace_failure();
};
#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 7ac2782772b..ebd77eb0b1e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -127,41 +127,6 @@ public:
};
-class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
- size_t _num_processed;
- CardTableModRefBS* _ctbs;
- int _histo[256];
-
- public:
- ClearLoggedCardTableEntryClosure() :
- _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set())
- {
- for (int i = 0; i < 256; i++) _histo[i] = 0;
- }
-
- bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
- unsigned char* ujb = (unsigned char*)card_ptr;
- int ind = (int)(*ujb);
- _histo[ind]++;
-
- *card_ptr = (jbyte)CardTableModRefBS::clean_card_val();
- _num_processed++;
-
- return true;
- }
-
- size_t num_processed() { return _num_processed; }
-
- void print_histo() {
- gclog_or_tty->print_cr("Card table value histogram:");
- for (int i = 0; i < 256; i++) {
- if (_histo[i] != 0) {
- gclog_or_tty->print_cr(" %d: %d", i, _histo[i]);
- }
- }
- }
-};
-
class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
private:
size_t _num_processed;
@@ -475,48 +440,6 @@ bool G1CollectedHeap::is_scavengable(const void* p) {
return !hr->is_humongous();
}
-void G1CollectedHeap::check_ct_logs_at_safepoint() {
- DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- CardTableModRefBS* ct_bs = g1_barrier_set();
-
- // Count the dirty cards at the start.
- CountNonCleanMemRegionClosure count1(this);
- ct_bs->mod_card_iterate(&count1);
- int orig_count = count1.n();
-
- // First clear the logged cards.
- ClearLoggedCardTableEntryClosure clear;
- dcqs.apply_closure_to_all_completed_buffers(&clear);
- dcqs.iterate_closure_all_threads(&clear, false);
- clear.print_histo();
-
- // Now ensure that there's no dirty cards.
- CountNonCleanMemRegionClosure count2(this);
- ct_bs->mod_card_iterate(&count2);
- if (count2.n() != 0) {
- gclog_or_tty->print_cr("Card table has %d entries; %d originally",
- count2.n(), orig_count);
- }
- guarantee(count2.n() == 0, "Card table should be clean.");
-
- RedirtyLoggedCardTableEntryClosure redirty;
- dcqs.apply_closure_to_all_completed_buffers(&redirty);
- dcqs.iterate_closure_all_threads(&redirty, false);
- gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
- clear.num_processed(), orig_count);
- guarantee(redirty.num_processed() == clear.num_processed(),
- err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT,
- redirty.num_processed(), clear.num_processed()));
-
- CountNonCleanMemRegionClosure count3(this);
- ct_bs->mod_card_iterate(&count3);
- if (count3.n() != orig_count) {
- gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
- orig_count, count3.n());
- guarantee(count3.n() >= orig_count, "Should have restored them all.");
- }
-}
-
// Private class members.
G1CollectedHeap* G1CollectedHeap::_g1h;
@@ -5760,14 +5683,10 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
// not copied during the pause.
process_discovered_references(n_workers);
- // Weak root processing.
- {
+ if (G1StringDedup::is_enabled()) {
G1STWIsAliveClosure is_alive(this);
G1KeepAliveClosure keep_alive(this);
- JNIHandles::weak_oops_do(&is_alive, &keep_alive);
- if (G1StringDedup::is_enabled()) {
- G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive);
- }
+ G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive);
}
_allocator->release_gc_alloc_regions(n_workers, evacuation_info);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 1307d4a6efd..f1aaceaacb4 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -797,9 +797,6 @@ protected:
// The closure used to refine a single card.
RefineCardTableEntryClosure* _refine_cte_cl;
- // A function to check the consistency of dirty card logs.
- void check_ct_logs_at_safepoint();
-
// A DirtyCardQueueSet that is used to hold cards that contain
// references into the current collection set. This is used to
// update the remembered sets of the regions in the collection
diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
index 124b1d1e3fc..53be23d848b 100644
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
@@ -1077,7 +1077,6 @@ IRT_END
address SignatureHandlerLibrary::set_handler_blob() {
BufferBlob* handler_blob = BufferBlob::create("native signature handlers", blob_size);
if (handler_blob == NULL) {
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return NULL;
}
address handler = handler_blob->code_begin();
diff --git a/hotspot/src/share/vm/memory/heap.cpp b/hotspot/src/share/vm/memory/heap.cpp
index 096c212a703..5ba099e78e8 100644
--- a/hotspot/src/share/vm/memory/heap.cpp
+++ b/hotspot/src/share/vm/memory/heap.cpp
@@ -171,13 +171,13 @@ void CodeHeap::clear() {
}
-void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
+void* CodeHeap::allocate(size_t instance_size) {
size_t number_of_segments = size_to_segments(instance_size + header_size());
assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
// First check if we can satisfy request from freelist
NOT_PRODUCT(verify());
- HeapBlock* block = search_freelist(number_of_segments, is_critical);
+ HeapBlock* block = search_freelist(number_of_segments);
NOT_PRODUCT(verify());
if (block != NULL) {
@@ -191,15 +191,6 @@ void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
// Ensure minimum size for allocation to the heap.
number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments);
- if (!is_critical) {
- // Make sure the allocation fits in the unallocated heap without using
- // the CodeCacheMimimumFreeSpace that is reserved for critical allocations.
- if (segments_to_size(number_of_segments) > (heap_unallocated_capacity() - CodeCacheMinimumFreeSpace)) {
- // Fail allocation
- return NULL;
- }
- }
-
if (_next_segment + number_of_segments <= _number_of_committed_segments) {
mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
HeapBlock* b = block_at(_next_segment);
@@ -427,24 +418,17 @@ void CodeHeap::add_to_freelist(HeapBlock* a) {
* Search freelist for an entry on the list with the best fit.
* @return NULL, if no one was found
*/
-FreeBlock* CodeHeap::search_freelist(size_t length, bool is_critical) {
+FreeBlock* CodeHeap::search_freelist(size_t length) {
FreeBlock* found_block = NULL;
FreeBlock* found_prev = NULL;
size_t found_length = 0;
FreeBlock* prev = NULL;
FreeBlock* cur = _freelist;
- const size_t critical_boundary = (size_t)high_boundary() - CodeCacheMinimumFreeSpace;
// Search for first block that fits
while(cur != NULL) {
if (cur->length() >= length) {
- // Non critical allocations are not allowed to use the last part of the code heap.
- // Make sure the end of the allocation doesn't cross into the last part of the code heap.
- if (!is_critical && (((size_t)cur + length) > critical_boundary)) {
- // The freelist is sorted by address - if one fails, all consecutive will also fail.
- break;
- }
// Remember block, its previous element, and its length
found_block = cur;
found_prev = prev;
diff --git a/hotspot/src/share/vm/memory/heap.hpp b/hotspot/src/share/vm/memory/heap.hpp
index c4150787768..4fdbeabbfc3 100644
--- a/hotspot/src/share/vm/memory/heap.hpp
+++ b/hotspot/src/share/vm/memory/heap.hpp
@@ -120,7 +120,7 @@ class CodeHeap : public CHeapObj<mtCode> {
// Toplevel freelist management
void add_to_freelist(HeapBlock* b);
- FreeBlock* search_freelist(size_t length, bool is_critical);
+ FreeBlock* search_freelist(size_t length);
// Iteration helpers
void* next_free(HeapBlock* b) const;
@@ -140,8 +140,8 @@ class CodeHeap : public CHeapObj<mtCode> {
bool expand_by(size_t size); // expands committed memory by size
// Memory allocation
- void* allocate (size_t size, bool is_critical); // allocates a block of size or returns NULL
- void deallocate(void* p); // deallocates a block
+ void* allocate (size_t size); // Allocate 'size' bytes in the code cache or return NULL
+ void deallocate(void* p); // Deallocate memory
// Attributes
char* low_boundary() const { return _memory.low_boundary (); }
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index c39c1353fe3..2f5d5843ee2 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -3157,6 +3157,16 @@ void Metaspace::global_initialize() {
SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment);
SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment);
+ // the min_misc_code_size estimate is based on MetaspaceShared::generate_vtable_methods()
+ uintx min_misc_code_size = align_size_up(
+ (MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) *
+ (sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size,
+ max_alignment);
+
+ if (SharedMiscCodeSize < min_misc_code_size) {
+ report_out_of_shared_space(SharedMiscCode);
+ }
+
// Initialize with the sum of the shared space sizes. The read-only
// and read write metaspace chunks will be allocated out of this and the
// remainder is the misc code and data chunks.
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index ab0d5de72b0..f71baaed660 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -714,12 +714,17 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
int class_list_path_len = (int)strlen(class_list_path_str);
if (class_list_path_len >= 3) {
if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) {
- strcat(class_list_path_str, os::file_separator());
- strcat(class_list_path_str, "lib");
+ if (class_list_path_len < JVM_MAXPATHLEN - 4) {
+ strncat(class_list_path_str, os::file_separator(), 1);
+ strncat(class_list_path_str, "lib", 3);
+ }
}
}
- strcat(class_list_path_str, os::file_separator());
- strcat(class_list_path_str, "classlist");
+ class_list_path_len = (int)strlen(class_list_path_str);
+ if (class_list_path_len < JVM_MAXPATHLEN - 10) {
+ strncat(class_list_path_str, os::file_separator(), 1);
+ strncat(class_list_path_str, "classlist", 9);
+ }
class_list_path = class_list_path_str;
} else {
class_list_path = SharedClassListFile;
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.hpp b/hotspot/src/share/vm/memory/metaspaceShared.hpp
index cc514c05050..db344359082 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp
@@ -57,11 +57,16 @@ class MetaspaceShared : AllStatic {
static bool _archive_loading_failed;
public:
enum {
- vtbl_list_size = 17, // number of entries in the shared space vtable list.
- num_virtuals = 200 // maximum number of virtual functions
- // If virtual functions are added to Metadata,
- // this number needs to be increased. Also,
- // SharedMiscCodeSize will need to be increased.
+ vtbl_list_size = 17, // number of entries in the shared space vtable list.
+ num_virtuals = 200, // maximum number of virtual functions
+ // If virtual functions are added to Metadata,
+ // this number needs to be increased. Also,
+ // SharedMiscCodeSize will need to be increased.
+ // The following 2 sizes were based on
+ // MetaspaceShared::generate_vtable_methods()
+ vtbl_method_size = 16, // conservative size of the mov1 and jmp instructions
+ // for the x64 platform
+ vtbl_common_code_size = (1*K) // conservative size of the "common_code" for the x64 platform
};
enum {
diff --git a/hotspot/src/share/vm/oops/constMethod.hpp b/hotspot/src/share/vm/oops/constMethod.hpp
index 8a8de131420..830a8f98a72 100644
--- a/hotspot/src/share/vm/oops/constMethod.hpp
+++ b/hotspot/src/share/vm/oops/constMethod.hpp
@@ -277,7 +277,7 @@ public:
bool has_stackmap_table() const { return _stackmap_data != NULL; }
void init_fingerprint() {
- const uint64_t initval = CONST64(0x8000000000000000);
+ const uint64_t initval = UCONST64(0x8000000000000000);
_fingerprint = initval;
}
diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp
index fb474cec05b..d547398dfae 100644
--- a/hotspot/src/share/vm/oops/constantPool.cpp
+++ b/hotspot/src/share/vm/oops/constantPool.cpp
@@ -206,7 +206,8 @@ void ConstantPool::trace_class_resolution(constantPoolHandle this_cp, KlassHandl
}
}
-Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) {
+Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which,
+ bool save_resolution_error, TRAPS) {
assert(THREAD->is_Java_thread(), "must be a Java thread");
// A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
@@ -249,7 +250,18 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS)
// Failed to resolve class. We must record the errors so that subsequent attempts
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
if (HAS_PENDING_EXCEPTION) {
- save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);
+ if (save_resolution_error) {
+ save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
+ // If CHECK_NULL above doesn't return the exception, that means that
+ // some other thread has beaten us and has resolved the class.
+ // To preserve old behavior, we return the resolved class.
+ entry = this_cp->resolved_klass_at(which);
+ assert(entry.is_resolved(), "must be resolved if exception was cleared");
+ assert(entry.get_klass()->is_klass(), "must be resolved to a klass");
+ return entry.get_klass();
+ } else {
+ return NULL; // return the pending exception
+ }
}
// Make this class loader depend upon the class loader owning the class reference
@@ -260,10 +272,10 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS)
// skip resolving the constant pool so that this code gets
// called the next time some bytecodes refer to this class.
trace_class_resolution(this_cp, k);
- return k();
- } else {
- this_cp->klass_at_put(which, k());
- }
+ return k();
+ } else {
+ this_cp->klass_at_put(which, k());
+ }
entry = this_cp->resolved_klass_at(which);
assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
@@ -573,24 +585,25 @@ void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int whic
Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION);
SystemDictionary::add_resolution_error(this_cp, which, error, message);
// CAS in the tag. If a thread beat us to registering this error that's fine.
- // If another thread resolved the reference, this is an error. The resolution
- // must deterministically get an error. So why do we save this?
- // We save this because jvmti can add classes to the bootclass path after this
- // error, so it needs to get the same error if the error is first.
+ // If another thread resolved the reference, this is a race condition. This
+ // thread may have had a security manager or something temporary.
+ // This doesn't deterministically get an error. So why do we save this?
+ // We save this because jvmti can add classes to the bootclass path after
+ // this error, so it needs to get the same error if the error is first.
jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag,
(jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value());
- assert(old_tag == error_tag || old_tag == tag.value(), "should not be resolved otherwise");
+ if (old_tag != error_tag && old_tag != tag.value()) {
+ // MethodHandles and MethodType doesn't change to resolved version.
+ assert(this_cp->tag_at(which).is_klass(), "Wrong tag value");
+ // Forget the exception and use the resolved class.
+ CLEAR_PENDING_EXCEPTION;
+ }
} else {
// some other thread put this in error state
throw_resolution_error(this_cp, which, CHECK);
}
-
- // This exits with some pending exception
- assert(HAS_PENDING_EXCEPTION, "should not be cleared");
}
-
-
// Called to resolve constants in the constant pool and return an oop.
// Some constant pool entries cache their resolved oop. This is also
// called to create oops from constants to use in arguments for invokedynamic
@@ -627,7 +640,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
case JVM_CONSTANT_Class:
{
assert(cache_index == _no_index_sentinel, "should not have been set");
- Klass* resolved = klass_at_impl(this_cp, index, CHECK_NULL);
+ Klass* resolved = klass_at_impl(this_cp, index, true, CHECK_NULL);
// ldc wants the java mirror.
result_oop = resolved->java_mirror();
break;
@@ -660,7 +673,7 @@ oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index
ref_kind, index, this_cp->method_handle_index_at(index),
callee_index, name->as_C_string(), signature->as_C_string());
KlassHandle callee;
- { Klass* k = klass_at_impl(this_cp, callee_index, CHECK_NULL);
+ { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
callee = KlassHandle(THREAD, k);
}
KlassHandle klass(THREAD, this_cp->pool_holder());
diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp
index 5e26ec5e622..18b86aa7ac6 100644
--- a/hotspot/src/share/vm/oops/constantPool.hpp
+++ b/hotspot/src/share/vm/oops/constantPool.hpp
@@ -336,7 +336,13 @@ class ConstantPool : public Metadata {
Klass* klass_at(int which, TRAPS) {
constantPoolHandle h_this(THREAD, this);
- return klass_at_impl(h_this, which, CHECK_NULL);
+ return klass_at_impl(h_this, which, true, CHECK_NULL);
+ }
+
+ // Version of klass_at that doesn't save the resolution error, called during deopt
+ Klass* klass_at_ignore_error(int which, TRAPS) {
+ constantPoolHandle h_this(THREAD, this);
+ return klass_at_impl(h_this, which, false, CHECK_NULL);
}
Symbol* klass_name_at(int which); // Returns the name, w/o resolving.
@@ -793,7 +799,8 @@ class ConstantPool : public Metadata {
// Implementation of methods that needs an exposed 'this' pointer, in order to
// handle GC while executing the method
- static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS);
+ static Klass* klass_at_impl(constantPoolHandle this_cp, int which,
+ bool save_resolution_error, TRAPS);
static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 8ea08cd54c7..ab925e46acb 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -736,6 +736,41 @@ void InstanceKlass::link_methods(TRAPS) {
}
}
+// Eagerly initialize superinterfaces that declare default methods (concrete instance: any access)
+void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) {
+ if (this_k->has_default_methods()) {
+ for (int i = 0; i < this_k->local_interfaces()->length(); ++i) {
+ Klass* iface = this_k->local_interfaces()->at(i);
+ InstanceKlass* ik = InstanceKlass::cast(iface);
+ if (ik->should_be_initialized()) {
+ if (ik->has_default_methods()) {
+ ik->initialize_super_interfaces(ik, THREAD);
+ }
+ // Only initialize() interfaces that "declare" concrete methods.
+ // has_default_methods drives searching superinterfaces since it
+ // means has_default_methods in its superinterface hierarchy
+ if (!HAS_PENDING_EXCEPTION && ik->declares_default_methods()) {
+ ik->initialize(THREAD);
+ }
+ if (HAS_PENDING_EXCEPTION) {
+ Handle e(THREAD, PENDING_EXCEPTION);
+ CLEAR_PENDING_EXCEPTION;
+ {
+ EXCEPTION_MARK;
+ // Locks object, set state, and notify all waiting threads
+ this_k->set_initialization_state_and_notify(
+ initialization_error, THREAD);
+
+ // ignore any exception thrown, superclass initialization error is
+ // thrown below
+ CLEAR_PENDING_EXCEPTION;
+ }
+ THROW_OOP(e());
+ }
+ }
+ }
+ }
+}
void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) {
// Make sure klass is linked (verified) before initialization
@@ -815,33 +850,11 @@ void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) {
}
}
+ // Recursively initialize any superinterfaces that declare default methods
+ // Only need to recurse if has_default_methods which includes declaring and
+ // inheriting default methods
if (this_k->has_default_methods()) {
- // Step 7.5: initialize any interfaces which have default methods
- for (int i = 0; i < this_k->local_interfaces()->length(); ++i) {
- Klass* iface = this_k->local_interfaces()->at(i);
- InstanceKlass* ik = InstanceKlass::cast(iface);
- if (ik->has_default_methods() && ik->should_be_initialized()) {
- ik->initialize(THREAD);
-
- if (HAS_PENDING_EXCEPTION) {
- Handle e(THREAD, PENDING_EXCEPTION);
- CLEAR_PENDING_EXCEPTION;
- {
- EXCEPTION_MARK;
- // Locks object, set state, and notify all waiting threads
- this_k->set_initialization_state_and_notify(
- initialization_error, THREAD);
-
- // ignore any exception thrown, superclass initialization error is
- // thrown below
- CLEAR_PENDING_EXCEPTION;
- }
- DTRACE_CLASSINIT_PROBE_WAIT(
- super__failed, InstanceKlass::cast(this_k()), -1, wait);
- THROW_OOP(e());
- }
- }
- }
+ this_k->initialize_super_interfaces(this_k, CHECK);
}
// Step 8
@@ -1717,6 +1730,25 @@ jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle m
return id;
}
+// Figure out how many jmethodIDs haven't been allocated, and make
+// sure space for them is pre-allocated. This makes getting all
+// method ids much, much faster with classes with more than 8
+// methods, and has a *substantial* effect on performance with jvmti
+// code that loads all jmethodIDs for all classes.
+void InstanceKlass::ensure_space_for_methodids(int start_offset) {
+ int new_jmeths = 0;
+ int length = methods()->length();
+ for (int index = start_offset; index < length; index++) {
+ Method* m = methods()->at(index);
+ jmethodID id = m->find_jmethod_id_or_null();
+ if (id == NULL) {
+ new_jmeths++;
+ }
+ }
+ if (new_jmeths != 0) {
+ Method::ensure_jmethod_ids(class_loader_data(), new_jmeths);
+ }
+}
// Common code to fetch the jmethodID from the cache or update the
// cache with the new jmethodID. This function should never do anything
@@ -2486,7 +2518,7 @@ const char* InstanceKlass::signature_name() const {
// If this is an anonymous class, append a hash to make the name unique
if (is_anonymous()) {
intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
- sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
+ jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
hash_len = (int)strlen(hash_buf);
}
@@ -2779,19 +2811,18 @@ void InstanceKlass::adjust_default_methods(Method** old_methods, Method** new_me
// On-stack replacement stuff
void InstanceKlass::add_osr_nmethod(nmethod* n) {
// only one compilation can be active
- NEEDS_CLEANUP
- // This is a short non-blocking critical region, so the no safepoint check is ok.
- OsrList_lock->lock_without_safepoint_check();
- assert(n->is_osr_method(), "wrong kind of nmethod");
- n->set_osr_link(osr_nmethods_head());
- set_osr_nmethods_head(n);
- // Raise the highest osr level if necessary
- if (TieredCompilation) {
- Method* m = n->method();
- m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level()));
+ {
+ // This is a short non-blocking critical region, so the no safepoint check is ok.
+ MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
+ assert(n->is_osr_method(), "wrong kind of nmethod");
+ n->set_osr_link(osr_nmethods_head());
+ set_osr_nmethods_head(n);
+ // Raise the highest osr level if necessary
+ if (TieredCompilation) {
+ Method* m = n->method();
+ m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level()));
+ }
}
- // Remember to unlock again
- OsrList_lock->unlock();
// Get rid of the osr methods for the same bci that have lower levels.
if (TieredCompilation) {
@@ -2807,7 +2838,7 @@ void InstanceKlass::add_osr_nmethod(nmethod* n) {
void InstanceKlass::remove_osr_nmethod(nmethod* n) {
// This is a short non-blocking critical region, so the no safepoint check is ok.
- OsrList_lock->lock_without_safepoint_check();
+ MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
assert(n->is_osr_method(), "wrong kind of nmethod");
nmethod* last = NULL;
nmethod* cur = osr_nmethods_head();
@@ -2844,13 +2875,27 @@ void InstanceKlass::remove_osr_nmethod(nmethod* n) {
}
m->set_highest_osr_comp_level(max_level);
}
- // Remember to unlock again
- OsrList_lock->unlock();
+}
+
+int InstanceKlass::mark_osr_nmethods(const Method* m) {
+ // This is a short non-blocking critical region, so the no safepoint check is ok.
+ MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
+ nmethod* osr = osr_nmethods_head();
+ int found = 0;
+ while (osr != NULL) {
+ assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
+ if (osr->method() == m) {
+ osr->mark_for_deoptimization();
+ found++;
+ }
+ osr = osr->osr_link();
+ }
+ return found;
}
nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_level, bool match_level) const {
// This is a short non-blocking critical region, so the no safepoint check is ok.
- OsrList_lock->lock_without_safepoint_check();
+ MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag);
nmethod* osr = osr_nmethods_head();
nmethod* best = NULL;
while (osr != NULL) {
@@ -2866,14 +2911,12 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
if (match_level) {
if (osr->comp_level() == comp_level) {
// Found a match - return it.
- OsrList_lock->unlock();
return osr;
}
} else {
if (best == NULL || (osr->comp_level() > best->comp_level())) {
if (osr->comp_level() == CompLevel_highest_tier) {
// Found the best possible - return it.
- OsrList_lock->unlock();
return osr;
}
best = osr;
@@ -2882,7 +2925,6 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
}
osr = osr->osr_link();
}
- OsrList_lock->unlock();
if (best != NULL && best->comp_level() >= comp_level && match_level == false) {
return best;
}
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index e50aa45eb69..a34a8dc5dbf 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -199,13 +199,14 @@ class InstanceKlass: public Klass {
bool _has_unloaded_dependent;
enum {
- _misc_rewritten = 1 << 0, // methods rewritten.
- _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
- _misc_should_verify_class = 1 << 2, // allow caching of preverification
- _misc_is_anonymous = 1 << 3, // has embedded _host_klass field
- _misc_is_contended = 1 << 4, // marked with contended annotation
- _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods
- _misc_has_been_redefined = 1 << 6 // class has been redefined
+ _misc_rewritten = 1 << 0, // methods rewritten.
+ _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
+ _misc_should_verify_class = 1 << 2, // allow caching of preverification
+ _misc_is_anonymous = 1 << 3, // has embedded _host_klass field
+ _misc_is_contended = 1 << 4, // marked with contended annotation
+ _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods
+ _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access)
+ _misc_has_been_redefined = 1 << 7 // class has been redefined
};
u2 _misc_flags;
u2 _minor_version; // minor version number of class file
@@ -651,6 +652,17 @@ class InstanceKlass: public Klass {
}
}
+ bool declares_default_methods() const {
+ return (_misc_flags & _misc_declares_default_methods) != 0;
+ }
+ void set_declares_default_methods(bool b) {
+ if (b) {
+ _misc_flags |= _misc_declares_default_methods;
+ } else {
+ _misc_flags &= ~_misc_declares_default_methods;
+ }
+ }
+
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline u2 next_method_idnum();
void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
@@ -686,6 +698,7 @@ class InstanceKlass: public Klass {
jmethodID** to_dealloc_jmeths_p);
static void get_jmethod_id_length_value(jmethodID* cache, size_t idnum,
size_t *length_p, jmethodID* id_p);
+ void ensure_space_for_methodids(int start_offset = 0);
jmethodID jmethod_id_or_null(Method* method);
// annotations support
@@ -742,6 +755,7 @@ class InstanceKlass: public Klass {
void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; };
void add_osr_nmethod(nmethod* n);
void remove_osr_nmethod(nmethod* n);
+ int mark_osr_nmethods(const Method* m);
nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
// Breakpoint support (see methods on Method* for details)
@@ -1022,6 +1036,7 @@ private:
static bool link_class_impl (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS);
static bool verify_code (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS);
static void initialize_impl (instanceKlassHandle this_k, TRAPS);
+ static void initialize_super_interfaces (instanceKlassHandle this_k, TRAPS);
static void eager_initialize_impl (instanceKlassHandle this_k);
static void set_initialization_state_and_notify_impl (instanceKlassHandle this_k, ClassState state, TRAPS);
static void call_class_initializer_impl (instanceKlassHandle this_k, TRAPS);
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index ef0349eeb26..e60245ba052 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -368,6 +368,13 @@ void Method::print_invocation_count() {
// Build a MethodData* object to hold information about this method
// collected in the interpreter.
void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
+ // Do not profile the method if metaspace has hit an OOM previously
+ // allocating profiling data. Callers clear pending exception so don't
+ // add one here.
+ if (ClassLoaderDataGraph::has_metaspace_oom()) {
+ return;
+ }
+
// Do not profile method if current thread holds the pending list lock,
// which avoids deadlock for acquiring the MethodData_lock.
if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
@@ -379,7 +386,13 @@ void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
MutexLocker ml(MethodData_lock, THREAD);
if (method->method_data() == NULL) {
ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
- MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
+ MethodData* method_data = MethodData::allocate(loader_data, method, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CompileBroker::log_metaspace_failure();
+ ClassLoaderDataGraph::set_metaspace_oom(true);
+ return; // return the exception (which is cleared)
+ }
+
method->set_method_data(method_data);
if (PrintMethodData && (Verbose || WizardMode)) {
ResourceMark rm(THREAD);
@@ -392,9 +405,19 @@ void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
}
MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
+ // Do not profile the method if metaspace has hit an OOM previously
+ if (ClassLoaderDataGraph::has_metaspace_oom()) {
+ return NULL;
+ }
+
methodHandle mh(m);
ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
- MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
+ MethodCounters* counters = MethodCounters::allocate(loader_data, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CompileBroker::log_metaspace_failure();
+ ClassLoaderDataGraph::set_metaspace_oom(true);
+ return NULL; // return the exception (which is cleared)
+ }
if (!mh->init_method_counters(counters)) {
MetadataFactory::free_metadata(loader_data, counters);
}
@@ -1295,6 +1318,10 @@ void Method::init_intrinsic_id() {
vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
if (id != vmIntrinsics::_none) {
set_intrinsic_id(id);
+ if (id == vmIntrinsics::_Class_cast) {
+ // Even if the intrinsic is rejected, we want to inline this simple method.
+ set_force_inline(true);
+ }
return;
}
@@ -1704,59 +1731,98 @@ void BreakpointInfo::clear(Method* method) {
// jmethodID handling
// This is a block allocating object, sort of like JNIHandleBlock, only a
-// lot simpler. There aren't many of these, they aren't long, they are rarely
-// deleted and so we can do some suboptimal things.
+// lot simpler.
// It's allocated on the CHeap because once we allocate a jmethodID, we can
// never get rid of it.
-// It would be nice to be able to parameterize the number of methods for
-// the null_class_loader but then we'd have to turn this and ClassLoaderData
-// into templates.
-// I feel like this brain dead class should exist somewhere in the STL
+static const int min_block_size = 8;
-class JNIMethodBlock : public CHeapObj<mtClass> {
- enum { number_of_methods = 8 };
-
- Method* _methods[number_of_methods];
+class JNIMethodBlockNode : public CHeapObj<mtClass> {
+ friend class JNIMethodBlock;
+ Method** _methods;
+ int _number_of_methods;
int _top;
- JNIMethodBlock* _next;
+ JNIMethodBlockNode* _next;
+
+ public:
+
+ JNIMethodBlockNode(int num_methods = min_block_size);
+
+ ~JNIMethodBlockNode() { FREE_C_HEAP_ARRAY(Method*, _methods, mtInternal); }
+
+ void ensure_methods(int num_addl_methods) {
+ if (_top < _number_of_methods) {
+ num_addl_methods -= _number_of_methods - _top;
+ if (num_addl_methods <= 0) {
+ return;
+ }
+ }
+ if (_next == NULL) {
+ _next = new JNIMethodBlockNode(MAX2(num_addl_methods, min_block_size));
+ } else {
+ _next->ensure_methods(num_addl_methods);
+ }
+ }
+};
+
+class JNIMethodBlock : public CHeapObj<mtClass> {
+ JNIMethodBlockNode _head;
+ JNIMethodBlockNode *_last_free;
public:
static Method* const _free_method;
- JNIMethodBlock() : _next(NULL), _top(0) {
- for (int i = 0; i< number_of_methods; i++) _methods[i] = _free_method;
+ JNIMethodBlock(int initial_capacity = min_block_size)
+ : _head(initial_capacity), _last_free(&_head) {}
+
+ void ensure_methods(int num_addl_methods) {
+ _last_free->ensure_methods(num_addl_methods);
}
Method** add_method(Method* m) {
- if (_top < number_of_methods) {
- // top points to the next free entry.
- int i = _top;
- _methods[i] = m;
- _top++;
- return &_methods[i];
- } else if (_top == number_of_methods) {
- // if the next free entry ran off the block see if there's a free entry
- for (int i = 0; i< number_of_methods; i++) {
- if (_methods[i] == _free_method) {
- _methods[i] = m;
- return &_methods[i];
+ for (JNIMethodBlockNode* b = _last_free; b != NULL; b = b->_next) {
+ if (b->_top < b->_number_of_methods) {
+ // top points to the next free entry.
+ int i = b->_top;
+ b->_methods[i] = m;
+ b->_top++;
+ _last_free = b;
+ return &(b->_methods[i]);
+ } else if (b->_top == b->_number_of_methods) {
+ // if the next free entry ran off the block see if there's a free entry
+ for (int i = 0; i < b->_number_of_methods; i++) {
+ if (b->_methods[i] == _free_method) {
+ b->_methods[i] = m;
+ _last_free = b;
+ return &(b->_methods[i]);
+ }
}
+ // Only check each block once for frees. They're very unlikely.
+ // Increment top past the end of the block.
+ b->_top++;
+ }
+ // need to allocate a next block.
+ if (b->_next == NULL) {
+ b->_next = _last_free = new JNIMethodBlockNode();
}
- // Only check each block once for frees. They're very unlikely.
- // Increment top past the end of the block.
- _top++;
- }
- // need to allocate a next block.
- if (_next == NULL) {
- _next = new JNIMethodBlock();
}
- return _next->add_method(m);
+ guarantee(false, "Should always allocate a free block");
+ return NULL;
}
bool contains(Method** m) {
- for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
- for (int i = 0; i< number_of_methods; i++) {
- if (&(b->_methods[i]) == m) {
+ if (m == NULL) return false;
+ for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
+ if (b->_methods <= m && m < b->_methods + b->_number_of_methods) {
+ // This is a bit of extra checking, for two reasons. One is
+ // that contains() deals with pointers that are passed in by
+ // JNI code, so making sure that the pointer is aligned
+ // correctly is valuable. The other is that <= and > are
+ // technically not defined on pointers, so the if guard can
+ // pass spuriously; no modern compiler is likely to make that
+ // a problem, though (and if one did, the guard could also
+ // fail spuriously, which would be bad).
+ ptrdiff_t idx = m - b->_methods;
+ if (b->_methods + idx == m) {
return true;
}
}
@@ -1775,9 +1841,9 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
// During class unloading the methods are cleared, which is different
// than freed.
void clear_all_methods() {
- for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
- for (int i = 0; i< number_of_methods; i++) {
- _methods[i] = NULL;
+ for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
+ for (int i = 0; i< b->_number_of_methods; i++) {
+ b->_methods[i] = NULL;
}
}
}
@@ -1785,9 +1851,9 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
int count_methods() {
// count all allocated methods
int count = 0;
- for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
- for (int i = 0; i< number_of_methods; i++) {
- if (_methods[i] != _free_method) count++;
+ for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
+ for (int i = 0; i< b->_number_of_methods; i++) {
+ if (b->_methods[i] != _free_method) count++;
}
}
return count;
@@ -1798,6 +1864,36 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
// Something that can't be mistaken for an address or a markOop
Method* const JNIMethodBlock::_free_method = (Method*)55;
+JNIMethodBlockNode::JNIMethodBlockNode(int num_methods) : _next(NULL), _top(0) {
+ _number_of_methods = MAX2(num_methods, min_block_size);
+ _methods = NEW_C_HEAP_ARRAY(Method*, _number_of_methods, mtInternal);
+ for (int i = 0; i < _number_of_methods; i++) {
+ _methods[i] = JNIMethodBlock::_free_method;
+ }
+}
+
+void Method::ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity) {
+ ClassLoaderData* cld = loader_data;
+ if (!SafepointSynchronize::is_at_safepoint()) {
+ // Have to add jmethod_ids() to class loader data thread-safely.
+ // Also have to add the method to the list safely, which the cld lock
+ // protects as well.
+ MutexLockerEx ml(cld->metaspace_lock(), Mutex::_no_safepoint_check_flag);
+ if (cld->jmethod_ids() == NULL) {
+ cld->set_jmethod_ids(new JNIMethodBlock(capacity));
+ } else {
+ cld->jmethod_ids()->ensure_methods(capacity);
+ }
+ } else {
+ // At safepoint, we are single threaded and can set this.
+ if (cld->jmethod_ids() == NULL) {
+ cld->set_jmethod_ids(new JNIMethodBlock(capacity));
+ } else {
+ cld->jmethod_ids()->ensure_methods(capacity);
+ }
+ }
+}
+
// Add a method id to the jmethod_ids
jmethodID Method::make_jmethod_id(ClassLoaderData* loader_data, Method* m) {
ClassLoaderData* cld = loader_data;
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index 9ffc9eea1ba..b2b4d791fc9 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -729,6 +729,11 @@ class Method : public Metadata {
static jmethodID make_jmethod_id(ClassLoaderData* loader_data, Method* mh);
static void destroy_jmethod_id(ClassLoaderData* loader_data, jmethodID mid);
+ // Ensure there is enough capacity in the internal tracking data
+ // structures to hold the number of jmethodIDs you plan to generate.
+ // This saves substantial time doing allocations.
+ static void ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity);
+
// Use resolve_jmethod_id() in situations where the caller is expected
// to provide a valid jmethodID; the only sanity checks are in asserts;
// result guaranteed not to be NULL.
@@ -813,6 +818,10 @@ class Method : public Metadata {
return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
}
+ int mark_osr_nmethods() {
+ return method_holder()->mark_osr_nmethods(this);
+ }
+
nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) {
return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
}
diff --git a/hotspot/src/share/vm/oops/objArrayOop.hpp b/hotspot/src/share/vm/oops/objArrayOop.hpp
index 897452a6624..bfb70564758 100644
--- a/hotspot/src/share/vm/oops/objArrayOop.hpp
+++ b/hotspot/src/share/vm/oops/objArrayOop.hpp
@@ -45,9 +45,10 @@ class objArrayOopDesc : public arrayOopDesc {
private:
// Give size of objArrayOop in HeapWords minus the header
static int array_size(int length) {
- const int OopsPerHeapWord = HeapWordSize/heapOopSize;
+ const uint OopsPerHeapWord = HeapWordSize/heapOopSize;
assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
"Else the following (new) computation would be in error");
+ uint res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
#ifdef ASSERT
// The old code is left in for sanity-checking; it'll
// go away pretty soon. XXX
@@ -55,16 +56,15 @@ private:
// oop->length() * HeapWordsPerOop;
// With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
// The oop elements are aligned up to wordSize
- const int HeapWordsPerOop = heapOopSize/HeapWordSize;
- int old_res;
+ const uint HeapWordsPerOop = heapOopSize/HeapWordSize;
+ uint old_res;
if (HeapWordsPerOop > 0) {
old_res = length * HeapWordsPerOop;
} else {
- old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
+ old_res = align_size_up((uint)length, OopsPerHeapWord)/OopsPerHeapWord;
}
-#endif // ASSERT
- int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
assert(res == old_res, "Inconsistency between old and new.");
+#endif // ASSERT
return res;
}
diff --git a/hotspot/src/share/vm/oops/typeArrayOop.hpp b/hotspot/src/share/vm/oops/typeArrayOop.hpp
index 20f30dc996d..7d61e8946a2 100644
--- a/hotspot/src/share/vm/oops/typeArrayOop.hpp
+++ b/hotspot/src/share/vm/oops/typeArrayOop.hpp
@@ -150,7 +150,7 @@ class typeArrayOopDesc : public arrayOopDesc {
DEBUG_ONLY(BasicType etype = Klass::layout_helper_element_type(lh));
assert(length <= arrayOopDesc::max_array_length(etype), "no overflow");
- julong size_in_bytes = length;
+ julong size_in_bytes = (juint)length;
size_in_bytes <<= element_shift;
size_in_bytes += instance_header_size;
julong size_in_words = ((size_in_bytes + (HeapWordSize-1)) >> LogHeapWordSize);
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index 4c7c92a7809..a49f31641dc 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -476,6 +476,9 @@
product(bool, DoEscapeAnalysis, true, \
"Perform escape analysis") \
\
+ product(double, EscapeAnalysisTimeout, 20. DEBUG_ONLY(+40.), \
+ "Abort EA when it reaches time limit (in sec)") \
+ \
develop(bool, ExitEscapeAnalysisOnTimeout, true, \
"Exit or throw assert in EA when it reaches time limit") \
\
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
index ccf23118bb3..619b37260b5 100644
--- a/hotspot/src/share/vm/opto/callnode.cpp
+++ b/hotspot/src/share/vm/opto/callnode.cpp
@@ -939,7 +939,8 @@ int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) {
#ifndef PRODUCT
if (!(call->req() > TypeFunc::Parms &&
call->in(TypeFunc::Parms) != NULL &&
- call->in(TypeFunc::Parms)->is_Con())) {
+ call->in(TypeFunc::Parms)->is_Con() &&
+ call->in(TypeFunc::Parms)->bottom_type()->isa_int())) {
assert(in_dump() != 0, "OK if dumping");
tty->print("[bad uncommon trap]");
return 0;
diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp
index 57a20bcb638..1e8af4e27ee 100644
--- a/hotspot/src/share/vm/opto/coalesce.cpp
+++ b/hotspot/src/share/vm/opto/coalesce.cpp
@@ -281,9 +281,11 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
Block *pred = _phc._cfg.get_block_for_node(b->pred(j));
Node *copy;
assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
- // Rematerialize constants instead of copying them
- if( m->is_Mach() && m->as_Mach()->is_Con() &&
- m->as_Mach()->rematerialize() ) {
+ // Rematerialize constants instead of copying them.
+ // We do this only for immediate constants, we avoid constant table loads
+ // because that will unsafely extend the live range of the constant table base.
+ if (m->is_Mach() && m->as_Mach()->is_Con() && !m->as_Mach()->is_MachConstant() &&
+ m->as_Mach()->rematerialize()) {
copy = m->clone();
// Insert the copy in the predecessor basic block
pred->add_inst(copy);
@@ -317,8 +319,8 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
// At this point it is unsafe to extend live ranges (6550579).
// Rematerialize only constants as we do for Phi above.
- if(m->is_Mach() && m->as_Mach()->is_Con() &&
- m->as_Mach()->rematerialize()) {
+ if (m->is_Mach() && m->as_Mach()->is_Con() && !m->as_Mach()->is_MachConstant() &&
+ m->as_Mach()->rematerialize()) {
copy = m->clone();
// Insert the copy in the basic block, just before us
b->insert_node(copy, l++);
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 6304ff2686b..ec74d5ef4a1 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -535,7 +535,6 @@ void Compile::init_scratch_buffer_blob(int const_size) {
if (scratch_buffer_blob() == NULL) {
// Let CompilerBroker disable further compilations.
record_failure("Not enough space for scratch buffer in CodeCache");
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return;
}
}
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index 2e454a70f88..9f09b62d761 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -38,6 +38,8 @@
ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
_nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
+ _in_worklist(C->comp_arena()),
+ _next_pidx(0),
_collecting(true),
_verify(false),
_compile(C),
@@ -125,13 +127,19 @@ bool ConnectionGraph::compute_escape() {
if (C->root() != NULL) {
ideal_nodes.push(C->root());
}
+ // Processed ideal nodes are unique on ideal_nodes list
+ // but several ideal nodes are mapped to the phantom_obj.
+ // To avoid duplicated entries on the following worklists
+ // add the phantom_obj only once to them.
+ ptnodes_worklist.append(phantom_obj);
+ java_objects_worklist.append(phantom_obj);
for( uint next = 0; next < ideal_nodes.size(); ++next ) {
Node* n = ideal_nodes.at(next);
// Create PointsTo nodes and add them to Connection Graph. Called
// only once per ideal node since ideal_nodes is Unique_Node list.
add_node_to_connection_graph(n, &delayed_worklist);
PointsToNode* ptn = ptnode_adr(n->_idx);
- if (ptn != NULL) {
+ if (ptn != NULL && ptn != phantom_obj) {
ptnodes_worklist.append(ptn);
if (ptn->is_JavaObject()) {
java_objects_worklist.append(ptn->as_JavaObject());
@@ -415,7 +423,7 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
}
case Op_CreateEx: {
// assume that all exception objects globally escape
- add_java_object(n, PointsToNode::GlobalEscape);
+ map_ideal_node(n, phantom_obj);
break;
}
case Op_LoadKlass:
@@ -1074,13 +1082,8 @@ bool ConnectionGraph::complete_connection_graph(
// on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
// Set limit to 20 to catch situation when something did go wrong and
// bailout Escape Analysis.
- // Also limit build time to 30 sec (60 in debug VM).
+ // Also limit build time to 20 sec (60 in debug VM), EscapeAnalysisTimeout flag.
#define CG_BUILD_ITER_LIMIT 20
-#ifdef ASSERT
-#define CG_BUILD_TIME_LIMIT 60.0
-#else
-#define CG_BUILD_TIME_LIMIT 30.0
-#endif
// Propagate GlobalEscape and ArgEscape escape states and check that
// we still have non-escaping objects. The method pushs on _worklist
@@ -1091,12 +1094,13 @@ bool ConnectionGraph::complete_connection_graph(
// Now propagate references to all JavaObject nodes.
int java_objects_length = java_objects_worklist.length();
elapsedTimer time;
+ bool timeout = false;
int new_edges = 1;
int iterations = 0;
do {
while ((new_edges > 0) &&
- (iterations++ < CG_BUILD_ITER_LIMIT) &&
- (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+ (iterations++ < CG_BUILD_ITER_LIMIT)) {
+ double start_time = time.seconds();
time.start();
new_edges = 0;
// Propagate references to phantom_object for nodes pushed on _worklist
@@ -1105,7 +1109,26 @@ bool ConnectionGraph::complete_connection_graph(
for (int next = 0; next < java_objects_length; ++next) {
JavaObjectNode* ptn = java_objects_worklist.at(next);
new_edges += add_java_object_edges(ptn, true);
+
+#define SAMPLE_SIZE 4
+ if ((next % SAMPLE_SIZE) == 0) {
+ // Each 4 iterations calculate how much time it will take
+ // to complete graph construction.
+ time.stop();
+ double stop_time = time.seconds();
+ double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE;
+ double time_until_end = time_per_iter * (double)(java_objects_length - next);
+ if ((start_time + time_until_end) >= EscapeAnalysisTimeout) {
+ timeout = true;
+ break; // Timeout
+ }
+ start_time = stop_time;
+ time.start();
+ }
+#undef SAMPLE_SIZE
+
}
+ if (timeout) break;
if (new_edges > 0) {
// Update escape states on each iteration if graph was updated.
if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
@@ -1113,9 +1136,12 @@ bool ConnectionGraph::complete_connection_graph(
}
}
time.stop();
+ if (time.seconds() >= EscapeAnalysisTimeout) {
+ timeout = true;
+ break;
+ }
}
- if ((iterations < CG_BUILD_ITER_LIMIT) &&
- (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+ if ((iterations < CG_BUILD_ITER_LIMIT) && !timeout) {
time.start();
// Find fields which have unknown value.
int fields_length = oop_fields_worklist.length();
@@ -1128,18 +1154,21 @@ bool ConnectionGraph::complete_connection_graph(
}
}
time.stop();
+ if (time.seconds() >= EscapeAnalysisTimeout) {
+ timeout = true;
+ break;
+ }
} else {
new_edges = 0; // Bailout
}
} while (new_edges > 0);
// Bailout if passed limits.
- if ((iterations >= CG_BUILD_ITER_LIMIT) ||
- (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
+ if ((iterations >= CG_BUILD_ITER_LIMIT) || timeout) {
Compile* C = _compile;
if (C->log() != NULL) {
C->log()->begin_elem("connectionGraph_bailout reason='reached ");
- C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
+ C->log()->text("%s", timeout ? "time" : "iterations");
C->log()->end_elem(" limit'");
}
assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
@@ -1156,7 +1185,6 @@ bool ConnectionGraph::complete_connection_graph(
#endif
#undef CG_BUILD_ITER_LIMIT
-#undef CG_BUILD_TIME_LIMIT
// Find fields initialized by NULL for non-escaping Allocations.
int non_escaped_length = non_escaped_worklist.length();
@@ -1280,8 +1308,8 @@ int ConnectionGraph::add_java_object_edges(JavaObjectNode* jobj, bool populate_w
}
}
}
- while(_worklist.length() > 0) {
- PointsToNode* use = _worklist.pop();
+ for (int l = 0; l < _worklist.length(); l++) {
+ PointsToNode* use = _worklist.at(l);
if (PointsToNode::is_base_use(use)) {
// Add reference from jobj to field and from field to jobj (field's base).
use = PointsToNode::get_use_node(use)->as_Field();
@@ -1328,6 +1356,8 @@ int ConnectionGraph::add_java_object_edges(JavaObjectNode* jobj, bool populate_w
add_field_uses_to_worklist(use->as_Field());
}
}
+ _worklist.clear();
+ _in_worklist.Reset();
return new_edges;
}
@@ -1906,7 +1936,7 @@ void ConnectionGraph::add_local_var(Node *n, PointsToNode::EscapeState es) {
return;
}
Compile* C = _compile;
- ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
+ ptadr = new (C->comp_arena()) LocalVarNode(this, n, es);
_nodes.at_put(n->_idx, ptadr);
}
@@ -1917,7 +1947,7 @@ void ConnectionGraph::add_java_object(Node *n, PointsToNode::EscapeState es) {
return;
}
Compile* C = _compile;
- ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
+ ptadr = new (C->comp_arena()) JavaObjectNode(this, n, es);
_nodes.at_put(n->_idx, ptadr);
}
@@ -1933,7 +1963,7 @@ void ConnectionGraph::add_field(Node *n, PointsToNode::EscapeState es, int offse
es = PointsToNode::GlobalEscape;
}
Compile* C = _compile;
- FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
+ FieldNode* field = new (C->comp_arena()) FieldNode(this, n, es, offset, is_oop);
_nodes.at_put(n->_idx, field);
}
@@ -1947,7 +1977,7 @@ void ConnectionGraph::add_arraycopy(Node *n, PointsToNode::EscapeState es,
return;
}
Compile* C = _compile;
- ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
+ ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
_nodes.at_put(n->_idx, ptadr);
// Add edge from arraycopy node to source object.
(void)add_edge(ptadr, src);
diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp
index 78447f03062..89a0d44a358 100644
--- a/hotspot/src/share/vm/opto/escape.hpp
+++ b/hotspot/src/share/vm/opto/escape.hpp
@@ -125,6 +125,8 @@ class LocalVarNode;
class FieldNode;
class ArraycopyNode;
+class ConnectionGraph;
+
// ConnectionGraph nodes
class PointsToNode : public ResourceObj {
GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
@@ -137,6 +139,7 @@ class PointsToNode : public ResourceObj {
Node* const _node; // Ideal node corresponding to this PointsTo node.
const int _idx; // Cached ideal node's _idx
+ const uint _pidx; // Index of this node
public:
typedef enum {
@@ -165,17 +168,9 @@ public:
} NodeFlags;
- PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
- _edges(C->comp_arena(), 2, 0, NULL),
- _uses (C->comp_arena(), 2, 0, NULL),
- _node(n),
- _idx(n->_idx),
- _type((u1)type),
- _escape((u1)es),
- _fields_escape((u1)es),
- _flags(ScalarReplaceable) {
- assert(n != NULL && es != UnknownEscape, "sanity");
- }
+ inline PointsToNode(ConnectionGraph* CG, Node* n, EscapeState es, NodeType type);
+
+ uint pidx() const { return _pidx; }
Node* ideal_node() const { return _node; }
int idx() const { return _idx; }
@@ -243,14 +238,14 @@ public:
class LocalVarNode: public PointsToNode {
public:
- LocalVarNode(Compile *C, Node* n, EscapeState es):
- PointsToNode(C, n, es, LocalVar) {}
+ LocalVarNode(ConnectionGraph *CG, Node* n, EscapeState es):
+ PointsToNode(CG, n, es, LocalVar) {}
};
class JavaObjectNode: public PointsToNode {
public:
- JavaObjectNode(Compile *C, Node* n, EscapeState es):
- PointsToNode(C, n, es, JavaObject) {
+ JavaObjectNode(ConnectionGraph *CG, Node* n, EscapeState es):
+ PointsToNode(CG, n, es, JavaObject) {
if (es > NoEscape)
set_scalar_replaceable(false);
}
@@ -262,8 +257,8 @@ class FieldNode: public PointsToNode {
const bool _is_oop; // Field points to object
bool _has_unknown_base; // Has phantom_object base
public:
- FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
- PointsToNode(C, n, es, Field),
+ FieldNode(ConnectionGraph *CG, Node* n, EscapeState es, int offs, bool is_oop):
+ PointsToNode(CG, n, es, Field),
_offset(offs), _is_oop(is_oop),
_has_unknown_base(false) {}
@@ -284,8 +279,8 @@ public:
class ArraycopyNode: public PointsToNode {
public:
- ArraycopyNode(Compile *C, Node* n, EscapeState es):
- PointsToNode(C, n, es, Arraycopy) {}
+ ArraycopyNode(ConnectionGraph *CG, Node* n, EscapeState es):
+ PointsToNode(CG, n, es, Arraycopy) {}
};
// Iterators for PointsTo node's edges:
@@ -323,11 +318,14 @@ public:
class ConnectionGraph: public ResourceObj {
+ friend class PointsToNode;
private:
GrowableArray<PointsToNode*> _nodes; // Map from ideal nodes to
// ConnectionGraph nodes.
GrowableArray<PointsToNode*> _worklist; // Nodes to be processed
+ VectorSet _in_worklist;
+ uint _next_pidx;
bool _collecting; // Indicates whether escape information
// is still being collected. If false,
@@ -353,6 +351,8 @@ private:
}
uint nodes_size() const { return _nodes.length(); }
+ uint next_pidx() { return _next_pidx++; }
+
// Add nodes to ConnectionGraph.
void add_local_var(Node* n, PointsToNode::EscapeState es);
void add_java_object(Node* n, PointsToNode::EscapeState es);
@@ -396,15 +396,26 @@ private:
int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
// Put node on worklist if it is (or was) not there.
- void add_to_worklist(PointsToNode* pt) {
- _worklist.push(pt);
- return;
+ inline void add_to_worklist(PointsToNode* pt) {
+ PointsToNode* ptf = pt;
+ uint pidx_bias = 0;
+ if (PointsToNode::is_base_use(pt)) {
+ // Create a separate entry in _in_worklist for a marked base edge
+ // because _worklist may have an entry for a normal edge pointing
+ // to the same node. To separate them use _next_pidx as bias.
+ ptf = PointsToNode::get_use_node(pt)->as_Field();
+ pidx_bias = _next_pidx;
+ }
+ if (!_in_worklist.test_set(ptf->pidx() + pidx_bias)) {
+ _worklist.append(pt);
+ }
}
// Put on worklist all uses of this node.
- void add_uses_to_worklist(PointsToNode* pt) {
- for (UseIterator i(pt); i.has_next(); i.next())
- _worklist.push(i.get());
+ inline void add_uses_to_worklist(PointsToNode* pt) {
+ for (UseIterator i(pt); i.has_next(); i.next()) {
+ add_to_worklist(i.get());
+ }
}
// Put on worklist all field's uses and related field nodes.
@@ -517,8 +528,8 @@ private:
}
// Helper functions
bool is_oop_field(Node* n, int offset, bool* unsafe);
- static Node* get_addp_base(Node *addp);
- static Node* find_second_addp(Node* addp, Node* n);
+ static Node* get_addp_base(Node *addp);
+ static Node* find_second_addp(Node* addp, Node* n);
// offset of a field reference
int address_offset(Node* adr, PhaseTransform *phase);
@@ -587,4 +598,17 @@ public:
#endif
};
+inline PointsToNode::PointsToNode(ConnectionGraph *CG, Node* n, EscapeState es, NodeType type):
+ _edges(CG->_compile->comp_arena(), 2, 0, NULL),
+ _uses (CG->_compile->comp_arena(), 2, 0, NULL),
+ _node(n),
+ _idx(n->_idx),
+ _pidx(CG->next_pidx()),
+ _type((u1)type),
+ _escape((u1)es),
+ _fields_escape((u1)es),
+ _flags(ScalarReplaceable) {
+ assert(n != NULL && es != UnknownEscape, "sanity");
+}
+
#endif // SHARE_VM_OPTO_ESCAPE_HPP
diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp
index 187d2699768..a601752d4cd 100644
--- a/hotspot/src/share/vm/opto/lcm.cpp
+++ b/hotspot/src/share/vm/opto/lcm.cpp
@@ -464,9 +464,7 @@ Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &re
iop == Op_CreateEx || // Create-exception must start block
iop == Op_CheckCastPP
) {
- // select the node n
- // remove n from worklist and retain the order of remaining nodes
- worklist.remove((uint)i);
+ worklist.map(i,worklist.pop());
return n;
}
@@ -552,9 +550,7 @@ Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray<int> &re
assert(idx >= 0, "index should be set");
Node *n = worklist[(uint)idx]; // Get the winner
- // select the node n
- // remove n from worklist and retain the order of remaining nodes
- worklist.remove((uint)idx);
+ worklist.map((uint)idx, worklist.pop()); // Compress worklist
return n;
}
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index a59007b7ccc..10c857ca0dd 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -268,6 +268,7 @@ class LibraryCallKit : public GraphKit {
bool inline_fp_conversions(vmIntrinsics::ID id);
bool inline_number_methods(vmIntrinsics::ID id);
bool inline_reference_get();
+ bool inline_Class_cast();
bool inline_aescrypt_Block(vmIntrinsics::ID id);
bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
@@ -869,6 +870,8 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_Reference_get: return inline_reference_get();
+ case vmIntrinsics::_Class_cast: return inline_Class_cast();
+
case vmIntrinsics::_aescrypt_encryptBlock:
case vmIntrinsics::_aescrypt_decryptBlock: return inline_aescrypt_Block(intrinsic_id());
@@ -3546,6 +3549,89 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) {
return true;
}
+//-------------------------inline_Class_cast-------------------
+bool LibraryCallKit::inline_Class_cast() {
+ Node* mirror = argument(0); // Class
+ Node* obj = argument(1);
+ const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr();
+ if (mirror_con == NULL) {
+ return false; // dead path (mirror->is_top()).
+ }
+ if (obj == NULL || obj->is_top()) {
+ return false; // dead path
+ }
+ const TypeOopPtr* tp = _gvn.type(obj)->isa_oopptr();
+
+ // First, see if Class.cast() can be folded statically.
+ // java_mirror_type() returns non-null for compile-time Class constants.
+ ciType* tm = mirror_con->java_mirror_type();
+ if (tm != NULL && tm->is_klass() &&
+ tp != NULL && tp->klass() != NULL) {
+ if (!tp->klass()->is_loaded()) {
+ // Don't use intrinsic when class is not loaded.
+ return false;
+ } else {
+ int static_res = C->static_subtype_check(tm->as_klass(), tp->klass());
+ if (static_res == Compile::SSC_always_true) {
+ // isInstance() is true - fold the code.
+ set_result(obj);
+ return true;
+ } else if (static_res == Compile::SSC_always_false) {
+ // Don't use intrinsic, have to throw ClassCastException.
+ // If the reference is null, the non-intrinsic bytecode will
+ // be optimized appropriately.
+ return false;
+ }
+ }
+ }
+
+ // Bailout intrinsic and do normal inlining if exception path is frequent.
+ if (too_many_traps(Deoptimization::Reason_intrinsic)) {
+ return false;
+ }
+
+ // Generate dynamic checks.
+ // Class.cast() is java implementation of _checkcast bytecode.
+ // Do checkcast (Parse::do_checkcast()) optimizations here.
+
+ mirror = null_check(mirror);
+ // If mirror is dead, only null-path is taken.
+ if (stopped()) {
+ return true;
+ }
+
+ // Not-subtype or the mirror's klass ptr is NULL (in case it is a primitive).
+ enum { _bad_type_path = 1, _prim_path = 2, PATH_LIMIT };
+ RegionNode* region = new RegionNode(PATH_LIMIT);
+ record_for_igvn(region);
+
+ // Now load the mirror's klass metaobject, and null-check it.
+ // If kls is null, we have a primitive mirror and
+ // nothing is an instance of a primitive type.
+ Node* kls = load_klass_from_mirror(mirror, false, region, _prim_path);
+
+ Node* res = top();
+ if (!stopped()) {
+ Node* bad_type_ctrl = top();
+ // Do checkcast optimizations.
+ res = gen_checkcast(obj, kls, &bad_type_ctrl);
+ region->init_req(_bad_type_path, bad_type_ctrl);
+ }
+ if (region->in(_prim_path) != top() ||
+ region->in(_bad_type_path) != top()) {
+ // Let Interpreter throw ClassCastException.
+ PreserveJVMState pjvms(this);
+ set_control(_gvn.transform(region));
+ uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_maybe_recompile);
+ }
+ if (!stopped()) {
+ set_result(res);
+ }
+ return true;
+}
+
+
//--------------------------inline_native_subtype_check------------------------
// This intrinsic takes the JNI calls out of the heart of
// UnsafeFieldAccessorImpl.set, which improves Field.set, readObject, etc.
@@ -4611,6 +4697,10 @@ bool LibraryCallKit::inline_arraycopy() {
Node* dest_offset = argument(3); // type: int
Node* length = argument(4); // type: int
+ // Check for allocation before we add nodes that would confuse
+ // tightly_coupled_allocation()
+ AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
+
// The following tests must be performed
// (1) src and dest are arrays.
// (2) src and dest arrays must have elements of the same BasicType
@@ -4784,7 +4874,6 @@ bool LibraryCallKit::inline_arraycopy() {
return true;
}
- AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
ArrayCopyNode* ac = ArrayCopyNode::make(this, true, src, src_offset, dest, dest_offset, length, alloc != NULL,
// Create LoadRange and LoadKlass nodes for use during macro expansion here
// so the compiler has a chance to eliminate them: during macro expansion,
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index 3d8271dc92a..8ed5154f7be 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -1257,6 +1257,16 @@ Node* LoadNode::eliminate_autobox(PhaseGVN* phase) {
result = new ConvI2LNode(phase->transform(result));
}
#endif
+ // Boxing/unboxing can be done from signed & unsigned loads (e.g. LoadUB -> ... -> LoadB pair).
+ // Need to preserve unboxing load type if it is unsigned.
+ switch(this->Opcode()) {
+ case Op_LoadUB:
+ result = new AndINode(phase->transform(result), phase->intcon(0xFF));
+ break;
+ case Op_LoadUS:
+ result = new AndINode(phase->transform(result), phase->intcon(0xFFFF));
+ break;
+ }
return result;
}
}
diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp
index 1406f8364a6..d4730e978e9 100644
--- a/hotspot/src/share/vm/opto/mulnode.cpp
+++ b/hotspot/src/share/vm/opto/mulnode.cpp
@@ -610,7 +610,7 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// convert masks which would cause a sign extension of the integer
// value. This check includes UI2L masks (0x00000000FFFFFFFF) which
// would be optimized away later in Identity.
- if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
+ if (op == Op_ConvI2L && (mask & UCONST64(0xFFFFFFFF80000000)) == 0) {
Node* andi = new AndINode(in1->in(1), phase->intcon(mask));
andi = phase->transform(andi);
return new ConvI2LNode(andi);
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index 165e187b964..6284abde6e2 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -1166,7 +1166,6 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) {
// Have we run out of code space?
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
C->record_failure("CodeCache is full");
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return NULL;
}
// Configure the code buffer.
@@ -1491,7 +1490,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
cb->insts()->maybe_expand_to_ensure_remaining(MAX_inst_size);
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
C->record_failure("CodeCache is full");
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return;
}
@@ -1648,7 +1646,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// One last check for failed CodeBuffer::expand:
if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
C->record_failure("CodeCache is full");
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return;
}
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index 7b6974e639a..3e730fdeab8 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -951,8 +951,9 @@ class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
// Optimized path if we have the bitvector form of signature
void iterate( uint64_t fingerprint ) {
- if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments
- else {
+ if (fingerprint == (uint64_t)CONST64(-1)) {
+ SignatureIterator::iterate(); // Must be too many arguments
+ } else {
_return_type = (BasicType)((fingerprint >> static_feature_size) &
result_feature_mask);
@@ -1022,8 +1023,9 @@ class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
// Optimized path if we have the bitvector form of signature
void iterate( uint64_t fingerprint ) {
- if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments
- else {
+ if (fingerprint == (uint64_t)CONST64(-1)) {
+ SignatureIterator::iterate(); // Must be too many arguments
+ } else {
_return_type = (BasicType)((fingerprint >> static_feature_size) &
result_feature_mask);
assert(fingerprint, "Fingerprint should not be 0");
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 98be942d9c7..a9eab534820 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -2583,7 +2583,14 @@ ATTRIBUTE_PRINTF(3, 0)
int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
// see bug 4399518, 4417214
if ((intptr_t)count <= 0) return -1;
- return vsnprintf(str, count, fmt, args);
+
+ int result = vsnprintf(str, count, fmt, args);
+ if ((result > 0 && (size_t)result >= count) || result == -1) {
+ str[count - 1] = '\0';
+ result = -1;
+ }
+
+ return result;
}
ATTRIBUTE_PRINTF(3, 0)
@@ -3271,8 +3278,10 @@ static inline arrayOop check_array(JNIEnv *env, jobject arr, bool type_array_onl
THROW_0(vmSymbols::java_lang_NullPointerException());
}
oop a = JNIHandles::resolve_non_null(arr);
- if (!a->is_array() || (type_array_only && !a->is_typeArray())) {
+ if (!a->is_array()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array");
+ } else if (type_array_only && !a->is_typeArray()) {
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array of primitive type");
}
return arrayOop(a);
}
diff --git a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
index c6633bf34a9..53b5850712e 100644
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
@@ -41,6 +41,7 @@
void JvmtiClassFileReconstituter::write_field_infos() {
HandleMark hm(thread());
Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations();
+ Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations();
// Compute the real number of Java fields
int java_fields = ikh()->java_fields_count();
@@ -55,6 +56,7 @@ void JvmtiClassFileReconstituter::write_field_infos() {
// int offset = ikh()->field_offset( index );
int generic_signature_index = fs.generic_signature_index();
AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index());
+ AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index());
// JVMSpec| field_info {
// JVMSpec| u2 access_flags;
@@ -80,6 +82,9 @@ void JvmtiClassFileReconstituter::write_field_infos() {
if (anno != NULL) {
++attr_count; // has RuntimeVisibleAnnotations attribute
}
+ if (type_anno != NULL) {
+ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
+ }
write_u2(attr_count);
@@ -97,6 +102,9 @@ void JvmtiClassFileReconstituter::write_field_infos() {
if (anno != NULL) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
}
+ if (type_anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
+ }
}
}
@@ -537,6 +545,7 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
AnnotationArray* anno = method->annotations();
AnnotationArray* param_anno = method->parameter_annotations();
AnnotationArray* default_anno = method->annotation_default();
+ AnnotationArray* type_anno = method->type_annotations();
// skip generated default interface methods
if (method->is_overpass()) {
@@ -572,6 +581,9 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
if (param_anno != NULL) {
++attr_count; // has RuntimeVisibleParameterAnnotations attribute
}
+ if (type_anno != NULL) {
+ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
+ }
write_u2(attr_count);
if (const_method->code_size() > 0) {
@@ -596,6 +608,9 @@ void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
if (param_anno != NULL) {
write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
}
+ if (type_anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
+ }
}
// Write the class attributes portion of ClassFile structure
@@ -605,6 +620,7 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
u2 inner_classes_length = inner_classes_attribute_length();
Symbol* generic_signature = ikh()->generic_signature();
AnnotationArray* anno = ikh()->class_annotations();
+ AnnotationArray* type_anno = ikh()->class_type_annotations();
int attr_count = 0;
if (generic_signature != NULL) {
@@ -622,6 +638,9 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
if (anno != NULL) {
++attr_count; // has RuntimeVisibleAnnotations attribute
}
+ if (type_anno != NULL) {
+ ++attr_count; // has RuntimeVisibleTypeAnnotations attribute
+ }
if (cpool()->operands() != NULL) {
++attr_count;
}
@@ -643,6 +662,9 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
if (anno != NULL) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
}
+ if (type_anno != NULL) {
+ write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
+ }
if (cpool()->operands() != NULL) {
write_bootstrapmethod_attribute();
}
diff --git a/hotspot/src/share/vm/prims/jvmtiEnv.cpp b/hotspot/src/share/vm/prims/jvmtiEnv.cpp
index 7d6b121e5fa..840fd65cc85 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp
@@ -2263,6 +2263,8 @@ JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** meth
int result_length = instanceK_h->methods()->length();
jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
int index;
+ bool jmethodids_found = true;
+
if (JvmtiExport::can_maintain_original_method_order()) {
// Use the original method ordering indices stored in the class, so we can emit
// jmethodIDs in the order they appeared in the class file
@@ -2270,14 +2272,40 @@ JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** meth
Method* m = instanceK_h->methods()->at(index);
int original_index = instanceK_h->method_ordering()->at(index);
assert(original_index >= 0 && original_index < result_length, "invalid original method index");
- jmethodID id = m->jmethod_id();
+ jmethodID id;
+ if (jmethodids_found) {
+ id = m->find_jmethod_id_or_null();
+ if (id == NULL) {
+ // If we find an uninitialized value, make sure there is
+ // enough space for all the uninitialized values we might
+ // find.
+ instanceK_h->ensure_space_for_methodids(index);
+ jmethodids_found = false;
+ id = m->jmethod_id();
+ }
+ } else {
+ id = m->jmethod_id();
+ }
result_list[original_index] = id;
}
} else {
// otherwise just copy in any order
for (index = 0; index < result_length; index++) {
Method* m = instanceK_h->methods()->at(index);
- jmethodID id = m->jmethod_id();
+ jmethodID id;
+ if (jmethodids_found) {
+ id = m->find_jmethod_id_or_null();
+ if (id == NULL) {
+ // If we find an uninitialized value, make sure there is
+ // enough space for all the uninitialized values we might
+ // find.
+ instanceK_h->ensure_space_for_methodids(index);
+ jmethodids_found = false;
+ id = m->jmethod_id();
+ }
+ } else {
+ id = m->jmethod_id();
+ }
result_list[index] = id;
}
}
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 796f5580326..9335857ee56 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -1569,6 +1569,29 @@ bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class,
return false;
}
+ // rewrite constant pool references in the class_type_annotations:
+ if (!rewrite_cp_refs_in_class_type_annotations(scratch_class, THREAD)) {
+ // propagate failure back to caller
+ return false;
+ }
+
+ // rewrite constant pool references in the fields_type_annotations:
+ if (!rewrite_cp_refs_in_fields_type_annotations(scratch_class, THREAD)) {
+ // propagate failure back to caller
+ return false;
+ }
+
+ // rewrite constant pool references in the methods_type_annotations:
+ if (!rewrite_cp_refs_in_methods_type_annotations(scratch_class, THREAD)) {
+ // propagate failure back to caller
+ return false;
+ }
+
+ // There can be type annotations in the Code part of a method_info attribute.
+ // These annotations are not accessible, even by reflection.
+ // Currently they are not even parsed by the ClassFileParser.
+ // If runtime access is added they will also need to be rewritten.
+
// rewrite source file name index:
u2 source_file_name_idx = scratch_class->source_file_name_index();
if (source_file_name_idx != 0) {
@@ -2239,6 +2262,588 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations(
} // end rewrite_cp_refs_in_methods_default_annotations()
+// Rewrite constant pool references in a class_type_annotations field.
+bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS) {
+
+ AnnotationArray* class_type_annotations = scratch_class->class_type_annotations();
+ if (class_type_annotations == NULL || class_type_annotations->length() == 0) {
+ // no class_type_annotations so nothing to do
+ return true;
+ }
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("class_type_annotations length=%d", class_type_annotations->length()));
+
+ int byte_i = 0; // byte index into class_type_annotations
+ return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations,
+ byte_i, "ClassFile", THREAD);
+} // end rewrite_cp_refs_in_class_type_annotations()
+
+
+// Rewrite constant pool references in a fields_type_annotations field.
+bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS) {
+
+ Array<AnnotationArray*>* fields_type_annotations = scratch_class->fields_type_annotations();
+ if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) {
+ // no fields_type_annotations so nothing to do
+ return true;
+ }
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("fields_type_annotations length=%d", fields_type_annotations->length()));
+
+ for (int i = 0; i < fields_type_annotations->length(); i++) {
+ AnnotationArray* field_type_annotations = fields_type_annotations->at(i);
+ if (field_type_annotations == NULL || field_type_annotations->length() == 0) {
+ // this field does not have any annotations so skip it
+ continue;
+ }
+
+ int byte_i = 0; // byte index into field_type_annotations
+ if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations,
+ byte_i, "field_info", THREAD)) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("bad field_type_annotations at %d", i));
+ // propagate failure back to caller
+ return false;
+ }
+ }
+
+ return true;
+} // end rewrite_cp_refs_in_fields_type_annotations()
+
+
+// Rewrite constant pool references in a methods_type_annotations field.
+bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS) {
+
+ for (int i = 0; i < scratch_class->methods()->length(); i++) {
+ Method* m = scratch_class->methods()->at(i);
+ AnnotationArray* method_type_annotations = m->constMethod()->type_annotations();
+
+ if (method_type_annotations == NULL || method_type_annotations->length() == 0) {
+ // this method does not have any annotations so skip it
+ continue;
+ }
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("methods type_annotations length=%d", method_type_annotations->length()));
+
+ int byte_i = 0; // byte index into method_type_annotations
+ if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations,
+ byte_i, "method_info", THREAD)) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("bad method_type_annotations at %d", i));
+ // propagate failure back to caller
+ return false;
+ }
+ }
+
+ return true;
+} // end rewrite_cp_refs_in_methods_type_annotations()
+
+
+// Rewrite constant pool references in a type_annotations
+// field. This "structure" is adapted from the
+// RuntimeVisibleTypeAnnotations_attribute described in
+// section 4.7.20 of the Java SE 8 Edition of the VM spec:
+//
+// type_annotations_typeArray {
+// u2 num_annotations;
+// type_annotation annotations[num_annotations];
+// }
+//
+bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS) {
+
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ // not enough room for num_annotations field
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for num_annotations field"));
+ return false;
+ }
+
+ u2 num_annotations = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("num_type_annotations=%d", num_annotations));
+
+ int calc_num_annotations = 0;
+ for (; calc_num_annotations < num_annotations; calc_num_annotations++) {
+ if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray,
+ byte_i_ref, location_mesg, THREAD)) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("bad type_annotation_struct at %d", calc_num_annotations));
+ // propagate failure back to caller
+ return false;
+ }
+ }
+ assert(num_annotations == calc_num_annotations, "sanity check");
+
+ if (byte_i_ref != type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("read wrong amount of bytes at end of processing "
+ "type_annotations_typeArray (%d of %d bytes were read)",
+ byte_i_ref, type_annotations_typeArray->length()));
+ return false;
+ }
+
+ return true;
+} // end rewrite_cp_refs_in_type_annotations_typeArray()
+
+
+// Rewrite constant pool references in a type_annotation
+// field. This "structure" is adapted from the
+// RuntimeVisibleTypeAnnotations_attribute described in
+// section 4.7.20 of the Java SE 8 Edition of the VM spec:
+//
+// type_annotation {
+// u1 target_type;
+// union {
+// type_parameter_target;
+// supertype_target;
+// type_parameter_bound_target;
+// empty_target;
+// method_formal_parameter_target;
+// throws_target;
+// localvar_target;
+// catch_target;
+// offset_target;
+// type_argument_target;
+// } target_info;
+// type_path target_path;
+// annotation anno;
+// }
+//
+bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS) {
+
+ if (!skip_type_annotation_target(type_annotations_typeArray,
+ byte_i_ref, location_mesg, THREAD)) {
+ return false;
+ }
+
+ if (!skip_type_annotation_type_path(type_annotations_typeArray,
+ byte_i_ref, THREAD)) {
+ return false;
+ }
+
+ if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray,
+ byte_i_ref, THREAD)) {
+ return false;
+ }
+
+ return true;
+} // end rewrite_cp_refs_in_type_annotation_struct()
+
+
+// Read, verify and skip over the target_type and target_info part
+// so that rewriting can continue in the later parts of the struct.
+//
+// u1 target_type;
+// union {
+// type_parameter_target;
+// supertype_target;
+// type_parameter_bound_target;
+// empty_target;
+// method_formal_parameter_target;
+// throws_target;
+// localvar_target;
+// catch_target;
+// offset_target;
+// type_argument_target;
+// } target_info;
+//
+bool VM_RedefineClasses::skip_type_annotation_target(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS) {
+
+ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
+ // not enough room for a target_type let alone the rest of a type_annotation
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a target_type"));
+ return false;
+ }
+
+ u1 target_type = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type));
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg));
+
+ // Skip over target_info
+ switch (target_type) {
+ case 0x00:
+ // kind: type parameter declaration of generic class or interface
+ // location: ClassFile
+ case 0x01:
+ // kind: type parameter declaration of generic method or constructor
+ // location: method_info
+
+ {
+ // struct:
+ // type_parameter_target {
+ // u1 type_parameter_index;
+ // }
+ //
+ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a type_parameter_target"));
+ return false;
+ }
+
+ u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("type_parameter_target: type_parameter_index=%d",
+ type_parameter_index));
+ } break;
+
+ case 0x10:
+ // kind: type in extends clause of class or interface declaration
+ // (including the direct superclass of an anonymous class declaration),
+ // or in implements clause of interface declaration
+ // location: ClassFile
+
+ {
+ // struct:
+ // supertype_target {
+ // u2 supertype_index;
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a supertype_target"));
+ return false;
+ }
+
+ u2 supertype_index = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("supertype_target: supertype_index=%d", supertype_index));
+ } break;
+
+ case 0x11:
+ // kind: type in bound of type parameter declaration of generic class or interface
+ // location: ClassFile
+ case 0x12:
+ // kind: type in bound of type parameter declaration of generic method or constructor
+ // location: method_info
+
+ {
+ // struct:
+ // type_parameter_bound_target {
+ // u1 type_parameter_index;
+ // u1 bound_index;
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a type_parameter_bound_target"));
+ return false;
+ }
+
+ u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+ u1 bound_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d",
+ type_parameter_index, bound_index));
+ } break;
+
+ case 0x13:
+ // kind: type in field declaration
+ // location: field_info
+ case 0x14:
+ // kind: return type of method, or type of newly constructed object
+ // location: method_info
+ case 0x15:
+ // kind: receiver type of method or constructor
+ // location: method_info
+
+ {
+ // struct:
+ // empty_target {
+ // }
+ //
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("empty_target"));
+ } break;
+
+ case 0x16:
+ // kind: type in formal parameter declaration of method, constructor, or lambda expression
+ // location: method_info
+
+ {
+ // struct:
+ // formal_parameter_target {
+ // u1 formal_parameter_index;
+ // }
+ //
+ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a formal_parameter_target"));
+ return false;
+ }
+
+ u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("formal_parameter_target: formal_parameter_index=%d",
+ formal_parameter_index));
+ } break;
+
+ case 0x17:
+ // kind: type in throws clause of method or constructor
+ // location: method_info
+
+ {
+ // struct:
+ // throws_target {
+ // u2 throws_type_index
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a throws_target"));
+ return false;
+ }
+
+ u2 throws_type_index = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("throws_target: throws_type_index=%d", throws_type_index));
+ } break;
+
+ case 0x40:
+ // kind: type in local variable declaration
+ // location: Code
+ case 0x41:
+ // kind: type in resource variable declaration
+ // location: Code
+
+ {
+ // struct:
+ // localvar_target {
+ // u2 table_length;
+ // struct {
+ // u2 start_pc;
+ // u2 length;
+ // u2 index;
+ // } table[table_length];
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ // not enough room for a table_length let alone the rest of a localvar_target
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a localvar_target table_length"));
+ return false;
+ }
+
+ u2 table_length = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("localvar_target: table_length=%d", table_length));
+
+ int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry
+ int table_size = table_length * table_struct_size;
+
+ if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) {
+ // not enough room for a table
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a table array of length %d", table_length));
+ return false;
+ }
+
+ // Skip over table
+ byte_i_ref += table_size;
+ } break;
+
+ case 0x42:
+ // kind: type in exception parameter declaration
+ // location: Code
+
+ {
+ // struct:
+ // catch_target {
+ // u2 exception_table_index;
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a catch_target"));
+ return false;
+ }
+
+ u2 exception_table_index = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("catch_target: exception_table_index=%d", exception_table_index));
+ } break;
+
+ case 0x43:
+ // kind: type in instanceof expression
+ // location: Code
+ case 0x44:
+ // kind: type in new expression
+ // location: Code
+ case 0x45:
+ // kind: type in method reference expression using ::new
+ // location: Code
+ case 0x46:
+ // kind: type in method reference expression using ::Identifier
+ // location: Code
+
+ {
+ // struct:
+ // offset_target {
+ // u2 offset;
+ // }
+ //
+ if ((byte_i_ref + 2) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a offset_target"));
+ return false;
+ }
+
+ u2 offset = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("offset_target: offset=%d", offset));
+ } break;
+
+ case 0x47:
+ // kind: type in cast expression
+ // location: Code
+ case 0x48:
+ // kind: type argument for generic constructor in new expression or
+ // explicit constructor invocation statement
+ // location: Code
+ case 0x49:
+ // kind: type argument for generic method in method invocation expression
+ // location: Code
+ case 0x4A:
+ // kind: type argument for generic constructor in method reference expression using ::new
+ // location: Code
+ case 0x4B:
+ // kind: type argument for generic method in method reference expression using ::Identifier
+ // location: Code
+
+ {
+ // struct:
+ // type_argument_target {
+ // u2 offset;
+ // u1 type_argument_index;
+ // }
+ //
+ if ((byte_i_ref + 3) > type_annotations_typeArray->length()) {
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a type_argument_target"));
+ return false;
+ }
+
+ u2 offset = Bytes::get_Java_u2((address)
+ type_annotations_typeArray->adr_at(byte_i_ref));
+ byte_i_ref += 2;
+ u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("type_argument_target: offset=%d, type_argument_index=%d",
+ offset, type_argument_index));
+ } break;
+
+ default:
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("unknown target_type"));
+#ifdef ASSERT
+ ShouldNotReachHere();
+#endif
+ return false;
+ }
+
+ return true;
+} // end skip_type_annotation_target()
+
+
+// Read, verify and skip over the type_path part so that rewriting
+// can continue in the later parts of the struct.
+//
+// type_path {
+// u1 path_length;
+// {
+// u1 type_path_kind;
+// u1 type_argument_index;
+// } path[path_length];
+// }
+//
+bool VM_RedefineClasses::skip_type_annotation_type_path(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) {
+
+ if ((byte_i_ref + 1) > type_annotations_typeArray->length()) {
+ // not enough room for a path_length let alone the rest of the type_path
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for a type_path"));
+ return false;
+ }
+
+ u1 path_length = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("type_path: path_length=%d", path_length));
+
+ int calc_path_length = 0;
+ for (; calc_path_length < path_length; calc_path_length++) {
+ if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) {
+ // not enough room for a path
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("length() is too small for path entry %d of %d",
+ calc_path_length, path_length));
+ return false;
+ }
+
+ u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+ u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref);
+ byte_i_ref += 1;
+
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d",
+ calc_path_length, type_path_kind, type_argument_index));
+
+ if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) {
+ // not enough room for a path
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD,
+ ("inconsistent type_path values"));
+ return false;
+ }
+ }
+ assert(path_length == calc_path_length, "sanity check");
+
+ return true;
+} // end skip_type_annotation_type_path()
+
+
// Rewrite constant pool references in the method's stackmap table.
// These "structures" are adapted from the StackMapTable_attribute that
// is described in section 4.8.4 of the 6.0 version of the VM spec
@@ -3223,23 +3828,6 @@ void VM_RedefineClasses::compute_added_deleted_matching_methods() {
void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class,
instanceKlassHandle scratch_class) {
- // Since there is currently no rewriting of type annotations indexes
- // into the CP, we null out type annotations on scratch_class before
- // we swap annotations with the_class rather than facing the
- // possibility of shipping annotations with broken indexes to
- // Java-land.
- ClassLoaderData* loader_data = scratch_class->class_loader_data();
- AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations();
- if (new_class_type_annotations != NULL) {
- MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations);
- scratch_class->annotations()->set_class_type_annotations(NULL);
- }
- Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations();
- if (new_field_type_annotations != NULL) {
- Annotations::free_contents(loader_data, new_field_type_annotations);
- scratch_class->annotations()->set_fields_type_annotations(NULL);
- }
-
// Swap annotation fields values
Annotations* old_annotations = the_class->annotations();
the_class->set_annotations(scratch_class->annotations());
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
index 2383aa86e17..8394f5f50a3 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp
@@ -452,6 +452,17 @@ class VM_RedefineClasses: public VM_Operation {
instanceKlassHandle scratch_class, TRAPS);
bool rewrite_cp_refs_in_element_value(
AnnotationArray* class_annotations, int &byte_i_ref, TRAPS);
+ bool rewrite_cp_refs_in_type_annotations_typeArray(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS);
+ bool rewrite_cp_refs_in_type_annotation_struct(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS);
+ bool skip_type_annotation_target(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref,
+ const char * location_mesg, TRAPS);
+ bool skip_type_annotation_type_path(
+ AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS);
bool rewrite_cp_refs_in_fields_annotations(
instanceKlassHandle scratch_class, TRAPS);
void rewrite_cp_refs_in_method(methodHandle method,
@@ -463,6 +474,12 @@ class VM_RedefineClasses: public VM_Operation {
instanceKlassHandle scratch_class, TRAPS);
bool rewrite_cp_refs_in_methods_parameter_annotations(
instanceKlassHandle scratch_class, TRAPS);
+ bool rewrite_cp_refs_in_class_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS);
+ bool rewrite_cp_refs_in_fields_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS);
+ bool rewrite_cp_refs_in_methods_type_annotations(
+ instanceKlassHandle scratch_class, TRAPS);
void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS);
void rewrite_cp_refs_in_verification_type_info(
address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 8053a3c9763..8013a1329a8 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -36,6 +36,7 @@
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
+#include "utilities/exceptions.hpp"
/*
@@ -55,26 +56,30 @@
bool MethodHandles::_enabled = false; // set true after successful native linkage
MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
-//------------------------------------------------------------------------------
-// MethodHandles::generate_adapters
-//
-void MethodHandles::generate_adapters() {
- if (SystemDictionary::MethodHandle_klass() == NULL) return;
+
+/**
+ * Generates method handle adapters. Returns 'false' if memory allocation
+ * failed and true otherwise.
+ */
+bool MethodHandles::generate_adapters() {
+ if (SystemDictionary::MethodHandle_klass() == NULL) {
+ return true;
+ }
assert(_adapter_code == NULL, "generate only once");
ResourceMark rm;
TraceTime timer("MethodHandles adapters generation", TraceStartupTime);
_adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size);
- if (_adapter_code == NULL)
- vm_exit_out_of_memory(adapter_code_size, OOM_MALLOC_ERROR,
- "CodeCache: no room for MethodHandles adapters");
- {
- CodeBuffer code(_adapter_code);
- MethodHandlesAdapterGenerator g(&code);
- g.generate();
- code.log_section_sizes("MethodHandlesAdapterBlob");
+ if (_adapter_code == NULL) {
+ return false;
}
+
+ CodeBuffer code(_adapter_code);
+ MethodHandlesAdapterGenerator g(&code);
+ g.generate();
+ code.log_section_sizes("MethodHandlesAdapterBlob");
+ return true;
}
//------------------------------------------------------------------------------
@@ -1401,7 +1406,9 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
}
if (enable_MH) {
- MethodHandles::generate_adapters();
+ if (MethodHandles::generate_adapters() == false) {
+ THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for method handle adapters");
+ }
MethodHandles::set_enabled(true);
}
}
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
index 323cd823664..4084d6c7d8b 100644
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
@@ -69,7 +69,7 @@ class MethodHandles: AllStatic {
enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 };
// Generate MethodHandles adapters.
- static void generate_adapters();
+ static bool generate_adapters();
// Called from MethodHandlesAdapterGenerator.
static address generate_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid);
diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp
index c0e4f30d2a2..f465e61589e 100644
--- a/hotspot/src/share/vm/prims/unsafe.cpp
+++ b/hotspot/src/share/vm/prims/unsafe.cpp
@@ -802,8 +802,7 @@ UNSAFE_END
static inline void throw_new(JNIEnv *env, const char *ename) {
char buf[100];
- strcpy(buf, "java/lang/");
- strcat(buf, ename);
+ jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
jclass cls = env->FindClass(buf);
if (env->ExceptionCheck()) {
env->ExceptionClear();
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
index 89b9807c4ca..0bc2b71c892 100644
--- a/hotspot/src/share/vm/prims/whitebox.cpp
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -282,7 +282,7 @@ WB_END
// NMT picks it up correctly
WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
jlong addr = 0;
- addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
+ addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
return addr;
WB_END
@@ -291,7 +291,7 @@ WB_END
WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack))
address pc = (address)(size_t)pseudo_stack;
NativeCallStack stack(&pc, 1);
- return (jlong)os::malloc(size, mtTest, stack);
+ return (jlong)(uintptr_t)os::malloc(size, mtTest, stack);
WB_END
// Free the memory allocated by NMTAllocTest
@@ -326,15 +326,6 @@ WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env))
return MemTracker::tracking_level() == NMT_detail;
WB_END
-WB_ENTRY(void, WB_NMTOverflowHashBucket(JNIEnv* env, jobject o, jlong num))
- address pc = (address)1;
- for (jlong index = 0; index < num; index ++) {
- NativeCallStack stack(&pc, 1);
- os::malloc(0, mtTest, stack);
- pc += MallocSiteTable::hash_buckets();
- }
-WB_END
-
WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
// Test that we can downgrade NMT levels but not upgrade them.
if (MemTracker::tracking_level() == NMT_off) {
@@ -365,6 +356,12 @@ WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
return MemTracker::tracking_level() == NMT_minimal;
}
WB_END
+
+WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
+ int hash_size = MallocSiteTable::hash_buckets();
+ assert(hash_size > 0, "NMT hash_size should be > 0");
+ return (jint)hash_size;
+WB_END
#endif // INCLUDE_NMT
static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
@@ -386,19 +383,10 @@ WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jbool
CHECK_JNI_EXCEPTION_(env, result);
MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
- nmethod* code;
if (is_osr) {
- int bci = InvocationEntryBci;
- while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) {
- code->mark_for_deoptimization();
- ++result;
- bci = code->osr_entry_bci() + 1;
- }
- } else {
- code = mh->code();
- }
- if (code != NULL) {
- code->mark_for_deoptimization();
+ result += mh->mark_osr_nmethods();
+ } else if (mh->code() != NULL) {
+ mh->code()->mark_for_deoptimization();
++result;
}
result += CodeCache::mark_for_deoptimization(mh());
@@ -518,16 +506,6 @@ class AlwaysFalseClosure : public BoolObjectClosure {
static AlwaysFalseClosure always_false;
-class VM_WhiteBoxCleanMethodData : public VM_WhiteBoxOperation {
- public:
- VM_WhiteBoxCleanMethodData(MethodData* mdo) : _mdo(mdo) { }
- void doit() {
- _mdo->clean_method_data(&always_false);
- }
- private:
- MethodData* _mdo;
-};
-
WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
CHECK_JNI_EXCEPTION(env);
@@ -543,8 +521,8 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
for (int i = 0; i < arg_count; i++) {
mdo->set_arg_modified(i, 0);
}
- VM_WhiteBoxCleanMethodData op(mdo);
- VMThread::execute(&op);
+ MutexLockerEx mu(mdo->extra_data_lock());
+ mdo->clean_method_data(&always_false);
}
mh->clear_not_c1_compilable();
@@ -566,13 +544,13 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
WB_END
template <typename T>
-static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) {
+static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*, bool, bool)) {
if (name == NULL) {
return false;
}
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
const char* flag_name = env->GetStringUTFChars(name, NULL);
- bool result = (*TAt)(flag_name, value);
+ bool result = (*TAt)(flag_name, value, true, true);
env->ReleaseStringUTFChars(name, flag_name);
return result;
}
@@ -619,6 +597,24 @@ static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) {
return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
}
+static Flag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
+ ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
+ const char* flag_name = env->GetStringUTFChars(name, NULL);
+ Flag* result = Flag::find_flag(flag_name, strlen(flag_name), true, true);
+ env->ReleaseStringUTFChars(name, flag_name);
+ return result;
+}
+
+WB_ENTRY(jboolean, WB_IsConstantVMFlag(JNIEnv* env, jobject o, jstring name))
+ Flag* flag = getVMFlag(thread, env, name);
+ return (flag != NULL) && flag->is_constant_in_binary();
+WB_END
+
+WB_ENTRY(jboolean, WB_IsLockedVMFlag(JNIEnv* env, jobject o, jstring name))
+ Flag* flag = getVMFlag(thread, env, name);
+ return (flag != NULL) && !(flag->is_unlocked() || flag->is_unlocker());
+WB_END
+
WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
bool result;
if (GetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAt)) {
@@ -794,20 +790,24 @@ WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jbo
ThreadToNativeFromVM ttn(thread);
jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
- result = env->NewObjectArray(2, clazz, NULL);
+ result = env->NewObjectArray(3, clazz, NULL);
if (result == NULL) {
return result;
}
- jobject obj = integerBox(thread, env, code->comp_level());
+ jobject level = integerBox(thread, env, code->comp_level());
CHECK_JNI_EXCEPTION_(env, NULL);
- env->SetObjectArrayElement(result, 0, obj);
+ env->SetObjectArrayElement(result, 0, level);
jbyteArray insts = env->NewByteArray(insts_size);
CHECK_JNI_EXCEPTION_(env, NULL);
env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
env->SetObjectArrayElement(result, 1, insts);
+ jobject id = integerBox(thread, env, code->compile_id());
+ CHECK_JNI_EXCEPTION_(env, NULL);
+ env->SetObjectArrayElement(result, 2, id);
+
return result;
WB_END
@@ -989,9 +989,9 @@ static JNINativeMethod methods[] = {
{CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
{CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
{CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
- {CC"NMTOverflowHashBucket", CC"(J)V", (void*)&WB_NMTOverflowHashBucket},
{CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
{CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel},
+ {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize },
#endif // INCLUDE_NMT
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
{CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
@@ -1018,6 +1018,8 @@ static JNINativeMethod methods[] = {
CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
{CC"clearMethodState",
CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
+ {CC"isConstantVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
+ {CC"isLockedVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
{CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
{CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
{CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 346208fa427..ff2a25fe1bc 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -54,7 +54,7 @@
#endif // INCLUDE_ALL_GCS
// Note: This is a special bug reporting site for the JVM
-#define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
+#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
#define DEFAULT_JAVA_LAUNCHER "generic"
// Disable options not supported in this release, with a warning if they
@@ -306,6 +306,9 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
{ "ReflectionWrapResolutionErrors",JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "VerifyReflectionBytecodes", JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "AutoShutdownNMT", JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "NmethodSweepFraction", JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "NmethodSweepCheckInterval", JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "CodeCacheMinimumFreeSpace", JDK_Version::jdk(9), JDK_Version::jdk(10) },
#ifndef ZERO
{ "UseFastAccessorMethods", JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "UseFastEmptyMethods", JDK_Version::jdk(9), JDK_Version::jdk(10) },
@@ -2528,7 +2531,7 @@ bool Arguments::check_vm_args_consistency() {
// Check lower bounds of the code cache
// Template Interpreter code is approximately 3X larger in debug builds.
- uint min_code_cache_size = (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3)) + CodeCacheMinimumFreeSpace;
+ uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
if (InitialCodeCacheSize < (uintx)os::vm_page_size()) {
jio_fprintf(defaultStream::error_stream(),
"Invalid InitialCodeCacheSize=%dK. Must be at least %dK.\n", InitialCodeCacheSize/K,
@@ -2564,10 +2567,11 @@ bool Arguments::check_vm_args_consistency() {
status = false;
}
- status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
status &= verify_interval(CodeCacheMinBlockLength, 1, 100, "CodeCacheMinBlockLength");
status &= verify_interval(CodeCacheSegmentSize, 1, 1024, "CodeCacheSegmentSize");
+ status &= verify_interval(StartAggressiveSweepingAt, 0, 100, "StartAggressiveSweepingAt");
+
int min_number_of_compiler_threads = get_min_number_of_compiler_threads();
// The default CICompilerCount's value is CI_COMPILER_COUNT.
@@ -3992,12 +3996,6 @@ jint Arguments::apply_ergo() {
#endif
#endif
- // Set NmethodSweepFraction after the size of the code cache is adapted (in case of tiered)
- if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
- FLAG_SET_DEFAULT(NmethodSweepFraction, 1 + ReservedCodeCacheSize / (16 * M));
- }
-
-
// Set heap size based on available physical memory
set_heap_size();
@@ -4065,13 +4063,6 @@ jint Arguments::apply_ergo() {
}
#ifndef PRODUCT
- if (CompileTheWorld) {
- // Force NmethodSweeper to sweep whole CodeCache each time.
- if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
- NmethodSweepFraction = 1;
- }
- }
-
if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) {
if (use_vm_log()) {
LogVMOutput = true;
diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp
index b94b7142b7e..95587bff533 100644
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp
@@ -1173,7 +1173,7 @@ Deoptimization::get_method_data(JavaThread* thread, methodHandle m,
void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
// in case of an unresolved klass entry, load the class.
if (constant_pool->tag_at(index).is_unresolved_klass()) {
- Klass* tk = constant_pool->klass_at(index, CHECK);
+ Klass* tk = constant_pool->klass_at_ignore_error(index, CHECK);
return;
}
diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp
index c5564c913c9..8d77691a282 100644
--- a/hotspot/src/share/vm/runtime/globals.cpp
+++ b/hotspot/src/share/vm/runtime/globals.cpp
@@ -28,6 +28,7 @@
#include "runtime/arguments.hpp"
#include "runtime/globals.hpp"
#include "runtime/globals_extension.hpp"
+#include "runtime/os.hpp"
#include "utilities/ostream.hpp"
#include "utilities/macros.hpp"
#include "utilities/top.hpp"
@@ -634,8 +635,8 @@ static void trace_flag_changed(const char* name, const T old_value, const T new_
e.commit();
}
-bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_bool()) return false;
*value = result->get_bool();
@@ -662,8 +663,8 @@ void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Fla
faddr->set_origin(origin);
}
-bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_intx()) return false;
*value = result->get_intx();
@@ -690,8 +691,8 @@ void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Fla
faddr->set_origin(origin);
}
-bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_uintx()) return false;
*value = result->get_uintx();
@@ -718,8 +719,8 @@ void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, F
faddr->set_origin(origin);
}
-bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_uint64_t()) return false;
*value = result->get_uint64_t();
@@ -746,8 +747,8 @@ void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t va
faddr->set_origin(origin);
}
-bool CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_size_t()) return false;
*value = result->get_size_t();
@@ -774,8 +775,8 @@ void CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value,
faddr->set_origin(origin);
}
-bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_double()) return false;
*value = result->get_double();
@@ -802,8 +803,8 @@ void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value,
faddr->set_origin(origin);
}
-bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value) {
- Flag* result = Flag::find_flag(name, len);
+bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
+ Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
if (result == NULL) return false;
if (!result->is_ccstr()) return false;
*value = result->get_ccstr();
@@ -818,15 +819,12 @@ bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Fl
trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
char* new_value = NULL;
if (*value != NULL) {
- new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal);
- strcpy(new_value, *value);
+ new_value = os::strdup_check_oom(*value);
}
result->set_ccstr(new_value);
if (result->is_default() && old_value != NULL) {
// Prior value is NOT heap allocated, but was a literal constant.
- char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
- strcpy(old_value_to_free, old_value);
- old_value = old_value_to_free;
+ old_value = os::strdup_check_oom(old_value);
}
*value = old_value;
result->set_origin(origin);
@@ -838,8 +836,7 @@ void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, F
guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
ccstr old_value = faddr->get_ccstr();
trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
- char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
- strcpy(new_value, value);
+ char* new_value = os::strdup_check_oom(value);
faddr->set_ccstr(new_value);
if (!faddr->is_default() && old_value != NULL) {
// Prior value is heap allocated so free it.
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index bbab0184627..e74b9bbdf20 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -379,38 +379,38 @@ class SizeTFlagSetting {
class CommandLineFlags {
public:
- static bool boolAt(const char* name, size_t len, bool* value);
- static bool boolAt(const char* name, bool* value) { return boolAt(name, strlen(name), value); }
+ static bool boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
+ static bool boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false) { return boolAt(name, strlen(name), value, allow_locked, return_flag); }
static bool boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin);
static bool boolAtPut(const char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); }
- static bool intxAt(const char* name, size_t len, intx* value);
- static bool intxAt(const char* name, intx* value) { return intxAt(name, strlen(name), value); }
+ static bool intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
+ static bool intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false) { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
static bool intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin);
static bool intxAtPut(const char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); }
- static bool uintxAt(const char* name, size_t len, uintx* value);
- static bool uintxAt(const char* name, uintx* value) { return uintxAt(name, strlen(name), value); }
+ static bool uintxAt(const char* name, size_t len, uintx* value, bool allow_locked = false, bool return_flag = false);
+ static bool uintxAt(const char* name, uintx* value, bool allow_locked = false, bool return_flag = false) { return uintxAt(name, strlen(name), value, allow_locked, return_flag); }
static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin);
static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
- static bool size_tAt(const char* name, size_t len, size_t* value);
- static bool size_tAt(const char* name, size_t* value) { return size_tAt(name, strlen(name), value); }
+ static bool size_tAt(const char* name, size_t len, size_t* value, bool allow_locked = false, bool return_flag = false);
+ static bool size_tAt(const char* name, size_t* value, bool allow_locked = false, bool return_flag = false) { return size_tAt(name, strlen(name), value, allow_locked, return_flag); }
static bool size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin);
static bool size_tAtPut(const char* name, size_t* value, Flag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
- static bool uint64_tAt(const char* name, size_t len, uint64_t* value);
- static bool uint64_tAt(const char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
+ static bool uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked = false, bool return_flag = false);
+ static bool uint64_tAt(const char* name, uint64_t* value, bool allow_locked = false, bool return_flag = false) { return uint64_tAt(name, strlen(name), value, allow_locked, return_flag); }
static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin);
static bool uint64_tAtPut(const char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
- static bool doubleAt(const char* name, size_t len, double* value);
- static bool doubleAt(const char* name, double* value) { return doubleAt(name, strlen(name), value); }
+ static bool doubleAt(const char* name, size_t len, double* value, bool allow_locked = false, bool return_flag = false);
+ static bool doubleAt(const char* name, double* value, bool allow_locked = false, bool return_flag = false) { return doubleAt(name, strlen(name), value, allow_locked, return_flag); }
static bool doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin);
static bool doubleAtPut(const char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
- static bool ccstrAt(const char* name, size_t len, ccstr* value);
- static bool ccstrAt(const char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); }
+ static bool ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked = false, bool return_flag = false);
+ static bool ccstrAt(const char* name, ccstr* value, bool allow_locked = false, bool return_flag = false) { return ccstrAt(name, strlen(name), value, allow_locked, return_flag); }
// Contract: Flag will make private copy of the incoming value.
// Outgoing value is always malloc-ed, and caller MUST call free.
static bool ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin);
@@ -2066,9 +2066,6 @@ class CommandLineFlags {
"Provide more detailed and expensive TLAB statistics " \
"(with PrintTLAB)") \
\
- EMBEDDED_ONLY(product(bool, LowMemoryProtection, true, \
- "Enable LowMemoryProtection")) \
- \
product_pd(bool, NeverActAsServerClassMachine, \
"Never act like a server-class machine") \
\
@@ -2984,12 +2981,6 @@ class CommandLineFlags {
product(intx, SafepointTimeoutDelay, 10000, \
"Delay in milliseconds for option SafepointTimeout") \
\
- product(intx, NmethodSweepFraction, 16, \
- "Number of invocations of sweeper to cover all nmethods") \
- \
- product(intx, NmethodSweepCheckInterval, 5, \
- "Compilers wake up every n seconds to possibly sweep nmethods") \
- \
product(intx, NmethodSweepActivity, 10, \
"Removes cold nmethods from code cache if > 0. Higher values " \
"result in more aggressive sweeping") \
@@ -3378,9 +3369,6 @@ class CommandLineFlags {
product_pd(uintx, NonNMethodCodeHeapSize, \
"Size of code heap with non-nmethods (in bytes)") \
\
- product(uintx, CodeCacheMinimumFreeSpace, 500*K, \
- "When less than X space left, we stop compiling") \
- \
product_pd(uintx, CodeCacheExpansionSize, \
"Code cache expansion size (in bytes)") \
\
@@ -3393,6 +3381,11 @@ class CommandLineFlags {
product(bool, UseCodeCacheFlushing, true, \
"Remove cold/old nmethods from the code cache") \
\
+ product(uintx, StartAggressiveSweepingAt, 10, \
+ "Start aggressive sweeping if X[%] of the code cache is free." \
+ "Segmented code cache: X[%] of the non-profiled heap." \
+ "Non-segmented code cache: X[%] of the total code cache") \
+ \
/* interpreter debugging */ \
develop(intx, BinarySwitchThreshold, 5, \
"Minimal number of lookupswitch entries for rewriting to binary " \
diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.cpp b/hotspot/src/share/vm/runtime/interfaceSupport.cpp
index 78a58200f5a..6a30aba6f8e 100644
--- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp
@@ -187,19 +187,22 @@ void InterfaceSupport::zap_dead_locals_old() {
# endif
-
+// invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions
int deoptimizeAllCounter = 0;
int zombieAllCounter = 0;
-
void InterfaceSupport::zombieAll() {
- if (is_init_completed() && zombieAllCounter > ZombieALotInterval) {
+ // This method is called by all threads when a thread make
+ // transition to VM state (for example, runtime calls).
+ // Divide number of calls by number of threads to avoid
+ // dependence of ZombieAll events frequency on number of threads.
+ int value = zombieAllCounter / Threads::number_of_threads();
+ if (is_init_completed() && value > ZombieALotInterval) {
zombieAllCounter = 0;
VM_ZombieAll op;
VMThread::execute(&op);
- } else {
- zombieAllCounter++;
}
+ zombieAllCounter++;
}
void InterfaceSupport::unlinkSymbols() {
@@ -208,12 +211,17 @@ void InterfaceSupport::unlinkSymbols() {
}
void InterfaceSupport::deoptimizeAll() {
- if (is_init_completed() ) {
- if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) {
+ // This method is called by all threads when a thread make
+ // transition to VM state (for example, runtime calls).
+ // Divide number of calls by number of threads to avoid
+ // dependence of DeoptimizeAll events frequency on number of threads.
+ int value = deoptimizeAllCounter / Threads::number_of_threads();
+ if (is_init_completed()) {
+ if (DeoptimizeALot && value > DeoptimizeALotInterval) {
deoptimizeAllCounter = 0;
VM_DeoptimizeAll op;
VMThread::execute(&op);
- } else if (DeoptimizeRandom && (deoptimizeAllCounter & 0x1f) == (os::random() & 0x1f)) {
+ } else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) {
VM_DeoptimizeAll op;
VMThread::execute(&op);
}
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index 586414a53d4..2e14b4a3e17 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -705,25 +705,35 @@ int JDK_Version::compare(const JDK_Version& other) const {
}
void JDK_Version::to_string(char* buffer, size_t buflen) const {
+ assert(buffer && buflen > 0, "call with useful buffer");
size_t index = 0;
+
if (!is_valid()) {
jio_snprintf(buffer, buflen, "%s", "(uninitialized)");
} else if (is_partially_initialized()) {
jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0");
} else {
- index += jio_snprintf(
+ int rc = jio_snprintf(
&buffer[index], buflen - index, "%d.%d", _major, _minor);
+ if (rc == -1) return;
+ index += rc;
if (_micro > 0) {
- index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
+ rc = jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
}
if (_update > 0) {
- index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
+ rc = jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
+ if (rc == -1) return;
+ index += rc;
}
if (_special > 0) {
- index += jio_snprintf(&buffer[index], buflen - index, "%c", _special);
+ rc = jio_snprintf(&buffer[index], buflen - index, "%c", _special);
+ if (rc == -1) return;
+ index += rc;
}
if (_build > 0) {
- index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
+ rc = jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
+ if (rc == -1) return;
+ index += rc;
}
}
}
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp
index 5cbbbeb3828..25a897a142f 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp
@@ -61,7 +61,7 @@ Mutex* SymbolTable_lock = NULL;
Mutex* StringTable_lock = NULL;
Monitor* StringDedupQueue_lock = NULL;
Mutex* StringDedupTable_lock = NULL;
-Mutex* CodeCache_lock = NULL;
+Monitor* CodeCache_lock = NULL;
Mutex* MethodData_lock = NULL;
Mutex* RetData_lock = NULL;
Monitor* VMOperationQueue_lock = NULL;
@@ -205,7 +205,7 @@ void mutex_init() {
}
def(ParGCRareEvent_lock , Mutex , leaf , true );
def(DerivedPointerTableGC_lock , Mutex, leaf, true );
- def(CodeCache_lock , Mutex , special, true );
+ def(CodeCache_lock , Monitor, special, true );
def(Interrupt_lock , Monitor, special, true ); // used for interrupt processing
def(RawMonitor_lock , Mutex, special, true );
def(OopMapCacheAlloc_lock , Mutex, leaf, true ); // used for oop_map_cache allocation.
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp
index ab027291d30..94d8adec813 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp
@@ -53,7 +53,7 @@ extern Mutex* SymbolTable_lock; // a lock on the symbol table
extern Mutex* StringTable_lock; // a lock on the interned string table
extern Monitor* StringDedupQueue_lock; // a lock on the string deduplication queue
extern Mutex* StringDedupTable_lock; // a lock on the string deduplication table
-extern Mutex* CodeCache_lock; // a lock on the CodeCache, rank is special, use MutexLockerEx
+extern Monitor* CodeCache_lock; // a lock on the CodeCache, rank is special, use MutexLockerEx
extern Mutex* MethodData_lock; // a lock on installation of method data
extern Mutex* RetData_lock; // a lock on installation of RetData inside method data
extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derived pointer table
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 8d7450b1d97..1e632f4d543 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -571,17 +571,6 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
-#if INCLUDE_NMT
- // NMT can not track malloc allocation size > MAX_MALLOC_SIZE, which is
- // (1GB - 1) on 32-bit system. It is not an issue on 64-bit system, where
- // MAX_MALLOC_SIZE = ((1 << 62) - 1).
- // VM code does not have such large malloc allocation. However, it can come
- // Unsafe call.
- if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
- return NULL;
- }
-#endif
-
#ifdef ASSERT
// checking for the WatcherThread and crash_protection first
// since os::malloc can be called when the libjvm.{dll,so} is
@@ -652,12 +641,6 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) {
}
void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
-#if INCLUDE_NMT
- // See comments in os::malloc() above
- if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
- return NULL;
- }
-#endif
#ifndef ASSERT
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index d2e78b43a4c..fa15d25b6c6 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -158,7 +158,6 @@ class os: AllStatic {
static void init_globals(void) { // Called from init_globals() in init.cpp
init_globals_ext();
}
- static void init_3(void); // Called at the end of vm init
// File names are case-insensitive on windows only
// Override me as needed
@@ -680,28 +679,10 @@ class os: AllStatic {
// SocketInterface (ex HPI SocketInterface )
static int socket(int domain, int type, int protocol);
static int socket_close(int fd);
- static int socket_shutdown(int fd, int howto);
static int recv(int fd, char* buf, size_t nBytes, uint flags);
static int send(int fd, char* buf, size_t nBytes, uint flags);
static int raw_send(int fd, char* buf, size_t nBytes, uint flags);
- static int timeout(int fd, long timeout);
- static int listen(int fd, int count);
static int connect(int fd, struct sockaddr* him, socklen_t len);
- static int bind(int fd, struct sockaddr* him, socklen_t len);
- static int accept(int fd, struct sockaddr* him, socklen_t* len);
- static int recvfrom(int fd, char* buf, size_t nbytes, uint flags,
- struct sockaddr* from, socklen_t* fromlen);
- static int get_sock_name(int fd, struct sockaddr* him, socklen_t* len);
- static int sendto(int fd, char* buf, size_t len, uint flags,
- struct sockaddr* to, socklen_t tolen);
- static int socket_available(int fd, jint* pbytes);
-
- static int get_sock_opt(int fd, int level, int optname,
- char* optval, socklen_t* optlen);
- static int set_sock_opt(int fd, int level, int optname,
- const char* optval, socklen_t optlen);
- static int get_host_name(char* name, int namelen);
-
static struct hostent* get_host_by_name(char* name);
// Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal)
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 7c47c6f2656..344c2a61f3e 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -2421,8 +2421,6 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
// CodeCache is full, disable compilation
// Ought to log this but compile log is only per compile thread
// and we're some non descript Java thread.
- MutexUnlocker mu(AdapterHandlerLibrary_lock);
- CompileBroker::handle_full_code_cache(CodeBlobType::NonNMethod);
return NULL; // Out of CodeCache space
}
entry->relocate(new_adapter->content_begin());
@@ -2594,9 +2592,6 @@ void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
}
nm->post_compiled_method_load_event();
- } else {
- // CodeCache is full, disable compilation
- CompileBroker::handle_full_code_cache(CodeBlobType::MethodNonProfiled);
}
}
diff --git a/hotspot/src/share/vm/runtime/signature.cpp b/hotspot/src/share/vm/runtime/signature.cpp
index a92f5e73b28..425a3705b7e 100644
--- a/hotspot/src/share/vm/runtime/signature.cpp
+++ b/hotspot/src/share/vm/runtime/signature.cpp
@@ -158,7 +158,7 @@ void SignatureIterator::iterate_parameters( uint64_t fingerprint ) {
uint64_t saved_fingerprint = fingerprint;
// Check for too many arguments
- if ( fingerprint == UCONST64(-1) ) {
+ if (fingerprint == (uint64_t)CONST64(-1)) {
SignatureIterator::iterate_parameters();
return;
}
diff --git a/hotspot/src/share/vm/runtime/signature.hpp b/hotspot/src/share/vm/runtime/signature.hpp
index 9c2e532a1fc..98151c64d57 100644
--- a/hotspot/src/share/vm/runtime/signature.hpp
+++ b/hotspot/src/share/vm/runtime/signature.hpp
@@ -243,7 +243,7 @@ class Fingerprinter: public SignatureIterator {
}
if (mh->size_of_parameters() > max_size_of_parameters ) {
- _fingerprint = UCONST64(-1);
+ _fingerprint = (uint64_t)CONST64(-1);
mh->constMethod()->set_fingerprint(_fingerprint);
return _fingerprint;
}
diff --git a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
index d70e8523a26..11803f1f6a4 100644
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
@@ -196,7 +196,6 @@ nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
// Don't trigger other compiles in testing mode
return NULL;
}
- nmethod *osr_nm = NULL;
handle_counter_overflow(method());
if (method() != inlinee()) {
@@ -210,14 +209,16 @@ nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
if (bci == InvocationEntryBci) {
method_invocation_event(method, inlinee, comp_level, nm, thread);
} else {
- method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
// method == inlinee if the event originated in the main method
- int highest_level = inlinee->highest_osr_comp_level();
- if (highest_level > comp_level) {
- osr_nm = inlinee->lookup_osr_nmethod_for(bci, highest_level, false);
+ method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
+ // Check if event led to a higher level OSR compilation
+ nmethod* osr_nm = inlinee->lookup_osr_nmethod_for(bci, comp_level, false);
+ if (osr_nm != NULL && osr_nm->comp_level() > comp_level) {
+ // Perform OSR with new nmethod
+ return osr_nm;
}
}
- return osr_nm;
+ return NULL;
}
// Check if the method can be compiled, change level if necessary
diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp
index cecb8ff08a1..1f70b6edc20 100644
--- a/hotspot/src/share/vm/runtime/sweeper.cpp
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp
@@ -52,7 +52,6 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
class SweeperRecord {
public:
int traversal;
- int invocation;
int compile_id;
long traversal_mark;
int state;
@@ -62,10 +61,9 @@ class SweeperRecord {
int line;
void print() {
- tty->print_cr("traversal = %d invocation = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
+ tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = "
PTR_FORMAT " state = %d traversal_mark %d line = %d",
traversal,
- invocation,
compile_id,
kind == NULL ? "" : kind,
uep,
@@ -117,7 +115,6 @@ void NMethodSweeper::record_sweep(nmethod* nm, int line) {
if (_records != NULL) {
_records[_sweep_index].traversal = _traversals;
_records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
- _records[_sweep_index].invocation = _sweep_fractions_left;
_records[_sweep_index].compile_id = nm->compile_id();
_records[_sweep_index].kind = nm->compile_kind();
_records[_sweep_index].state = nm->_state;
@@ -127,6 +124,14 @@ void NMethodSweeper::record_sweep(nmethod* nm, int line) {
_sweep_index = (_sweep_index + 1) % SweeperLogEntries;
}
}
+
+void NMethodSweeper::init_sweeper_log() {
+ if (LogSweeper && _records == NULL) {
+ // Create the ring buffer for the logging code
+ _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
+ memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
+ }
+}
#else
#define SWEEP(nm)
#endif
@@ -142,8 +147,6 @@ int NMethodSweeper::_zombified_count = 0; // Nof. nmethods
int NMethodSweeper::_marked_for_reclamation_count = 0; // Nof. nmethods marked for reclaim in current sweep
volatile bool NMethodSweeper::_should_sweep = true; // Indicates if we should invoke the sweeper
-volatile int NMethodSweeper::_sweep_fractions_left = 0; // Nof. invocations left until we are completed with this pass
-volatile int NMethodSweeper::_sweep_started = 0; // Flag to control conc sweeper
volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from:
// 1) alive -> not_entrant
// 2) not_entrant -> zombie
@@ -190,13 +193,15 @@ int NMethodSweeper::hotness_counter_reset_val() {
}
return _hotness_counter_reset_val;
}
-bool NMethodSweeper::sweep_in_progress() {
- return !_current.end();
+bool NMethodSweeper::wait_for_stack_scanning() {
+ return _current.end();
}
-// Scans the stacks of all Java threads and marks activations of not-entrant methods.
-// No need to synchronize access, since 'mark_active_nmethods' is always executed at a
-// safepoint.
+/**
+ * Scans the stacks of all Java threads and marks activations of not-entrant methods.
+ * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
+ * safepoint.
+ */
void NMethodSweeper::mark_active_nmethods() {
assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
// If we do not want to reclaim not-entrant or zombie methods there is no need
@@ -210,9 +215,8 @@ void NMethodSweeper::mark_active_nmethods() {
// Check for restart
assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
- if (!sweep_in_progress()) {
+ if (wait_for_stack_scanning()) {
_seen = 0;
- _sweep_fractions_left = NmethodSweepFraction;
_current = NMethodIterator();
// Initialize to first nmethod
_current.next();
@@ -231,6 +235,64 @@ void NMethodSweeper::mark_active_nmethods() {
OrderAccess::storestore();
}
+
+/**
+ * This function triggers a VM operation that does stack scanning of active
+ * methods. Stack scanning is mandatory for the sweeper to make progress.
+ */
+void NMethodSweeper::do_stack_scanning() {
+ assert(!CodeCache_lock->owned_by_self(), "just checking");
+ if (wait_for_stack_scanning()) {
+ VM_MarkActiveNMethods op;
+ VMThread::execute(&op);
+ _should_sweep = true;
+ }
+}
+
+void NMethodSweeper::sweeper_loop() {
+ bool timeout;
+ while (true) {
+ {
+ ThreadBlockInVM tbivm(JavaThread::current());
+ MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ const long wait_time = 60*60*24 * 1000;
+ timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
+ }
+ if (!timeout) {
+ possibly_sweep();
+ }
+ }
+}
+
+/**
+ * Wakes up the sweeper thread to possibly sweep.
+ */
+void NMethodSweeper::notify(int code_blob_type) {
+ // Makes sure that we do not invoke the sweeper too often during startup.
+ double start_threshold = 100.0 / (double)StartAggressiveSweepingAt;
+ double aggressive_sweep_threshold = MIN2(start_threshold, 1.1);
+ if (CodeCache::reverse_free_ratio(code_blob_type) >= aggressive_sweep_threshold) {
+ assert_locked_or_safepoint(CodeCache_lock);
+ CodeCache_lock->notify();
+ }
+}
+
+/**
+ * Handle a safepoint request
+ */
+void NMethodSweeper::handle_safepoint_request() {
+ if (SafepointSynchronize::is_synchronizing()) {
+ if (PrintMethodFlushing && Verbose) {
+ tty->print_cr("### Sweep at %d out of %d, yielding to safepoint", _seen, CodeCache::nof_nmethods());
+ }
+ MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+
+ JavaThread* thread = JavaThread::current();
+ ThreadBlockInVM tbivm(thread);
+ thread->java_suspend_self();
+ }
+}
+
/**
* This function invokes the sweeper if at least one of the three conditions is met:
* (1) The code cache is getting full
@@ -239,11 +301,6 @@ void NMethodSweeper::mark_active_nmethods() {
*/
void NMethodSweeper::possibly_sweep() {
assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
- // Only compiler threads are allowed to sweep
- if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) {
- return;
- }
-
// If there was no state change while nmethod sweeping, 'should_sweep' will be false.
// This is one of the two places where should_sweep can be set to true. The general
// idea is as follows: If there is enough free space in the code cache, there is no
@@ -280,46 +337,37 @@ void NMethodSweeper::possibly_sweep() {
}
}
- if (_should_sweep && _sweep_fractions_left > 0) {
- // Only one thread at a time will sweep
- jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 );
- if (old != 0) {
- return;
- }
-#ifdef ASSERT
- if (LogSweeper && _records == NULL) {
- // Create the ring buffer for the logging code
- _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
- memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
- }
-#endif
+ // Force stack scanning if there is only 10% free space in the code cache.
+ // We force stack scanning only non-profiled code heap gets full, since critical
+ // allocation go to the non-profiled heap and we must be make sure that there is
+ // enough space.
+ double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100;
+ if (free_percent <= StartAggressiveSweepingAt) {
+ do_stack_scanning();
+ }
- if (_sweep_fractions_left > 0) {
- sweep_code_cache();
- _sweep_fractions_left--;
- }
+ if (_should_sweep) {
+ init_sweeper_log();
+ sweep_code_cache();
+ }
- // We are done with sweeping the code cache once.
- if (_sweep_fractions_left == 0) {
- _total_nof_code_cache_sweeps++;
- _last_sweep = _time_counter;
- // Reset flag; temporarily disables sweeper
- _should_sweep = false;
- // If there was enough state change, 'possibly_enable_sweeper()'
- // sets '_should_sweep' to true
- possibly_enable_sweeper();
- // Reset _bytes_changed only if there was enough state change. _bytes_changed
- // can further increase by calls to 'report_state_change'.
- if (_should_sweep) {
- _bytes_changed = 0;
- }
- }
- // Release work, because another compiler thread could continue.
- OrderAccess::release_store((int*)&_sweep_started, 0);
+ // We are done with sweeping the code cache once.
+ _total_nof_code_cache_sweeps++;
+ _last_sweep = _time_counter;
+ // Reset flag; temporarily disables sweeper
+ _should_sweep = false;
+ // If there was enough state change, 'possibly_enable_sweeper()'
+ // sets '_should_sweep' to true
+ possibly_enable_sweeper();
+ // Reset _bytes_changed only if there was enough state change. _bytes_changed
+ // can further increase by calls to 'report_state_change'.
+ if (_should_sweep) {
+ _bytes_changed = 0;
}
}
void NMethodSweeper::sweep_code_cache() {
+ ResourceMark rm;
Ticks sweep_start_counter = Ticks::now();
_flushed_count = 0;
@@ -327,25 +375,10 @@ void NMethodSweeper::sweep_code_cache() {
_marked_for_reclamation_count = 0;
if (PrintMethodFlushing && Verbose) {
- tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
- }
-
- if (!CompileBroker::should_compile_new_jobs()) {
- // If we have turned off compilations we might as well do full sweeps
- // in order to reach the clean state faster. Otherwise the sleeping compiler
- // threads will slow down sweeping.
- _sweep_fractions_left = 1;
+ tty->print_cr("### Sweep at %d out of %d", _seen, CodeCache::nof_nmethods());
}
- // We want to visit all nmethods after NmethodSweepFraction
- // invocations so divide the remaining number of nmethods by the
- // remaining number of invocations. This is only an estimate since
- // the number of nmethods changes during the sweep so the final
- // stage must iterate until it there are no more nmethods.
- int todo = (CodeCache::nof_nmethods() - _seen) / _sweep_fractions_left;
int swept_count = 0;
-
-
assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
assert(!CodeCache_lock->owned_by_self(), "just checking");
@@ -354,19 +387,9 @@ void NMethodSweeper::sweep_code_cache() {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
// The last invocation iterates until there are no more nmethods
- while ((swept_count < todo || _sweep_fractions_left == 1) && !_current.end()) {
+ while (!_current.end()) {
swept_count++;
- if (SafepointSynchronize::is_synchronizing()) { // Safepoint request
- if (PrintMethodFlushing && Verbose) {
- tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _sweep_fractions_left);
- }
- MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-
- assert(Thread::current()->is_Java_thread(), "should be java thread");
- JavaThread* thread = (JavaThread*)Thread::current();
- ThreadBlockInVM tbivm(thread);
- thread->java_suspend_self();
- }
+ handle_safepoint_request();
// Since we will give up the CodeCache_lock, always skip ahead
// to the next nmethod. Other blobs can be deleted by other
// threads but nmethods are only reclaimed by the sweeper.
@@ -382,7 +405,7 @@ void NMethodSweeper::sweep_code_cache() {
}
}
- assert(_sweep_fractions_left > 1 || _current.end(), "must have scanned the whole cache");
+ assert(_current.end(), "must have scanned the whole cache");
const Ticks sweep_end_counter = Ticks::now();
const Tickspan sweep_time = sweep_end_counter - sweep_start_counter;
@@ -397,7 +420,6 @@ void NMethodSweeper::sweep_code_cache() {
event.set_starttime(sweep_start_counter);
event.set_endtime(sweep_end_counter);
event.set_sweepIndex(_traversals);
- event.set_sweepFractionIndex(NmethodSweepFraction - _sweep_fractions_left + 1);
event.set_sweptCount(swept_count);
event.set_flushedCount(_flushed_count);
event.set_markedCount(_marked_for_reclamation_count);
@@ -407,15 +429,12 @@ void NMethodSweeper::sweep_code_cache() {
#ifdef ASSERT
if(PrintMethodFlushing) {
- tty->print_cr("### sweeper: sweep time(%d): "
- INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value());
+ tty->print_cr("### sweeper: sweep time(%d): ", (jlong)sweep_time.value());
}
#endif
- if (_sweep_fractions_left == 1) {
- _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
- log_sweep("finished");
- }
+ _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
+ log_sweep("finished");
// Sweeper is the only case where memory is released, check here if it
// is time to restart the compiler. Only checking if there is a certain
@@ -459,10 +478,12 @@ void NMethodSweeper::possibly_enable_sweeper() {
class NMethodMarker: public StackObj {
private:
- CompilerThread* _thread;
+ CodeCacheSweeperThread* _thread;
public:
NMethodMarker(nmethod* nm) {
- _thread = CompilerThread::current();
+ JavaThread* current = JavaThread::current();
+ assert (current->is_Code_cache_sweeper_thread(), "Must be");
+ _thread = (CodeCacheSweeperThread*)JavaThread::current();
if (!nm->is_zombie() && !nm->is_unloaded()) {
// Only expose live nmethods for scanning
_thread->set_scanned_nmethod(nm);
@@ -473,7 +494,7 @@ class NMethodMarker: public StackObj {
}
};
-void NMethodSweeper::release_nmethod(nmethod *nm) {
+void NMethodSweeper::release_nmethod(nmethod* nm) {
// Clean up any CompiledICHolders
{
ResourceMark rm;
@@ -490,7 +511,7 @@ void NMethodSweeper::release_nmethod(nmethod *nm) {
nm->flush();
}
-int NMethodSweeper::process_nmethod(nmethod *nm) {
+int NMethodSweeper::process_nmethod(nmethod* nm) {
assert(!CodeCache_lock->owned_by_self(), "just checking");
int freed_memory = 0;
diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp
index 82b1a279c2a..2da9425390e 100644
--- a/hotspot/src/share/vm/runtime/sweeper.hpp
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp
@@ -49,9 +49,7 @@
// remove the nmethod, all inline caches (IC) that point to the the nmethod must be
// cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's
// state change happens during separate sweeps. It may take at least 3 sweeps before an
-// nmethod's space is freed. Sweeping is currently done by compiler threads between
-// compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache
-// is full.
+// nmethod's space is freed.
class NMethodSweeper : public AllStatic {
static long _traversals; // Stack scan count, also sweep ID.
@@ -64,7 +62,6 @@ class NMethodSweeper : public AllStatic {
static int _zombified_count; // Nof. nmethods made zombie in current sweep
static int _marked_for_reclamation_count; // Nof. nmethods marked for reclaim in current sweep
- static volatile int _sweep_fractions_left; // Nof. invocations left until we are completed with this pass
static volatile int _sweep_started; // Flag to control conc sweeper
static volatile bool _should_sweep; // Indicates if we should invoke the sweeper
static volatile int _bytes_changed; // Counts the total nmethod size if the nmethod changed from:
@@ -85,8 +82,12 @@ class NMethodSweeper : public AllStatic {
static int process_nmethod(nmethod *nm);
static void release_nmethod(nmethod* nm);
- static bool sweep_in_progress();
+ static void init_sweeper_log() NOT_DEBUG_RETURN;
+ static bool wait_for_stack_scanning();
static void sweep_code_cache();
+ static void handle_safepoint_request();
+ static void do_stack_scanning();
+ static void possibly_sweep();
public:
static long traversal_count() { return _traversals; }
@@ -106,7 +107,8 @@ class NMethodSweeper : public AllStatic {
#endif
static void mark_active_nmethods(); // Invoked at the end of each safepoint
- static void possibly_sweep(); // Compiler threads call this to sweep
+ static void sweeper_loop();
+ static void notify(int code_blob_type); // Possibly start the sweeper thread.
static int hotness_counter_reset_val();
static void report_state_change(nmethod* nm);
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index 7e7dc5c75cb..4e406f9efbe 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -66,6 +66,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/statSampler.hpp"
#include "runtime/stubRoutines.hpp"
+#include "runtime/sweeper.hpp"
#include "runtime/task.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/threadCritical.hpp"
@@ -1553,6 +1554,7 @@ void JavaThread::block_if_vm_exited() {
// Remove this ifdef when C1 is ported to the compiler interface.
static void compiler_thread_entry(JavaThread* thread, TRAPS);
+static void sweeper_thread_entry(JavaThread* thread, TRAPS);
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
Thread()
@@ -3172,6 +3174,10 @@ static void compiler_thread_entry(JavaThread* thread, TRAPS) {
CompileBroker::compiler_thread_loop();
}
+static void sweeper_thread_entry(JavaThread* thread, TRAPS) {
+ NMethodSweeper::sweeper_loop();
+}
+
// Create a CompilerThread
CompilerThread::CompilerThread(CompileQueue* queue,
CompilerCounters* counters)
@@ -3182,7 +3188,6 @@ CompilerThread::CompilerThread(CompileQueue* queue,
_queue = queue;
_counters = counters;
_buffer_blob = NULL;
- _scanned_nmethod = NULL;
_compiler = NULL;
#ifndef PRODUCT
@@ -3190,7 +3195,12 @@ CompilerThread::CompilerThread(CompileQueue* queue,
#endif
}
-void CompilerThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
+// Create sweeper thread
+CodeCacheSweeperThread::CodeCacheSweeperThread()
+: JavaThread(&sweeper_thread_entry) {
+ _scanned_nmethod = NULL;
+}
+void CodeCacheSweeperThread::oops_do(OopClosure* f, CLDClosure* 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
@@ -3607,9 +3617,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
}
}
- // Give os specific code one last chance to start
- os::init_3();
-
create_vm_timer.end();
#ifdef ASSERT
_vm_complete = true;
@@ -3632,7 +3639,7 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent,
if (!agent->valid()) {
char buffer[JVM_MAXPATHLEN];
- char ebuf[1024];
+ char ebuf[1024] = "";
const char *name = agent->name();
const char *msg = "Could not find agent library ";
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index e1110f2b2c7..c39b2eff624 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -311,6 +311,7 @@ class Thread: public ThreadShadow {
virtual bool is_VM_thread() const { return false; }
virtual bool is_Java_thread() const { return false; }
virtual bool is_Compiler_thread() const { return false; }
+ virtual bool is_Code_cache_sweeper_thread() const { return false; }
virtual bool is_hidden_from_external_view() const { return false; }
virtual bool is_jvmti_agent_thread() const { return false; }
// True iff the thread can perform GC operations at a safepoint.
@@ -1755,6 +1756,27 @@ inline CompilerThread* JavaThread::as_CompilerThread() {
return (CompilerThread*)this;
}
+// Dedicated thread to sweep the code cache
+class CodeCacheSweeperThread : public JavaThread {
+ nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper
+ public:
+ CodeCacheSweeperThread();
+ // Track the nmethod currently being scanned by the sweeper
+ void set_scanned_nmethod(nmethod* nm) {
+ assert(_scanned_nmethod == NULL || nm == NULL, "should reset to NULL before writing a new value");
+ _scanned_nmethod = nm;
+ }
+
+ // Hide sweeper thread from external view.
+ bool is_hidden_from_external_view() const { return true; }
+
+ bool is_Code_cache_sweeper_thread() const { return true; }
+ // 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, CLDClosure* cld_f, CodeBlobClosure* cf);
+};
+
// A thread used for Compilation.
class CompilerThread : public JavaThread {
friend class VMStructs;
@@ -1767,7 +1789,6 @@ class CompilerThread : public JavaThread {
CompileQueue* _queue;
BufferBlob* _buffer_blob;
- nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper
AbstractCompiler* _compiler;
public:
@@ -1801,28 +1822,17 @@ class CompilerThread : public JavaThread {
_log = log;
}
- // 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, CLDClosure* cld_f, CodeBlobClosure* cf);
-
#ifndef PRODUCT
private:
IdealGraphPrinter *_ideal_graph_printer;
public:
- IdealGraphPrinter *ideal_graph_printer() { return _ideal_graph_printer; }
- void set_ideal_graph_printer(IdealGraphPrinter *n) { _ideal_graph_printer = n; }
+ IdealGraphPrinter *ideal_graph_printer() { return _ideal_graph_printer; }
+ void set_ideal_graph_printer(IdealGraphPrinter *n) { _ideal_graph_printer = n; }
#endif
// Get/set the thread's current task
- CompileTask* task() { return _task; }
- void set_task(CompileTask* task) { _task = task; }
-
- // Track the nmethod currently being scanned by the sweeper
- void set_scanned_nmethod(nmethod* nm) {
- assert(_scanned_nmethod == NULL || nm == NULL, "should reset to NULL before writing a new value");
- _scanned_nmethod = nm;
- }
+ CompileTask* task() { return _task; }
+ void set_task(CompileTask* task) { _task = task; }
};
inline CompilerThread* CompilerThread::current() {
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index c81cd8a2c9a..6bb6394841b 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -1594,6 +1594,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
declare_type(JvmtiAgentThread, JavaThread) \
declare_type(ServiceThread, JavaThread) \
declare_type(CompilerThread, JavaThread) \
+ declare_type(CodeCacheSweeperThread, JavaThread) \
declare_toplevel_type(OSThread) \
declare_toplevel_type(JavaFrameAnchor) \
\
diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp
index da07423db81..efacdc7c610 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp
@@ -111,6 +111,9 @@ void VM_Deoptimize::doit() {
CodeCache::make_marked_nmethods_zombies();
}
+void VM_MarkActiveNMethods::doit() {
+ NMethodSweeper::mark_active_nmethods();
+}
VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) {
_thread = thread;
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
index b5a1532338e..c8b4a3855fc 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
@@ -100,6 +100,7 @@
template(RotateGCLog) \
template(WhiteBoxOperation) \
template(ClassLoaderStatsOperation) \
+ template(MarkActiveNMethods) \
template(PrintCompileQueue) \
template(PrintCodeList) \
template(PrintCodeCache) \
@@ -252,6 +253,13 @@ class VM_Deoptimize: public VM_Operation {
bool allow_nested_vm_operations() const { return true; }
};
+class VM_MarkActiveNMethods: public VM_Operation {
+ public:
+ VM_MarkActiveNMethods() {}
+ VMOp_Type type() const { return VMOp_MarkActiveNMethods; }
+ void doit();
+ bool allow_nested_vm_operations() const { return true; }
+};
// Deopt helper that can deoptimize frames in threads other than the
// current thread. Only used through Deoptimization::deoptimize_frame.
diff --git a/hotspot/src/share/vm/services/jmm.h b/hotspot/src/share/vm/services/jmm.h
index de9d78b7f91..40dfb4e7325 100644
--- a/hotspot/src/share/vm/services/jmm.h
+++ b/hotspot/src/share/vm/services/jmm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -143,7 +143,8 @@ typedef enum {
JMM_VMGLOBAL_TYPE_UNKNOWN = 0,
JMM_VMGLOBAL_TYPE_JBOOLEAN = 1,
JMM_VMGLOBAL_TYPE_JSTRING = 2,
- JMM_VMGLOBAL_TYPE_JLONG = 3
+ JMM_VMGLOBAL_TYPE_JLONG = 3,
+ JMM_VMGLOBAL_TYPE_JDOUBLE = 4
} jmmVMGlobalType;
typedef enum {
diff --git a/hotspot/src/share/vm/services/mallocTracker.cpp b/hotspot/src/share/vm/services/mallocTracker.cpp
index a5d8d1f7ffd..dc4f08f94a6 100644
--- a/hotspot/src/share/vm/services/mallocTracker.cpp
+++ b/hotspot/src/share/vm/services/mallocTracker.cpp
@@ -72,7 +72,7 @@ void MallocHeader::release() const {
MallocMemorySummary::record_free(size(), flags());
MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader));
- if (tracking_level() == NMT_detail) {
+ if (MemTracker::tracking_level() == NMT_detail) {
MallocSiteTable::deallocation_at(size(), _bucket_idx, _pos_idx);
}
}
@@ -128,36 +128,18 @@ void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flag
}
// Uses placement global new operator to initialize malloc header
- switch(level) {
- case NMT_off:
- return malloc_base;
- case NMT_minimal: {
- MallocHeader* hdr = ::new (malloc_base) MallocHeader();
- break;
- }
- case NMT_summary: {
- assert(size <= MAX_MALLOC_SIZE, "malloc size overrun for NMT");
- header = ::new (malloc_base) MallocHeader(size, flags);
- break;
- }
- case NMT_detail: {
- assert(size <= MAX_MALLOC_SIZE, "malloc size overrun for NMT");
- header = ::new (malloc_base) MallocHeader(size, flags, stack);
- break;
- }
- default:
- ShouldNotReachHere();
+
+ if (level == NMT_off) {
+ return malloc_base;
}
+
+ header = ::new (malloc_base)MallocHeader(size, flags, stack, level);
memblock = (void*)((char*)malloc_base + sizeof(MallocHeader));
// The alignment check: 8 bytes alignment for 32 bit systems.
// 16 bytes alignment for 64-bit systems.
assert(((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0, "Alignment check");
- // Sanity check
- assert(get_memory_tracking_level(memblock) == level,
- "Wrong tracking level");
-
#ifdef ASSERT
if (level > NMT_minimal) {
// Read back
diff --git a/hotspot/src/share/vm/services/mallocTracker.hpp b/hotspot/src/share/vm/services/mallocTracker.hpp
index 6d7efabea8d..00f1b0027d5 100644
--- a/hotspot/src/share/vm/services/mallocTracker.hpp
+++ b/hotspot/src/share/vm/services/mallocTracker.hpp
@@ -239,68 +239,46 @@ class MallocMemorySummary : AllStatic {
class MallocHeader VALUE_OBJ_CLASS_SPEC {
#ifdef _LP64
- size_t _size : 62;
- size_t _level : 2;
+ size_t _size : 64;
size_t _flags : 8;
size_t _pos_idx : 16;
size_t _bucket_idx: 40;
#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40)
#define MAX_BUCKET_LENGTH ((size_t)(1 << 16))
-#define MAX_MALLOC_SIZE (((size_t)1 << 62) - 1)
#else
- size_t _size : 30;
- size_t _level : 2;
+ size_t _size : 32;
size_t _flags : 8;
size_t _pos_idx : 8;
size_t _bucket_idx: 16;
#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)(1 << 16))
#define MAX_BUCKET_LENGTH ((size_t)(1 << 8))
-// Max malloc size = 1GB - 1 on 32 bit system, such has total 4GB memory
-#define MAX_MALLOC_SIZE ((size_t)(1 << 30) - 1)
#endif // _LP64
public:
- // Summary tracking header
- MallocHeader(size_t size, MEMFLAGS flags) {
+ MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) {
assert(sizeof(MallocHeader) == sizeof(void*) * 2,
"Wrong header size");
- _level = NMT_summary;
- _flags = flags;
- set_size(size);
- MallocMemorySummary::record_malloc(size, flags);
- MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
- }
- // Detail tracking header
- MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack) {
- assert(sizeof(MallocHeader) == sizeof(void*) * 2,
- "Wrong header size");
+ if (level == NMT_minimal) {
+ return;
+ }
- _level = NMT_detail;
_flags = flags;
set_size(size);
- size_t bucket_idx;
- size_t pos_idx;
- if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
- assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
- assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
- _bucket_idx = bucket_idx;
- _pos_idx = pos_idx;
+ if (level == NMT_detail) {
+ size_t bucket_idx;
+ size_t pos_idx;
+ if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
+ assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
+ assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
+ _bucket_idx = bucket_idx;
+ _pos_idx = pos_idx;
+ }
}
+
MallocMemorySummary::record_malloc(size, flags);
MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
}
- // Minimal tracking header
- MallocHeader() {
- assert(sizeof(MallocHeader) == sizeof(void*) * 2,
- "Wrong header size");
-
- _level = (unsigned short)NMT_minimal;
- }
-
- inline NMT_TrackingLevel tracking_level() const {
- return (NMT_TrackingLevel)_level;
- }
inline size_t size() const { return _size; }
inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
@@ -311,7 +289,6 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC {
private:
inline void set_size(size_t size) {
- assert(size <= MAX_MALLOC_SIZE, "Malloc size too large, should use virtual memory?");
_size = size;
}
bool record_malloc_site(const NativeCallStack& stack, size_t size,
@@ -347,10 +324,6 @@ class MallocTracker : AllStatic {
// Record free on specified memory block
static void* record_free(void* memblock);
- // Get tracking level of specified memory block
- static inline NMT_TrackingLevel get_memory_tracking_level(void* memblock);
-
-
// Offset memory address to header address
static inline void* get_base(void* memblock);
static inline void* get_base(void* memblock, NMT_TrackingLevel level) {
@@ -361,16 +334,12 @@ class MallocTracker : AllStatic {
// Get memory size
static inline size_t get_size(void* memblock) {
MallocHeader* header = malloc_header(memblock);
- assert(header->tracking_level() >= NMT_summary,
- "Wrong tracking level");
return header->size();
}
// Get memory type
static inline MEMFLAGS get_flags(void* memblock) {
MallocHeader* header = malloc_header(memblock);
- assert(header->tracking_level() >= NMT_summary,
- "Wrong tracking level");
return header->flags();
}
@@ -394,7 +363,6 @@ class MallocTracker : AllStatic {
static inline MallocHeader* malloc_header(void *memblock) {
assert(memblock != NULL, "NULL pointer");
MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader));
- assert(header->tracking_level() >= NMT_minimal, "Bad header");
return header;
}
};
diff --git a/hotspot/src/share/vm/services/mallocTracker.inline.hpp b/hotspot/src/share/vm/services/mallocTracker.inline.hpp
index 338295b6566..e8203bbc54e 100644
--- a/hotspot/src/share/vm/services/mallocTracker.inline.hpp
+++ b/hotspot/src/share/vm/services/mallocTracker.inline.hpp
@@ -28,13 +28,6 @@
#include "services/mallocTracker.hpp"
#include "services/memTracker.hpp"
-inline NMT_TrackingLevel MallocTracker::get_memory_tracking_level(void* memblock) {
- assert(memblock != NULL, "Sanity check");
- if (MemTracker::tracking_level() == NMT_off) return NMT_off;
- MallocHeader* header = malloc_header(memblock);
- return header->tracking_level();
-}
-
inline void* MallocTracker::get_base(void* memblock){
return get_base(memblock, MemTracker::tracking_level());
}
diff --git a/hotspot/src/share/vm/services/management.cpp b/hotspot/src/share/vm/services/management.cpp
index ba5e5f40882..fbe4901a3f7 100644
--- a/hotspot/src/share/vm/services/management.cpp
+++ b/hotspot/src/share/vm/services/management.cpp
@@ -1333,7 +1333,7 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
GrowableArray<oop>* locked_monitors = frame->locked_monitors();
for (j = 0; j < len; j++) {
oop monitor = locked_monitors->at(j);
- assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
+ assert(monitor != NULL, "must be a Java object");
monitors_array->obj_at_put(count, monitor);
depths_array->int_at_put(count, depth);
count++;
@@ -1343,7 +1343,7 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
GrowableArray<oop>* jni_locked_monitors = stacktrace->jni_locked_monitors();
for (j = 0; j < jni_locked_monitors->length(); j++) {
oop object = jni_locked_monitors->at(j);
- assert(object != NULL && object->is_instance(), "must be a Java object");
+ assert(object != NULL, "must be a Java object");
monitors_array->obj_at_put(count, object);
// Monitor locked via JNI MonitorEnter call doesn't have stack depth info
depths_array->int_at_put(count, -1);
@@ -1572,6 +1572,9 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag,
} else if (flag->is_uint64_t()) {
global->value.j = (jlong)flag->get_uint64_t();
global->type = JMM_VMGLOBAL_TYPE_JLONG;
+ } else if (flag->is_double()) {
+ global->value.d = (jdouble)flag->get_double();
+ global->type = JMM_VMGLOBAL_TYPE_JDOUBLE;
} else if (flag->is_size_t()) {
global->value.j = (jlong)flag->get_size_t();
global->type = JMM_VMGLOBAL_TYPE_JLONG;
diff --git a/hotspot/src/share/vm/services/runtimeService.cpp b/hotspot/src/share/vm/services/runtimeService.cpp
index e2b829c41f5..413261b6572 100644
--- a/hotspot/src/share/vm/services/runtimeService.cpp
+++ b/hotspot/src/share/vm/services/runtimeService.cpp
@@ -38,6 +38,7 @@ PerfCounter* RuntimeService::_sync_time_ticks = NULL;
PerfCounter* RuntimeService::_total_safepoints = NULL;
PerfCounter* RuntimeService::_safepoint_time_ticks = NULL;
PerfCounter* RuntimeService::_application_time_ticks = NULL;
+double RuntimeService::_last_safepoint_sync_time_sec = 0.0;
void RuntimeService::init() {
// Make sure the VM version is initialized
@@ -96,6 +97,7 @@ void RuntimeService::record_safepoint_begin() {
// update the time stamp to begin recording safepoint time
_safepoint_timer.update();
+ _last_safepoint_sync_time_sec = 0.0;
if (UsePerfData) {
_total_safepoints->inc();
if (_app_timer.is_updated()) {
@@ -108,6 +110,9 @@ void RuntimeService::record_safepoint_synchronized() {
if (UsePerfData) {
_sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
}
+ if (PrintGCApplicationStoppedTime) {
+ _last_safepoint_sync_time_sec = last_safepoint_time_sec();
+ }
}
void RuntimeService::record_safepoint_end() {
@@ -119,8 +124,10 @@ void RuntimeService::record_safepoint_end() {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print_cr("Total time for which application threads "
- "were stopped: %3.7f seconds",
- last_safepoint_time_sec());
+ "were stopped: %3.7f seconds, "
+ "Stopping threads took: %3.7f seconds",
+ last_safepoint_time_sec(),
+ _last_safepoint_sync_time_sec);
}
// update the time stamp to begin recording app time
diff --git a/hotspot/src/share/vm/services/runtimeService.hpp b/hotspot/src/share/vm/services/runtimeService.hpp
index 90981ee2ebe..228f6645f3a 100644
--- a/hotspot/src/share/vm/services/runtimeService.hpp
+++ b/hotspot/src/share/vm/services/runtimeService.hpp
@@ -37,6 +37,7 @@ private:
static TimeStamp _safepoint_timer;
static TimeStamp _app_timer;
+ static double _last_safepoint_sync_time_sec;
public:
static void init();
diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp
index 74d3ea1383a..1995450bbf0 100644
--- a/hotspot/src/share/vm/services/threadService.cpp
+++ b/hotspot/src/share/vm/services/threadService.cpp
@@ -597,7 +597,7 @@ bool ThreadStackTrace::is_owned_monitor_on_stack(oop object) {
GrowableArray<oop>* locked_monitors = frame->locked_monitors();
for (int j = 0; j < len; j++) {
oop monitor = locked_monitors->at(j);
- assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
+ assert(monitor != NULL, "must be a Java object");
if (monitor == object) {
found = true;
break;
diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml
index 9ffc764599b..120d27f4d4d 100644
--- a/hotspot/src/share/vm/trace/trace.xml
+++ b/hotspot/src/share/vm/trace/trace.xml
@@ -383,7 +383,6 @@ Declares a structure type that can be used in other events.
<event id="SweepCodeCache" path="vm/code_sweeper/sweep" label="Sweep Code Cache"
has_thread="true" is_requestable="false" is_constant="false">
<value type="INTEGER" field="sweepIndex" label="Sweep Index" relation="SWEEP_ID"/>
- <value type="USHORT" field="sweepFractionIndex" label="Fraction Index"/>
<value type="UINT" field="sweptCount" label="Methods Swept"/>
<value type="UINT" field="flushedCount" label="Methods Flushed"/>
<value type="UINT" field="markedCount" label="Methods Reclaimed"/>
diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp
index bb0195d58d1..adacdc4233f 100644
--- a/hotspot/src/share/vm/utilities/debug.cpp
+++ b/hotspot/src/share/vm/utilities/debug.cpp
@@ -256,16 +256,18 @@ void report_out_of_shared_space(SharedSpaceType shared_space) {
static const char* name[] = {
"shared read only space",
"shared read write space",
- "shared miscellaneous data space"
+ "shared miscellaneous data space",
+ "shared miscellaneous code space"
};
static const char* flag[] = {
"SharedReadOnlySize",
"SharedReadWriteSize",
- "SharedMiscDataSize"
+ "SharedMiscDataSize",
+ "SharedMiscCodeSize"
};
warning("\nThe %s is not large enough\n"
- "to preload requested classes. Use -XX:%s=\n"
+ "to preload requested classes. Use -XX:%s=<size>\n"
"to increase the initial size of %s.\n",
name[shared_space], flag[shared_space], name[shared_space]);
exit(2);
diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp
index 51e516a5bb5..7995e6c085d 100644
--- a/hotspot/src/share/vm/utilities/debug.hpp
+++ b/hotspot/src/share/vm/utilities/debug.hpp
@@ -245,7 +245,8 @@ template <> struct StaticAssert<true> {};
enum SharedSpaceType {
SharedReadOnly,
SharedReadWrite,
- SharedMiscData
+ SharedMiscData,
+ SharedMiscCode
};
void report_out_of_shared_space(SharedSpaceType space_type);
diff --git a/hotspot/src/share/vm/utilities/dtrace_disabled.hpp b/hotspot/src/share/vm/utilities/dtrace_disabled.hpp
index 2906fe22e93..40093592791 100644
--- a/hotspot/src/share/vm/utilities/dtrace_disabled.hpp
+++ b/hotspot/src/share/vm/utilities/dtrace_disabled.hpp
@@ -27,7 +27,7 @@
/* This file contains dummy provider probes needed when compiling a hotspot
* that does not support dtrace probes. This could be because we're building
- * on a system that doesn't suuport dtrace or because we're bulding a variant
+ * on a system that doesn't support dtrace or because we're bulding a variant
* of hotspot (like core) where we do not support dtrace
*/
#if !defined(DTRACE_ENABLED)
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index e27cb166209..318c62b4708 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -1048,7 +1048,7 @@ const int badHandleValue = 0xBC; // value used to zap
const int badResourceValue = 0xAB; // value used to zap resource area
const int freeBlockPad = 0xBA; // value used to pad freed blocks.
const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks.
-const intptr_t badJNIHandleVal = (intptr_t) CONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
+const intptr_t badJNIHandleVal = (intptr_t) UCONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC
const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC
const int badCodeHeapNewVal= 0xCC; // value used to zap Code heap at allocation
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
index 46e8f9e8e93..1be86e1b832 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp
@@ -151,11 +151,11 @@ inline int g_isfinite(jdouble f) { return _finite(f); }
// Constant for jlong (specifying an long long constant is C++ compiler specific)
// Build a 64bit integer constant on with Visual C++
-#define CONST64(x) (x ## i64)
-#define UCONST64(x) ((uint64_t)CONST64(x))
+#define CONST64(x) (x ## i64)
+#define UCONST64(x) (x ## ui64)
-const jlong min_jlong = CONST64(0x8000000000000000);
-const jlong max_jlong = CONST64(0x7fffffffffffffff);
+const jlong min_jlong = (jlong)UCONST64(0x8000000000000000);
+const jlong max_jlong = CONST64(0x7fffffffffffffff);
//----------------------------------------------------------------------------------------------------
// Miscellaneous
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index ceb5774fe81..f6880d7ac86 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -76,6 +76,8 @@ const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
const char* format, va_list ap,
bool add_cr,
size_t& result_len) {
+ assert(buflen >= 2, "buffer too small");
+
const char* result;
if (add_cr) buflen--;
if (!strchr(format, '%')) {
@@ -88,14 +90,21 @@ const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
result = va_arg(ap, const char*);
result_len = strlen(result);
if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
- } else if (vsnprintf(buffer, buflen, format, ap) >= 0) {
- result = buffer;
- result_len = strlen(result);
} else {
- DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
+ // Handle truncation:
+ // posix: upon truncation, vsnprintf returns number of bytes which
+ // would have been written (excluding terminating zero) had the buffer
+ // been large enough
+ // windows: upon truncation, vsnprintf returns -1
+ const int written = vsnprintf(buffer, buflen, format, ap);
result = buffer;
- result_len = buflen - 1;
- buffer[result_len] = 0;
+ if (written < (int) buflen && written >= 0) {
+ result_len = written;
+ } else {
+ DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
+ result_len = buflen - 1;
+ buffer[result_len] = 0;
+ }
}
if (add_cr) {
if (result != buffer) {
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index 37a363570aa..5957d74adaa 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -975,11 +975,13 @@ void VMError::report_and_die() {
// Run error reporting to determine whether or not to report the crash.
if (!transmit_report_done && should_report_bug(first_error->_id)) {
transmit_report_done = true;
- FILE* hs_err = os::open(log.fd(), "r");
+ const int fd2 = ::dup(log.fd());
+ FILE* const hs_err = ::fdopen(fd2, "r");
if (NULL != hs_err) {
ErrorReporter er;
er.call(hs_err, buffer, O_BUFLEN);
}
+ ::fclose(hs_err);
}
if (log.fd() != defaultStream::output_fd()) {
diff --git a/hotspot/test/TEST.ROOT b/hotspot/test/TEST.ROOT
index 6bf9e9a9009..d9414f507e1 100644
--- a/hotspot/test/TEST.ROOT
+++ b/hotspot/test/TEST.ROOT
@@ -30,3 +30,4 @@
keys=cte_test jcmd nmt regression gc stress
groups=TEST.groups [closed/TEST.groups]
+requires.properties=sun.arch.data.model
diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups
index 0b65e906df7..8dbacc847f3 100644
--- a/hotspot/test/TEST.groups
+++ b/hotspot/test/TEST.groups
@@ -87,7 +87,6 @@ needs_jdk = \
runtime/NMT/SummarySanityCheck.java \
runtime/NMT/ThreadedMallocTestType.java \
runtime/NMT/ThreadedVirtualAllocTestType.java \
- runtime/NMT/UnsafeMallocLimit.java \
runtime/NMT/VirtualAllocCommitUncommitRecommit.java \
runtime/NMT/VirtualAllocTestType.java \
runtime/RedefineObject/TestRedefineObject.java \
@@ -198,7 +197,8 @@ compact2_minimal = \
# Tests that require compact2 API's
#
-needs_compact2 =
+needs_compact2 = \
+ compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java
# All tests that run on the most minimal configuration: Minimal VM on Compact 1
compact1_minimal = \
@@ -443,6 +443,7 @@ hotspot_compiler_3 = \
compiler/arraycopy/TestMissingControl.java \
compiler/ciReplay/TestVM_no_comp_level.sh \
compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java \
+ compiler/codecache/CheckSegmentedCodeCache.java \
compiler/codecache/CheckUpperLimit.java \
compiler/codegen/ \
compiler/cpuflags/RestoreMXCSR.java \
@@ -477,9 +478,9 @@ hotspot_compiler_3 = \
compiler/intrinsics/mathexact/SubExactILoopDependentTest.java \
compiler/intrinsics/stringequals/TestStringEqualsBadLength.java \
compiler/intrinsics/unsafe/UnsafeGetAddressTest.java \
+ compiler/intrinsics/classcast/NullCheckDroppingsTest.java \
compiler/jsr292/ConcurrentClassLoadingTest.java \
compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java \
- compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java \
compiler/loopopts/TestLogSum.java \
compiler/macronodes/TestEliminateAllocationPhi.java \
compiler/membars/TestMemBarAcquire.java \
@@ -602,3 +603,14 @@ hotspot_all = \
:hotspot_gc \
:hotspot_runtime \
:hotspot_serviceability
+
+#All tests that depends on nashorn extension.
+#
+needs_nashorn = \
+ compiler/jsr292/CreatesInterfaceDotEqualsCallInfo.java
+
+#All tests that do not depends on nashorn extension
+#
+not_needs_nashorn = \
+ :jdk \
+ -:needs_nashorh
diff --git a/hotspot/test/compiler/6896617/Test6896617.java b/hotspot/test/compiler/6896617/Test6896617.java
index e28d3d7d57b..38835e0e420 100644
--- a/hotspot/test/compiler/6896617/Test6896617.java
+++ b/hotspot/test/compiler/6896617/Test6896617.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,20 @@
* @test
* @bug 6896617
* @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x86
+ * @library /testlibrary
* @run main/othervm/timeout=1200 -Xbatch -Xmx256m Test6896617
*
*/
-import java.util.*;
-import java.nio.*;
-import java.nio.charset.*;
+import com.oracle.java.testlibrary.Utils;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
+import java.util.Random;
public class Test6896617 {
final static int SIZE = 256;
@@ -54,7 +61,7 @@ public class Test6896617 {
sun.nio.cs.ArrayDecoder arrdec = (sun.nio.cs.ArrayDecoder)dec;
// Populate char[] with chars which can be encoded by ISO_8859_1 (<= 0xFF)
- Random rnd = new Random(0);
+ Random rnd = Utils.getRandomInstance();
int maxchar = 0xFF;
char[] a = new char[SIZE];
byte[] b = new byte[SIZE];
diff --git a/hotspot/test/compiler/7100757/Test7100757.java b/hotspot/test/compiler/7100757/Test7100757.java
index daa0bfeb22e..50ee9e11550 100644
--- a/hotspot/test/compiler/7100757/Test7100757.java
+++ b/hotspot/test/compiler/7100757/Test7100757.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,13 @@
* @test
* @bug 7100757
* @summary The BitSet.nextSetBit() produces incorrect result in 32bit VM on Sparc
- *
+ * @library /testlibrary
* @run main/timeout=300 Test7100757
*/
-import java.util.*;
+import com.oracle.java.testlibrary.Utils;
+import java.util.BitSet;
+import java.util.Random;
public class Test7100757 {
@@ -39,7 +41,7 @@ public class Test7100757 {
public static void main(String[] args) {
BitSet bs = new BitSet(NBITS);
- Random rnd = new Random();
+ Random rnd = Utils.getRandomInstance();
long[] ra = new long[(NBITS+63)/64];
for(int l=0; l < 5000000; l++) {
diff --git a/hotspot/test/compiler/7177917/Test7177917.java b/hotspot/test/compiler/7177917/Test7177917.java
index 7d2c76490a9..708f8c3f424 100644
--- a/hotspot/test/compiler/7177917/Test7177917.java
+++ b/hotspot/test/compiler/7177917/Test7177917.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,13 +26,14 @@
* Micro-benchmark for Math.pow() and Math.exp()
*/
-import java.util.*;
+import com.oracle.java.testlibrary.Utils;
+import java.util.Random;
public class Test7177917 {
static double d;
- static Random r = new Random(0);
+ static final Random R = Utils.getRandomInstance();
static long m_pow(double[][] values) {
double res = 0;
@@ -59,10 +60,10 @@ public class Test7177917 {
static double[][] pow_values(int nb) {
double[][] res = new double[nb][2];
for (int i = 0; i < nb; i++) {
- double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
- double x = Math.abs(Double.longBitsToDouble(r.nextLong()));
+ double ylogx = (1 + (R.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
+ double x = Math.abs(Double.longBitsToDouble(R.nextLong()));
while (x != x) {
- x = Math.abs(Double.longBitsToDouble(r.nextLong()));
+ x = Math.abs(Double.longBitsToDouble(R.nextLong()));
}
double logx = Math.log(x) / Math.log(2);
double y = ylogx / logx;
@@ -76,7 +77,7 @@ public class Test7177917 {
static double[] exp_values(int nb) {
double[] res = new double[nb];
for (int i = 0; i < nb; i++) {
- double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
+ double ylogx = (1 + (R.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
double x = Math.E;
double logx = Math.log(x) / Math.log(2);
double y = ylogx / logx;
diff --git a/hotspot/test/compiler/7184394/TestAESBase.java b/hotspot/test/compiler/7184394/TestAESBase.java
index 4d3204880bc..73a4994e662 100644
--- a/hotspot/test/compiler/7184394/TestAESBase.java
+++ b/hotspot/test/compiler/7184394/TestAESBase.java
@@ -26,15 +26,13 @@
* @author Tom Deneau
*/
+import com.oracle.java.testlibrary.Utils;
+import java.security.AlgorithmParameters;
+import java.util.Random;
import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-import java.security.AlgorithmParameters;
-
-import java.util.Random;
-import java.util.Arrays;
abstract public class TestAESBase {
int msgSize = Integer.getInteger("msgSize", 646);
@@ -59,7 +57,7 @@ abstract public class TestAESBase {
byte[] expectedEncode;
byte[] decode;
byte[] expectedDecode;
- Random random = new Random(0);
+ final Random random = Utils.getRandomInstance();
Cipher cipher;
Cipher dCipher;
AlgorithmParameters algParams;
diff --git a/hotspot/test/compiler/7184394/TestAESMain.java b/hotspot/test/compiler/7184394/TestAESMain.java
index 20929e8ba68..d09a305a3b4 100644
--- a/hotspot/test/compiler/7184394/TestAESMain.java
+++ b/hotspot/test/compiler/7184394/TestAESMain.java
@@ -26,6 +26,7 @@
* @test
* @bug 7184394
* @summary add intrinsics to use AES instructions
+ * @library /testlibrary
*
* @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=CBC TestAESMain
* @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true -Dmode=CBC -DencInputOffset=1 TestAESMain
diff --git a/hotspot/test/compiler/8005956/PolynomialRoot.java b/hotspot/test/compiler/8005956/PolynomialRoot.java
index 1ec220955a5..54cc8f3d5c5 100644
--- a/hotspot/test/compiler/8005956/PolynomialRoot.java
+++ b/hotspot/test/compiler/8005956/PolynomialRoot.java
@@ -1,4 +1,3 @@
-//package com.polytechnik.utils;
/*
* (C) Vladislav Malyshkin 2010
* This file is under GPL version 3.
@@ -14,10 +13,14 @@
* @test
* @bug 8005956
* @summary C2: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG defined in this block
-*
+* @library /testlibrary
* @run main/timeout=300 PolynomialRoot
*/
+import com.oracle.java.testlibrary.Utils;
+import java.util.Arrays;
+import java.util.Random;
+
public class PolynomialRoot {
@@ -57,7 +60,7 @@ private static final boolean PRINT_DEBUG=false;
public static int root4(final double [] p,final double [] re_root,final double [] im_root)
{
- if(PRINT_DEBUG) System.err.println("=====================root4:p="+java.util.Arrays.toString(p));
+ if (PRINT_DEBUG) { System.err.println("=====================root4:p=" + Arrays.toString(p)); }
final double vs=p[4];
if(PRINT_DEBUG) System.err.println("p[4]="+p[4]);
if(!(Math.abs(vs)>EPS))
@@ -367,7 +370,7 @@ public static int root4(final double [] p,final double [] re_root,final double [
- static void setRandomP(final double [] p,final int n,java.util.Random r)
+ static void setRandomP(final double [] p, final int n, Random r)
{
if(r.nextDouble()<0.1)
{
@@ -465,7 +468,7 @@ public static int root4(final double [] p,final double [] re_root,final double [
static void testRoots(final int n,
final int n_tests,
- final java.util.Random rn,
+ final Random rn,
final double eps)
{
final double [] p=new double [n+1];
@@ -763,7 +766,7 @@ public static int root4(final double [] p,final double [] re_root,final double [
final long t0=System.currentTimeMillis();
final double eps=1e-6;
//checkRoots();
- final java.util.Random r=new java.util.Random(-1381923);
+ final Random r = Utils.getRandomInstance();
printSpecialValues();
final int n_tests=100000;
diff --git a/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java b/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java
new file mode 100644
index 00000000000..982c5f7beb1
--- /dev/null
+++ b/hotspot/test/compiler/EliminateAutoBox/UnsignedLoads.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary
+ * @run main/othervm -Xbatch -XX:+EliminateAutoBox
+ * -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort
+ * UnsignedLoads
+ */
+import static com.oracle.java.testlibrary.Asserts.assertEQ;
+
+public class UnsignedLoads {
+ public static int testUnsignedByte() {
+ byte[] bytes = new byte[] {-1};
+ int res = 0;
+ for (int i = 0; i < 100000; i++) {
+ for (Byte b : bytes) {
+ res = b & 0xff;
+ }
+ }
+ return res;
+ }
+
+ public static int testUnsignedShort() {
+ int res = 0;
+ short[] shorts = new short[] {-1};
+ for (int i = 0; i < 100000; i++) {
+ for (Short s : shorts) {
+ res = s & 0xffff;
+ }
+ }
+ return res;
+ }
+
+ public static void main(String[] args) {
+ assertEQ(testUnsignedByte(), 255);
+ assertEQ(testUnsignedShort(), 65535);
+ System.out.println("TEST PASSED");
+ }
+}
diff --git a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java
index 06330d840b6..da739765bea 100644
--- a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java
+++ b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java
@@ -22,15 +22,20 @@
*/
import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
/*
* @test CheckSegmentedCodeCache
* @bug 8015774
+ * @library /testlibrary /testlibrary/whitebox
* @summary "Checks VM options related to the segmented code cache"
- * @library /testlibrary
- * @run main/othervm CheckSegmentedCodeCache
+ * @build CheckSegmentedCodeCache
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI CheckSegmentedCodeCache
*/
public class CheckSegmentedCodeCache {
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
// Code heap names
private static final String NON_METHOD = "CodeHeap 'non-nmethods'";
private static final String PROFILED = "CodeHeap 'profiled nmethods'";
@@ -133,8 +138,11 @@ public class CheckSegmentedCodeCache {
failsWith(pb, "Invalid code heap sizes");
// Fails if not enough space for VM internal code
+ long minUseSpace = WHITE_BOX.getUintxVMFlag("CodeCacheMinimumUseSpace");
+ // minimum size: CodeCacheMinimumUseSpace DEBUG_ONLY(* 3)
+ long minSize = (Platform.isDebugBuild() ? 3 : 1) * minUseSpace;
pb = ProcessTools.createJavaProcessBuilder("-XX:+SegmentedCodeCache",
- "-XX:ReservedCodeCacheSize=1700K",
+ "-XX:ReservedCodeCacheSize=" + minSize,
"-XX:InitialCodeCacheSize=100K");
failsWith(pb, "Not enough space in non-nmethod code heap to run VM");
}
diff --git a/hotspot/test/compiler/debug/TraceIterativeGVN.java b/hotspot/test/compiler/debug/TraceIterativeGVN.java
new file mode 100644
index 00000000000..7d98dd660b9
--- /dev/null
+++ b/hotspot/test/compiler/debug/TraceIterativeGVN.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * @run main/othervm -Xbatch -XX:-TieredCompilation
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceIterativeGVN
+ * TraceIterativeGVN
+ */
+public class TraceIterativeGVN {
+ public static void main(String[] args) {
+ for (int i = 0; i < 100_000; i++) {
+ Byte.valueOf((byte)0);
+ }
+ System.out.println("TEST PASSED");
+ }
+}
diff --git a/hotspot/test/compiler/exceptions/CatchInlineExceptions.java b/hotspot/test/compiler/exceptions/CatchInlineExceptions.java
index 01be927cf7b..64e986f55c0 100644
--- a/hotspot/test/compiler/exceptions/CatchInlineExceptions.java
+++ b/hotspot/test/compiler/exceptions/CatchInlineExceptions.java
@@ -70,7 +70,7 @@ public class CatchInlineExceptions {
if (counter1 != 0) {
throw new RuntimeException("Failed: counter1(" + counter1 + ") != 0");
}
- if (counter2 != counter) {
+ if (counter2 != counter0) {
throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter0(" + counter0 + ")");
}
if (counter2 != counter) {
diff --git a/hotspot/test/compiler/intrinsics/bmi/BMITestRunner.java b/hotspot/test/compiler/intrinsics/bmi/BMITestRunner.java
index ea7fd821f33..31a65115c22 100644
--- a/hotspot/test/compiler/intrinsics/bmi/BMITestRunner.java
+++ b/hotspot/test/compiler/intrinsics/bmi/BMITestRunner.java
@@ -22,13 +22,17 @@
*
*/
-import java.util.*;
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Utils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.nio.charset.StandardCharsets;
-
-import com.oracle.java.testlibrary.*;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
/**
* Test runner that invokes all methods implemented by particular Expr
@@ -69,7 +73,7 @@ public class BMITestRunner {
String... additionalVMOpts)
throws Throwable {
- int seed = new Random().nextInt();
+ int seed = Utils.getRandomInstance().nextInt();
int iterations = DEFAULT_ITERATIONS_COUNT;
for (String testOption : testOpts) {
@@ -81,8 +85,6 @@ public class BMITestRunner {
}
}
- System.out.println("Running test with seed: " + seed);
-
OutputAnalyzer intOutput = runTest(expr, VMMode.INT,
additionalVMOpts,
seed, iterations);
@@ -139,9 +141,9 @@ public class BMITestRunner {
Collections.addAll(vmOpts, new String[] {
"-XX:+DisplayVMOutputToStderr",
+ "-D" + Utils.SEED_PROPERTY_NAME + "=" + seed,
Executor.class.getName(),
expr.getName(),
- new Integer(seed).toString(),
new Integer(iterations).toString()
});
@@ -179,16 +181,15 @@ public class BMITestRunner {
public static class Executor {
/**
- * Usage: BMITestRunner$Executor <ExprClassName> <seed> <iterations>
+ * Usage: BMITestRunner$Executor &lt;ExprClassName&gt; &lt;iterations&gt;
*/
public static void main(String args[]) throws Exception {
@SuppressWarnings("unchecked")
Class<? extends Expr> exprClass =
(Class<? extends Expr>)Class.forName(args[0]);
Expr expr = exprClass.getConstructor().newInstance();
- Random rng = new Random(Integer.valueOf(args[1]));
- int iterations = Integer.valueOf(args[2]);
- runTests(expr, iterations, rng);
+ int iterations = Integer.valueOf(args[1]);
+ runTests(expr, iterations, Utils.getRandomInstance());
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
index 45a79b0df37..fa7b842380e 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java
@@ -41,14 +41,14 @@ public class TestAndnI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. "+
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(AndnIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(AndnICommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
index 8746fefa483..6e7fbe4fbf8 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java
@@ -41,14 +41,14 @@ public class TestAndnL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(AndnLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(AndnLCommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java
index 7ced5242692..794676252a0 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java
@@ -41,14 +41,14 @@ public class TestBlsiI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsiIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsiICommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java
index d1fe59c204b..046351222e9 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java
@@ -41,14 +41,14 @@ public class TestBlsiL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsiLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsiLCommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java
index 7cba5d88e36..3f1b95ffec2 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java
@@ -41,14 +41,14 @@ public class TestBlsmskI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsmskIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsmskICommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java
index d2f3a3f6aea..aca3981f779 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java
@@ -41,14 +41,14 @@ public class TestBlsmskL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsmskLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsmskLCommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java
index 53e7251143b..90121c88942 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java
@@ -41,14 +41,14 @@ public class TestBlsrI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsrIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsrICommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java b/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java
index 5e3c885542b..ad267769dac 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java
@@ -41,14 +41,14 @@ public class TestBlsrL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(BlsrLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
BMITestRunner.runTests(BlsrLCommutativeExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseBMI1Instructions");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java b/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java
index d13b89c0246..5cb08e0a381 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java
@@ -41,12 +41,11 @@ public class TestLzcntI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("lzcnt")) {
- System.out.println("CPU does not support lzcnt feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support lzcnt feature.");
}
BMITestRunner.runTests(LzcntIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseCountLeadingZerosInstruction");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java b/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java
index b75830df18a..fbcadf49dad 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java
@@ -41,12 +41,11 @@ public class TestLzcntL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("lzcnt")) {
- System.out.println("CPU does not support lzcnt feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support lzcnt feature.");
}
BMITestRunner.runTests(LzcntLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseCountLeadingZerosInstruction");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java b/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java
index 285519537aa..bd8c8764617 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java
@@ -41,12 +41,11 @@ public class TestTzcntI {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(TzcntIExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseCountTrailingZerosInstruction");
}
diff --git a/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java b/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java
index 36683fe7283..0a008aa4d58 100644
--- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java
+++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java
@@ -41,12 +41,11 @@ public class TestTzcntL {
public static void main(String args[]) throws Throwable {
if (!CPUInfo.hasFeature("bmi1")) {
- System.out.println("CPU does not support bmi1 feature. " +
- "Test skipped.");
- return;
+ System.out.println("INFO: CPU does not support bmi1 feature.");
}
BMITestRunner.runTests(TzcntLExpr.class, args,
+ "-XX:+IgnoreUnrecognizedVMOptions",
"-XX:+UseCountTrailingZerosInstruction");
}
diff --git a/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java b/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java
new file mode 100644
index 00000000000..9f88fe44f70
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2014, 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 NullCheckDroppingsTest
+ * @bug 8054492
+ * @summary "Casting can result in redundant null checks in generated code"
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/com/oracle/java/testlibrary
+ * @build NullCheckDroppingsTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -Xmixed -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:CompileThreshold=1000
+ * -XX:CompileCommand=exclude,NullCheckDroppingsTest::runTest NullCheckDroppingsTest
+ */
+
+import sun.hotspot.WhiteBox;
+import sun.hotspot.code.NMethod;
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.function.BiFunction;
+
+public class NullCheckDroppingsTest {
+
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ static final BiFunction<Class, Object, Object> fCast = (c, o) -> c.cast(o);
+
+ static final MethodHandle SET_SSINK;
+ static final MethodHandle MH_CAST;
+
+ static {
+ try {
+ SET_SSINK = MethodHandles.lookup().findSetter(NullCheckDroppingsTest.class, "ssink", String.class);
+ MH_CAST = MethodHandles.lookup().findVirtual(Class.class,
+ "cast",
+ MethodType.methodType(Object.class, Object.class));
+ }
+ catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ static volatile String svalue = "A";
+ static volatile String snull = null;
+ static volatile Integer iobj = new Integer(0);
+ static volatile int[] arr = new int[2];
+ static volatile Class objClass = String.class;
+ static volatile Class nullClass = null;
+
+ String ssink;
+ Integer isink;
+ int[] asink;
+
+ public static void main(String[] args) throws Exception {
+
+ // Only test C2 in Server VM
+ if (!Platform.isServer()) {
+ return;
+ }
+ // Make sure background compilation is disabled
+ if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
+ throw new AssertionError("Background compilation enabled");
+ }
+ // Make sure Tiered compilation is disabled
+ if (WHITE_BOX.getBooleanVMFlag("TieredCompilation")) {
+ throw new AssertionError("Tiered compilation enabled");
+ }
+
+ Method methodClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCast", String.class);
+ Method methodMHCast = NullCheckDroppingsTest.class.getDeclaredMethod("testMHCast", String.class);
+ Method methodMHSetter = NullCheckDroppingsTest.class.getDeclaredMethod("testMHSetter", String.class);
+ Method methodFunction = NullCheckDroppingsTest.class.getDeclaredMethod("testFunction", String.class);
+
+ NullCheckDroppingsTest t = new NullCheckDroppingsTest();
+ t.runTest(methodClassCast, false);
+ t.runTest(methodMHCast, false);
+ t.runTest(methodMHSetter, false);
+ t.runTest(methodFunction, false);
+
+ // Edge cases
+ Method methodClassCastNull = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCastNull", String.class);
+ Method methodNullClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testNullClassCast", String.class);
+ Method methodClassCastObj = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCastObj", Object.class);
+ Method methodObjClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testObjClassCast", String.class);
+ Method methodVarClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testVarClassCast", String.class);
+ Method methodClassCastInt = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCastInt", Object.class);
+ Method methodIntClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testIntClassCast", Object.class);
+ Method methodClassCastint = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCastint", Object.class);
+ Method methodintClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testintClassCast", Object.class);
+ Method methodClassCastPrim = NullCheckDroppingsTest.class.getDeclaredMethod("testClassCastPrim", Object.class);
+ Method methodPrimClassCast = NullCheckDroppingsTest.class.getDeclaredMethod("testPrimClassCast", Object.class);
+
+ t.runTest(methodClassCastNull, false);
+ t.runTest(methodNullClassCast, false);
+ t.runTest(methodClassCastObj, false);
+ t.runTest(methodObjClassCast, true);
+ t.runTest(methodVarClassCast, true);
+ t.runTest(methodClassCastInt, false);
+ t.runTest(methodIntClassCast, true);
+ t.runTest(methodClassCastint, false);
+ t.runTest(methodintClassCast, false);
+ t.runTest(methodClassCastPrim, false);
+ t.runTest(methodPrimClassCast, true);
+ }
+
+ void testClassCast(String s) {
+ try {
+ ssink = String.class.cast(s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testClassCastNull(String s) {
+ try {
+ ssink = String.class.cast(null);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testNullClassCast(String s) {
+ try {
+ ssink = (String)nullClass.cast(s);
+ throw new AssertionError("NullPointerException is not thrown");
+ } catch (NullPointerException t) {
+ // Ignore NullPointerException
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testClassCastObj(Object s) {
+ try {
+ ssink = String.class.cast(s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testObjClassCast(String s) {
+ try {
+ ssink = (String)objClass.cast(s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testVarClassCast(String s) {
+ Class cl = (s == null) ? null : String.class;
+ try {
+ ssink = (String)cl.cast(svalue);
+ if (s == null) {
+ throw new AssertionError("NullPointerException is not thrown");
+ }
+ } catch (NullPointerException t) {
+ // Ignore NullPointerException
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testClassCastInt(Object s) {
+ try {
+ ssink = String.class.cast(iobj);
+ throw new AssertionError("ClassCastException is not thrown");
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast java.lang.Integer to java.lang.String
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testIntClassCast(Object s) {
+ try {
+ isink = Integer.class.cast(s);
+ if (s != null) {
+ throw new AssertionError("ClassCastException is not thrown");
+ }
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast java.lang.String to java.lang.Integer
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testClassCastint(Object s) {
+ try {
+ ssink = String.class.cast(45);
+ throw new AssertionError("ClassCastException is not thrown");
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast java.lang.Integer to java.lang.String
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testintClassCast(Object s) {
+ try {
+ isink = int.class.cast(s);
+ if (s != null) {
+ throw new AssertionError("ClassCastException is not thrown");
+ }
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast java.lang.String to java.lang.Integer
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testClassCastPrim(Object s) {
+ try {
+ ssink = String.class.cast(arr);
+ throw new AssertionError("ClassCastException is not thrown");
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast [I to java.lang.String
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testPrimClassCast(Object s) {
+ try {
+ asink = int[].class.cast(s);
+ if (s != null) {
+ throw new AssertionError("ClassCastException is not thrown");
+ }
+ } catch (ClassCastException t) {
+ // Ignore ClassCastException: Cannot cast java.lang.String to [I
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testMHCast(String s) {
+ try {
+ ssink = (String) (Object) MH_CAST.invokeExact(String.class, (Object) s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testMHSetter(String s) {
+ try {
+ SET_SSINK.invokeExact(this, s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void testFunction(String s) {
+ try {
+ ssink = (String) fCast.apply(String.class, s);
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ void runTest(Method method, boolean deopt) {
+ if (method == null) {
+ throw new AssertionError("method was not found");
+ }
+ // Ensure method is compiled
+ WHITE_BOX.testSetDontInlineMethod(method, true);
+ for (int i = 0; i < 3000; i++) {
+ try {
+ method.invoke(this, svalue);
+ } catch (Exception e) {
+ throw new Error("Unexpected exception: ", e);
+ }
+ }
+ NMethod nm = getNMethod(method);
+
+ // Passing null should cause a de-optimization
+ // if method is compiled with a null-check.
+ try {
+ method.invoke(this, snull);
+ } catch (Exception e) {
+ throw new Error("Unexpected exception: ", e);
+ }
+ checkDeoptimization(method, nm, deopt);
+ }
+
+ static NMethod getNMethod(Method test) {
+ // Because background compilation is disabled, method should now be compiled
+ if (!WHITE_BOX.isMethodCompiled(test)) {
+ throw new AssertionError(test + " not compiled");
+ }
+
+ NMethod nm = NMethod.get(test, false); // not OSR nmethod
+ if (nm == null) {
+ throw new AssertionError(test + " missing nmethod?");
+ }
+ if (nm.comp_level != 4) {
+ throw new AssertionError(test + " compiled by not C2: " + nm);
+ }
+ return nm;
+ }
+
+ static void checkDeoptimization(Method method, NMethod nmOrig, boolean deopt) {
+ // Check deoptimization event (intrinsic Class.cast() works).
+ if (WHITE_BOX.isMethodCompiled(method) == deopt) {
+ throw new AssertionError(method + " was" + (deopt ? " not" : "") + " deoptimized");
+ }
+ if (deopt) {
+ return;
+ }
+ // Ensure no recompilation when no deoptimization is expected.
+ NMethod nm = NMethod.get(method, false); // not OSR nmethod
+ if (nm == null) {
+ throw new AssertionError(method + " missing nmethod?");
+ }
+ if (nm.comp_level != 4) {
+ throw new AssertionError(method + " compiled by not C2: " + nm);
+ }
+ if (nm.compile_id != nmOrig.compile_id) {
+ throw new AssertionError(method + " was recompiled: old nmethod=" + nmOrig + ", new nmethod=" + nm);
+ }
+ }
+}
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java
index 77000a1d958..71e1a9762fa 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8024924
* @summary Test constant addExact
+ * @library /testlibrary
* @compile AddExactIConstantTest.java Verify.java
* @run main AddExactIConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java
index 2d96bb8b8a6..81bcc240ad5 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8024924
* @summary Test non constant addExact
+ * @library /testlibrary
* @compile AddExactILoadTest.java Verify.java
* @run main AddExactILoadTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java
index 99aae0d7b21..f0adb45018e 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8024924
* @summary Test non constant addExact
+ * @library /testlibrary
* @compile AddExactILoopDependentTest.java Verify.java
* @run main AddExactILoopDependentTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java
index b3a24758569..96c0b6014df 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8024924
* @summary Test non constant addExact
+ * @library /testlibrary
* @compile AddExactINonConstantTest.java Verify.java
* @run main AddExactINonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java
index d111b66ce82..2ba7268838d 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,15 @@
* @test
* @bug 8025657
* @summary Test repeating addExact
+ * @library /testlibrary
* @compile AddExactIRepeatTest.java Verify.java
* @run main AddExactIRepeatTest
*
*/
+import com.oracle.java.testlibrary.Utils;
+import java.util.Random;
+
public class AddExactIRepeatTest {
public static void main(String[] args) {
runTest(new Verify.AddExactI());
@@ -44,7 +48,7 @@ public class AddExactIRepeatTest {
}
public static void runTest(Verify.BinaryMethod method) {
- java.util.Random rnd = new java.util.Random();
+ Random rnd = Utils.getRandomInstance();
for (int i = 0; i < 50000; ++i) {
int x = Integer.MAX_VALUE - 10;
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java
index dc751406192..f36c925f7fd 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant addExact
+ * @library /testlibrary
* @compile AddExactLConstantTest.java Verify.java
* @run main AddExactLConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java
index efd5fd7c92b..01860ba94a7 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant addExact
+ * @library /testlibrary
* @compile AddExactLNonConstantTest.java Verify.java
* @run main AddExactLNonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java b/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java
index 7e6e1ca3bde..256aa916563 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactITest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test decrementExact
+ * @library /testlibrary
* @compile DecExactITest.java Verify.java
* @run main DecExactITest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java b/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java
index 53a16596e3c..1a9f0c86aa1 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/DecExactLTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test decrementExact
+ * @library /testlibrary
* @compile DecExactLTest.java Verify.java
* @run main DecExactLTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java b/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java
index 9f7ddbd3211..14ab592a885 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactITest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test incrementExact
+ * @library /testlibrary
* @compile IncExactITest.java Verify.java
* @run main IncExactITest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java b/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java
index 755d81908ce..5665b8080c1 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/IncExactLTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test incrementExact
+ * @library /testlibrary
* @compile IncExactLTest.java Verify.java
* @run main IncExactLTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java
index 120bef5e9b9..3d3f23ea90e 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant multiplyExact
+ * @library /testlibrary
* @compile MulExactIConstantTest.java Verify.java
* @run main MulExactIConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java
index 36aa3d46230..4551e9d4d62 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test multiplyExact
+ * @library /testlibrary
* @compile MulExactILoadTest.java Verify.java
* @run main MulExactILoadTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java
index 5ba4ad3cfc3..b324135ab53 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test loop dependent multiplyExact
+ * @library /testlibrary
* @compile MulExactILoopDependentTest.java Verify.java
* @run main MulExactILoopDependentTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java
index e108059885b..5f60c66c611 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant multiplyExact
+ * @library /testlibrary
* @compile MulExactINonConstantTest.java Verify.java
* @run main MulExactINonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java
index dd14ce21ed6..5d1784e8560 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,15 @@
* @test
* @bug 8026844
* @summary Test repeating multiplyExact
+ * @library /testlibrary
* @compile MulExactIRepeatTest.java Verify.java
* @run main MulExactIRepeatTest
*
*/
+import com.oracle.java.testlibrary.Utils;
+import java.util.Random;
+
public class MulExactIRepeatTest {
public static void main(String[] args) {
runTest(new Verify.MulExactI());
@@ -44,7 +48,7 @@ public class MulExactIRepeatTest {
}
public static void runTest(Verify.BinaryMethod method) {
- java.util.Random rnd = new java.util.Random();
+ Random rnd = Utils.getRandomInstance();
for (int i = 0; i < 50000; ++i) {
int x = Integer.MAX_VALUE - 10;
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java
index c687cc276f2..d830cf54812 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant mulExact
+ * @library /testlibrary
* @compile MulExactLConstantTest.java Verify.java
* @run main MulExactLConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java
index f9d82ed0876..c0f97a9c143 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant mulExact
+ * @library /testlibrary
* @compile MulExactLNonConstantTest.java Verify.java
* @run main MulExactLNonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java
index ba49d778762..a8e6c7c9984 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant negExact
+ * @library /testlibrary
* @compile NegExactIConstantTest.java Verify.java
* @run main NegExactIConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java
index d7e8215600a..dfa8ba21d11 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test negExact
+ * @library /testlibrary
* @compile NegExactILoadTest.java Verify.java
* @run main NegExactILoadTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java
index 882f80b91a1..17e49739e71 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test negExact loop dependent
+ * @library /testlibrary
* @compile NegExactILoopDependentTest.java Verify.java
* @run main NegExactILoopDependentTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java
index 6f044f0d969..883dc4f82b7 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant negExact
+ * @library /testlibrary
* @compile NegExactINonConstantTest.java Verify.java
* @run main NegExactINonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java
index 382cd5c5f9e..6425f81b4b2 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant negExact
+ * @library /testlibrary
* @compile NegExactLConstantTest.java Verify.java
* @run main NegExactLConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java
index 0bcad8b2b78..105b80d539e 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant negExact
+ * @library /testlibrary
* @compile NegExactLNonConstantTest.java Verify.java
* @run main NegExactLNonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java
index f539bdc7cbe..213aa02c29b 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactICondTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test subtractExact as condition
+ * @library /testlibrary
* @compile SubExactICondTest.java Verify.java
* @run main SubExactICondTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java
index b450bd90b11..094b47497ac 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test constant subtractExact
+ * @library /testlibrary
* @compile SubExactIConstantTest.java Verify.java
* @run main SubExactIConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java
index af2ed018258..976bf9babc4 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoadTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant subtractExact
+ * @library /testlibrary
* @compile SubExactILoadTest.java Verify.java
* @run main SubExactILoadTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java
index 67ebcbca321..959bbb9eb92 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant subtractExact
+ * @library /testlibrary
* @compile SubExactILoopDependentTest.java Verify.java
* @run main SubExactILoopDependentTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java
index b8153810892..74f41f38a0e 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
* @test
* @bug 8026844
* @summary Test non constant subtractExact
+ * @library /testlibrary
* @compile SubExactINonConstantTest.java Verify.java
* @run main SubExactINonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java
index 3c57f6f3f76..a7494c77583 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,14 @@
* @test
* @bug 8026844
* @summary Test repeating subtractExact
+ * @library /testlibrary
* @compile SubExactIRepeatTest.java Verify.java
* @run main SubExactIRepeatTest
*
*/
-import java.lang.ArithmeticException;
+import com.oracle.java.testlibrary.Utils;
+import java.util.Random;
public class SubExactIRepeatTest {
public static void main(String[] args) {
@@ -46,7 +48,7 @@ public class SubExactIRepeatTest {
}
public static void runTest(Verify.BinaryMethod method) {
- java.util.Random rnd = new java.util.Random();
+ Random rnd = Utils.getRandomInstance();
for (int i = 0; i < 50000; ++i) {
int x = Integer.MIN_VALUE + 10;
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java
index ec554d7662b..67427615f29 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @bug 8026844
* @bug 8027353
* @summary Test constant subtractExact
+ * @library /testlibrary
* @compile SubExactLConstantTest.java Verify.java
* @run main SubExactLConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java
index 86ecf20f366..ec68f88e061 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @bug 8026844
* @bug 8027353
* @summary Test non constant subtractExact
+ * @library /testlibrary
* @compile SubExactLNonConstantTest.java Verify.java
* @run main SubExactLNonConstantTest
*
diff --git a/hotspot/test/compiler/intrinsics/mathexact/Verify.java b/hotspot/test/compiler/intrinsics/mathexact/Verify.java
index 3936bf1b4f4..1f5871aff95 100644
--- a/hotspot/test/compiler/intrinsics/mathexact/Verify.java
+++ b/hotspot/test/compiler/intrinsics/mathexact/Verify.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -21,6 +21,13 @@
* questions.
*/
+import com.oracle.java.testlibrary.Utils;
+import java.util.Random;
+
+/**
+ * The class depends on Utils class from testlibrary package.
+ * It uses factory method that obtains random generator.
+ */
public class Verify {
public static String throwWord(boolean threw) {
return (threw ? "threw" : "didn't throw");
@@ -134,7 +141,7 @@ public class Verify {
public static class LoadTest {
- public static java.util.Random rnd = new java.util.Random();
+ public static Random rnd = Utils.getRandomInstance();
public static int[] values = new int[256];
public static void init() {
@@ -159,7 +166,7 @@ public class Verify {
}
public static class NonConstantTest {
- public static java.util.Random rnd = new java.util.Random();
+ public static Random rnd = Utils.getRandomInstance();
public static int[] values = new int[] { Integer.MAX_VALUE, Integer.MIN_VALUE };
public static void verify(BinaryMethod method) {
@@ -180,7 +187,7 @@ public class Verify {
public static class NonConstantLongTest {
public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 };
- public static java.util.Random rnd = new java.util.Random();
+ public static Random rnd = Utils.getRandomInstance();
public static void verify(BinaryLongMethod method) {
for (int i = 0; i < 50000; ++i) {
@@ -199,7 +206,7 @@ public class Verify {
}
public static class LoopDependentTest {
- public static java.util.Random rnd = new java.util.Random();
+ public static Random rnd = Utils.getRandomInstance();
public static void verify(BinaryMethod method) {
int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
diff --git a/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java
index 06e900f077d..3aa6b061204 100644
--- a/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java
+++ b/hotspot/test/compiler/jsr292/ConcurrentClassLoadingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,21 @@
* @test
* @bug 8022595
* @summary JSR292: deadlock during class loading of MethodHandles, MethodHandleImpl & MethodHandleNatives
- *
+ * @library /testlibrary
* @run main/othervm ConcurrentClassLoadingTest
*/
-import java.util.*;
+import com.oracle.java.testlibrary.Utils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ConcurrentClassLoadingTest {
int numThreads = 0;
- long seed = 0;
CyclicBarrier l;
- Random rand;
+ private static final Random rand = Utils.getRandomInstance();
public static void main(String[] args) throws Throwable {
ConcurrentClassLoadingTest test = new ConcurrentClassLoadingTest();
@@ -49,9 +52,6 @@ public class ConcurrentClassLoadingTest {
while (i < args.length) {
String flag = args[i];
switch(flag) {
- case "-seed":
- seed = Long.parseLong(args[++i]);
- break;
case "-numThreads":
numThreads = Integer.parseInt(args[++i]);
break;
@@ -67,15 +67,9 @@ public class ConcurrentClassLoadingTest {
numThreads = Runtime.getRuntime().availableProcessors();
}
- if (seed == 0) {
- seed = (new Random()).nextLong();
- }
- rand = new Random(seed);
-
l = new CyclicBarrier(numThreads + 1);
System.out.printf("Threads: %d\n", numThreads);
- System.out.printf("Seed: %d\n", seed);
}
final List<Loader> loaders = new ArrayList<>();
@@ -90,7 +84,9 @@ public class ConcurrentClassLoadingTest {
System.out.printf("Thread #%d:\n", t);
for (int i = 0; i < count; i++) {
- if (c.size() == 0) break;
+ if (c.isEmpty()) {
+ break;
+ }
int k = rand.nextInt(c.size());
String elem = c.remove(k);
diff --git a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java
index 5db43673fa8..72583df8502 100644
--- a/hotspot/test/compiler/startup/SmallCodeCacheStartup.java
+++ b/hotspot/test/compiler/startup/SmallCodeCacheStartup.java
@@ -27,10 +27,20 @@
* @summary Test ensures that there is no crash if there is not enough ReservedCodeacacheSize
* to initialize all compiler threads. The option -Xcomp gives the VM more time to
* to trigger the old bug.
- * @run main/othervm -XX:ReservedCodeCacheSize=3m -XX:CICompilerCount=64 -Xcomp SmallCodeCacheStartup
+ * @library /testlibrary
*/
+import com.oracle.java.testlibrary.*;
+
public class SmallCodeCacheStartup {
public static void main(String[] args) throws Exception {
+ try {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=3m",
+ "-XX:CICompilerCount=64",
+ "-Xcomp",
+ "SmallCodeCacheStartup");
+ pb.start();
+ } catch (VirtualMachineError e) {}
+
System.out.println("TEST PASSED");
}
}
diff --git a/hotspot/test/compiler/types/correctness/OffTest.java b/hotspot/test/compiler/types/correctness/OffTest.java
index 04be21cd2ee..374db539b80 100644
--- a/hotspot/test/compiler/types/correctness/OffTest.java
+++ b/hotspot/test/compiler/types/correctness/OffTest.java
@@ -36,9 +36,9 @@
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
-import scenarios.ProfilingType;
-
+import com.oracle.java.testlibrary.Utils;
import java.util.Random;
+import scenarios.ProfilingType;
public class OffTest {
private static final String[] OPTIONS = {
@@ -63,14 +63,7 @@ public class OffTest {
private static final int PROFILING_TYPE_INDEX = OPTIONS.length - 1;
private static final int TYPE_PROFILE_INDEX = OPTIONS.length - 4;
private static final int USE_TYPE_SPECULATION_INDEX = OPTIONS.length - 3;
- private static final Random RNG;
-
- static {
- String str = System.getProperty("seed");
- long seed = str != null ? Long.parseLong(str) : new Random().nextLong();
- RNG = new Random(seed);
- System.out.printf("-Dseed=%d%n", seed);
- }
+ private static final Random RNG = Utils.getRandomInstance();
public static void main(String[] args) throws Exception {
int count = DEFAULT_COUNT;
diff --git a/hotspot/test/compiler/unsafe/UnsafeRaw.java b/hotspot/test/compiler/unsafe/UnsafeRaw.java
index 5d172a5f4a9..f2a19ff06af 100644
--- a/hotspot/test/compiler/unsafe/UnsafeRaw.java
+++ b/hotspot/test/compiler/unsafe/UnsafeRaw.java
@@ -80,7 +80,7 @@ public class UnsafeRaw {
final int element_size = 4;
final int magic = 0x12345678;
- Random rnd = new Random();
+ Random rnd = Utils.getRandomInstance();
long array = unsafe.allocateMemory(array_size * element_size); // 128 ints
long addr = array + array_size * element_size / 2; // something in the middle to work with
diff --git a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
index f1a23314703..efacb470d89 100644
--- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
+++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java
@@ -73,8 +73,6 @@ public abstract class CompilerWhiteBoxTest {
protected static final int THRESHOLD;
/** invocation count to trigger OSR compilation */
protected static final long BACKEDGE_THRESHOLD;
- /** invocation count to warm up method before triggering OSR compilation */
- protected static final long OSR_WARMUP = 2000;
/** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
protected static final String MODE = System.getProperty("java.vm.info");
@@ -197,7 +195,6 @@ public abstract class CompilerWhiteBoxTest {
* is compiled, or if {@linkplain #method} has zero
* compilation level.
*/
-
protected final void checkNotCompiled(int compLevel) {
if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue");
@@ -218,24 +215,30 @@ public abstract class CompilerWhiteBoxTest {
* compilation level.
*/
protected final void checkNotCompiled() {
- if (WHITE_BOX.isMethodCompiled(method, false)) {
- throw new RuntimeException(method + " must be not compiled");
- }
- if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
- throw new RuntimeException(method + " comp_level must be == 0");
- }
- checkNotOsrCompiled();
+ checkNotCompiled(true);
+ checkNotCompiled(false);
}
- protected final void checkNotOsrCompiled() {
+ /**
+ * Checks, that {@linkplain #method} is not (OSR-)compiled.
+ *
+ * @param isOsr Check for OSR compilation if true
+ * @throws RuntimeException if {@linkplain #method} is in compiler queue or
+ * is compiled, or if {@linkplain #method} has zero
+ * compilation level.
+ */
+ protected final void checkNotCompiled(boolean isOsr) {
+ waitBackgroundCompilation();
if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue");
}
- if (WHITE_BOX.isMethodCompiled(method, true)) {
- throw new RuntimeException(method + " must be not osr_compiled");
+ if (WHITE_BOX.isMethodCompiled(method, isOsr)) {
+ throw new RuntimeException(method + " must not be " +
+ (isOsr ? "osr_" : "") + "compiled");
}
- if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
- throw new RuntimeException(method + " osr_comp_level must be == 0");
+ if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) {
+ throw new RuntimeException(method + (isOsr ? " osr_" : " ") +
+ "comp_level must be == 0");
}
}
@@ -498,8 +501,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
- int result = warmup(OSR_CONSTRUCTOR);
- return result + new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
+ return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
}
};
@@ -509,8 +511,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
@Override
public Integer call() throws Exception {
- int result = warmup(OSR_METHOD);
- return result + helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
+ return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
}
};
@@ -518,11 +519,54 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
- int result = warmup(OSR_STATIC);
- return result + osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
+ return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
}
};
+ private static final Constructor CONSTRUCTOR;
+ private static final Constructor OSR_CONSTRUCTOR;
+ private static final Method METHOD;
+ private static final Method STATIC;
+ private static final Method OSR_METHOD;
+ private static final Method OSR_STATIC;
+
+ static {
+ try {
+ CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper.<init>(int)", e);
+ }
+ try {
+ OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
+ Object.class, long.class);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper.<init>(Object, long)", e);
+ }
+ METHOD = getMethod("method");
+ STATIC = getMethod("staticMethod");
+ OSR_METHOD = getMethod("osrMethod", long.class);
+ OSR_STATIC = getMethod("osrStaticMethod", long.class);
+ }
+
+ private static Method getMethod(String name, Class<?>... parameterTypes) {
+ try {
+ return Helper.class.getDeclaredMethod(name, parameterTypes);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new RuntimeException(
+ "exception on getting method Helper." + name, e);
+ }
+ }
+
+ private static int staticMethod() {
+ return 1138;
+ }
+
+ private int method() {
+ return 42;
+ }
+
/**
* Deoptimizes all non-osr versions of the given executable after
* compilation finished.
@@ -530,7 +574,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
* @param e Executable
* @throws Exception
*/
- private static void waitAndDeoptimize(Executable e) throws Exception {
+ private static void waitAndDeoptimize(Executable e) {
CompilerWhiteBoxTest.waitBackgroundCompilation(e);
if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
throw new RuntimeException(e + " must not be in queue");
@@ -549,13 +593,15 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
* @throws Exception
*/
private static int warmup(Method m) throws Exception {
+ waitAndDeoptimize(m);
Helper helper = new Helper();
int result = 0;
- for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) {
+ for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
result += (int)m.invoke(helper, 1);
}
- // Deoptimize non-osr versions
- waitAndDeoptimize(m);
+ // Wait to make sure OSR compilation is not blocked by
+ // non-OSR compilation in the compile queue
+ CompilerWhiteBoxTest.waitBackgroundCompilation(m);
return result;
}
@@ -569,69 +615,35 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
* @throws Exception
*/
private static int warmup(Constructor c) throws Exception {
+ waitAndDeoptimize(c);
int result = 0;
- for (long i = 0; i < CompilerWhiteBoxTest.OSR_WARMUP; ++i) {
+ for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
result += c.newInstance(null, 1).hashCode();
}
- // Deoptimize non-osr versions
- waitAndDeoptimize(c);
+ // Wait to make sure OSR compilation is not blocked by
+ // non-OSR compilation in the compile queue
+ CompilerWhiteBoxTest.waitBackgroundCompilation(c);
return result;
}
- private static final Constructor CONSTRUCTOR;
- private static final Constructor OSR_CONSTRUCTOR;
- private static final Method METHOD;
- private static final Method STATIC;
- private static final Method OSR_METHOD;
- private static final Method OSR_STATIC;
-
- static {
- try {
- CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new RuntimeException(
- "exception on getting method Helper.<init>(int)", e);
- }
- try {
- OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
- Object.class, long.class);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new RuntimeException(
- "exception on getting method Helper.<init>(Object, long)", e);
- }
- METHOD = getMethod("method");
- STATIC = getMethod("staticMethod");
- OSR_METHOD = getMethod("osrMethod", long.class);
- OSR_STATIC = getMethod("osrStaticMethod", long.class);
- }
-
- private static Method getMethod(String name, Class<?>... parameterTypes) {
- try {
- return Helper.class.getDeclaredMethod(name, parameterTypes);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new RuntimeException(
- "exception on getting method Helper." + name, e);
- }
- }
-
- private static int staticMethod() {
- return 1138;
- }
-
- private int method() {
- return 42;
- }
-
- private static int osrStaticMethod(long limit) {
+ private static int osrStaticMethod(long limit) throws Exception {
int result = 0;
+ if (limit != 1) {
+ result = warmup(OSR_STATIC);
+ }
+ // Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += staticMethod();
}
return result;
}
- private int osrMethod(long limit) {
+ private int osrMethod(long limit) throws Exception {
int result = 0;
+ if (limit != 1) {
+ result = warmup(OSR_METHOD);
+ }
+ // Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += method();
}
@@ -646,8 +658,12 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
}
// for OSR constructor test case
- private Helper(Object o, long limit) {
+ private Helper(Object o, long limit) throws Exception {
int result = 0;
+ if (limit != 1) {
+ result = warmup(OSR_CONSTRUCTOR);
+ }
+ // Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += method();
}
diff --git a/hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java b/hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java
new file mode 100644
index 00000000000..f81d199a8d0
--- /dev/null
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, 2014, 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 sun.hotspot.WhiteBox;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+
+/*
+ * @test DeoptimizeMultipleOSRTest
+ * @bug 8061817
+ * @library /testlibrary /testlibrary/whitebox
+ * @build DeoptimizeMultipleOSRTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,DeoptimizeMultipleOSRTest::triggerOSR DeoptimizeMultipleOSRTest
+ * @summary testing of WB::deoptimizeMethod()
+ */
+public class DeoptimizeMultipleOSRTest {
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+ private static final long BACKEDGE_THRESHOLD = 150000;
+ private Method method;
+ private int counter = 0;
+
+ public static void main(String[] args) throws Exception {
+ DeoptimizeMultipleOSRTest test = new DeoptimizeMultipleOSRTest();
+ test.test();
+ }
+
+ /**
+ * Triggers two different OSR compilations for the same method and
+ * checks if WhiteBox.deoptimizeMethod() deoptimizes both.
+ *
+ * @throws Exception
+ */
+ public void test() throws Exception {
+ method = DeoptimizeMultipleOSRTest.class.getDeclaredMethod("triggerOSR", boolean.class, long.class);
+ // Trigger two OSR compiled versions
+ triggerOSR(true, BACKEDGE_THRESHOLD);
+ triggerOSR(false, BACKEDGE_THRESHOLD);
+ // Wait for compilation
+ CompilerWhiteBoxTest.waitBackgroundCompilation(method);
+ // Deoptimize
+ WHITE_BOX.deoptimizeMethod(method, true);
+ if (WHITE_BOX.isMethodCompiled(method, true)) {
+ throw new AssertionError("Not all OSR compiled versions were deoptimized");
+ }
+ }
+
+ /**
+ * Triggers OSR compilations by executing loops.
+ *
+ * @param first Determines which loop to execute
+ * @param limit The number of loop iterations
+ */
+ public void triggerOSR(boolean first, long limit) {
+ if (limit != 1) {
+ // Warmup method to avoid uncommon traps
+ for (int i = 0; i < limit; ++i) {
+ triggerOSR(first, 1);
+ }
+ CompilerWhiteBoxTest.waitBackgroundCompilation(method);
+ }
+ if (first) {
+ // Trigger OSR compilation 1
+ for (int i = 0; i < limit; ++i) {
+ counter++;
+ }
+ } else {
+ // Trigger OSR compilation 2
+ for (int i = 0; i < limit; ++i) {
+ counter++;
+ }
+ }
+ }
+}
diff --git a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java
index e93702bf7f9..6a79d8a5dba 100644
--- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java
@@ -132,14 +132,15 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
-
+ // Make method not (OSR-)compilable (depending on testCase.isOsr())
makeNotCompilable();
if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable");
}
-
+ // Try to (OSR-)compile method
compile();
- checkNotOsrCompiled();
+ // Method should not be (OSR-)compiled
+ checkNotCompiled(testCase.isOsr());
if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable");
}
diff --git a/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java
new file mode 100644
index 00000000000..edc6f9faf2f
--- /dev/null
+++ b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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 TestUseNUMAInterleaving
+ * @summary Tests that UseNUMAInterleaving enabled for all collectors by
+ * ergonomics, on all platforms when UseNUMA feature is enabled.
+ * @bug 8059614
+ * @key gc
+ * @library /testlibrary
+ * @run driver TestUseNUMAInterleaving
+ */
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestUseNUMAInterleaving {
+
+ public static void main(String[] args) throws Exception {
+ String[] vmargs = new String[]{
+ "-XX:+UseNUMA",
+ "-XX:+PrintFlagsFinal",
+ "-version"
+ };
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, vmargs);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ boolean isNUMAEnabled
+ = Boolean.parseBoolean(output.firstMatch(NUMA_FLAG_PATTERN, 1));
+
+ if (isNUMAEnabled) {
+ output.shouldMatch("\\bUseNUMAInterleaving\\b.*?=.*?true");
+ System.out.println(output.getStdout());
+ } else {
+ System.out.println(output.firstMatch(NUMA_FLAG_PATTERN));
+ System.out.println(output.firstMatch(NUMA_FLAG_PATTERN, 1));
+ }
+ }
+
+ private static final String NUMA_FLAG_PATTERN = "\\bUseNUMA\\b.*?=.*?([a-z]+)";
+}
diff --git a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java
index 122597aea64..d234cf81dfb 100644
--- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java
+++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java
@@ -135,7 +135,6 @@ public class TestHumongousCodeCacheRoots {
"-XX:+UnlockDiagnosticVMOptions",
"-XX:InitiatingHeapOccupancyPercent=1", // strong code root marking
"-XX:+G1VerifyHeapRegionCodeRoots", "-XX:+VerifyAfterGC", // make sure that verification is run
- "-XX:NmethodSweepFraction=1", "-XX:NmethodSweepCheckInterval=1", // make the code cache sweep more predictable
};
runTest("-client", baseArguments);
runTest("-server", baseArguments);
diff --git a/hotspot/test/runtime/7194254/Test7194254.java b/hotspot/test/runtime/7194254/Test7194254.java
index 356077b3bd7..08f55e55b22 100644
--- a/hotspot/test/runtime/7194254/Test7194254.java
+++ b/hotspot/test/runtime/7194254/Test7194254.java
@@ -27,6 +27,7 @@
* @summary Creates several threads with different java priorities and checks
* whether jstack reports correct priorities for them.
*
+ * @ignore 8060219
* @run main Test7194254
*/
diff --git a/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java b/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java
index 4868731526a..0e3109b52bb 100644
--- a/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java
+++ b/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java
@@ -24,41 +24,56 @@
/*
* @test
* @summary Test corner case that overflows malloc site hashtable bucket
+ * @requires sun.arch.data.model == "32"
* @key nmt jcmd stress
* @library /testlibrary /testlibrary/whitebox
- * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
+ * @ignore 8062870
* @build MallocSiteHashOverflow
* @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm/timeout=480 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
*/
import com.oracle.java.testlibrary.*;
import sun.hotspot.WhiteBox;
public class MallocSiteHashOverflow {
- private static long K = 1024;
+
public static void main(String args[]) throws Exception {
- String vm_name = System.getProperty("java.vm.name");
+ // Size of entries based on malloc tracking header defined in mallocTracker.hpp
// For 32-bit systems, create 257 malloc sites with the same hash bucket to overflow a hash bucket
- // For 64-bit systems, create 64K + 1 malloc sites with the same hash bucket to overflow a hash bucket
long entries = 257;
- if (Platform.is64bit()) {
- entries = 64 * K + 1;
- }
OutputAnalyzer output;
WhiteBox wb = WhiteBox.getWhiteBox();
+ int MAX_HASH_SIZE = wb.NMTGetHashSize();
// Grab my own PID
String pid = Integer.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
- wb.NMTOverflowHashBucket(entries);
-
- // Run 'jcmd <pid> VM.native_memory summary'
+ // Verify that current tracking level is "detail"
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
output = new OutputAnalyzer(pb.start());
- output.shouldContain("Tracking level has been downgraded due to lack of resources");
+ output.shouldContain("Native Memory Tracking Statistics");
+
+ // Attempt to cause NMT to downgrade tracking level by allocating small amounts
+ // of memory with random pseudo call stack
+ int pc = 1;
+ for (int i = 0; i < entries; i++) {
+ long addr = wb.NMTMallocWithPseudoStack(1, pc);
+ if (addr == 0) {
+ throw new RuntimeException("NMTMallocWithPseudoStack: out of memory");
+ }
+ // We free memory here since it doesn't affect pseudo malloc alloc site hash table entries
+ wb.NMTFree(addr);
+ pc += MAX_HASH_SIZE;
+ if (i == entries) {
+ // Verify that tracking has been downgraded
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Tracking level has been downgraded due to lack of resources");
+ }
+ }
}
}
diff --git a/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java b/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java
new file mode 100644
index 00000000000..eb74b68426e
--- /dev/null
+++ b/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary
+ * @summary Test that type annotations are retained after a retransform
+ * @run main RedefineAnnotations buildagent
+ * @run main/othervm -javaagent:redefineagent.jar RedefineAnnotations
+ */
+
+import static com.oracle.java.testlibrary.Asserts.assertTrue;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.lang.NoSuchFieldException;
+import java.lang.NoSuchMethodException;
+import java.lang.RuntimeException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import java.lang.reflect.AnnotatedArrayType;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.AnnotatedWildcardType;
+import java.lang.reflect.Executable;
+import java.lang.reflect.TypeVariable;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASM5;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE_USE)
+@interface TestAnn {
+ String site();
+}
+
+public class RedefineAnnotations {
+ static Instrumentation inst;
+ public static void premain(String agentArgs, Instrumentation inst) {
+ RedefineAnnotations.inst = inst;
+ }
+
+ static class Transformer implements ClassFileTransformer {
+
+ public byte[] asm(ClassLoader loader, String className,
+ Class<?> classBeingRedefined,
+ ProtectionDomain protectionDomain, byte[] classfileBuffer)
+ throws IllegalClassFormatException {
+
+ ClassWriter cw = new ClassWriter(0);
+ ClassVisitor cv = new ReAddDummyFieldsClassVisitor(ASM5, cw) { };
+ ClassReader cr = new ClassReader(classfileBuffer);
+ cr.accept(cv, 0);
+ return cw.toByteArray();
+ }
+
+ public class ReAddDummyFieldsClassVisitor extends ClassVisitor {
+
+ LinkedList<F> fields = new LinkedList<>();
+
+ public ReAddDummyFieldsClassVisitor(int api, ClassVisitor cv) {
+ super(api, cv);
+ }
+
+ @Override public FieldVisitor visitField(int access, String name,
+ String desc, String signature, Object value) {
+ if (name.startsWith("dummy")) {
+ // Remove dummy field
+ fields.addLast(new F(access, name, desc, signature, value));
+ return null;
+ }
+ return cv.visitField(access, name, desc, signature, value);
+ }
+
+ @Override public void visitEnd() {
+ F f;
+ while ((f = fields.pollFirst()) != null) {
+ // Re-add dummy fields
+ cv.visitField(f.access, f.name, f.desc, f.signature, f.value);
+ }
+ }
+
+ private class F {
+ private int access;
+ private String name;
+ private String desc;
+ private String signature;
+ private Object value;
+ F(int access, String name, String desc, String signature, Object value) {
+ this.access = access;
+ this.name = name;
+ this.desc = desc;
+ this.signature = signature;
+ this.value = value;
+ }
+ }
+ }
+
+ @Override public byte[] transform(ClassLoader loader, String className,
+ Class<?> classBeingRedefined,
+ ProtectionDomain protectionDomain, byte[] classfileBuffer)
+ throws IllegalClassFormatException {
+
+ if (className.contains("TypeAnnotatedTestClass")) {
+ try {
+ // Here we remove and re-add the dummy fields. This shuffles the constant pool
+ return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
+ } catch (Throwable e) {
+ // The retransform native code that called this method does not propagate
+ // exceptions. Instead of getting an uninformative generic error, catch
+ // problems here and print it, then exit.
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ return null;
+ }
+ }
+
+ private static void buildAgent() {
+ try {
+ ClassFileInstaller.main("RedefineAnnotations");
+ } catch (Exception e) {
+ throw new RuntimeException("Could not write agent classfile", e);
+ }
+
+ try {
+ PrintWriter pw = new PrintWriter("MANIFEST.MF");
+ pw.println("Premain-Class: RedefineAnnotations");
+ pw.println("Agent-Class: RedefineAnnotations");
+ pw.println("Can-Retransform-Classes: true");
+ pw.close();
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException("Could not write manifest file for the agent", e);
+ }
+
+ sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
+ if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineAnnotations.class" })) {
+ throw new RuntimeException("Could not write the agent jar file");
+ }
+ }
+
+ public static void main(String argv[]) throws NoSuchFieldException, NoSuchMethodException {
+ if (argv.length == 1 && argv[0].equals("buildagent")) {
+ buildAgent();
+ return;
+ }
+
+ if (inst == null) {
+ throw new RuntimeException("Instrumentation object was null");
+ }
+
+ RedefineAnnotations test = new RedefineAnnotations();
+ test.testTransformAndVerify();
+ }
+
+ // Class type annotations
+ private Annotation classTypeParameterTA;
+ private Annotation extendsTA;
+ private Annotation implementsTA;
+
+ // Field type annotations
+ private Annotation fieldTA;
+ private Annotation innerTA;
+ private Annotation[] arrayTA = new Annotation[4];
+ private Annotation[] mapTA = new Annotation[5];
+
+ // Method type annotations
+ private Annotation returnTA, methodTypeParameterTA, formalParameterTA, throwsTA;
+
+ private void testTransformAndVerify()
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ Class<TypeAnnotatedTestClass> c = TypeAnnotatedTestClass.class;
+ Class<?> myClass = c;
+
+ /*
+ * Verify that the expected annotations are where they should be before transform.
+ */
+ verifyClassTypeAnnotations(c);
+ verifyFieldTypeAnnotations(c);
+ verifyMethodTypeAnnotations(c);
+
+ try {
+ inst.addTransformer(new Transformer(), true);
+ inst.retransformClasses(myClass);
+ } catch (UnmodifiableClassException e) {
+ throw new RuntimeException(e);
+ }
+
+ /*
+ * Verify that the expected annotations are where they should be after transform.
+ * Also verify that before and after are equal.
+ */
+ verifyClassTypeAnnotations(c);
+ verifyFieldTypeAnnotations(c);
+ verifyMethodTypeAnnotations(c);
+ }
+
+ private void verifyClassTypeAnnotations(Class c) {
+ Annotation anno;
+
+ anno = c.getTypeParameters()[0].getAnnotations()[0];
+ verifyTestAnn(classTypeParameterTA, anno, "classTypeParameter");
+ classTypeParameterTA = anno;
+
+ anno = c.getAnnotatedSuperclass().getAnnotations()[0];
+ verifyTestAnn(extendsTA, anno, "extends");
+ extendsTA = anno;
+
+ anno = c.getAnnotatedInterfaces()[0].getAnnotations()[0];
+ verifyTestAnn(implementsTA, anno, "implements");
+ implementsTA = anno;
+ }
+
+ private void verifyFieldTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ verifyBasicFieldTypeAnnotations(c);
+ verifyInnerFieldTypeAnnotations(c);
+ verifyArrayFieldTypeAnnotations(c);
+ verifyMapFieldTypeAnnotations(c);
+ }
+
+ private void verifyBasicFieldTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ Annotation anno = c.getDeclaredField("typeAnnotatedBoolean").getAnnotatedType().getAnnotations()[0];
+ verifyTestAnn(fieldTA, anno, "field");
+ fieldTA = anno;
+ }
+
+ private void verifyInnerFieldTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ AnnotatedType at = c.getDeclaredField("typeAnnotatedInner").getAnnotatedType();
+ Annotation anno = at.getAnnotations()[0];
+ verifyTestAnn(innerTA, anno, "inner");
+ innerTA = anno;
+ }
+
+ private void verifyArrayFieldTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ Annotation anno;
+ AnnotatedType at;
+
+ at = c.getDeclaredField("typeAnnotatedArray").getAnnotatedType();
+ anno = at.getAnnotations()[0];
+ verifyTestAnn(arrayTA[0], anno, "array1");
+ arrayTA[0] = anno;
+
+ for (int i = 1; i <= 3; i++) {
+ at = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType();
+ anno = at.getAnnotations()[0];
+ verifyTestAnn(arrayTA[i], anno, "array" + (i + 1));
+ arrayTA[i] = anno;
+ }
+ }
+
+ private void verifyMapFieldTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+
+ Annotation anno;
+ AnnotatedType atBase;
+ AnnotatedType atParameter;
+ atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType();
+
+ anno = atBase.getAnnotations()[0];
+ verifyTestAnn(mapTA[0], anno, "map1");
+ mapTA[0] = anno;
+
+ atParameter =
+ ((AnnotatedParameterizedType) atBase).
+ getAnnotatedActualTypeArguments()[0];
+ anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0];
+ verifyTestAnn(mapTA[1], anno, "map2");
+ mapTA[1] = anno;
+
+ anno =
+ ((AnnotatedWildcardType) atParameter).
+ getAnnotatedUpperBounds()[0].getAnnotations()[0];
+ verifyTestAnn(mapTA[2], anno, "map3");
+ mapTA[2] = anno;
+
+ atParameter =
+ ((AnnotatedParameterizedType) atBase).
+ getAnnotatedActualTypeArguments()[1];
+ anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0];
+ verifyTestAnn(mapTA[3], anno, "map4");
+ mapTA[3] = anno;
+
+ anno =
+ ((AnnotatedParameterizedType) atParameter).
+ getAnnotatedActualTypeArguments()[0].getAnnotations()[0];
+ verifyTestAnn(mapTA[4], anno, "map5");
+ mapTA[4] = anno;
+ }
+
+ private void verifyMethodTypeAnnotations(Class c)
+ throws NoSuchFieldException, NoSuchMethodException {
+ Annotation anno;
+ Executable typeAnnotatedMethod =
+ c.getDeclaredMethod("typeAnnotatedMethod", TypeAnnotatedTestClass.class);
+
+ anno = typeAnnotatedMethod.getAnnotatedReturnType().getAnnotations()[0];
+ verifyTestAnn(returnTA, anno, "return");
+ returnTA = anno;
+
+ anno = typeAnnotatedMethod.getTypeParameters()[0].getAnnotations()[0];
+ verifyTestAnn(methodTypeParameterTA, anno, "methodTypeParameter");
+ methodTypeParameterTA = anno;
+
+ anno = typeAnnotatedMethod.getAnnotatedParameterTypes()[0].getAnnotations()[0];
+ verifyTestAnn(formalParameterTA, anno, "formalParameter");
+ formalParameterTA = anno;
+
+ anno = typeAnnotatedMethod.getAnnotatedExceptionTypes()[0].getAnnotations()[0];
+ verifyTestAnn(throwsTA, anno, "throws");
+ throwsTA = anno;
+ }
+
+ private static void verifyTestAnn(Annotation verifyAgainst, Annotation anno, String expectedSite) {
+ verifyTestAnnSite(anno, expectedSite);
+
+ // When called before transform verifyAgainst will be null, when called
+ // after transform it will be the annotation from before the transform
+ if (verifyAgainst != null) {
+ assertTrue(anno.equals(verifyAgainst),
+ "Annotations do not match before and after." +
+ " Before: \"" + verifyAgainst + "\", After: \"" + anno + "\"");
+ }
+ }
+
+ private static void verifyTestAnnSite(Annotation testAnn, String expectedSite) {
+ String expectedAnn = "@TestAnn(site=" + expectedSite + ")";
+ assertTrue(testAnn.toString().equals(expectedAnn),
+ "Expected \"" + expectedAnn + "\", got \"" + testAnn + "\"");
+ }
+
+ public static class TypeAnnotatedTestClass <@TestAnn(site="classTypeParameter") S,T>
+ extends @TestAnn(site="extends") Thread
+ implements @TestAnn(site="implements") Runnable {
+
+ public @TestAnn(site="field") boolean typeAnnotatedBoolean;
+
+ public
+ RedefineAnnotations.
+ @TestAnn(site="inner") TypeAnnotatedTestClass
+ typeAnnotatedInner;
+
+ public
+ @TestAnn(site="array4") boolean
+ @TestAnn(site="array1") []
+ @TestAnn(site="array2") []
+ @TestAnn(site="array3") []
+ typeAnnotatedArray;
+
+ public @TestAnn(site="map1") Map
+ <@TestAnn(site="map2") ? extends @TestAnn(site="map3") String,
+ @TestAnn(site="map4") List<@TestAnn(site="map5") Object>> typeAnnotatedMap;
+
+ public int dummy1;
+ public int dummy2;
+ public int dummy3;
+
+ @TestAnn(site="return") <@TestAnn(site="methodTypeParameter") U,V> Class
+ typeAnnotatedMethod(@TestAnn(site="formalParameter") TypeAnnotatedTestClass arg)
+ throws @TestAnn(site="throws") ClassNotFoundException {
+
+ @TestAnn(site="local_variable_type") int foo = 0;
+ throw new ClassNotFoundException();
+ }
+
+ public void run() {}
+ }
+}
diff --git a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java
index 6989a643f59..b2505be0d7d 100644
--- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java
+++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java
@@ -51,9 +51,12 @@ public class LimitSharedSizes {
// Known issue, JDK-8038422 (assert() on Windows)
// new SharedSizeTestData("-XX:SharedMiscDataSize", "500k", "miscellaneous data"),
- // This will cause a VM crash; commenting out for now; see bug JDK-8038268
- // @ignore JDK-8038268
- // new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"),
+ // Too small of a misc code size should not cause a vm crash.
+ // It should result in the following error message:
+ // The shared miscellaneous code space is not large enough
+ // to preload requested classes. Use -XX:SharedMiscCodeSize=
+ // to increase the initial size of shared miscellaneous code space.
+ new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"),
// these values are larger than default ones, but should
// be acceptable and not cause failure
diff --git a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java
index c33dd56ef64..3b32dd7e552 100644
--- a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java
+++ b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java
@@ -33,11 +33,12 @@
import java.util.function.*;
import java.util.*;
+public class InvokespecialInterface {
interface I {
default void imethod() { System.out.println("I::imethod"); }
}
-class C implements I {
+static class C implements I {
public void foo() { I.super.imethod(); } // invokespecial InterfaceMethod
public void bar() { I i = this; i.imethod(); } // invokeinterface same
public void doSomeInvokedynamic() {
@@ -48,7 +49,6 @@ class C implements I {
}
}
-public class InvokespecialInterface {
public static void main(java.lang.String[] unused) {
// need to create C and call I::foo()
C c = new C();
diff --git a/hotspot/test/runtime/lambda-features/TestInterfaceInit.java b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java
new file mode 100644
index 00000000000..0493a60bb1e
--- /dev/null
+++ b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, 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 8034275
+ * @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods
+ * @run main TestInterfaceInit
+ */
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+
+public class TestInterfaceInit {
+
+ static List<Class<?>> cInitOrder = new ArrayList<>();
+
+ // Declares a default method and initializes
+ interface I {
+ boolean v = TestInterfaceInit.out(I.class);
+ default void x() {}
+ }
+
+ // Declares a default method and initializes
+ interface J extends I {
+ boolean v = TestInterfaceInit.out(J.class);
+ default void x() {}
+ }
+ // No default method, does not initialize
+ interface JN extends J {
+ boolean v = TestInterfaceInit.out(JN.class);
+ }
+
+ // Declares a default method and initializes
+ interface K extends I {
+ boolean v = TestInterfaceInit.out(K.class);
+ default void x() {}
+ }
+
+ // No default method, does not initialize
+ interface KN extends K {
+ boolean v = TestInterfaceInit.out(KN.class);
+ }
+
+ interface L extends JN, KN {
+ boolean v = TestInterfaceInit.out(L.class);
+ default void x() {}
+ }
+
+ public static void main(String[] args) {
+ // Trigger initialization
+ boolean v = L.v;
+
+ List<Class<?>> expectedCInitOrder = Arrays.asList(I.class,J.class,K.class,L.class);
+ if (!cInitOrder.equals(expectedCInitOrder)) {
+ throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder));
+ }
+ }
+
+ static boolean out(Class c) {
+ System.out.println("#: initializing " + c.getName());
+ cInitOrder.add(c);
+ return true;
+ }
+
+}
diff --git a/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java b/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java
new file mode 100644
index 00000000000..245742ece14
--- /dev/null
+++ b/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, 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 8034275
+ * @summary [JDK 8u40] Test interface initialization order
+ * @run main TestInterfaceOrder
+ */
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+
+public class TestInterfaceOrder {
+ static List<Class<?>> cInitOrder = new ArrayList<>();
+
+ public static void main(java.lang.String[] args) {
+ //Trigger initialization
+ C c = new C();
+
+ List<Class<?>> expectedCInitOrder = Arrays.asList(I.class, J.class, A.class, K.class, B.class, L.class, C.class);
+ if (!cInitOrder.equals(expectedCInitOrder)) {
+ throw new RuntimeException(String.format("Class initialization order %s not equal to expected order %s", cInitOrder, expectedCInitOrder));
+ }
+ }
+
+ interface I {
+ boolean v = TestInterfaceOrder.out(I.class);
+ default void i() {}
+ }
+
+ interface J extends I {
+ boolean v = TestInterfaceOrder.out(J.class);
+ default void j() {}
+ }
+
+ static class A implements J {
+ static boolean v = TestInterfaceOrder.out(A.class);
+ }
+
+ interface K extends I {
+ boolean v = TestInterfaceOrder.out(K.class);
+ default void k() {}
+ }
+
+ static class B extends A implements K {
+ static boolean v = TestInterfaceOrder.out(B.class);
+ }
+
+ interface L {
+ boolean v = TestInterfaceOrder.out(L.class);
+ default void l() {}
+ }
+
+ static class C extends B implements L {
+ static boolean v = TestInterfaceOrder.out(C.class);
+ }
+
+
+ static boolean out(Class c) {
+ System.out.println("#: initializing " + c.getName());
+ cInitOrder.add(c);
+ return true;
+ }
+
+}
diff --git a/hotspot/test/runtime/reflect/ArrayGetIntException.java b/hotspot/test/runtime/reflect/ArrayGetIntException.java
new file mode 100644
index 00000000000..e5ee5cb93dc
--- /dev/null
+++ b/hotspot/test/runtime/reflect/ArrayGetIntException.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014, 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 6191224
+ * @summary (reflect) Misleading detail string in IllegalArgumentException thrown by Array.get<Type>
+ * @run main ArrayGetIntException
+ */
+import java.io.*;
+import java.lang.reflect.Array;
+
+public class ArrayGetIntException {
+ public static void main(String[] args) throws Exception {
+ Object[] objArray = {new Integer(Integer.MAX_VALUE)};
+
+ // this access is legal
+ try {
+ System.out.println(Array.get(objArray, 0));
+ System.out.println("Test #1 PASSES");
+ } catch(Exception e) {
+ failTest("Test #1 FAILS - legal access denied" + e.getMessage());
+ }
+
+ // this access is not legal, but needs to generate the proper exception message
+ try {
+ System.out.println(Array.getInt(objArray, 0));
+ failTest("Test #2 FAILS - no exception");
+ } catch(Exception e) {
+ System.out.println(e);
+ if (e.getMessage().equals("Argument is not an array of primitive type")) {
+ System.out.println("Test #2 PASSES");
+ } else {
+ failTest("Test #2 FAILS - incorrect message: " + e.getMessage());
+ }
+ }
+
+ // this access is not legal, but needs to generate the proper exception message
+ try {
+ System.out.println(Array.getInt(new Object(), 0));
+ failTest("Test #3 FAILS - no exception");
+ } catch(Exception e) {
+ System.out.println(e);
+ if (e.getMessage().equals("Argument is not an array")) {
+ System.out.println("Test #3 PASSES");
+ } else {
+ failTest("Test #3 FAILS - incorrect message: " + e.getMessage());
+ }
+ }
+ }
+
+ private static void failTest(String errStr) {
+ System.out.println(errStr);
+ throw new Error(errStr);
+ }
+}
diff --git a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java
index b2923dfb69a..1a96dd8c200 100644
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java
@@ -27,6 +27,7 @@
* @library ..
* @build DcmdUtil CompilerQueueTest
* @run main CompilerQueueTest
+ * @run main/othervm -XX:-TieredCompilation CompilerQueueTest
* @run main/othervm -Xint CompilerQueueTest
* @summary Test of diagnostic command Compiler.queue
*/
@@ -87,7 +88,9 @@ public class CompilerQueueTest {
}
private static void validateMethodLine(String str) throws Exception {
- String name = str.substring(19);
+ // Skip until package/class name begins. Trim to remove whitespace that
+ // may differ.
+ String name = str.substring(14).trim();
int sep = name.indexOf("::");
if (sep == -1) {
throw new Exception("Failed dcmd queue, didn't find separator :: in: " + name);
diff --git a/hotspot/test/serviceability/threads/TestFalseDeadLock.java b/hotspot/test/serviceability/threads/TestFalseDeadLock.java
index 7ee0fe1116f..c2797c232b3 100644
--- a/hotspot/test/serviceability/threads/TestFalseDeadLock.java
+++ b/hotspot/test/serviceability/threads/TestFalseDeadLock.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -21,14 +21,17 @@
* questions.
*/
+import com.oracle.java.testlibrary.Utils;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.Random;
/*
* @test
+ * @ignore 8061157
* @bug 8016304
* @summary Make sure no deadlock is reported for this program which has no deadlocks.
+ * @library /testlibrary
* @run main/othervm TestFalseDeadLock
*/
@@ -65,7 +68,7 @@ public class TestFalseDeadLock {
public static class Test implements Runnable {
public void run() {
- Random r = new Random();
+ Random r = Utils.getRandomInstance();
while (running) {
try {
synchronized (this) {
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
index ba4bea5e937..8ad6155eeb9 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java
@@ -24,21 +24,21 @@
package com.oracle.java.testlibrary;
import static com.oracle.java.testlibrary.Asserts.assertTrue;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.ArrayList;
-import java.util.List;
import java.util.Arrays;
import java.util.Collections;
-import java.util.regex.Pattern;
+import java.util.List;
+import java.util.Random;
import java.util.regex.Matcher;
-import java.lang.reflect.Field;
+import java.util.regex.Pattern;
import sun.misc.Unsafe;
/**
@@ -64,6 +64,21 @@ public final class Utils {
private static Unsafe unsafe = null;
/**
+ * Defines property name for seed value.
+ */
+ public static final String SEED_PROPERTY_NAME = "com.oracle.java.testlibrary.random.seed";
+
+ /* (non-javadoc)
+ * Random generator with (or without) predefined seed. Depends on
+ * "com.oracle.java.testlibrary.random.seed" property value.
+ */
+ private static volatile Random RANDOM_GENERATOR;
+
+ /**
+ * Contains the seed value used for {@link java.util.Random} creation.
+ */
+ public static final long SEED = Long.getLong(SEED_PROPERTY_NAME, new Random().nextLong());
+ /**
* Returns the value of 'test.timeout.factor' system property
* converted to {@code double}.
*/
@@ -332,4 +347,24 @@ public final class Utils {
}
return new String(hexView);
}
+
+ /**
+ * Returns {@link java.util.Random} generator initialized with particular seed.
+ * The seed could be provided via system property {@link Utils#SEED_PROPERTY_NAME}
+ * In case no seed is provided, the method uses a random number.
+ * The used seed printed to stdout.
+ * @return {@link java.util.Random} generator with particular seed.
+ */
+ public static Random getRandomInstance() {
+ if (RANDOM_GENERATOR == null) {
+ synchronized (Utils.class) {
+ if (RANDOM_GENERATOR == null) {
+ RANDOM_GENERATOR = new Random(SEED);
+ System.out.printf("For random generator using seed: %d%n", SEED);
+ System.out.printf("To re-run test with same seed value please add \"-D%s=%d\" to command line.%n", SEED_PROPERTY_NAME, SEED);
+ }
+ }
+ }
+ return RANDOM_GENERATOR;
+ }
}
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
index 228d1ddb319..a5a07947954 100644
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
@@ -98,10 +98,10 @@ public class WhiteBox {
public native void NMTCommitMemory(long addr, long size);
public native void NMTUncommitMemory(long addr, long size);
public native void NMTReleaseMemory(long addr, long size);
- public native void NMTOverflowHashBucket(long num);
public native long NMTMallocWithPseudoStack(long size, int index);
public native boolean NMTIsDetailSupported();
public native boolean NMTChangeTrackingLevel();
+ public native int NMTGetHashSize();
// Compiler
public native void deoptimizeAll();
@@ -179,6 +179,8 @@ public class WhiteBox {
public native void printRegionInfo(int context);
// VM flags
+ public native boolean isConstantVMFlag(String name);
+ public native boolean isLockedVMFlag(String name);
public native void setBooleanVMFlag(String name, boolean value);
public native void setIntxVMFlag(String name, long value);
public native void setUintxVMFlag(String name, long value);
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java
index 4bdb49d0b3e..9ac182df343 100644
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java
@@ -34,18 +34,21 @@ public class NMethod {
return obj == null ? null : new NMethod(obj);
}
private NMethod(Object[] obj) {
- assert obj.length == 2;
+ assert obj.length == 3;
comp_level = (Integer) obj[0];
insts = (byte[]) obj[1];
+ compile_id = (Integer) obj[2];
}
public byte[] insts;
public int comp_level;
+ public int compile_id;
@Override
public String toString() {
return "NMethod{" +
"insts=" + insts +
", comp_level=" + comp_level +
+ ", compile_id=" + compile_id +
'}';
}
}
diff --git a/hotspot/test/testlibrary_tests/RandomGeneratorTest.java b/hotspot/test/testlibrary_tests/RandomGeneratorTest.java
new file mode 100644
index 00000000000..ff00999e9b9
--- /dev/null
+++ b/hotspot/test/testlibrary_tests/RandomGeneratorTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014, 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
+ * @summary Verify correctnes of the random generator from Utility.java
+ * @library /testlibrary
+ * @run driver RandomGeneratorTest SAME_SEED
+ * @run driver RandomGeneratorTest NO_SEED
+ * @run driver RandomGeneratorTest DIFFERENT_SEED
+ */
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Utils;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * The test verifies correctness of work {@link com.oracle.java.testlibrary.Utils#getRandomInstance()}.
+ * Test works in three modes: same seed provided, no seed provided and
+ * different seed provided. In the first case the test expects that all random numbers
+ * will be repeated in all next iterations. For other two modes test expects that
+ * randomly generated numbers differ from original.
+ */
+public class RandomGeneratorTest {
+ private static final String SEED_VM_OPTION = "-D" + Utils.SEED_PROPERTY_NAME + "=";
+
+ public static void main( String[] args) throws Throwable {
+ if (args.length == 0) {
+ throw new Error("TESTBUG: No test mode provided.");
+ }
+ SeedOption seedOpt = SeedOption.valueOf(args[0]);
+ List<String> jvmArgs = new ArrayList<String>();
+ String optStr = seedOpt.getSeedOption();
+ if (optStr != null) {
+ jvmArgs.add(optStr);
+ }
+ jvmArgs.add(RandomRunner.class.getName());
+ String[] cmdLineArgs = jvmArgs.toArray(new String[jvmArgs.size()]);
+ String etalon = ProcessTools.executeTestJvm(cmdLineArgs).getOutput().trim();
+ seedOpt.verify(etalon, cmdLineArgs);
+ }
+
+ /**
+ * The utility enum helps to generate an appropriate string that should be passed
+ * to the command line depends on the testing mode. It is also responsible for the result
+ * validation.
+ */
+ private enum SeedOption {
+ SAME_SEED {
+ @Override
+ public String getSeedOption() {
+ return SEED_VM_OPTION + Utils.SEED;
+ }
+
+ @Override
+ protected boolean isOutputExpected(String orig, String output) {
+ return output.equals(orig);
+ }
+ },
+ DIFFERENT_SEED {
+ @Override
+ public String getSeedOption() {
+ return SEED_VM_OPTION + Utils.getRandomInstance().nextLong();
+ }
+
+ @Override
+ public void verify(String orig, String[] cmdLine) {
+ cmdLine[0] = getSeedOption();
+ super.verify(orig, cmdLine);
+ }
+ },
+ NO_SEED {
+ @Override
+ public String getSeedOption() {
+ return null;
+ }
+ };
+
+ /**
+ * Generates a string to be added as a command line argument.
+ * It contains "-D" prefix, system property name, '=' sign
+ * and seed value.
+ * @return command line argument
+ */
+ public abstract String getSeedOption();
+
+ protected boolean isOutputExpected(String orig, String output) {
+ return !output.equals(orig);
+ }
+
+ /**
+ * Verifies that the original output meets expectations
+ * depending on the test mode. It compares the output of second execution
+ * to original one.
+ * @param orig original output
+ * @param cmdLine command line arguments
+ * @throws Throwable - Throws an exception in case test failure.
+ */
+ public void verify(String orig, String[] cmdLine) {
+ String lastLineOrig = getLastLine(orig);
+ String lastLine;
+ try {
+ lastLine = getLastLine(ProcessTools.executeTestJvm(cmdLine).getOutput().trim());
+ } catch (Throwable t) {
+ throw new Error("TESTBUG: Unexpedted exception during jvm execution.", t);
+ }
+ if (!isOutputExpected(lastLineOrig, lastLine)) {
+ throw new AssertionError("Unexpected random number sequence for mode: " + this.name());
+ }
+ }
+
+ private static String getLastLine(String output) {
+ return output.substring(output.lastIndexOf(Utils.NEW_LINE)).trim();
+ }
+ }
+
+ /**
+ * The helper class generates several random numbers
+ * and prints them out.
+ */
+ public static class RandomRunner {
+ private static final int COUNT = 10;
+ public static void main(String[] args) {
+ StringBuilder sb = new StringBuilder();
+ Random rng = Utils.getRandomInstance();
+ for (int i = 0; i < COUNT; i++) {
+ sb.append(rng.nextLong()).append(' ');
+ }
+ System.out.println(sb.toString());
+ }
+ }
+}
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java
index ae068f8867a..1da1728877d 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java
@@ -43,6 +43,7 @@ public class BooleanTest {
private static final Boolean[] TESTS = {true, false, true, true, false};
private static final String TEST_NAME = "BooleanTest";
private static final String FLAG_NAME = "PrintCompilation";
+ private static final String FLAG_DEBUG_NAME = "SafepointALot";
private static final String METHOD = TEST_NAME + "::method";
private static final String METHOD1 = METHOD + "1";
private static final String METHOD2 = METHOD + "2";
@@ -54,6 +55,7 @@ public class BooleanTest {
VmFlagTest.WHITE_BOX::getBooleanVMFlag);
testFunctional(false);
testFunctional(true);
+ VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getBooleanVMFlag);
} else {
boolean value = Boolean.valueOf(args[0]);
method1();
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java
index 0b320e7b21b..08fb73d87cf 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java
@@ -34,7 +34,7 @@
*/
public class DoubleTest {
- private static final String FLAG_NAME = null;
+ private static final String FLAG_NAME = "CompileThresholdScaling";
private static final Double[] TESTS = {0d, -0d, -1d, 1d,
Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN,
Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java
index 3b957eff084..9acdd31dd8b 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java
@@ -35,6 +35,7 @@
public class IntxTest {
private static final String FLAG_NAME = "OnStackReplacePercentage";
+ private static final String FLAG_DEBUG_NAME = "InlineFrequencyCount";
private static final Long[] TESTS = {0L, 100L, -1L,
(long) Integer.MAX_VALUE, (long) Integer.MIN_VALUE};
@@ -42,6 +43,7 @@ public class IntxTest {
VmFlagTest.runTest(FLAG_NAME, TESTS,
VmFlagTest.WHITE_BOX::setIntxVMFlag,
VmFlagTest.WHITE_BOX::getIntxVMFlag);
+ VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getIntxVMFlag);
}
}
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java
index 77a02d3d2d4..e613df85b78 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java
@@ -35,12 +35,14 @@
public class StringTest {
private static final String FLAG_NAME = "CompileOnly";
+ private static final String FLAG_DEBUG_NAME = "SuppressErrorAt";
private static final String[] TESTS = {"StringTest::*", ""};
public static void main(String[] args) throws Exception {
VmFlagTest.runTest(FLAG_NAME, TESTS,
VmFlagTest.WHITE_BOX::setStringVMFlag,
VmFlagTest.WHITE_BOX::getStringVMFlag);
+ VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getStringVMFlag);
}
}
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java
index 40eb85f868f..bdb1f647209 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java
@@ -36,6 +36,7 @@ import com.oracle.java.testlibrary.Platform;
public class UintxTest {
private static final String FLAG_NAME = "VerifyGCStartAt";
+ private static final String FLAG_DEBUG_NAME = "CodeCacheMinimumUseSpace";
private static final Long[] TESTS = {0L, 100L, (long) Integer.MAX_VALUE,
(1L << 32L) - 1L, 1L << 32L};
private static final Long[] EXPECTED_64 = TESTS;
@@ -47,6 +48,7 @@ public class UintxTest {
Platform.is64bit() ? EXPECTED_64 : EXPECTED_32,
VmFlagTest.WHITE_BOX::setUintxVMFlag,
VmFlagTest.WHITE_BOX::getUintxVMFlag);
+ VmFlagTest.runTest(FLAG_DEBUG_NAME, VmFlagTest.WHITE_BOX::getUintxVMFlag);
}
}
diff --git a/hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java b/hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java
index 6c98889e6ae..e2d15630c04 100644
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/VmFlagTest.java
@@ -37,16 +37,18 @@ public final class VmFlagTest<T> {
private final BiConsumer<T, T> test;
private final BiConsumer<String, T> set;
private final Function<String, T> get;
+ private final boolean isPositive;
protected VmFlagTest(String flagName, BiConsumer<String, T> set,
Function<String, T> get, boolean isPositive) {
this.flagName = flagName;
this.set = set;
this.get = get;
+ this.isPositive = isPositive;
if (isPositive) {
- test = this::testPositive;
+ test = this::testWritePositive;
} else {
- test = this::testNegative;
+ test = this::testWriteNegative;
}
}
@@ -63,6 +65,10 @@ public final class VmFlagTest<T> {
runTest(existentFlag, tests, tests, set, get);
}
+ protected static <T> void runTest(String existentFlag, Function<String, T> get) {
+ runTest(existentFlag, null, null, null, get);
+ }
+
protected static <T> void runTest(String existentFlag, T[] tests,
T[] results, BiConsumer<String, T> set, Function<String, T> get) {
if (existentFlag != null) {
@@ -72,13 +78,23 @@ public final class VmFlagTest<T> {
}
public final void test(T[] tests, T[] results) {
- Asserts.assertEQ(tests.length, results.length, "[TESTBUG] tests.length != results.length");
- for (int i = 0, n = tests.length ; i < n; ++i) {
- test.accept(tests[i], results[i]);
+ if (isPositive) {
+ testRead();
+ }
+ if (tests != null) {
+ Asserts.assertEQ(tests.length, results.length, "[TESTBUG] tests.length != results.length");
+ for (int i = 0, n = tests.length ; i < n; ++i) {
+ test.accept(tests[i], results[i]);
+ }
}
}
protected String getVMOptionAsString() {
+ if (WHITE_BOX.isConstantVMFlag(flagName) || WHITE_BOX.isLockedVMFlag(flagName)) {
+ // JMM cannot access debug flags in product builds or locked flags,
+ // use whitebox methods to get such flags value.
+ return asString(getValue());
+ }
HotSpotDiagnosticMXBean diagnostic
= ManagementFactoryHelper.getDiagnosticMXBean();
VMOption tmp;
@@ -90,18 +106,24 @@ public final class VmFlagTest<T> {
return tmp == null ? null : tmp.getValue();
}
- private void testPositive(T value, T expected) {
- String oldValue = getVMOptionAsString();
- Asserts.assertEQ(oldValue, asString(getValue()));
- Asserts.assertEQ(oldValue, asString(WHITE_BOX.getVMFlag(flagName)));
+ private String testRead() {
+ String value = getVMOptionAsString();
+ Asserts.assertNotNull(value);
+ Asserts.assertEQ(value, asString(getValue()));
+ Asserts.assertEQ(value, asString(WHITE_BOX.getVMFlag(flagName)));
+ return value;
+ }
+
+ private void testWritePositive(T value, T expected) {
setNewValue(value);
- String newValue = getVMOptionAsString();
+ String newValue = testRead();
Asserts.assertEQ(newValue, asString(expected));
- Asserts.assertEQ(newValue, asString(getValue()));
- Asserts.assertEQ(newValue, asString(WHITE_BOX.getVMFlag(flagName)));
}
- private void testNegative(T value, T expected) {
+ private void testWriteNegative(T value, T expected) {
+ // Should always return false for non-existing flags
+ Asserts.assertFalse(WHITE_BOX.isConstantVMFlag(flagName));
+ Asserts.assertFalse(WHITE_BOX.isLockedVMFlag(flagName));
String oldValue = getVMOptionAsString();
Asserts.assertEQ(oldValue, asString(getValue()));
Asserts.assertEQ(oldValue, asString(WHITE_BOX.getVMFlag(flagName)));
@@ -114,4 +136,3 @@ public final class VmFlagTest<T> {
return value == null ? null : "" + value;
}
}
-
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 7aeb3f4c9b7..e63cca060f0 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -281,3 +281,4 @@ e549291a0227031310fa91c574891f892d27f959 jdk9-b35
cdcf2e599e42935c2d1d19a24bb19e808aeb43b5 jdk9-b36
27c3345d6dce39a22c262f30bb1f0e0b00c3709e jdk9-b37
d2d745313c81d1fc01f426983b9f784ab1f750e8 jdk9-b38
+ca6edf957fe1c6ea818530b503578e872cea7239 jdk9-b39
diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java
index 15c6574d078..21c90f41da3 100644
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java
@@ -286,6 +286,53 @@ public abstract class Executable extends AccessibleObject
}
/**
+ * Behaves like {@code getGenericParameterTypes}, but returns type
+ * information for all parameters, including synthetic parameters.
+ */
+ Type[] getAllGenericParameterTypes() {
+ final boolean genericInfo = hasGenericInformation();
+
+ // Easy case: we don't have generic parameter information. In
+ // this case, we just return the result of
+ // getParameterTypes().
+ if (!genericInfo) {
+ return getParameterTypes();
+ } else {
+ final boolean realParamData = hasRealParameterData();
+ final Type[] genericParamTypes = getGenericParameterTypes();
+ final Type[] nonGenericParamTypes = getParameterTypes();
+ final Type[] out = new Type[nonGenericParamTypes.length];
+ final Parameter[] params = getParameters();
+ int fromidx = 0;
+ // If we have real parameter data, then we use the
+ // synthetic and mandate flags to our advantage.
+ if (realParamData) {
+ for (int i = 0; i < out.length; i++) {
+ final Parameter param = params[i];
+ if (param.isSynthetic() || param.isImplicit()) {
+ // If we hit a synthetic or mandated parameter,
+ // use the non generic parameter info.
+ out[i] = nonGenericParamTypes[i];
+ } else {
+ // Otherwise, use the generic parameter info.
+ out[i] = genericParamTypes[fromidx];
+ fromidx++;
+ }
+ }
+ } else {
+ // Otherwise, use the non-generic parameter data.
+ // Without method parameter reflection data, we have
+ // no way to figure out which parameters are
+ // synthetic/mandated, thus, no way to match up the
+ // indexes.
+ return genericParamTypes.length == nonGenericParamTypes.length ?
+ genericParamTypes : nonGenericParamTypes;
+ }
+ return out;
+ }
+ }
+
+ /**
* Returns an array of {@code Parameter} objects that represent
* all the parameters to the underlying executable represented by
* this object. Returns an array of length 0 if the executable
@@ -646,7 +693,7 @@ public abstract class Executable extends AccessibleObject
getConstantPool(getDeclaringClass()),
this,
getDeclaringClass(),
- getGenericParameterTypes(),
+ getAllGenericParameterTypes(),
TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
}
diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
index 69c568f09fe..5c178503fa8 100644
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
@@ -198,7 +198,7 @@ public final class Parameter implements AnnotatedElement {
public Type getParameterizedType() {
Type tmp = parameterTypeCache;
if (null == tmp) {
- tmp = executable.getGenericParameterTypes()[index];
+ tmp = executable.getAllGenericParameterTypes()[index];
parameterTypeCache = tmp;
}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java
index 9c8e8335945..d44fc8904fe 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/BootstrapConstructorAccessorImpl.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Constructor;
bootstrapping. */
class BootstrapConstructorAccessorImpl extends ConstructorAccessorImpl {
- private Constructor<?> constructor;
+ private final Constructor<?> constructor;
BootstrapConstructorAccessorImpl(Constructor<?> c) {
this.constructor = c;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java
index 08f921f82c6..854febe7b3f 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/InstantiationExceptionConstructorAccessorImpl.java
@@ -33,7 +33,7 @@ import java.lang.reflect.InvocationTargetException;
class InstantiationExceptionConstructorAccessorImpl
extends ConstructorAccessorImpl {
- private String message;
+ private final String message;
InstantiationExceptionConstructorAccessorImpl(String message) {
this.message = message;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/Label.java b/jdk/src/java.base/share/classes/sun/reflect/Label.java
index 53c912d1891..4caa3b40a83 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/Label.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/Label.java
@@ -47,10 +47,10 @@ class Label {
}
// This won't work for more than one assembler anyway, so this is
// unnecessary
- ClassFileAssembler asm;
- short instrBCI;
- short patchBCI;
- int stackDepth;
+ final ClassFileAssembler asm;
+ final short instrBCI;
+ final short patchBCI;
+ final int stackDepth;
}
private List<PatchInfo> patches = new ArrayList<>();
diff --git a/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
index d56c3caab08..171521dd2ae 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/NativeConstructorAccessorImpl.java
@@ -32,7 +32,7 @@ import sun.reflect.misc.ReflectUtil;
afterward, switches to bytecode-based implementation */
class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
- private Constructor<?> c;
+ private final Constructor<?> c;
private DelegatingConstructorAccessorImpl parent;
private int numInvocations;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java b/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java
index b1d39e7c965..a33670fe8ce 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/NativeMethodAccessorImpl.java
@@ -32,7 +32,7 @@ import sun.reflect.misc.ReflectUtil;
switches to bytecode-based implementation */
class NativeMethodAccessorImpl extends MethodAccessorImpl {
- private Method method;
+ private final Method method;
private DelegatingMethodAccessorImpl parent;
private int numInvocations;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java
index 0dbada7d5f3..dc26fab816b 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java
@@ -50,9 +50,9 @@ import sun.reflect.misc.ReflectUtil;
public class ReflectionFactory {
private static boolean initted = false;
- private static Permission reflectionFactoryAccessPerm
+ private static final Permission reflectionFactoryAccessPerm
= new RuntimePermission("reflectionFactoryAccess");
- private static ReflectionFactory soleInstance = new ReflectionFactory();
+ private static final ReflectionFactory soleInstance = new ReflectionFactory();
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java b/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java
index 7b4ac45cbb4..ea7fd3c80f2 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/SignatureIterator.java
@@ -28,7 +28,7 @@ package sun.reflect;
/** Assists in iterating down a method's signature */
public class SignatureIterator {
- private String sig;
+ private final String sig;
private int idx;
public SignatureIterator(String sig) {
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java
index 71a34bb6df0..fb939f415c9 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/factory/CoreReflectionFactory.java
@@ -45,8 +45,8 @@ import sun.reflect.generics.tree.FieldTypeSignature;
* core reflection (java.lang.reflect).
*/
public class CoreReflectionFactory implements GenericsFactory {
- private GenericDeclaration decl;
- private Scope scope;
+ private final GenericDeclaration decl;
+ private final Scope scope;
private CoreReflectionFactory(GenericDeclaration d, Scope s) {
decl = d;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
index 423a0ebf3f8..7520403ffdb 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java
@@ -34,7 +34,7 @@ import java.util.Objects;
*/
public class GenericArrayTypeImpl
implements GenericArrayType {
- private Type genericComponentType;
+ private final Type genericComponentType;
// private constructor enforces use of static factory
private GenericArrayTypeImpl(Type ct) {
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java
index 7cedafd64e2..0bc6f608811 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/LazyReflectiveObjectGenerator.java
@@ -40,7 +40,7 @@ import sun.reflect.generics.visitor.Reifier;
*
*/
public abstract class LazyReflectiveObjectGenerator {
- private GenericsFactory factory; // cached factory
+ private final GenericsFactory factory; // cached factory
protected LazyReflectiveObjectGenerator(GenericsFactory f) {
factory = f;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
index 7e80afb7282..1addbcc9c17 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java
@@ -38,9 +38,9 @@ import java.util.Objects;
/** Implementing class for ParameterizedType interface. */
public class ParameterizedTypeImpl implements ParameterizedType {
- private Type[] actualTypeArguments;
- private Class<?> rawType;
- private Type ownerType;
+ private final Type[] actualTypeArguments;
+ private final Class<?> rawType;
+ private final Type ownerType;
private ParameterizedTypeImpl(Class<?> rawType,
Type[] actualTypeArguments,
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java
index a28d88d3a1e..42f9446c33a 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/repository/AbstractRepository.java
@@ -40,9 +40,9 @@ public abstract class AbstractRepository<T extends Tree> {
// A factory used to produce reflective objects. Provided when the
//repository is created. Will vary across implementations.
- private GenericsFactory factory;
+ private final GenericsFactory factory;
- private T tree; // the AST for the generic type info
+ private final T tree; // the AST for the generic type info
//accessors
private GenericsFactory getFactory() { return factory;}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java
index bc0132eeab7..8709b3e82a3 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/AbstractScope.java
@@ -41,7 +41,7 @@ import java.lang.reflect.TypeVariable;
public abstract class AbstractScope<D extends GenericDeclaration>
implements Scope {
- private D recvr; // the declaration whose scope this instance represents
+ private final D recvr; // the declaration whose scope this instance represents
private Scope enclosingScope; // the enclosing scope of this scope
/**
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java
index 3370c9f3bc0..8a012dc3362 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/scope/DummyScope.java
@@ -38,7 +38,7 @@ import java.lang.reflect.TypeVariable;
public class DummyScope implements Scope {
// Caches the unique instance of this class; instances contain no data
// so we can use the singleton pattern
- private static DummyScope singleton = new DummyScope();
+ private static final DummyScope singleton = new DummyScope();
// constructor is private to enforce use of factory method
private DummyScope(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java
index b6606d2fb58..ba0a0d4165b 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ArrayTypeSignature.java
@@ -28,7 +28,7 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.TypeTreeVisitor;
public class ArrayTypeSignature implements FieldTypeSignature {
- private TypeSignature componentType;
+ private final TypeSignature componentType;
private ArrayTypeSignature(TypeSignature ct) {componentType = ct;}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java
index 5e3b8a3e4b1..133c7e191da 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BooleanSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type boolean. */
public class BooleanSignature implements BaseType {
- private static BooleanSignature singleton = new BooleanSignature();
+ private static final BooleanSignature singleton = new BooleanSignature();
private BooleanSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java
index b0aaedb2f7d..0fbbe2ea5a2 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/BottomSignature.java
@@ -28,7 +28,7 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.TypeTreeVisitor;
public class BottomSignature implements FieldTypeSignature {
- private static BottomSignature singleton = new BottomSignature();
+ private static final BottomSignature singleton = new BottomSignature();
private BottomSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java
index 47b64f90301..5335782fc4d 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ByteSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type byte. */
public class ByteSignature implements BaseType {
- private static ByteSignature singleton = new ByteSignature();
+ private static final ByteSignature singleton = new ByteSignature();
private ByteSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java
index 365c36108a2..44766a5776f 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/CharSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type char. */
public class CharSignature implements BaseType {
- private static CharSignature singleton = new CharSignature();
+ private static final CharSignature singleton = new CharSignature();
private CharSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java
index ca77d9f8a04..9347f977061 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassSignature.java
@@ -28,9 +28,9 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.Visitor;
public class ClassSignature implements Signature {
- private FormalTypeParameter[] formalTypeParams;
- private ClassTypeSignature superclass;
- private ClassTypeSignature[] superInterfaces;
+ private final FormalTypeParameter[] formalTypeParams;
+ private final ClassTypeSignature superclass;
+ private final ClassTypeSignature[] superInterfaces;
private ClassSignature(FormalTypeParameter[] ftps,
ClassTypeSignature sc,
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java
index f16622bf69f..320764a4fb4 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ClassTypeSignature.java
@@ -33,7 +33,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
* AST representing class types.
*/
public class ClassTypeSignature implements FieldTypeSignature {
- private List<SimpleClassTypeSignature> path;
+ private final List<SimpleClassTypeSignature> path;
private ClassTypeSignature(List<SimpleClassTypeSignature> p) {
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java
index 533d43e54ea..a394228eb99 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/DoubleSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type double. */
public class DoubleSignature implements BaseType {
- private static DoubleSignature singleton = new DoubleSignature();
+ private static final DoubleSignature singleton = new DoubleSignature();
private DoubleSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java
index 61f8f45cc9d..70bf8c5c303 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FloatSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type float. */
public class FloatSignature implements BaseType {
- private static FloatSignature singleton = new FloatSignature();
+ private static final FloatSignature singleton = new FloatSignature();
private FloatSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java
index 262cdb3d504..c25c4179784 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/FormalTypeParameter.java
@@ -29,8 +29,8 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents a formal type parameter. */
public class FormalTypeParameter implements TypeTree {
- private String name;
- private FieldTypeSignature[] bounds;
+ private final String name;
+ private final FieldTypeSignature[] bounds;
private FormalTypeParameter(String n, FieldTypeSignature[] bs) {
name = n;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java
index e622b235065..e1d3a443903 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/IntSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type int. */
public class IntSignature implements BaseType {
- private static IntSignature singleton = new IntSignature();
+ private static final IntSignature singleton = new IntSignature();
private IntSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java
index a730a983caa..13eef0596e1 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/LongSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type long. */
public class LongSignature implements BaseType {
- private static LongSignature singleton = new LongSignature();
+ private static final LongSignature singleton = new LongSignature();
private LongSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java
index 2d4bc1947ca..efbda03bfcd 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/MethodTypeSignature.java
@@ -28,10 +28,10 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.Visitor;
public class MethodTypeSignature implements Signature {
- private FormalTypeParameter[] formalTypeParams;
- private TypeSignature[] parameterTypes;
- private ReturnType returnType;
- private FieldTypeSignature[] exceptionTypes;
+ private final FormalTypeParameter[] formalTypeParams;
+ private final TypeSignature[] parameterTypes;
+ private final ReturnType returnType;
+ private final FieldTypeSignature[] exceptionTypes;
private MethodTypeSignature(FormalTypeParameter[] ftps,
TypeSignature[] pts,
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java
index ccdadcf0af4..374f6fba883 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/ShortSignature.java
@@ -29,7 +29,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the type short. */
public class ShortSignature implements BaseType {
- private static ShortSignature singleton = new ShortSignature();
+ private static final ShortSignature singleton = new ShortSignature();
private ShortSignature(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java
index 45ba803cfab..8c287018fb1 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/SimpleClassTypeSignature.java
@@ -28,9 +28,9 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.TypeTreeVisitor;
public class SimpleClassTypeSignature implements FieldTypeSignature {
- private boolean dollar;
- private String name;
- private TypeArgument[] typeArgs;
+ private final boolean dollar;
+ private final String name;
+ private final TypeArgument[] typeArgs;
private SimpleClassTypeSignature(String n, boolean dollar, TypeArgument[] tas) {
name = n;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java
index 68e46e54639..9f1196586cb 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/TypeVariableSignature.java
@@ -28,7 +28,7 @@ package sun.reflect.generics.tree;
import sun.reflect.generics.visitor.TypeTreeVisitor;
public class TypeVariableSignature implements FieldTypeSignature {
- private String identifier;
+ private final String identifier;
private TypeVariableSignature(String id) {identifier = id;}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java
index d685c60c6da..5544ebc6b9a 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/tree/VoidDescriptor.java
@@ -30,7 +30,7 @@ import sun.reflect.generics.visitor.TypeTreeVisitor;
/** AST that represents the pseudo-type void. */
public class VoidDescriptor implements ReturnType {
- private static VoidDescriptor singleton = new VoidDescriptor();
+ private static final VoidDescriptor singleton = new VoidDescriptor();
private VoidDescriptor(){}
diff --git a/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java b/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java
index b49ed0a65cb..ebe802b60a2 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/MethodUtil.java
@@ -76,9 +76,9 @@ class Trampoline {
* Create a trampoline class.
*/
public final class MethodUtil extends SecureClassLoader {
- private static String MISC_PKG = "sun.reflect.misc.";
- private static String TRAMPOLINE = MISC_PKG + "Trampoline";
- private static Method bounce = getTrampoline();
+ private static final String MISC_PKG = "sun.reflect.misc.";
+ private static final String TRAMPOLINE = MISC_PKG + "Trampoline";
+ private static final Method bounce = getTrampoline();
private MethodUtil() {
super();
diff --git a/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c b/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c
index 4880123a31d..05f568001b5 100644
--- a/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c
+++ b/jdk/src/java.base/windows/native/libnio/MappedByteBuffer.c
@@ -83,9 +83,9 @@ Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo,
HANDLE h;
if (handle_fdID == NULL) {
jclass clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
- if (clazz == NULL)
- return; // exception thrown
+ CHECK_NULL(clazz); //exception thrown
handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J");
+ CHECK_NULL(handle_fdID);
}
h = jlong_to_ptr((*env)->GetLongField(env, fdo, handle_fdID));
result = FlushFileBuffers(h);
diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index 671fee74657..363faebac51 100644
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -678,7 +678,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
final long nsWindowPtr = getNSWindowPtr();
LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- if( w != null
+ if( w != null && w.getPeer() != null
&& ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME
&& !lwcToolkit.isApplicationActive()) {
lwcToolkit.activateApplicationIgnoringOtherApps();
diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m
index 647042f578f..1ad7d042e6a 100644
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m
@@ -72,7 +72,9 @@ OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)
}
[pool drain];
free(ctxinfo);
+ oglc->ctxInfo = NULL;
}
+ cglinfo->context = NULL;
}
free(cglinfo);
diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m
index 84c1fb12c5b..e4dccabcf38 100644
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m
@@ -187,6 +187,11 @@ OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo)
}
OGLContext *oglc = cglInfo->context;
+ if (oglc == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null");
+ return NULL;
+ }
+
CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
JNF_COCOA_ENTER(env);
diff --git a/jdk/src/java.desktop/share/classes/java/awt/Component.java b/jdk/src/java.desktop/share/classes/java/awt/Component.java
index cfc6d24e157..95e5d094b01 100644
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java
@@ -8607,7 +8607,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
* @param propertyName the programmatic name of the property
* that was changed
* @param oldValue the old value of the property (as a short)
- * @param newValue the old value of the property (as a short)
+ * @param newValue the new value of the property (as a short)
* @see #firePropertyChange(java.lang.String, java.lang.Object,
* java.lang.Object)
* @since 1.5
diff --git a/jdk/src/java.desktop/share/classes/java/awt/Robot.java b/jdk/src/java.desktop/share/classes/java/awt/Robot.java
index 8de89ee8ed9..1442dc8d4e5 100644
--- a/jdk/src/java.desktop/share/classes/java/awt/Robot.java
+++ b/jdk/src/java.desktop/share/classes/java/awt/Robot.java
@@ -34,9 +34,12 @@ import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.peer.RobotPeer;
import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+
import sun.awt.AWTPermissions;
import sun.awt.ComponentFactory;
import sun.awt.SunToolkit;
+import sun.awt.OSInfo;
import sun.awt.image.SunWritableRaster;
/**
@@ -555,15 +558,21 @@ public class Robot {
*/
public synchronized void waitForIdle() {
checkNotDispatchThread();
- // post a dummy event to the queue so we know when
- // all the events before it have been processed
+
try {
SunToolkit.flushPendingEvents();
- EventQueue.invokeAndWait( new Runnable() {
- public void run() {
- // dummy implementation
- }
- } );
+ // 7185258: realSync() call blocks all DnD tests on OS X
+ if (AccessController.doPrivileged(OSInfo.getOSTypeAction()) == OSInfo.OSType.MACOSX) {
+ // post a dummy event to the queue so we know when
+ // all the events before it have been processed
+ EventQueue.invokeAndWait( new Runnable() {
+ public void run() {
+ // dummy implementation
+ }
+ } );
+ } else {
+ ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ }
} catch(InterruptedException ite) {
System.err.println("Robot.waitForIdle, non-fatal exception caught:");
ite.printStackTrace();
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java
index e65f669c66d..15e96468f4a 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java
@@ -1320,7 +1320,8 @@ implements ItemSelectable,ListDataListener,ActionListener, Accessible {
*/
public void actionPerformed(ActionEvent e) {
ComboBoxEditor editor = getEditor();
- if ((editor != null) && (e != null) && (editor == e.getSource())) {
+ if ((editor != null) && (e != null)
+ && (editor.getEditorComponent() == e.getSource())) {
setPopupVisible(false);
getModel().setSelectedItem(editor.getItem());
String oldCommand = getActionCommand();
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java
index ac401648f54..6b10d247e43 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java
@@ -278,18 +278,34 @@ public class DrawImage implements DrawImagePipe
Color bgColor, int interpType,
double coords[])
{
- double dx = coords[0];
- double dy = coords[1];
- double dw = coords[2] - dx;
- double dh = coords[3] - dy;
+ double dx1 = coords[0];
+ double dy1 = coords[1];
+ double dx2 = coords[2];
+ double dy2 = coords[3];
+ double dw = dx2 - dx1;
+ double dh = dy2 - dy1;
+
+ /* If any of the destination coordinates exceed the integer range,
+ * then the calculations performed in calls made here cannot be
+ * guaranteed to be correct, or to converge (terminate).
+ * So return out of here, deferring to code that can handle this.
+ */
+ if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
+ dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
+ dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
+ dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
+ {
+ return false;
+ }
+
// First check if width and height are very close to img w&h.
if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) {
// Round location to nearest pixel and then test
// if it will cause interpolation anomalies.
- int idx = (int) Math.floor(dx + 0.5);
- int idy = (int) Math.floor(dy + 0.5);
+ int idx = (int) Math.floor(dx1 + 0.5);
+ int idy = (int) Math.floor(dy1 + 0.5);
if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
- (closeToInteger(idx, dx) && closeToInteger(idy, dy)))
+ (closeToInteger(idx, dx1) && closeToInteger(idy, dy1)))
{
renderImageCopy(sg, img, bgColor,
idx, idy,
@@ -302,7 +318,7 @@ public class DrawImage implements DrawImagePipe
if (dw > 0 && dh > 0) {
if (renderImageScale(sg, img, bgColor, interpType,
sx1, sy1, sx2, sy2,
- coords[0], coords[1], coords[2], coords[3]))
+ dx1, dy1, dx2, dy2))
{
return true;
}
@@ -494,7 +510,7 @@ public class DrawImage implements DrawImagePipe
// We need to transform to a temp image and then copy
// just the pieces that are valid data to the dest.
BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1,
- BufferedImage.TYPE_INT_ARGB);
+ BufferedImage.TYPE_INT_ARGB_PRE);
SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
SurfaceType tmpType = tmpData.getSurfaceType();
MaskBlit tmpmaskblit =
diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
index 94495da083e..93dc53d4f27 100644
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@ import sun.java2d.pipe.RenderQueue;
import static sun.java2d.pipe.BufferedOpCodes.*;
import sun.java2d.windows.GDIWindowSurfaceData;
-class D3DBlitLoops {
+final class D3DBlitLoops {
static void register() {
Blit blitIntArgbPreToSurface =
@@ -57,7 +57,9 @@ class D3DBlitLoops {
Blit blitIntArgbPreToTexture =
new D3DSwToTextureBlit(SurfaceType.IntArgbPre,
D3DSurfaceData.ST_INT_ARGB_PRE);
-
+ TransformBlit transformBlitIntArgbPreToSurface =
+ new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE);
GraphicsPrimitive[] primitives = {
// prevent D3DSurface -> Screen blits
new D3DSurfaceToGDIWindowSurfaceBlit(),
@@ -123,8 +125,6 @@ class D3DBlitLoops {
new D3DSwToSurfaceTransform(SurfaceType.IntArgb,
D3DSurfaceData.ST_INT_ARGB),
- new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
- D3DSurfaceData.ST_INT_ARGB_PRE),
new D3DSwToSurfaceTransform(SurfaceType.IntRgb,
D3DSurfaceData.ST_INT_RGB),
new D3DSwToSurfaceTransform(SurfaceType.IntBgr,
@@ -140,6 +140,9 @@ class D3DBlitLoops {
// REMIND: we don't have a native sw loop to back this loop up
// new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,
// D3DSurfaceData.ST_BYTE_INDEXED_BM),
+ transformBlitIntArgbPreToSurface,
+
+ new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
// texture->surface ops
new D3DTextureToSurfaceBlit(),
@@ -712,11 +715,11 @@ class D3DTextureToSurfaceTransform extends TransformBlit {
* This general Blit implementation converts any source surface to an
* intermediate IntArgbPre surface, and then uses the more specific
* IntArgbPre->D3DSurface/Texture loop to get the intermediate
- * (premultiplied) surface down to D3D.
+ * (premultiplied) surface down to D3D using simple blit.
*/
class D3DGeneralBlit extends Blit {
- private Blit performop;
+ private final Blit performop;
private WeakReference<SurfaceData> srcTmp;
D3DGeneralBlit(SurfaceType dstType,
@@ -757,6 +760,49 @@ class D3DGeneralBlit extends Blit {
}
}
+/**
+ * This general TransformedBlit implementation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->D3DSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to D3D using simple transformBlit.
+ */
+final class D3DGeneralTransformedBlit extends TransformBlit {
+
+ private final TransformBlit performop;
+ private WeakReference<SurfaceData> srcTmp;
+
+ D3DGeneralTransformedBlit(final TransformBlit performop) {
+ super(SurfaceType.Any, CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ this.performop = performop;
+ }
+
+ @Override
+ public synchronized void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint, int srcx,
+ int srcy, int dstx, int dsty, int width,
+ int height){
+ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
+ CompositeType.SrcNoEa,
+ SurfaceType.IntArgbPre);
+ // use cached intermediate surface, if available
+ final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
+ // convert source to IntArgbPre
+ src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
+ BufferedImage.TYPE_INT_ARGB_PRE);
+
+ // transform IntArgbPre intermediate surface to D3D surface
+ performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
+ width, height);
+
+ if (src != cachedSrc) {
+ // cache the intermediate surface
+ srcTmp = new WeakReference<>(src);
+ }
+ }
+}
+
/*
* The following classes prohibit copying D3DSurfaces to the screen
* (the D3D->sysmem->GDI path is known to be very very slow).
diff --git a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java
index 9bcdd8547f6..c95ac52b68d 100644
--- a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java
+++ b/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package com.sun.management;
-import java.util.List;
import java.lang.management.PlatformManagedObject;
/**
@@ -109,7 +108,7 @@ public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
* @throws IllegalArgumentException if the VM option of the given name
* does not exist.
* @throws IllegalArgumentException if the new value is invalid.
- * @throws IllegalArgumentException if the VM option is not writeable.
+ * @throws IllegalArgumentException if the VM option is not writable.
* @throws NullPointerException if name or value is <tt>null</tt>.
*
* @throws java.lang.SecurityException
diff --git a/jdk/src/java.management/share/classes/sun/management/Flag.java b/jdk/src/java.management/share/classes/sun/management/Flag.java
index 6bb1bf66460..4f52cb51495 100644
--- a/jdk/src/java.management/share/classes/sun/management/Flag.java
+++ b/jdk/src/java.management/share/classes/sun/management/Flag.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -110,6 +110,7 @@ class Flag {
// These set* methods are synchronized on the class object
// to avoid multiple threads updating the same flag at the same time.
static synchronized native void setLongValue(String name, long value);
+ static synchronized native void setDoubleValue(String name, double value);
static synchronized native void setBooleanValue(String name, boolean value);
static synchronized native void setStringValue(String name, String value);
diff --git a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java b/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java
index d2e7b397208..7c39ea7e9d3 100644
--- a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java
+++ b/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -40,6 +40,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
public HotSpotDiagnostic() {
}
+ @Override
public void dumpHeap(String outputFile, boolean live) throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) {
@@ -52,6 +53,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
private native void dumpHeap0(String outputFile, boolean live) throws IOException;
+ @Override
public List<VMOption> getDiagnosticOptions() {
List<Flag> allFlags = Flag.getAllFlags();
List<VMOption> result = new ArrayList<>();
@@ -63,6 +65,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
return result;
}
+ @Override
public VMOption getVMOption(String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
@@ -76,6 +79,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
return f.getVMOption();
}
+ @Override
public void setVMOption(String name, String value) {
if (name == null) {
throw new NullPointerException("name cannot be null");
@@ -102,12 +106,18 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
long l = Long.parseLong(value);
Flag.setLongValue(name, l);
} catch (NumberFormatException e) {
- IllegalArgumentException iae =
- new IllegalArgumentException("Invalid value:" +
+ throw new IllegalArgumentException("Invalid value:" +
+ " VM Option \"" + name + "\"" +
+ " expects numeric value", e);
+ }
+ } else if (v instanceof Double) {
+ try {
+ double d = Double.parseDouble(value);
+ Flag.setDoubleValue(name, d);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid value:" +
" VM Option \"" + name + "\"" +
- " expects numeric value");
- iae.initCause(e);
- throw iae;
+ " expects numeric value", e);
}
} else if (v instanceof Boolean) {
if (!value.equalsIgnoreCase("true") &&
@@ -126,6 +136,7 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
}
}
+ @Override
public ObjectName getObjectName() {
return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
}
diff --git a/jdk/src/java.management/share/native/include/jmm.h b/jdk/src/java.management/share/native/include/jmm.h
index f55610d1c0a..1730541d076 100644
--- a/jdk/src/java.management/share/native/include/jmm.h
+++ b/jdk/src/java.management/share/native/include/jmm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -143,7 +143,8 @@ typedef enum {
JMM_VMGLOBAL_TYPE_UNKNOWN = 0,
JMM_VMGLOBAL_TYPE_JBOOLEAN = 1,
JMM_VMGLOBAL_TYPE_JSTRING = 2,
- JMM_VMGLOBAL_TYPE_JLONG = 3
+ JMM_VMGLOBAL_TYPE_JLONG = 3,
+ JMM_VMGLOBAL_TYPE_JDOUBLE = 4
} jmmVMGlobalType;
typedef enum {
diff --git a/jdk/src/java.management/share/native/libmanagement/Flag.c b/jdk/src/java.management/share/native/libmanagement/Flag.c
index 7a45e8d62f6..00828f34967 100644
--- a/jdk/src/java.management/share/native/libmanagement/Flag.c
+++ b/jdk/src/java.management/share/native/libmanagement/Flag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -133,6 +133,10 @@ Java_sun_management_Flag_getFlags
valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V",
globals[i].value.j);
break;
+ case JMM_VMGLOBAL_TYPE_JDOUBLE:
+ valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V",
+ globals[i].value.d);
+ break;
default:
// ignore unsupported type
continue;
@@ -202,6 +206,16 @@ Java_sun_management_Flag_setLongValue
}
JNIEXPORT void JNICALL
+Java_sun_management_Flag_setDoubleValue
+ (JNIEnv *env, jclass cls, jstring name, jdouble value)
+{
+ jvalue v;
+ v.d = value;
+
+ jmm_interface->SetVMGlobal(env, name, v);
+}
+
+JNIEXPORT void JNICALL
Java_sun_management_Flag_setBooleanValue
(JNIEnv *env, jclass cls, jstring name, jboolean value)
{
diff --git a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c b/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c
index 412212f7c34..04dbf8497c8 100644
--- a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c
+++ b/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c
@@ -53,8 +53,6 @@
typedef unsigned __int32 juint;
typedef unsigned __int64 julong;
-typedef enum boolean_values { false=0, true=1};
-
static void set_low(jlong* value, jint low) {
*value &= (jlong)0xffffffff << 32;
*value |= (jlong)(julong)(juint)low;
@@ -66,22 +64,22 @@ static void set_high(jlong* value, jint high) {
}
static jlong jlong_from(jint h, jint l) {
- jlong result = 0; // initialization to avoid warning
- set_high(&result, h);
- set_low(&result, l);
- return result;
+ jlong result = 0; // initialization to avoid warning
+ set_high(&result, h);
+ set_low(&result, l);
+ return result;
}
static HANDLE main_process;
-int perfiInit(void);
+static void perfInit(void);
JNIEXPORT void JNICALL
Java_sun_management_OperatingSystemImpl_initialize0
(JNIEnv *env, jclass cls)
{
main_process = GetCurrentProcess();
- perfiInit();
+ perfInit();
}
JNIEXPORT jlong JNICALL
@@ -155,26 +153,7 @@ Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0
return (jlong) ms.ullTotalPhys;
}
-// Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
-// Let's just ignore it, since we make sure we have enough buffer anyway.
-static int
-pdh_fail(PDH_STATUS pdhStat) {
- return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
-}
-
-// INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
-// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
-// The index value for the base system counters and objects like processor,
-// process, thread, memory, and so forth are always the same irrespective
-// of the localized version of the operating system or service pack installed.
-#define PDH_PROCESSOR_IDX ((DWORD) 238)
-#define PDH_PROCESSOR_TIME_IDX ((DWORD) 6)
-#define PDH_PRIV_PROCESSOR_TIME_IDX ((DWORD) 144)
-#define PDH_PROCESS_IDX ((DWORD) 230)
-#define PDH_ID_PROCESS_IDX ((DWORD) 784)
-#define PDH_CONTEXT_SWITCH_RATE_IDX ((DWORD) 146)
-#define PDH_SYSTEM_IDX ((DWORD) 2)
-#define PDH_VIRTUAL_BYTES_IDX ((DWORD) 174)
+/* Performance Data Helper API (PDH) support */
typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
HQUERY hQuery,
@@ -183,48 +162,44 @@ typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
HCOUNTER *phCounter
);
typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
- LPCWSTR szDataSource,
- DWORD dwUserData,
- HQUERY *phQuery
- );
-typedef DWORD (WINAPI *PdhCloseQueryFunc)(
- HQUERY hQuery
- );
+ LPCWSTR szDataSource,
+ DWORD dwUserData,
+ HQUERY *phQuery
+ );
typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
- HQUERY hQuery
- );
-typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
- HCOUNTER hCounter,
- DWORD dwFormat,
- LPDWORD lpdwType,
- PPDH_FMT_COUNTERVALUE pValue
- );
+ HQUERY hQuery
+ );
+
typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
- LPCTSTR szDataSource,
- LPCTSTR szMachineName,
- LPCTSTR szObjectName,
- LPTSTR mszCounterList,
- LPDWORD pcchCounterListLength,
- LPTSTR mszInstanceList,
- LPDWORD pcchInstanceListLength,
- DWORD dwDetailLevel,
- DWORD dwFlags
- );
+ LPCTSTR szDataSource,
+ LPCTSTR szMachineName,
+ LPCTSTR szObjectName,
+ LPTSTR mszCounterList,
+ LPDWORD pcchCounterListLength,
+ LPTSTR mszInstanceList,
+ LPDWORD pcchInstanceListLength,
+ DWORD dwDetailLevel,
+ DWORD dwFlags
+ );
typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
- HCOUNTER hCounter
- );
+ HCOUNTER hCounter
+ );
typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
- LPCSTR szMachineName,
- DWORD dwNameIndex,
- LPSTR szNameBuffer,
- LPDWORD pcchNameBufferSize
- );
-typedef PDH_STATUS (WINAPI *PdhMakeCounterPathFunc)(
- PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
- LPTSTR szFullPathBuffer,
- LPDWORD pcchBufferSize,
- DWORD dwFlags
- );
+ LPCSTR szMachineName,
+ DWORD dwNameIndex,
+ LPSTR szNameBuffer,
+ LPDWORD pcchNameBufferSize
+ );
+typedef DWORD (WINAPI *PdhCloseQueryFunc)(
+ HQUERY hQuery
+ );
+
+typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
+ HCOUNTER hCounter,
+ DWORD dwFormat,
+ LPDWORD lpdwType,
+ PPDH_FMT_COUNTERVALUE pValue
+ );
static PdhAddCounterFunc PdhAddCounter_i;
static PdhOpenQueryFunc PdhOpenQuery_i;
@@ -234,624 +209,1112 @@ static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i;
static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
static PdhRemoveCounterFunc PdhRemoveCounter_i;
static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;
-static PdhMakeCounterPathFunc PdhMakeCounterPath_i;
-
-static HANDLE thisProcess;
-static double cpuFactor;
-static DWORD num_cpus;
-#define FT2JLONG(X) ((((jlong)X.dwHighDateTime) << 32) | ((jlong)X.dwLowDateTime))
-#define COUNTER_BUF_SIZE 256
-// Min time between query updates.
-#define MIN_UPDATE_INTERVAL 500
-#define CONFIG_SUCCESSFUL 0
-
-/**
+/*
* Struct for PDH queries.
*/
typedef struct {
HQUERY query;
- uint64_t lastUpdate; // Last time query was updated (current millis).
+ uint64_t lastUpdate; // Last time query was updated (ticks)
} UpdateQueryS, *UpdateQueryP;
-/**
- * Struct for the processor load counters.
+// Min time between query updates (ticks)
+static const int MIN_UPDATE_INTERVAL = 500;
+
+/*
+ * Struct for a PDH query with multiple counters.
*/
typedef struct {
- UpdateQueryS query;
- HCOUNTER* counters;
- int noOfCounters;
+ UpdateQueryS query;
+ HCOUNTER* counters;
+ int noOfCounters;
} MultipleCounterQueryS, *MultipleCounterQueryP;
-/**
- * Struct for the jvm process load counter.
+/*
+ * Struct for a PDH query with a single counter.
*/
typedef struct {
- UpdateQueryS query;
+ UpdateQueryS query;
HCOUNTER counter;
} SingleCounterQueryS, *SingleCounterQueryP;
-static char* getProcessPDHHeader(void);
-/**
- * Currently available counters.
+typedef struct {
+ CRITICAL_SECTION cs;
+ DWORD owningThread;
+ DWORD recursionCount;
+} PdhCriticalSectionS, *PdhCriticalSectionP;
+
+static PdhCriticalSectionS initializationLock;
+
+static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+
+ InitializeCriticalSection(&criticalSection->cs);
+ criticalSection->owningThread = 0;
+ criticalSection->recursionCount = 0;
+}
+
+static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+
+ EnterCriticalSection(&criticalSection->cs);
+ criticalSection->recursionCount++;
+ if (!criticalSection->owningThread) {
+ criticalSection->owningThread = GetCurrentThreadId();
+ }
+}
+
+static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+ assert(GetCurrentThreadId() == criticalSection->owningThread);
+ assert(criticalSection->recursionCount >= 1);
+
+ criticalSection->recursionCount--;
+ if (!criticalSection->recursionCount) {
+ criticalSection->owningThread = 0;
+ }
+ LeaveCriticalSection(&criticalSection->cs);
+}
+
+/*
+ * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
+ * http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
+ * The index value for the base system counters and objects like processor,
+ * process, thread, memory, and so forth are always the same irrespective
+ * of the localized version of the operating system or service pack installed.
+ * To find the correct index for an object or counter, inspect the registry key/value:
+ * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
*/
-static SingleCounterQueryS cntCtxtSwitchRate;
-static SingleCounterQueryS cntVirtualSize;
-static SingleCounterQueryS cntProcLoad;
-static SingleCounterQueryS cntProcSystemLoad;
-static MultipleCounterQueryS multiCounterCPULoad;
+static const DWORD PDH_PROCESSOR_IDX = 238;
+static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
+static const DWORD PDH_PROCESS_IDX = 230;
+static const DWORD PDH_ID_PROCESS_IDX = 784;
+
+/* useful pdh fmt's */
+static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
+static const size_t OBJECT_COUNTER_FMT_LEN = 2;
+static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
+static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
+static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
+static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
+
+static const char* pdhProcessImageName = NULL; /* "java" */
+static char* pdhIDProcessCounterFmt = NULL; /* "\Process(java#%d)\ID Process" */
-static CRITICAL_SECTION processHeaderLock;
-static CRITICAL_SECTION initializationLock;
+static int numberOfJavaProcessesAtInitialization = 0;
-/**
- * Initialize the perf module at startup.
+/*
+ * Currently used CPU queries/counters and variables
*/
-int
-perfiInit(void)
-{
- InitializeCriticalSection(&processHeaderLock);
- InitializeCriticalSection(&initializationLock);
- return 0;
-}
+static SingleCounterQueryP processTotalCPULoad = NULL;
+static MultipleCounterQueryP multiCounterCPULoad = NULL;
+static double cpuFactor = .0;
+static DWORD numCpus = 0;
-/**
- * Dynamically sets up function pointers to the PDH library.
- *
- * @return CONFIG_SUCCESSFUL on success, negative on failure.
+/*
+ * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
+ * Let's just ignore it, since we make sure we have enough buffer anyway.
*/
static int
-get_functions(HMODULE h, char *ebuf, size_t elen) {
- // The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods
- PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
- PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
- PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
- PdhCollectQueryData_i = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
- PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
- PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
- PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
- PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
- PdhMakeCounterPath_i = (PdhMakeCounterPathFunc)GetProcAddress(h, "PdhMakeCounterPathA");
+pdhFail(PDH_STATUS pdhStat) {
+ return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
+}
- if (PdhAddCounter_i == NULL || PdhOpenQuery_i == NULL ||
- PdhCloseQuery_i == NULL || PdhCollectQueryData_i == NULL ||
- PdhGetFormattedCounterValue_i == NULL || PdhEnumObjectItems_i == NULL ||
- PdhRemoveCounter_i == NULL || PdhLookupPerfNameByIndex_i == NULL || PdhMakeCounterPath_i == NULL)
- {
- _snprintf(ebuf, elen, "Required method could not be found.");
- return -1;
+static const char*
+allocateAndCopy(const char* const originalString) {
+ size_t len;
+ char* allocatedString;
+
+ assert(originalString);
+
+ len = strlen(originalString);
+
+ allocatedString = malloc(len + 1);
+
+ if (!allocatedString) {
+ return NULL;
}
- return CONFIG_SUCCESSFUL;
+
+ strncpy(allocatedString, originalString, len);
+ allocatedString[len] = '\0';
+
+ return allocatedString;
}
-/**
- * Returns the counter value as a double for the specified query.
- * Will collect the query data and update the counter values as necessary.
+/*
+ * Allocates memory into the supplied pointer and
+ * fills it with the localized PDH artifact description, if indexed correctly.
+ * Caller owns the memory from the point of returning from this function.
*
- * @param query the query to update (if needed).
- * @param c the counter to read.
- * @param value where to store the formatted value.
- * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
- * @return CONFIG_SUCCESSFUL if no error
- * -1 if PdhCollectQueryData fails
- * -2 if PdhGetFormattedCounterValue fails
+ * @param index the PDH counter index as specified in the registry
+ * @param ppBuffer pointer to a char*.
+ * @return 0 if successful, negative on failure.
*/
static int
-getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
- clock_t now;
- now = clock();
-
- // Need to limit how often we update the query
- // to mimise the heisenberg effect.
- // (PDH behaves erratically if the counters are
- // queried too often, especially counters that
- // store and use values from two consecutive updates,
- // like cpu load.)
- if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
- if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
- return -1;
- }
- query->lastUpdate = now;
+lookupNameByIndex(DWORD index, char** ppBuffer) {
+ DWORD size;
+
+ assert(ppBuffer);
+
+ /* determine size needed */
+ if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
+ /* invalid index? */
+ return -1;
}
- if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
- return -2;
+ *ppBuffer = malloc((size_t)size);
+
+ if (!*ppBuffer) {
+ return -1;
+ }
+
+ if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
+ free(*ppBuffer);
+ *ppBuffer = NULL;
+ return -1;
}
- return CONFIG_SUCCESSFUL;
+
+ /* windows vista does not null-terminate the string
+ * (although the docs says it will) */
+ (*ppBuffer)[size - 1] = '\0';
+
+ return 0;
}
-/**
- * Places the resolved counter name of the counter at the specified index in the
- * supplied buffer. There must be enough space in the buffer to hold the counter name.
+/*
+* Construct a fully qualified PDH path
+*
+* @param objectName a PDH Object string representation (required)
+* @param counterName a PDH Counter string representation (required)
+* @param imageName a process image name string, ex. "java" (opt)
+* @param instance an instance string, ex. "0", "1", ... (opt)
+* @return the fully qualified PDH path.
+*
+* Caller will own the returned malloc:ed string
+*/
+static const char*
+makeFullCounterPath(const char* const objectName,
+ const char* const counterName,
+ const char* const imageName,
+ const char* const instance) {
+
+ size_t fullCounterPathLen;
+ char* fullCounterPath;
+
+ assert(objectName);
+ assert(counterName);
+
+ fullCounterPathLen = strlen(objectName);
+ fullCounterPathLen += strlen(counterName);
+
+ if (imageName) {
+ /*
+ * For paths using the "Process" Object.
+ *
+ * Examples:
+ * abstract: "\Process(imageName#instance)\Counter"
+ * actual: "\Process(java#2)\ID Process"
+ */
+ fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+ fullCounterPathLen += strlen(imageName);
+
+ /*
+ * imageName must be passed together with an associated
+ * instance "number" ("0", "1", "2", ...).
+ * This is required in order to create valid "Process" Object paths.
+ *
+ * Examples: "\Process(java#0)", \Process(java#1"), ...
+ */
+ assert(instance);
+
+ fullCounterPathLen += strlen(instance);
+
+ fullCounterPath = malloc(fullCounterPathLen + 1);
+
+ if (!fullCounterPath) {
+ return NULL;
+ }
+
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ objectName,
+ imageName,
+ instance,
+ counterName);
+ } else {
+ if (instance) {
+ /*
+ * For paths where the Object has multiple instances.
+ *
+ * Examples:
+ * abstract: "\Object(instance)\Counter"
+ * actual: "\Processor(0)\% Privileged Time"
+ */
+ fullCounterPathLen += strlen(instance);
+ fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
+ } else {
+ /*
+ * For "normal" paths.
+ *
+ * Examples:
+ * abstract: "\Object\Counter"
+ * actual: "\Memory\Available Mbytes"
+ */
+ fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
+ }
+
+ fullCounterPath = malloc(fullCounterPathLen + 1);
+
+ if (!fullCounterPath) {
+ return NULL;
+ }
+
+ if (instance) {
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_WITH_INSTANCES_COUNTER_FMT,
+ objectName,
+ instance,
+ counterName);
+ } else {
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_COUNTER_FMT,
+ objectName,
+ counterName);
+ }
+ }
+
+ fullCounterPath[fullCounterPathLen] = '\0';
+
+ return fullCounterPath;
+}
+
+/*
+ * Resolves an index for a PDH artifact to
+ * a localized, malloc:ed string representation.
+ * Caller will own the returned malloc:ed string.
*
- * @param index the counter index as specified in the registry.
- * @param buf the buffer in which to place the counter name.
- * @param size the size of the counter name buffer.
- * @param ebuf the error message buffer.
- * @param elen the length of the error buffer.
- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
+ * @param pdhArtifactIndex PDH index
+ * @return malloc:ed string representation
+ * of the requested pdh artifact (localized).
+ * NULL on failure.
*/
+static const char*
+getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
+ char* pdhLocalizedArtifactString;
+
+ if (lookupNameByIndex(pdhArtifactIndex,
+ &pdhLocalizedArtifactString) != 0) {
+ return NULL;
+ }
+
+ return pdhLocalizedArtifactString;
+}
+
+static void
+pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
+ if (counter && *counter) {
+ PdhRemoveCounter_i(*counter);
+ *counter = NULL;
+ }
+ if (query && *query) {
+ PdhCloseQuery_i(*query);
+ *query = NULL;
+ }
+}
+
+static void
+destroySingleCounter(SingleCounterQueryP counterQuery) {
+ if (counterQuery) {
+ pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
+ }
+}
+
+static void
+destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
+ int i;
+ if (multiCounterQuery) {
+ if (multiCounterQuery->counters) {
+ for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
+ pdhCleanup(NULL, &multiCounterQuery->counters[i]);
+ }
+ free(multiCounterQuery->counters);
+ multiCounterQuery->counters = NULL;
+ }
+ pdhCleanup(&multiCounterQuery->query.query, NULL);
+ }
+}
+
static int
-find_name(DWORD index, char *buf, DWORD size) {
- PDH_STATUS res;
-
- if ((res = PdhLookupPerfNameByIndex_i(NULL, index, buf, &size)) != ERROR_SUCCESS) {
-
- /* printf("Could not open counter %d: error=0x%08x", index, res); */
- /* if (res == PDH_CSTATUS_NO_MACHINE) { */
- /* printf("User probably does not have sufficient privileges to use"); */
- /* printf("performance counters. If you are running on Windows 2003"); */
- /* printf("or Windows Vista, make sure the user is in the"); */
- /* printf("Performance Logs user group."); */
- /* } */
+openQuery(HQUERY* const query) {
+ assert(query);
+
+ if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
return -1;
}
- if (size == 0) {
- /* printf("Failed to get counter name for %d: empty string", index); */
+ return 0;
+}
+
+static int
+addCounter(HQUERY query,
+ const char* const fullCounterPath,
+ HCOUNTER* const counter) {
+
+ assert(fullCounterPath);
+ assert(counter);
+
+ if (PdhAddCounter_i(query,
+ fullCounterPath,
+ 0,
+ counter) != ERROR_SUCCESS) {
return -1;
}
- // windows vista does not null-terminate the string (allthough the docs says it will)
- buf[size - 1] = '\0';
- return CONFIG_SUCCESSFUL;
+ return 0;
}
-/**
+/*
* Sets up the supplied SingleCounterQuery to listen for the specified counter.
- * initPDH() must have been run prior to calling this function!
*
- * @param counterQuery the counter query to set up.
- * @param counterString the string specifying the path to the counter.
- * @param ebuf the error buffer.
- * @param elen the length of the error buffer.
- * @returns CONFIG_SUCCESSFUL if successful, negative on failure.
+ * @param counterQuery the counter query to set up.
+ * @param fullCounterPath the string specifying the full path to the counter.
+ * @returns 0 if successful, negative on failure.
*/
static int
-initSingleCounterQuery(SingleCounterQueryP counterQuery, char *counterString) {
- if (PdhOpenQuery_i(NULL, 0, &counterQuery->query.query) != ERROR_SUCCESS) {
- /* printf("Could not open query for %s", counterString); */
- return -1;
- }
- if (PdhAddCounter_i(counterQuery->query.query, counterString, 0, &counterQuery->counter) != ERROR_SUCCESS) {
- /* printf("Could not add counter %s for query", counterString); */
- if (counterQuery->counter != NULL) {
- PdhRemoveCounter_i(counterQuery->counter);
- }
- if (counterQuery->query.query != NULL) {
- PdhCloseQuery_i(counterQuery->query.query);
+initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
+ const char* const fullCounterPath) {
+ assert(counterQuery);
+ assert(fullCounterPath);
+
+ if (openQuery(&counterQuery->query.query) == 0) {
+ if (addCounter(counterQuery->query.query,
+ fullCounterPath,
+ &counterQuery->counter) == 0) {
+ return 0;
}
- memset(counterQuery, 0, sizeof(SingleCounterQueryS));
- return -1;
}
- return CONFIG_SUCCESSFUL;
+
+ return -1;
}
-/**
- * Sets up the supplied SingleCounterQuery to listen for the time spent
- * by the HotSpot process.
+/*
+ * Sets up a SingleCounterQuery
+ *
+ * param counter the counter query to set up.
+ * param localizedObject string representing the PDH object to query
+ * param localizedCounter string representing the PDH counter to query
+ * param processImageName if the counter query needs the process image name ("java")
+ * param instance if the counter has instances, this is the instance ("\Processor(0)\")
+ where 0 is the instance
+ * param firstSampleOnInit for counters that need two queries to yield their values,
+ the first query can be issued just after initialization
*
- * @param counterQuery the counter query to set up as a process counter.
- * @param ebuf the error buffer.
- * @param elen the length of the error buffer.
- * @returns CONFIG_SUCCESSFUL if successful, negative on failure.
+ * @returns 0 if successful, negative on failure.
*/
static int
-initProcLoadCounter(void) {
- char time[COUNTER_BUF_SIZE];
- char counter[COUNTER_BUF_SIZE*2];
+initializeSingleCounter(SingleCounterQueryP const counter,
+ const char* const localizedObject,
+ const char* const localizedCounter,
+ const char* const processImageName,
+ const char* const instance,
+ BOOL firstSampleOnInit) {
+ int retValue = -1;
+
+ const char* fullCounterPath = makeFullCounterPath(localizedObject,
+ localizedCounter,
+ processImageName,
+ instance);
+
+ if (fullCounterPath) {
+
+ assert(counter);
+
+ if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
+ /*
+ * According to the MSDN documentation, rate counters must be read twice:
+ *
+ * "Obtaining the value of rate counters such as Page faults/sec requires that
+ * PdhCollectQueryData be called twice, with a specific time interval between
+ * the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
+ * implement the waiting period between the two calls to PdhCollectQueryData."
+ *
+ * Take the first sample here already to allow for the next (first) "real" sample
+ * to succeed.
+ */
+ if (firstSampleOnInit) {
+ PdhCollectQueryData_i(counter->query.query);
+ }
- if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
- return -1;
+ retValue = 0;
+ }
+ free((char*)fullCounterPath);
}
- _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
- return initSingleCounterQuery(&cntProcLoad, counter);
+
+ return retValue;
+}
+
+static void
+perfInit(void) {
+ InitializePdhCriticalSection(&initializationLock);
}
static int
-initProcSystemLoadCounter(void) {
- char time[COUNTER_BUF_SIZE];
- char counter[COUNTER_BUF_SIZE*2];
+getProcessID() {
+ static int myPid = 0;
+ if (0 == myPid) {
+ myPid = _getpid();
+ }
+ return myPid;
+}
- if (find_name(PDH_PRIV_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
- return -1;
+/*
+ * Working against the Process object and it's related counters is inherently problematic
+ * when using the PDH API:
+ *
+ * For PDH, a process is not primarily identified by it's process id,
+ * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
+ * The really bad part is that this list is reset as soon as one process exits:
+ * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
+ *
+ * The PDH query api requires a process identifier to be submitted when registering
+ * a query, but as soon as the list resets, the query is invalidated (since the name
+ * changed).
+ *
+ * Solution:
+ * The #number identifier for a Process query can only decrease after process creation.
+ *
+ * Therefore we create an array of counter queries for all process object instances
+ * up to and including ourselves:
+ *
+ * Ex. we come in as third process instance (java#2), we then create and register
+ * queries for the following Process object instances:
+ * java#0, java#1, java#2
+ *
+ * currentQueryIndexForProcess() keeps track of the current "correct" query
+ * (in order to keep this index valid when the list resets from underneath,
+ * ensure to call getCurrentQueryIndexForProcess() before every query involving
+ * Process object instance data).
+ */
+static int
+currentQueryIndexForProcess(void) {
+ HQUERY tmpQuery = NULL;
+ HCOUNTER handleCounter = NULL;
+ int retValue = -1;
+
+ assert(pdhProcessImageName);
+ assert(pdhIDProcessCounterFmt);
+
+ if (openQuery(&tmpQuery) == 0) {
+ int index;
+
+ /* iterate over all instance indexes and try to find our own pid */
+ for (index = 0; index < INT_MAX; ++index) {
+ char fullIDProcessCounterPath[MAX_PATH];
+ PDH_FMT_COUNTERVALUE counterValue;
+ PDH_STATUS res;
+
+ _snprintf(fullIDProcessCounterPath,
+ MAX_PATH,
+ pdhIDProcessCounterFmt,
+ index);
+
+ if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
+ break;
+ }
+
+ res = PdhCollectQueryData_i(tmpQuery);
+
+ if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
+ break;
+ }
+
+ PdhGetFormattedCounterValue_i(handleCounter,
+ PDH_FMT_LONG,
+ NULL,
+ &counterValue);
+ /*
+ * This check seems to be needed for Win2k SMP boxes, since
+ * they for some reason don't return PDH_NO_DATA for non existing
+ * counters.
+ */
+ if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
+ break;
+ }
+
+ if ((LONG)getProcessID() == counterValue.longValue) {
+ retValue = index;
+ break;
+ }
+ }
}
- _snprintf(counter, sizeof(counter)-1, "%s\\%s", getProcessPDHHeader(), time);
- return initSingleCounterQuery(&cntProcSystemLoad, counter);
+
+ pdhCleanup(&tmpQuery, &handleCounter);
+
+ return retValue;
+}
+
+/*
+ * If successful, returns the #index corresponding to our PID
+ * as resolved by the pdh query:
+ * "\Process(java#index)\ID Process" (or localized equivalent)
+ *
+ * This function should be called before attempting to read
+ * from any Process related counter(s), and the return value
+ * is the index to be used for indexing an array of Process object query's:
+ *
+ * Example:
+ * processTotalCPULoad[currentQueryIndex].query
+ *
+ * Returns -1 on failure.
+ */
+static int
+getCurrentQueryIndexForProcess() {
+ int currentQueryIndex = currentQueryIndexForProcess();
+
+ assert(currentQueryIndex >= 0 &&
+ currentQueryIndex < numberOfJavaProcessesAtInitialization);
+
+ return currentQueryIndex;
}
-/**
- * Sets up the supplied MultipleCounterQuery to check on the processors.
- * (Comment: Refactor and prettify as with the the SingleCounter queries
- * if more MultipleCounterQueries are discovered.)
+/*
+ * Returns the PDH string identifying the current process image name.
+ * Use this name as a qualifier when getting counters from the PDH Process Object
+ * representing your process.
+
+ * Example:
+ * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
+ * image name.
+ *
+ * Please note that the process image name is not necessarily "java",
+ * hence the use of GetModuleFileName() to detect the process image name.
*
- * initPDH() must have been run prior to calling this function.
+ * @return the process image name to be used when retrieving
+ * PDH counters from the current process. The caller will
+ own the returned malloc:ed string. NULL if failure.
+ */
+static const char*
+getPdhProcessImageName() {
+ char moduleName[MAX_PATH];
+ char* processImageName;
+ char* dotPos;
+
+ // Find our module name and use it to extract the image name used by PDH
+ DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
+
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ return NULL;
+ }
+
+ if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
+ return NULL;
+ }
+
+ processImageName = strrchr(moduleName, '\\'); //drop path
+ processImageName++; //skip slash
+ dotPos = strrchr(processImageName, '.'); //drop .exe
+ dotPos[0] = '\0';
+
+ return allocateAndCopy(processImageName);
+}
+
+/*
+ * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
+ * TODO: Refactor and prettify as with the the SingleCounter queries
+ * if more MultipleCounterQueries are discovered/needed.
*
- * @param multiQuery a pointer to a MultipleCounterQueryS, will be filled in with
- * the necessary info to check the PDH processor counters.
- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
+ * @param multiCounterCPULoad a pointer to a MultipleCounterQueryS, will be filled in with
+ * the necessary info to check the PDH processor counters.
+ * @return 0 if successful, negative on failure.
*/
static int
-initProcessorCounters(void) {
- char processor[COUNTER_BUF_SIZE]; //'Processor' == #238
- char time[COUNTER_BUF_SIZE]; //'Time' == 6
- DWORD c_size, i_size;
- HQUERY tmpQuery;
- DWORD i, p_count;
- BOOL error;
- char *instances, *tmp;
+initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
+ DWORD cSize = 0;
+ DWORD iSize = 0;
+ DWORD pCount;
+ DWORD index;
+ char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
+ char* time = NULL; //'Time' == PDH_PROCESSOR_TIME_IDX
+ char* instances = NULL;
+ char* tmp;
+ int retValue = -1;
PDH_STATUS pdhStat;
- c_size = i_size = 0;
- tmpQuery = NULL;
- error = false;
-
- // This __try / __except stuff is there since Windows 2000 beta (or so) sometimes triggered
- // an access violation when the user had insufficient privileges to use the performance
- // counters. This was previously guarded by a very ugly piece of code which disabled the
- // global trap handling in JRockit. Don't know if this really is needed anymore, but otoh,
- // if we keep it we don't crash on Win2k beta. /Ihse, 2005-05-30
- __try {
- if (find_name(PDH_PROCESSOR_IDX, processor, sizeof(processor)-1) < 0) {
- return -1;
- }
- } __except (EXCEPTION_EXECUTE_HANDLER) { // We'll catch all exceptions here.
- /* printf("User does not have sufficient privileges to use performance counters"); */
- return -1;
+ if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
+ goto end;
}
- if (find_name(PDH_PROCESSOR_TIME_IDX, time, sizeof(time)-1) < 0) {
- return -1;
+ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
+ goto end;
}
+
//ok, now we have enough to enumerate all processors.
- pdhStat = PdhEnumObjectItems_i (
- NULL, // reserved
- NULL, // local machine
- processor, // object to enumerate
- NULL, // pass in NULL buffers
- &c_size, // and 0 length to get
- NULL, // required size
- &i_size, // of the buffers in chars
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
- if (pdh_fail(pdhStat)) {
- /* printf("could not enumerate processors (1) error=%d", pdhStat); */
- return -1;
+ pdhStat = PdhEnumObjectItems_i(
+ NULL, // reserved
+ NULL, // local machine
+ processor, // object to enumerate
+ NULL, // pass in NULL buffers
+ &cSize, // and 0 length to get
+ NULL, // required size
+ &iSize, // of the buffers in chars
+ PERF_DETAIL_WIZARD, // counter detail level
+ 0);
+
+ if (pdhFail(pdhStat)) {
+ goto end;
}
- // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
- instances = calloc(i_size, 1);
- if (instances == NULL) {
- /* printf("could not allocate memory (1) %d bytes", i_size); */
- error = true;
+ instances = calloc(iSize, 1);
+
+ if (!instances) {
goto end;
}
- c_size = 0;
- pdhStat = PdhEnumObjectItems_i (
- NULL, // reserved
- NULL, // local machine
- processor, // object to enumerate
- NULL, // pass in NULL buffers
- &c_size, // and 0 length to get
- instances, // required size
- &i_size, // of the buffers in chars
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
-
- if (pdh_fail(pdhStat)) {
- /* printf("could not enumerate processors (2) error=%d", pdhStat); */
- error = true;
+ cSize = 0;
+
+ pdhStat = PdhEnumObjectItems_i(
+ NULL, // reserved
+ NULL, // local machine
+ processor, // object to enumerate
+ NULL, // pass in NULL buffers
+ &cSize,
+ instances, // now allocated to be filled in
+ &iSize, // and size is known
+ PERF_DETAIL_WIZARD, // counter detail level
+ 0);
+
+ if (pdhFail(pdhStat)) {
goto end;
}
- //count perf count instances.
- for (p_count = 0, tmp = instances; *tmp != 0; tmp = &tmp[lstrlen(tmp)+1], p_count++);
- //is this correct for HT?
- assert(p_count == num_cpus+1);
+ // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
+ for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);
+
+ assert(pCount == numCpus+1);
- //ok, have number of perf counters.
- multiCounterCPULoad.counters = calloc(p_count, sizeof(HCOUNTER));
- if (multiCounterCPULoad.counters == NULL) {
- /* printf("could not allocate memory (2) count=%d", p_count); */
- error = true;
+ //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
+ multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));
+
+ if (!multiCounterCPULoad->counters) {
goto end;
}
- multiCounterCPULoad.noOfCounters = p_count;
+ multiCounterCPULoad->noOfCounters = pCount;
- if (PdhOpenQuery_i(NULL, 0, &multiCounterCPULoad.query.query) != ERROR_SUCCESS) {
- /* printf("could not create query"); */
- error = true;
+ if (openQuery(&multiCounterCPULoad->query.query) != 0) {
goto end;
}
- //now, fetch the counters.
- for (i = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[lstrlen(tmp)+1], i++) {
- char counter[2*COUNTER_BUF_SIZE];
- _snprintf(counter, sizeof(counter)-1, "\\%s(%s)\\%s", processor, tmp, time);
+ // fetch instance and register its corresponding HCOUNTER with the query
+ for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
+ const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);
- if (PdhAddCounter_i(multiCounterCPULoad.query.query, counter, 0, &multiCounterCPULoad.counters[i]) != ERROR_SUCCESS) {
- /* printf("error adding processor counter %s", counter); */
- error = true;
+ if (!fullCounterPath) {
goto end;
}
- }
- free(instances);
- instances = NULL;
+ retValue = addCounter(multiCounterCPULoad->query.query,
+ fullCounterPath,
+ &multiCounterCPULoad->counters[index]);
- // Query once to initialize the counters needing at least two queries
+ free((char*)fullCounterPath);
+
+ if (retValue != 0) {
+ goto end;
+ }
+ }
+
+ // Query once to initialize the counters which require at least two samples
// (like the % CPU usage) to calculate correctly.
- if (PdhCollectQueryData_i(multiCounterCPULoad.query.query) != ERROR_SUCCESS)
- error = true;
+ PdhCollectQueryData_i(multiCounterCPULoad->query.query);
- end:
- if (instances != NULL) {
- free(instances);
+ end:
+ if (processor) {
+ free(processor);
}
- if (tmpQuery != NULL) {
- PdhCloseQuery_i(tmpQuery);
+
+ if (time) {
+ free(time);
}
- if (error) {
- int i;
- if (multiCounterCPULoad.counters != NULL) {
- for (i = 0; i < multiCounterCPULoad.noOfCounters; i++) {
- if (multiCounterCPULoad.counters[i] != NULL) {
- PdhRemoveCounter_i(multiCounterCPULoad.counters[i]);
- }
- }
- free(multiCounterCPULoad.counters[i]);
- }
- if (multiCounterCPULoad.query.query != NULL) {
- PdhCloseQuery_i(multiCounterCPULoad.query.query);
- }
- memset(&multiCounterCPULoad, 0, sizeof(MultipleCounterQueryS));
- return -1;
+ if (instances) {
+ free(instances);
}
- return CONFIG_SUCCESSFUL;
+
+ return retValue;
}
-/**
- * Help function that initializes the PDH process header for the JRockit process.
- * (You should probably use getProcessPDHHeader() instead!)
- *
- * initPDH() must have been run prior to calling this function.
+/*
+ * Dynamically sets up function pointers to the PDH library.
*
- * @param ebuf the error buffer.
- * @param elen the length of the error buffer.
+ * @param h HMODULE for the PDH library
+ * @return 0 on success, negative on failure.
+ */
+static int
+bindPdhFunctionPointers(HMODULE h) {
+ assert(h);
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
+ PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
+ PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
+ PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
+ PdhCollectQueryData_i = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
+ PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
+ PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
+ PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
+ PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
+
+ if (!PdhAddCounter_i || !PdhOpenQuery_i ||
+ !PdhCloseQuery_i || !PdhCollectQueryData_i ||
+ !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
+ !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Returns the counter value as a double for the specified query.
+ * Will collect the query data and update the counter values as necessary.
*
- * @return the PDH instance description corresponding to the JVM process.
+ * @param query the query to update (if needed).
+ * @param c the counter to read.
+ * @param value where to store the formatted value.
+ * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
+ * @return 0 if no error
+ * -1 if PdhCollectQueryData fails
+ * -2 if PdhGetFormattedCounterValue fails
*/
-static char*
-initProcessPDHHeader(void) {
- static char hotspotheader[2*COUNTER_BUF_SIZE];
-
- char counter[2*COUNTER_BUF_SIZE];
- char processes[COUNTER_BUF_SIZE]; //'Process' == #230
- char pid[COUNTER_BUF_SIZE]; //'ID Process' == 784
- char module_name[MAX_PATH];
- PDH_STATUS pdhStat;
- DWORD c_size = 0, i_size = 0;
- HQUERY tmpQuery = NULL;
- int i, myPid = _getpid();
- BOOL error = false;
- char *instances, *tmp, *instance_name, *dot_pos;
-
- tmpQuery = NULL;
- myPid = _getpid();
- error = false;
-
- if (find_name(PDH_PROCESS_IDX, processes, sizeof(processes) - 1) < 0) {
- return NULL;
+static int
+getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
+ clock_t now = clock();
+
+ /*
+ * Need to limit how often we update the query
+ * to minimize the Heisenberg effect.
+ * (PDH behaves erratically if the counters are
+ * queried too often, especially counters that
+ * store and use values from two consecutive updates,
+ * like cpu load.)
+ */
+ if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
+ if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
+ return -1;
+ }
+ query->lastUpdate = now;
}
- if (find_name(PDH_ID_PROCESS_IDX, pid, sizeof(pid) - 1) < 0) {
- return NULL;
+ if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
+ return -2;
}
- //time is same.
-
- c_size = 0;
- i_size = 0;
-
- pdhStat = PdhEnumObjectItems_i (
- NULL, // reserved
- NULL, // local machine
- processes, // object to enumerate
- NULL, // pass in NULL buffers
- &c_size, // and 0 length to get
- NULL, // required size
- &i_size, // of the buffers in chars
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
-
- //ok, now we have enough to enumerate all processes
- if (pdh_fail(pdhStat)) {
- /* printf("Could not enumerate processes (1) error=%d", pdhStat); */
- return NULL;
+
+ return 0;
+}
+
+static int
+allocateAndInitializePdhConstants() {
+ const char* pdhLocalizedProcessObject = NULL;
+ const char* pdhLocalizedIDProcessCounter = NULL;
+ size_t pdhIDProcessCounterFmtLen;
+ int currentQueryIndex;
+ int retValue = -1;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ assert(!pdhProcessImageName);
+ pdhProcessImageName = getPdhProcessImageName();
+ if (!pdhProcessImageName) {
+ goto end;
+ }
+
+ pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
+ if (!pdhLocalizedProcessObject) {
+ goto end;
}
- // use calloc because windows vista does not null terminate the instance names (allthough the docs says it will)
- if ((instances = calloc(i_size, 1)) == NULL) {
- /* printf("Could not allocate memory %d bytes", i_size); */
- error = true;
+ pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
+ if (!pdhLocalizedIDProcessCounter) {
goto end;
}
- c_size = 0;
+ assert(!pdhIDProcessCounterFmt);
- pdhStat = PdhEnumObjectItems_i (
- NULL, // reserved
- NULL, // local machine
- processes, // object to enumerate
- NULL, // pass in NULL buffers
- &c_size, // and 0 length to get
- instances, // required size
- &i_size, // of the buffers in chars
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
+ pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
+ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
+ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
+ pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+ pdhIDProcessCounterFmtLen += 2; // "%d"
- // ok, now we have enough to enumerate all processes
- if (pdh_fail(pdhStat)) {
- /* printf("Could not enumerate processes (2) error=%d", pdhStat); */
- error = true;
+ assert(pdhIDProcessCounterFmtLen < MAX_PATH);
+ pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
+ if (!pdhIDProcessCounterFmt) {
goto end;
}
- if (PdhOpenQuery_i(NULL, 0, &tmpQuery) != ERROR_SUCCESS) {
- /* printf("Could not create temporary query"); */
- error = true;
+ /* "\Process(java#%d)\ID Process" */
+ _snprintf(pdhIDProcessCounterFmt,
+ pdhIDProcessCounterFmtLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ pdhLocalizedProcessObject,
+ pdhProcessImageName,
+ "%d",
+ pdhLocalizedIDProcessCounter);
+
+ pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
+
+ assert(0 == numberOfJavaProcessesAtInitialization);
+ currentQueryIndex = currentQueryIndexForProcess();
+ if (-1 == currentQueryIndex) {
goto end;
}
- // Find our module name and use it to extract the instance name used by PDH
- if (GetModuleFileName(NULL, module_name, MAX_PATH) >= MAX_PATH-1) {
- /* printf("Module name truncated"); */
- error = true;
- goto end;
+ numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
+ assert(numberOfJavaProcessesAtInitialization >= 1);
+
+ retValue = 0;
+
+ end:
+
+ if (pdhLocalizedProcessObject) {
+ free((char*)pdhLocalizedProcessObject);
}
- instance_name = strrchr(module_name, '\\'); //drop path
- instance_name++; //skip slash
- dot_pos = strchr(instance_name, '.'); //drop .exe
- dot_pos[0] = '\0';
- //now, fetch the counters.
- for (tmp = instances; *tmp != 0 && !error; tmp = &tmp[lstrlen(tmp)+1]) {
- HCOUNTER hc = NULL;
- BOOL done = false;
+ if (pdhLocalizedIDProcessCounter) {
+ free((char*)pdhLocalizedIDProcessCounter);
+ }
- // Skip until we find our own process name
- if (strcmp(tmp, instance_name) != 0) {
- continue;
- }
+ return retValue;
+}
- // iterate over all instance indexes and try to find our own pid
- for (i = 0; !done && !error; i++){
- PDH_STATUS res;
- _snprintf(counter, sizeof(counter)-1, "\\%s(%s#%d)\\%s", processes, tmp, i, pid);
+static void
+deallocatePdhConstants() {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
- if (PdhAddCounter_i(tmpQuery, counter, 0, &hc) != ERROR_SUCCESS) {
- /* printf("Failed to create process id query"); */
- error = true;
- goto end;
- }
+ if (pdhProcessImageName) {
+ free((char*)pdhProcessImageName);
+ pdhProcessImageName = NULL;
+ }
- res = PdhCollectQueryData_i(tmpQuery);
+ if (pdhIDProcessCounterFmt) {
+ free(pdhIDProcessCounterFmt);
+ pdhIDProcessCounterFmt = NULL;
+ }
- if (res == PDH_INVALID_HANDLE) {
- /* printf("Failed to query process id"); */
- res = -1;
- done = true;
- } else if (res == PDH_NO_DATA) {
- done = true;
- } else {
- PDH_FMT_COUNTERVALUE cv;
-
- PdhGetFormattedCounterValue_i(hc, PDH_FMT_LONG, NULL, &cv);
- /*
- * This check seems to be needed for Win2k SMP boxes, since
- * they for some reason don't return PDH_NO_DATA for non existing
- * counters.
- */
- if (cv.CStatus != PDH_CSTATUS_VALID_DATA) {
- done = true;
- } else if (cv.longValue == myPid) {
- _snprintf(hotspotheader, sizeof(hotspotheader)-1, "\\%s(%s#%d)\0", processes, tmp, i);
- PdhRemoveCounter_i(hc);
- goto end;
+ numberOfJavaProcessesAtInitialization = 0;
+}
+
+static int
+initializeCPUCounters() {
+ SYSTEM_INFO si;
+ char* localizedProcessObject;
+ char* localizedProcessorTimeCounter;
+ int i;
+ int retValue = -1;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ assert(0 == numCpus);
+ GetSystemInfo(&si);
+ numCpus = si.dwNumberOfProcessors;
+ assert(numCpus >= 1);
+
+ /* Initialize the denominator for the jvm load calculations */
+ assert(.0 == cpuFactor);
+ cpuFactor = numCpus * 100;
+
+ if (lookupNameByIndex(PDH_PROCESS_IDX,
+ &localizedProcessObject) == 0) {
+
+ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
+ &localizedProcessorTimeCounter) == 0) {
+
+ assert(processTotalCPULoad);
+ assert(pdhProcessImageName);
+
+ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+ char instanceIndexBuffer[32];
+ retValue = initializeSingleCounter(&processTotalCPULoad[i],
+ localizedProcessObject,
+ localizedProcessorTimeCounter,
+ pdhProcessImageName,
+ itoa(i, instanceIndexBuffer, 10),
+ TRUE);
+ if (retValue != 0) {
+ break;
}
}
- PdhRemoveCounter_i(hc);
+ free(localizedProcessorTimeCounter);
}
+ free(localizedProcessObject);
}
- end:
- if (instances != NULL) {
- free(instances);
+
+ if (retValue != 0) {
+ return -1;
}
- if (tmpQuery != NULL) {
- PdhCloseQuery_i(tmpQuery);
+
+ assert(multiCounterCPULoad);
+ return initializeMultipleCounterForCPUs(multiCounterCPULoad);
+}
+
+static void
+deallocateCPUCounters() {
+ int i;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ if (processTotalCPULoad) {
+ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+ destroySingleCounter(&processTotalCPULoad[i]);
+ }
+ free(processTotalCPULoad);
+ processTotalCPULoad = NULL;
}
- if (error) {
- return NULL;
+
+ if (multiCounterCPULoad) {
+ destroyMultiCounter(multiCounterCPULoad);
+ free(multiCounterCPULoad);
+ multiCounterCPULoad = NULL;
}
- return hotspotheader;
+
+ cpuFactor = .0;
+ numCpus = 0;
}
-/**
- * Returns the PDH string prefix identifying the HotSpot process. Use this prefix when getting
- * counters from the PDH process object representing HotSpot.
- *
- * Note: this call may take some time to complete.
- *
- * @param ebuf error buffer.
- * @param elen error buffer length.
+static void
+pdhInitErrorHandler(HMODULE h) {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ deallocatePdhConstants();
+
+ if (h) {
+ FreeLibrary(h);
+ }
+}
+
+/*
+ * Helper to initialize the PDH library, function pointers and constants.
*
- * @return the header to be used when retrieving PDH counters from the HotSpot process.
- * Will return NULL if the call failed.
+ * @return 0 if successful, negative on failure.
*/
-static char *
-getProcessPDHHeader(void) {
- static char *processHeader = NULL;
+static int
+pdhInit() {
+ static BOOL initialized = FALSE;
+ int retValue;
+
+ if (initialized) {
+ return 0;
+ }
+
+ retValue = 0;
+
+ EnterPdhCriticalSection(&initializationLock); {
+ if (!initialized) {
+ HMODULE h = NULL;
+ if ((h = LoadLibrary("pdh.dll")) == NULL) {
+ retValue = -1;
+ } else if (bindPdhFunctionPointers(h) < 0) {
+ retValue = -1;
+ } else if (allocateAndInitializePdhConstants() < 0) {
+ retValue = -1;
+ }
- EnterCriticalSection(&processHeaderLock); {
- if (processHeader == NULL) {
- processHeader = initProcessPDHHeader();
+ if (0 == retValue) {
+ initialized = TRUE;
+ } else {
+ pdhInitErrorHandler(h);
+ }
}
- } LeaveCriticalSection(&processHeaderLock);
- return processHeader;
+ } LeavePdhCriticalSection(&initializationLock);
+
+ return retValue;
}
-int perfInit(void);
+static int
+allocateCPUCounters() {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+ assert(numberOfJavaProcessesAtInitialization >= 1);
+ assert(!processTotalCPULoad);
+ assert(!multiCounterCPULoad);
+
+ /*
+ * Create an array of Process object queries, for each instance
+ * up to and including our own (java#0, java#1, java#2, ...).
+ */
+ processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
+ sizeof(SingleCounterQueryS));
+
+ if (!processTotalCPULoad) {
+ return -1;
+ }
-double
-perfGetCPULoad(int which)
-{
- PDH_FMT_COUNTERVALUE cv;
- HCOUNTER c;
+ multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));
- if (perfInit() < 0) {
- // warn?
- return -1.0;
+ if (!multiCounterCPULoad) {
+ return -1;
}
- if (multiCounterCPULoad.query.query == NULL) {
- // warn?
- return -1.0;
+ return 0;
+}
+
+static int
+initializePdhCPUCounters() {
+ static BOOL initialized = FALSE;
+ int retValue;
+
+ if (initialized) {
+ return 0;
}
- if (which == -1) {
- c = multiCounterCPULoad.counters[multiCounterCPULoad.noOfCounters - 1];
- } else {
- if (which < multiCounterCPULoad.noOfCounters) {
- c = multiCounterCPULoad.counters[which];
- } else {
- return -1.0;
+ retValue = 0;
+
+ EnterPdhCriticalSection(&initializationLock); {
+ if (!initialized) {
+ if (pdhInit() < 0) {
+ retValue = -1;
+ } else if (allocateCPUCounters() < 0) {
+ retValue = -1;
+ } else if (initializeCPUCounters() < 0) {
+ retValue = -1;
+ }
+
+ if (0 == retValue) {
+ initialized = TRUE;
+ } else {
+ deallocateCPUCounters();
+ }
}
- }
- if (getPerformanceData(&multiCounterCPULoad.query, c, &cv, PDH_FMT_DOUBLE ) == CONFIG_SUCCESSFUL) {
- return cv.doubleValue / 100;
- }
- return -1.0;
+ } LeavePdhCriticalSection(&initializationLock);
+
+ return retValue;
}
-double
-perfGetProcessLoad(void)
-{
+static int
+perfCPUInit() {
+ return initializePdhCPUCounters();
+}
+
+static double
+perfGetProcessCPULoad() {
PDH_FMT_COUNTERVALUE cv;
+ int currentQueryIndex;
- if (perfInit() < 0) {
+ if (perfCPUInit() < 0) {
// warn?
return -1.0;
}
- if (cntProcLoad.query.query == NULL) {
- // warn?
- return -1.0;
- }
+ currentQueryIndex = getCurrentQueryIndexForProcess();
- if (getPerformanceData(&cntProcLoad.query, cntProcLoad.counter, &cv, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == CONFIG_SUCCESSFUL) {
+ if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
+ processTotalCPULoad[currentQueryIndex].counter,
+ &cv,
+ PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
double d = cv.doubleValue / cpuFactor;
d = min(1, d);
d = max(0, d);
@@ -860,70 +1323,29 @@ perfGetProcessLoad(void)
return -1.0;
}
-/**
- * Helper to initialize the PDH library. Loads the library and sets up the functions.
- * Note that once loaded, we will never unload the PDH library.
- *
- * @return CONFIG_SUCCESSFUL if successful, negative on failure.
- */
-int
-perfInit(void) {
- static HMODULE h;
- static BOOL running, inited;
-
- int error;
+static double
+perfGetCPULoad(int which) {
+ PDH_FMT_COUNTERVALUE cv;
+ HCOUNTER c;
- if (running) {
- return CONFIG_SUCCESSFUL;
+ if (perfCPUInit() < 0) {
+ // warn?
+ return -1.0;
}
- error = CONFIG_SUCCESSFUL;
-
- // this is double checked locking again, but we try to bypass the worst by
- // implicit membar at end of lock.
- EnterCriticalSection(&initializationLock); {
- if (!inited) {
- char buf[64] = "";
- SYSTEM_INFO si;
-
- // CMH. But windows will not care about our affinity when giving
- // us measurements. Need the real, raw num cpus.
-
- GetSystemInfo(&si);
- num_cpus = si.dwNumberOfProcessors;
- // Initialize the denominator for the jvm load calculations
- cpuFactor = num_cpus * 100;
-
- /**
- * Do this dynamically, so we don't fail to start on systems without pdh.
- */
- if ((h = LoadLibrary("pdh.dll")) == NULL) {
- /* printf("Could not load pdh.dll (%d)", GetLastError()); */
- error = -2;
- } else if (get_functions(h, buf, sizeof(buf)) < 0) {
- FreeLibrary(h);
- h = NULL;
- error = -2;
- /* printf("Failed to init pdh functions: %s.\n", buf); */
- } else {
- if (initProcessorCounters() != 0) {
- /* printf("Failed to init system load counters.\n"); */
- } else if (initProcLoadCounter() != 0) {
- /* printf("Failed to init process load counter.\n"); */
- } else if (initProcSystemLoadCounter() != 0) {
- /* printf("Failed to init process system load counter.\n"); */
- } else {
- inited = true;
- }
- }
+ if (-1 == which) {
+ c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
+ } else {
+ if (which < multiCounterCPULoad->noOfCounters) {
+ c = multiCounterCPULoad->counters[which];
+ } else {
+ return -1.0;
}
- } LeaveCriticalSection(&initializationLock);
-
- if (inited && error == CONFIG_SUCCESSFUL) {
- running = true;
}
-
- return error;
+ if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
+ return cv.doubleValue / 100;
+ }
+ return -1.0;
}
JNIEXPORT jdouble JNICALL
@@ -937,5 +1359,5 @@ JNIEXPORT jdouble JNICALL
Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0
(JNIEnv *env, jobject dummy)
{
- return perfGetProcessLoad();
+ return perfGetProcessCPULoad();
}
diff --git a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c
index b56608a8f57..2696483f730 100644
--- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c
+++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_crypt.c
@@ -141,8 +141,8 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckEncryptedPartLen);
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
ckAssertReturnValueOK(env, rv);
return ckEncryptedPartLen;
@@ -214,7 +214,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
}
if (directOut == 0) {
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
@@ -266,7 +266,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
//printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
if (directOut == 0) {
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
@@ -361,8 +361,8 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckPartLen);
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
ckAssertReturnValueOK(env, rv);
@@ -429,7 +429,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
}
if (directOut == 0) {
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
@@ -478,7 +478,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
&ckLastPartLen);
if (directOut == 0) {
- (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java
index 286c05136ab..a2436e587e1 100644
--- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java
+++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java
@@ -294,11 +294,11 @@ public final class KeychainStore extends KeyStoreSpi {
if (entry instanceof TrustedCertEntry) {
return ((TrustedCertEntry)entry).cert;
} else {
- if (((KeyEntry)entry).chain == null) {
+ KeyEntry ke = (KeyEntry)entry;
+ if (ke.chain == null || ke.chain.length == 0) {
return null;
- } else {
- return ((KeyEntry)entry).chain[0];
}
+ return ke.chain[0];
}
} else {
return null;
@@ -618,10 +618,12 @@ public final class KeychainStore extends KeyStoreSpi {
Object entry = entries.get(alias);
if (entry instanceof TrustedCertEntry) {
certElem = ((TrustedCertEntry)entry).cert;
- } else if (((KeyEntry)entry).chain != null) {
- certElem = ((KeyEntry)entry).chain[0];
} else {
- continue;
+ KeyEntry ke = (KeyEntry)entry;
+ if (ke.chain == null || ke.chain.length == 0) {
+ continue;
+ }
+ certElem = ke.chain[0];
}
if (certElem.equals(cert)) {
return alias;
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m b/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m
index 1e26771eb1a..2fe5c4bb79e 100644
--- a/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m
+++ b/jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -279,7 +279,8 @@ static void addIdentitiesToKeystore(JNIEnv *env, jobject keyStore)
// Search the user keychain list for all identities. Identities are a certificate/private key association that
// can be chosen for a purpose such as signing or an SSL connection.
SecIdentitySearchRef identitySearch = NULL;
- OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_ANY, &identitySearch);
+ // Pass 0 if you want all identities returned by this search
+ OSStatus err = SecIdentitySearchCreate(NULL, 0, &identitySearch);
SecIdentityRef theIdentity = NULL;
OSErr searchResult = noErr;
diff --git a/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java b/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java
index 7e2e8beea86..ad5603d2eb8 100644
--- a/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java
+++ b/jdk/src/jdk.runtime/share/classes/sun/security/tools/policytool/PolicyTool.java
@@ -1400,7 +1400,13 @@ class ToolWindow extends JFrame {
if (t instanceof NoDisplayException) {
return;
}
- displayErrorDialog(w, t.toString());
+ if (t.getClass() == Exception.class) {
+ // Exception is usually thrown inside policytool for user
+ // interaction error. There is no need to show the type.
+ displayErrorDialog(w, t.getLocalizedMessage());
+ } else {
+ displayErrorDialog(w, t.toString());
+ }
}
/**
diff --git a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
index ba507479e02..092416eff3e 100644
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
@@ -46,8 +46,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
public class LdapTimeoutTest {
- private static final ScheduledExecutorService pool =
- Executors.newScheduledThreadPool(1);
+
static volatile int passed = 0, failed = 0;
static void pass() {passed++;}
static void fail() {failed++; Thread.dumpStack();}
@@ -80,7 +79,6 @@ public class LdapTimeoutTest {
new LdapTimeoutTest().simpleAuthConnectTest(env);
} finally {
s.interrupt();
- LdapTimeoutTest.pool.shutdown();
}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
@@ -90,7 +88,6 @@ public class LdapTimeoutTest {
void ldapReadTimeoutTest(Hashtable env, boolean ssl) {
InitialContext ctx = null;
if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl");
- ScheduledFuture killer = killSwitch(5_000);
long start = System.nanoTime();
try {
ctx = new InitialDirContext(env);
@@ -112,13 +109,12 @@ public class LdapTimeoutTest {
pass();
}
} finally {
- if (!shutItDown(killer, ctx)) fail();
+ if (!shutItDown(ctx)) fail();
}
}
void simpleAuthConnectTest(Hashtable env) {
InitialContext ctx = null;
- ScheduledFuture killer = killSwitch(5_000);
long start = System.nanoTime();
try {
ctx = new InitialDirContext(env);
@@ -141,13 +137,12 @@ public class LdapTimeoutTest {
fail();
}
} finally {
- if (!shutItDown(killer, ctx)) fail();
+ if (!shutItDown(ctx)) fail();
}
}
void deadServerNoTimeout(Hashtable env) {
InitialContext ctx = null;
- ScheduledFuture killer = killSwitch(30_000);
long start = System.currentTimeMillis();
try {
ctx = new InitialDirContext(env);
@@ -169,12 +164,11 @@ public class LdapTimeoutTest {
pass();
}
} finally {
- if (!shutItDown(killer, ctx)) fail();
+ if (!shutItDown(ctx)) fail();
}
}
- boolean shutItDown(ScheduledFuture killer, InitialContext ctx) {
- killer.cancel(true);
+ boolean shutItDown(InitialContext ctx) {
try {
if (ctx != null) ctx.close();
return true;
@@ -183,17 +177,6 @@ public class LdapTimeoutTest {
}
}
- ScheduledFuture killSwitch(int ms) {
- final Thread current = Thread.currentThread();
- return LdapTimeoutTest.pool.schedule(new Callable<Void>() {
- public Void call() throws Exception {
- System.err.println("Fail: killSwitch()");
- System.exit(0);
- return null;
- }
- }, ms, MILLISECONDS);
- }
-
static class Server extends Thread {
final ServerSocket serverSock;
diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java
new file mode 100644
index 00000000000..95c50f326c4
--- /dev/null
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDoubleVMOption.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014, 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 8061616
+ * @summary Basic Test for HotSpotDiagnosticMXBean.getVMOption() and double values
+ * @author Jaroslav Bachorik
+ *
+ * @run main/othervm -XX:CompileThresholdScaling=0.14 GetDoubleVMOption
+ */
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import javax.management.MBeanServer;
+
+public class GetDoubleVMOption {
+ private static final String COMPILE_THRESHOLD_SCALING = "CompileThresholdScaling";
+ private static final String EXPECTED_VALUE = "0.14";
+ private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=HotSpotDiagnostic";
+
+ public static void main(String[] args) throws Exception {
+ List<HotSpotDiagnosticMXBean> list =
+ ManagementFactory.getPlatformMXBeans(HotSpotDiagnosticMXBean.class);
+ HotSpotDiagnosticMXBean mbean = list.get(0);
+ checkVMOption(mbean);
+
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
+ HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
+ HotSpotDiagnosticMXBean.class);
+ checkVMOption(mbean);
+ }
+
+ private static void checkVMOption(HotSpotDiagnosticMXBean mbean) {
+ VMOption option = mbean.getVMOption(COMPILE_THRESHOLD_SCALING);
+ if (!option.getValue().equalsIgnoreCase(EXPECTED_VALUE)) {
+ throw new RuntimeException("Unexpected value: " +
+ option.getValue() + " expected: " + EXPECTED_VALUE);
+ }
+ }
+}
diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java
index 14976e0dfd6..f00c7916d9a 100644
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetVMOption.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,16 +32,15 @@
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
-import com.sun.management.VMOption.Origin;
import java.lang.management.ManagementFactory;
import java.util.List;
import javax.management.MBeanServer;
public class GetVMOption {
- private static String PRINT_GC_DETAILS = "PrintGCDetails";
- private static String EXPECTED_VALUE = "true";
- private static String BAD_OPTION = "BadOption";
- private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ private static final String PRINT_GC_DETAILS = "PrintGCDetails";
+ private static final String EXPECTED_VALUE = "true";
+ private static final String BAD_OPTION = "BadOption";
+ private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=HotSpotDiagnostic";
public static void main(String[] args) throws Exception {
diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java
index 04e2cae1b60..1e2b807c3d5 100644
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/SetVMOption.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,11 +39,11 @@ import com.sun.management.VMOption;
import com.sun.management.VMOption.Origin;
public class SetVMOption {
- private static String PRINT_GC_DETAILS = "PrintGCDetails";
- private static String EXPECTED_VALUE = "true";
- private static String BAD_VALUE = "yes";
- private static String NEW_VALUE = "false";
- private static String MANAGEMENT_SERVER = "ManagementServer";
+ private static final String PRINT_GC_DETAILS = "PrintGCDetails";
+ private static final String EXPECTED_VALUE = "true";
+ private static final String BAD_VALUE = "yes";
+ private static final String NEW_VALUE = "false";
+ private static final String MANAGEMENT_SERVER = "ManagementServer";
private static HotSpotDiagnosticMXBean mbean;
public static void main(String[] args) throws Exception {
diff --git a/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html
new file mode 100644
index 00000000000..41944bc31eb
--- /dev/null
+++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html
@@ -0,0 +1,21 @@
+<html>
+<!--
+ @test
+ @bug 4051487 4145670
+ @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
+ while it is being created does not crash the VM.
+ @author dpm area=Threads
+ @run applet/timeout=7200 DisposeStressTest.html
+ -->
+<head>
+<title>DisposeStressTest</title>
+</head>
+<body>
+
+<h1>DisposeStressTest<br>Bug ID: 4051487, 4145670</h1>
+
+<p> This is an AUTOMATIC test, simply wait for completion </p>
+
+<APPLET CODE="DisposeStressTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
diff --git a/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java
new file mode 100644
index 00000000000..7e13bc3e3ba
--- /dev/null
+++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014, 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 4051487 4145670 8062021
+ @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
+ while it is being created does not crash the VM.
+ @author dpm area=Threads
+ @run applet/timeout=7200 DisposeStressTest.html
+*/
+
+// Note there is no @ in front of test above. This is so that the
+// harness will not mistake this file as a test file. It should
+// only see the html file as a test file. (the harness runs all
+// valid test files, so it would run this test twice if this file
+// were valid as well as the html file.)
+// Also, note the area= after Your Name in the author tag. Here, you
+// should put which functional area the test falls in. See the
+// AWT-core home page -> test areas and/or -> AWT team for a list of
+// areas.
+// Note also the 'DisposeStressTest.html' in the run tag. This should
+// be changed to the name of the test.
+
+
+/**
+ * DisposeStressTest.java
+ *
+ * summary:
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+
+
+//Automated tests should run as applet tests if possible because they
+// get their environments cleaned up, including AWT threads, any
+// test created threads, and any system resources used by the test
+// such as file descriptors. (This is normally not a problem as
+// main tests usually run in a separate VM, however on some platforms
+// such as the Mac, separate VMs are not possible and non-applet
+// tests will cause problems). Also, you don't have to worry about
+// synchronisation stuff in Applet tests they way you do in main
+// tests...
+
+
+public class DisposeStressTest extends Applet
+ {
+ //Declare things used in the test, like buttons and labels here
+
+ public void init()
+ {
+ //Create instructions for the user here, as well as set up
+ // the environment -- set the layout manager, add buttons,
+ // etc.
+
+ this.setLayout (new BorderLayout ());
+
+ String[] instructions =
+ {
+ "This is an AUTOMATIC test",
+ "simply wait until it is done"
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ }//End init()
+
+ public void start ()
+ {
+ for (int i = 0; i < 1000; i++) {
+ Frame f = new Frame();
+ f.setBounds(10, 10, 10, 10);
+ f.show();
+ f.dispose();
+
+ Frame f2 = new Frame();
+ f2.setBounds(10, 10, 100, 100);
+ MenuBar bar = new MenuBar();
+ Menu menu = new Menu();
+ menu.add(new MenuItem("foo"));
+ bar.add(menu);
+ f2.setMenuBar(bar);
+ f2.show();
+ f2.dispose();
+ }
+ }// start()
+
+ }// class DisposeStressTest
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+ {
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.show();
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.show();
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+ }// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+ {
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("South", messageText);
+
+ pack();
+
+ show();
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ }
+
+ }// TestDialog class
diff --git a/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy b/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy
new file mode 100644
index 00000000000..da9ee9c0c5c
--- /dev/null
+++ b/jdk/test/java/awt/TrayIcon/SecurityCheck/NoPermissionTest/tray.policy
@@ -0,0 +1,3 @@
+//NoPermission Test
+grant{
+};
diff --git a/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java b/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java
new file mode 100644
index 00000000000..c26c14671ac
--- /dev/null
+++ b/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2002, 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 4418285
+ * @summary Tests that transforms modified with degenerate operations
+ * continue to return their more optimal type from getType().
+ * This test also confirms that isIdentity() returns the
+ * optimal value under all histories of modification.
+ * @run main GetTypeOptimization
+ */
+
+import java.awt.geom.AffineTransform;
+import java.util.Random;
+
+public class GetTypeOptimization {
+ static int TYPE_IDENTITY = AffineTransform.TYPE_IDENTITY;
+ static int TYPE_TRANSLATION = AffineTransform.TYPE_TRANSLATION;
+ static int TYPE_UNIFORM_SCALE = AffineTransform.TYPE_UNIFORM_SCALE;
+ static int TYPE_GENERAL_SCALE = AffineTransform.TYPE_GENERAL_SCALE;
+ static int TYPE_FLIP = AffineTransform.TYPE_FLIP;
+ static int TYPE_QUADRANT_ROTATION = AffineTransform.TYPE_QUADRANT_ROTATION;
+ static int TYPE_GENERAL_ROTATION = AffineTransform.TYPE_GENERAL_ROTATION;
+ static int TYPE_GENERAL_TRANSFORM = AffineTransform.TYPE_GENERAL_TRANSFORM;
+
+ public static Random rand = new Random();
+
+ public static boolean verbose;
+ public static int numerrors;
+
+ public static void main(String argv[]) {
+ verbose = (argv.length != 0);
+
+ checkBug4418285();
+
+ checkAtType(new AffineTransform());
+ checkAtType(AffineTransform.getTranslateInstance(0, 0));
+ checkAtType(AffineTransform.getScaleInstance(1, 1));
+ checkAtType(AffineTransform.getShearInstance(0, 0));
+ checkAtType(AffineTransform.getRotateInstance(0));
+ checkAtType(AffineTransform.getRotateInstance(0, 0, 0));
+ for (int i = 90; i <= 360; i += 90) {
+ double angle = Math.toRadians(i);
+ checkAtType(AffineTransform.getRotateInstance(angle));
+ checkAtType(AffineTransform.getRotateInstance(angle, 0, 0));
+ }
+
+ AffineTransform at = new AffineTransform();
+ checkAtType(at);
+
+ at.setToIdentity(); checkAtType(at);
+ at.setToTranslation(0.0, 0.0); checkAtType(at);
+ at.setToScale(1.0, 1.0); checkAtType(at);
+ at.setToShear(0.0, 0.0); checkAtType(at);
+ at.setToRotation(0); checkAtType(at);
+ at.setToRotation(0, 0, 0); checkAtType(at);
+ for (int i = 90; i <= 360; i += 90) {
+ double angle = Math.toRadians(i);
+ at.setToRotation(angle); checkAtType(at);
+ at.setToRotation(angle, 0, 0); checkAtType(at);
+ }
+
+ at.setToIdentity(); at.scale(1, 1); checkAtType(at);
+ at.setToIdentity(); at.translate(0, 0); checkAtType(at);
+ at.setToIdentity(); at.shear(0, 0); checkAtType(at);
+ at.setToIdentity(); at.rotate(0); checkAtType(at);
+ for (int i = 90; i <= 360; i += 90) {
+ double angle = Math.toRadians(i);
+ at.setToIdentity(); at.rotate(angle); checkAtType(at);
+ at.setToIdentity(); at.rotate(angle, 0, 0); checkAtType(at);
+ }
+
+ at.setToIdentity();
+ for (int i = 0; i < 4; i++) {
+ at.rotate(Math.toRadians(90)); checkAtType(at);
+ }
+
+ at.setToIdentity();
+ at.scale(2, 2); checkAtType(at);
+ at.scale(.5, .5); checkAtType(at);
+
+ for (int n = 1; n <= 3; n++) {
+ for (int i = 0; i < 500; i++) {
+ checkAtType(makeRandomTransform(n));
+ }
+ }
+ if (numerrors != 0) {
+ if (!verbose) {
+ System.err.println("Rerun test with an argument for details");
+ }
+ throw new RuntimeException(numerrors+" tests failed!");
+ }
+ }
+
+ public static void checkBug4418285() {
+ AffineTransform id =
+ new AffineTransform ();
+ AffineTransform translate0 =
+ AffineTransform.getTranslateInstance (0, 0);
+ if (id.isIdentity() != translate0.isIdentity() ||
+ id.getType() != translate0.getType())
+ {
+ numerrors++;
+ if (verbose) {
+ System.err.println("id= " + id +
+ ", isIdentity()=" +
+ id.isIdentity());
+ System.err.println("translate0=" + translate0 +
+ ", isIdentity()=" +
+ translate0.isIdentity());
+ System.err.println("equals=" + id.equals (translate0));
+ System.err.println();
+ }
+ }
+ }
+
+ public static AffineTransform makeRandomTransform(int numops) {
+ AffineTransform at = new AffineTransform();
+ while (--numops >= 0) {
+ switch (rand.nextInt(4)) {
+ case 0:
+ at.scale(rand.nextDouble() * 5 - 2.5,
+ rand.nextDouble() * 5 - 2.5);
+ break;
+ case 1:
+ at.shear(rand.nextDouble() * 5 - 2.5,
+ rand.nextDouble() * 5 - 2.5);
+ break;
+ case 2:
+ at.rotate(rand.nextDouble() * Math.PI * 2);
+ break;
+ case 3:
+ at.translate(rand.nextDouble() * 50 - 25,
+ rand.nextDouble() * 50 - 25);
+ break;
+ default:
+ throw new InternalError("bad case!");
+ }
+ }
+ return at;
+ }
+
+ public static void checkAtType(AffineTransform at) {
+ int reftype = getRefType(at);
+ boolean isident = isIdentity(at);
+ for (int i = 0; i < 5; i++) {
+ boolean atisident = at.isIdentity();
+ int attype = at.getType();
+ if (isident != atisident || reftype != attype) {
+ numerrors++;
+ if (verbose) {
+ System.err.println(at+".isIdentity() == "+atisident);
+ System.err.println(at+".getType() == "+attype);
+ System.err.println("should be "+isident+", "+reftype);
+ new Throwable().printStackTrace();
+ System.err.println();
+ }
+ break;
+ }
+ }
+ }
+
+ public static boolean isIdentity(AffineTransform at) {
+ return (at.getScaleX() == 1 &&
+ at.getScaleY() == 1 &&
+ at.getShearX() == 0 &&
+ at.getShearY() == 0 &&
+ at.getTranslateX() == 0 &&
+ at.getTranslateY() == 0);
+
+ }
+
+ public static int getRefType(AffineTransform at) {
+ double m00 = at.getScaleX();
+ double m11 = at.getScaleY();
+ double m01 = at.getShearX();
+ double m10 = at.getShearY();
+ if (m00 * m01 + m10 * m11 != 0) {
+ // Transformed unit vectors are not perpendicular...
+ return TYPE_GENERAL_TRANSFORM;
+ }
+ int type = ((at.getTranslateX() != 0 || at.getTranslateY() != 0)
+ ? TYPE_TRANSLATION : TYPE_IDENTITY);
+ boolean sgn0, sgn1;
+ if (m01 == 0 && m10 == 0) {
+ sgn0 = (m00 >= 0.0);
+ sgn1 = (m11 >= 0.0);
+ if (sgn0 == sgn1) {
+ if (sgn0) {
+ // Both scaling factors non-negative - simple scale
+ if (m00 != m11) {
+ type |= TYPE_GENERAL_SCALE;
+ } else if (m00 != 1.0) {
+ type |= TYPE_UNIFORM_SCALE;
+ }
+ } else {
+ // Both scaling factors negative - 180 degree rotation
+ type |= TYPE_QUADRANT_ROTATION;
+ if (m00 != m11) {
+ type |= TYPE_GENERAL_SCALE;
+ } else if (m00 != -1.0) {
+ type |= TYPE_UNIFORM_SCALE;
+ }
+ }
+ } else {
+ // Scaling factor signs different - flip about some axis
+ type |= TYPE_FLIP;
+ if (m00 != -m11) {
+ type |= TYPE_GENERAL_SCALE;
+ } else if (m00 != 1.0 && m00 != -1.0) {
+ type |= TYPE_UNIFORM_SCALE;
+ }
+ }
+ } else if (m00 == 0 && m11 == 0) {
+ sgn0 = (m01 >= 0.0);
+ sgn1 = (m10 >= 0.0);
+ if (sgn0 != sgn1) {
+ // Different signs - simple 90 degree rotation
+ if (m01 != -m10) {
+ type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE);
+ } else if (m01 != 1.0 && m01 != -1.0) {
+ type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE);
+ } else {
+ type |= TYPE_QUADRANT_ROTATION;
+ }
+ } else {
+ // Same signs - 90 degree rotation plus an axis flip too
+ if (m01 == m10) {
+ if (m01 == 0) {
+ // All four m[01][01] elements are 0
+ type |= TYPE_UNIFORM_SCALE;
+ } else {
+ // Note - shouldn't (1,1) be no scale at all?
+ type |= (TYPE_QUADRANT_ROTATION |
+ TYPE_FLIP |
+ TYPE_UNIFORM_SCALE);
+ }
+ } else {
+ type |= (TYPE_QUADRANT_ROTATION |
+ TYPE_FLIP |
+ TYPE_GENERAL_SCALE);
+ }
+ }
+ } else {
+ if (m00 * m11 >= 0.0) {
+ // sgn(m00) == sgn(m11) therefore sgn(m01) == -sgn(m10)
+ // This is the "unflipped" (right-handed) state
+ if (m00 != m11 || m01 != -m10) {
+ type |= (TYPE_GENERAL_ROTATION | TYPE_GENERAL_SCALE);
+ } else if (m00 == 0) {
+ // then m11 == 0 also
+ if (m01 == -m10) {
+ type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE);
+ } else {
+ type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE);
+ }
+ } else if (m00 * m11 - m01 * m10 != 1.0) {
+ type |= (TYPE_GENERAL_ROTATION | TYPE_UNIFORM_SCALE);
+ } else {
+ type |= TYPE_GENERAL_ROTATION;
+ }
+ } else {
+ // sgn(m00) == -sgn(m11) therefore sgn(m01) == sgn(m10)
+ // This is the "flipped" (left-handed) state
+ if (m00 != -m11 || m01 != m10) {
+ type |= (TYPE_GENERAL_ROTATION |
+ TYPE_FLIP |
+ TYPE_GENERAL_SCALE);
+ } else if (m01 == 0) {
+ if (m00 == 1.0 || m00 == -1.0) {
+ type |= TYPE_FLIP;
+ } else {
+ type |= (TYPE_FLIP | TYPE_UNIFORM_SCALE);
+ }
+ } else if (m00 * m11 - m01 * m10 != 1.0) {
+ type |= (TYPE_GENERAL_ROTATION |
+ TYPE_FLIP |
+ TYPE_UNIFORM_SCALE);
+ } else {
+ type |= (TYPE_GENERAL_ROTATION | TYPE_FLIP);
+ }
+ }
+ }
+ return type;
+ }
+}
diff --git a/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java b/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java
new file mode 100644
index 00000000000..6d260a1ad89
--- /dev/null
+++ b/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2005, 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 4987374
+ * @summary Unit test for inversion methods:
+ *
+ * AffineTransform.createInverse();
+ * AffineTransform.invert();
+ *
+ * @author flar
+ * @run main TestInvertMethods
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+
+/*
+ * Instances of the inner class Tester are "nodes" which take an input
+ * AffineTransform (AT), modify it in some way and pass the modified
+ * AT onto another Tester node.
+ *
+ * There is one particular Tester node of note called theVerifier.
+ * This is a leaf node which takes the input AT and tests the various
+ * inversion methods on that matrix.
+ *
+ * Most of the other Tester nodes will perform a single affine operation
+ * on their input, such as a rotate by various angles, or a scale by
+ * various predefined scale values, and then pass the modified AT on
+ * to the next node in the chain which may be a verifier or another
+ * modifier.
+ *
+ * The Tester instances can also be chained together using the chain
+ * method so that we can test not only matrices modified by some single
+ * affine operation (scale, rotate, etc.) but also composite matrices
+ * that represent multiple operations concatenated together.
+ */
+public class TestInvertMethods {
+ public static boolean verbose;
+
+ public static final double MAX_ULPS = 2.0;
+ public static double MAX_TX_ULPS = MAX_ULPS;
+ public static double maxulps = 0.0;
+ public static double maxtxulps = 0.0;
+ public static int numtests = 0;
+
+ public static void main(String argv[]) {
+ Tester rotate = new Tester.Rotate();
+ Tester scale = new Tester.Scale();
+ Tester shear = new Tester.Shear();
+ Tester translate = new Tester.Translate();
+
+ if (argv.length > 1) {
+ // This next line verifies that chaining works correctly...
+ scale.chain(translate.chain(new Tester.Debug())).test(false);
+ return;
+ }
+
+ verbose = (argv.length > 0);
+
+ new Tester.Identity().test(true);
+ translate.test(true);
+ scale.test(true);
+ rotate.test(true);
+ shear.test(true);
+ scale.chain(translate).test(true);
+ rotate.chain(translate).test(true);
+ shear.chain(translate).test(true);
+ translate.chain(scale).test(true);
+ translate.chain(rotate).test(true);
+ translate.chain(shear).test(true);
+ translate.chain(scale.chain(rotate.chain(shear))).test(false);
+ shear.chain(rotate.chain(scale.chain(translate))).test(false);
+
+ System.out.println(numtests+" tests performed");
+ System.out.println("Max scale and shear difference: "+maxulps+" ulps");
+ System.out.println("Max translate difference: "+maxtxulps+" ulps");
+ }
+
+ public abstract static class Tester {
+ public static AffineTransform IdentityTx = new AffineTransform();
+
+ /*
+ * This is the leaf node that performs inversion testing
+ * on the incoming AffineTransform.
+ */
+ public static final Tester theVerifier = new Tester() {
+ public void test(AffineTransform at, boolean full) {
+ numtests++;
+ AffineTransform inv1, inv2;
+ boolean isinvertible =
+ (Math.abs(at.getDeterminant()) >= Double.MIN_VALUE);
+ try {
+ inv1 = at.createInverse();
+ if (!isinvertible) missingNTE("createInverse", at);
+ } catch (NoninvertibleTransformException e) {
+ inv1 = null;
+ if (isinvertible) extraNTE("createInverse", at);
+ }
+ inv2 = new AffineTransform(at);
+ try {
+ inv2.invert();
+ if (!isinvertible) missingNTE("invert", at);
+ } catch (NoninvertibleTransformException e) {
+ if (isinvertible) extraNTE("invert", at);
+ }
+ if (verbose) System.out.println("at = "+at);
+ if (isinvertible) {
+ if (verbose) System.out.println(" inv1 = "+inv1);
+ if (verbose) System.out.println(" inv2 = "+inv2);
+ if (!inv1.equals(inv2)) {
+ report(at, inv1, inv2,
+ "invert methods do not agree");
+ }
+ inv1.concatenate(at);
+ inv2.concatenate(at);
+ // "Fix" some values that don't always behave
+ // well with all the math that we've done up
+ // to this point.
+ // See the note on the concatfix method below.
+ concatfix(inv1);
+ concatfix(inv2);
+ if (verbose) System.out.println(" at*inv1 = "+inv1);
+ if (verbose) System.out.println(" at*inv2 = "+inv2);
+ if (!compare(inv1, IdentityTx)) {
+ report(at, inv1, IdentityTx,
+ "createInverse() check failed");
+ }
+ if (!compare(inv2, IdentityTx)) {
+ report(at, inv2, IdentityTx,
+ "invert() check failed");
+ }
+ } else {
+ if (verbose) System.out.println(" is not invertible");
+ }
+ if (verbose) System.out.println();
+ }
+
+ void missingNTE(String methodname, AffineTransform at) {
+ throw new RuntimeException("Noninvertible was not "+
+ "thrown from "+methodname+
+ " for: "+at);
+ }
+
+ void extraNTE(String methodname, AffineTransform at) {
+ throw new RuntimeException("Unexpected Noninvertible "+
+ "thrown from "+methodname+
+ " for: "+at);
+ }
+ };
+
+ /*
+ * The inversion math may work out fairly exactly, but when
+ * we concatenate the inversions back with the original matrix
+ * in an attempt to restore them to the identity matrix,
+ * then we can end up compounding errors to a fairly high
+ * level, particularly if the component values had mantissas
+ * that were repeating fractions. This function therefore
+ * "fixes" the results of concatenating the inversions back
+ * with their original matrices to get rid of small variations
+ * in the values that should have ended up being 0.0.
+ */
+ public void concatfix(AffineTransform at) {
+ double m00 = at.getScaleX();
+ double m10 = at.getShearY();
+ double m01 = at.getShearX();
+ double m11 = at.getScaleY();
+ double m02 = at.getTranslateX();
+ double m12 = at.getTranslateY();
+ if (Math.abs(m02) < 1E-10) m02 = 0.0;
+ if (Math.abs(m12) < 1E-10) m12 = 0.0;
+ if (Math.abs(m01) < 1E-15) m01 = 0.0;
+ if (Math.abs(m10) < 1E-15) m10 = 0.0;
+ at.setTransform(m00, m10,
+ m01, m11,
+ m02, m12);
+ }
+
+ public void test(boolean full) {
+ test(IdentityTx, full);
+ }
+
+ public void test(AffineTransform init, boolean full) {
+ test(init, theVerifier, full);
+ }
+
+ public void test(AffineTransform init, Tester next, boolean full) {
+ next.test(init, full);
+ }
+
+ public Tester chain(Tester next) {
+ return new Chain(this, next);
+ }
+
+ /*
+ * Utility node used to chain together two other nodes for
+ * implementing the "chain" method.
+ */
+ public static class Chain extends Tester {
+ Tester prev;
+ Tester next;
+
+ public Chain(Tester prev, Tester next) {
+ this.prev = prev;
+ this.next = next;
+ }
+
+ public void test(AffineTransform init, boolean full) {
+ prev.test(init, next, full);
+ }
+
+ public Tester chain(Tester next) {
+ this.next = this.next.chain(next);
+ return this;
+ }
+ }
+
+ /*
+ * Utility node for testing.
+ */
+ public static class Fail extends Tester {
+ public void test(AffineTransform init, Tester next, boolean full) {
+ throw new RuntimeException("Debug: Forcing failure");
+ }
+ }
+
+ /*
+ * Utility node for testing that chaining works.
+ */
+ public static class Debug extends Tester {
+ public void test(AffineTransform init, Tester next, boolean full) {
+ new Throwable().printStackTrace();
+ next.test(init, full);
+ }
+ }
+
+ /*
+ * NOP node.
+ */
+ public static class Identity extends Tester {
+ public void test(AffineTransform init, Tester next, boolean full) {
+ if (verbose) System.out.println("*Identity = "+init);
+ next.test(init, full);
+ }
+ }
+
+ /*
+ * Affine rotation node.
+ */
+ public static class Rotate extends Tester {
+ public void test(AffineTransform init, Tester next, boolean full) {
+ int inc = full ? 10 : 45;
+ for (int i = -720; i <= 720; i += inc) {
+ AffineTransform at2 = new AffineTransform(init);
+ at2.rotate(Math.toRadians(i));
+ if (verbose) System.out.println("*Rotate("+i+") = "+at2);
+ next.test(at2, full);
+ }
+ }
+ }
+
+ public static final double SMALL_VALUE = .0001;
+ public static final double LARGE_VALUE = 10000;
+
+ /*
+ * Affine scale node.
+ */
+ public static class Scale extends Tester {
+ public double fullvals[] = {
+ // Noninvertibles
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+
+ // Invertibles
+ SMALL_VALUE, SMALL_VALUE,
+ SMALL_VALUE, 1.0,
+ 1.0, SMALL_VALUE,
+
+ SMALL_VALUE, LARGE_VALUE,
+ LARGE_VALUE, SMALL_VALUE,
+
+ LARGE_VALUE, LARGE_VALUE,
+ LARGE_VALUE, 1.0,
+ 1.0, LARGE_VALUE,
+
+ 0.5, 0.5,
+ 1.0, 1.0,
+ 2.0, 2.0,
+ Math.PI, Math.E,
+ };
+ public double abbrevvals[] = {
+ 0.0, 0.0,
+ 1.0, 1.0,
+ 2.0, 3.0,
+ };
+
+ public void test(AffineTransform init, Tester next, boolean full) {
+ double scales[] = (full ? fullvals : abbrevvals);
+ for (int i = 0; i < scales.length; i += 2) {
+ AffineTransform at2 = new AffineTransform(init);
+ at2.scale(scales[i], scales[i+1]);
+ if (verbose) System.out.println("*Scale("+scales[i]+", "+
+ scales[i+1]+") = "+at2);
+ next.test(at2, full);
+ }
+ }
+ }
+
+ /*
+ * Affine shear node.
+ */
+ public static class Shear extends Tester {
+ public double fullvals[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+
+ // Noninvertible
+ 1.0, 1.0,
+
+ SMALL_VALUE, SMALL_VALUE,
+ SMALL_VALUE, LARGE_VALUE,
+ LARGE_VALUE, SMALL_VALUE,
+ LARGE_VALUE, LARGE_VALUE,
+
+ Math.PI, Math.E,
+ };
+ public double abbrevvals[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+
+ // Noninvertible
+ 1.0, 1.0,
+ };
+
+ public void test(AffineTransform init, Tester next, boolean full) {
+ double shears[] = (full ? fullvals : abbrevvals);
+ for (int i = 0; i < shears.length; i += 2) {
+ AffineTransform at2 = new AffineTransform(init);
+ at2.shear(shears[i], shears[i+1]);
+ if (verbose) System.out.println("*Shear("+shears[i]+", "+
+ shears[i+1]+") = "+at2);
+ next.test(at2, full);
+ }
+ }
+ }
+
+ /*
+ * Affine translate node.
+ */
+ public static class Translate extends Tester {
+ public double fullvals[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+
+ SMALL_VALUE, SMALL_VALUE,
+ SMALL_VALUE, LARGE_VALUE,
+ LARGE_VALUE, SMALL_VALUE,
+ LARGE_VALUE, LARGE_VALUE,
+
+ Math.PI, Math.E,
+ };
+ public double abbrevvals[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ Math.PI, Math.E,
+ };
+
+ public void test(AffineTransform init, Tester next, boolean full) {
+ double translates[] = (full ? fullvals : abbrevvals);
+ for (int i = 0; i < translates.length; i += 2) {
+ AffineTransform at2 = new AffineTransform(init);
+ at2.translate(translates[i], translates[i+1]);
+ if (verbose) System.out.println("*Translate("+
+ translates[i]+", "+
+ translates[i+1]+") = "+at2);
+ next.test(at2, full);
+ }
+ }
+ }
+ }
+
+ public static void report(AffineTransform orig,
+ AffineTransform at1, AffineTransform at2,
+ String message)
+ {
+ System.out.println(orig+", type = "+orig.getType());
+ System.out.println(at1+", type = "+at1.getType());
+ System.out.println(at2+", type = "+at2.getType());
+ System.out.println("ScaleX values differ by "+
+ ulps(at1.getScaleX(),
+ at2.getScaleX())+" ulps");
+ System.out.println("ScaleY values differ by "+
+ ulps(at1.getScaleY(),
+ at2.getScaleY())+" ulps");
+ System.out.println("ShearX values differ by "+
+ ulps(at1.getShearX(),
+ at2.getShearX())+" ulps");
+ System.out.println("ShearY values differ by "+
+ ulps(at1.getShearY(),
+ at2.getShearY())+" ulps");
+ System.out.println("TranslateX values differ by "+
+ ulps(at1.getTranslateX(),
+ at2.getTranslateX())+" ulps");
+ System.out.println("TranslateY values differ by "+
+ ulps(at1.getTranslateY(),
+ at2.getTranslateY())+" ulps");
+ throw new RuntimeException(message);
+ }
+
+ public static boolean compare(AffineTransform at1, AffineTransform at2) {
+ maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX()));
+ maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY()));
+ maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX()));
+ maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY()));
+ maxtxulps = Math.max(maxtxulps,
+ ulps(at1.getTranslateX(), at2.getTranslateX()));
+ maxtxulps = Math.max(maxtxulps,
+ ulps(at1.getTranslateY(), at2.getTranslateY()));
+ return (getModifiedType(at1) == getModifiedType(at2) &&
+ (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) &&
+ (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) &&
+ (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) &&
+ (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) &&
+ (compare(at1.getTranslateX(),
+ at2.getTranslateX(), MAX_TX_ULPS)) &&
+ (compare(at1.getTranslateY(),
+ at2.getTranslateY(), MAX_TX_ULPS)));
+ }
+
+ public static final int ANY_SCALE_MASK =
+ (AffineTransform.TYPE_UNIFORM_SCALE |
+ AffineTransform.TYPE_GENERAL_SCALE);
+ public static int getModifiedType(AffineTransform at) {
+ int type = at.getType();
+ // Some of the vector methods can introduce a tiny uniform scale
+ // at some angles...
+ if ((type & ANY_SCALE_MASK) != 0) {
+ maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0));
+ if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) {
+ // Really tiny - we will ignore it
+ type &= ~ ANY_SCALE_MASK;
+ }
+ }
+ return type;
+ }
+
+ public static boolean compare(double val1, double val2, double maxulps) {
+ if (Math.abs(val1 - val2) < 1E-15) return true;
+ return (ulps(val1, val2) <= maxulps);
+ }
+
+ public static double ulps(double val1, double val2) {
+ double diff = Math.abs(val1 - val2);
+ double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2));
+ return (diff / ulpmax);
+ }
+}
diff --git a/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java b/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java
new file mode 100644
index 00000000000..0664eacdd64
--- /dev/null
+++ b/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2004, 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 4980035
+ * @summary Unit test for new methods:
+ *
+ * AffineTransform.getRotateInstance(double x, double y);
+ * AffineTransform.setToRotation(double x, double y);
+ * AffineTransform.rotate(double x, double y);
+ *
+ * AffineTransform.getQuadrantRotateInstance(int numquads);
+ * AffineTransform.setToQuadrantRotation(int numquads);
+ * AffineTransform.quadrantRotate(int numquads);
+ *
+ * @author flar
+ * @run main TestRotateMethods
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+public class TestRotateMethods {
+ /* The maximum errors allowed, measured in double precision "ulps"
+ * Note that for most fields, the tests are extremely accurate - to
+ * within 3 ulps of the smaller value in the comparison
+ * For the translation components, the tests are still very accurate,
+ * but the absolute number of ulps can be noticeably higher when we
+ * use one of the rotate methods that takes an anchor point.
+ * Since a double precision value has 56 bits of precision, even
+ * 1024 ulps is extremely small as a ratio of the value.
+ */
+ public static final double MAX_ULPS = 3.0;
+ public static final double MAX_ANCHOR_TX_ULPS = 1024.0;
+ public static double MAX_TX_ULPS = MAX_ULPS;
+
+ // Vectors for quadrant rotations
+ public static final double quadxvec[] = { 1.0, 0.0, -1.0, 0.0 };
+ public static final double quadyvec[] = { 0.0, 1.0, 0.0, -1.0 };
+
+ // Run tests once for each type of method:
+ // tx = AffineTransform.get<Rotate>Instance()
+ // tx.set<Rotate>()
+ // tx.<rotate>()
+ public static enum Mode { GET, SET, MOD };
+
+ // Used to accumulate and report largest differences encountered by tests
+ public static double maxulps = 0.0;
+ public static double maxtxulps = 0.0;
+
+ // Sample anchor points for testing.
+ public static Point2D zeropt = new Point2D.Double(0, 0);
+ public static Point2D testtxpts[] = {
+ new Point2D.Double( 5, 5),
+ new Point2D.Double( 20, -10),
+ new Point2D.Double(-Math.PI, Math.E),
+ };
+
+ public static void main(String argv[]) {
+ test(Mode.GET);
+ test(Mode.SET);
+ test(Mode.MOD);
+
+ System.out.println("Max scale and shear difference: "+maxulps+" ulps");
+ System.out.println("Max translate difference: "+maxtxulps+" ulps");
+ }
+
+ public static void test(Mode mode) {
+ MAX_TX_ULPS = MAX_ULPS; // Stricter tx testing with no anchor point
+ test(mode, 0.5, null);
+ test(mode, 1.0, null);
+ test(mode, 3.0, null);
+
+ // Anchor points make the tx values less reliable
+ MAX_TX_ULPS = MAX_ANCHOR_TX_ULPS;
+ for (int i = 0; i < testtxpts.length; i++) {
+ test(mode, 1.0, testtxpts[i]);
+ }
+ MAX_TX_ULPS = MAX_ULPS; // Restore to default
+ }
+
+ public static void verify(AffineTransform at1, AffineTransform at2,
+ Mode mode, double vectorscale, Point2D txpt,
+ String message, double num, String units)
+ {
+ if (!compare(at1, at2)) {
+ System.out.println("mode == "+mode);
+ System.out.println("vectorscale == "+vectorscale);
+ System.out.println("txpt == "+txpt);
+ System.out.println(at1+", type = "+at1.getType());
+ System.out.println(at2+", type = "+at2.getType());
+ System.out.println("ScaleX values differ by "+
+ ulps(at1.getScaleX(), at2.getScaleX())+" ulps");
+ System.out.println("ScaleY values differ by "+
+ ulps(at1.getScaleY(), at2.getScaleY())+" ulps");
+ System.out.println("ShearX values differ by "+
+ ulps(at1.getShearX(), at2.getShearX())+" ulps");
+ System.out.println("ShearY values differ by "+
+ ulps(at1.getShearY(), at2.getShearY())+" ulps");
+ System.out.println("TranslateX values differ by "+
+ ulps(at1.getTranslateX(),
+ at2.getTranslateX())+" ulps");
+ System.out.println("TranslateY values differ by "+
+ ulps(at1.getTranslateY(),
+ at2.getTranslateY())+" ulps");
+ throw new RuntimeException(message + num + units);
+ }
+ }
+
+ public static void test(Mode mode, double vectorscale, Point2D txpt) {
+ AffineTransform at1, at2, at3;
+
+ for (int deg = -720; deg <= 720; deg++) {
+ if ((deg % 90) == 0) continue;
+ double radians = Math.toRadians(deg);
+ double vecy = Math.sin(radians) * vectorscale;
+ double vecx = Math.cos(radians) * vectorscale;
+
+ at1 = makeAT(mode, txpt, radians);
+ at2 = makeAT(mode, txpt, vecx, vecy);
+ verify(at1, at2, mode, vectorscale, txpt,
+ "vector and radians do not match for ", deg, " degrees");
+
+ if (txpt == null) {
+ // Make sure output was same as a with a 0,0 anchor point
+ if (vectorscale == 1.0) {
+ // Only need to test radians method for one scale factor
+ at3 = makeAT(mode, zeropt, radians);
+ verify(at1, at3, mode, vectorscale, zeropt,
+ "radians not invariant with 0,0 translate at ",
+ deg, " degrees");
+ }
+ // But test vector methods with all scale factors
+ at3 = makeAT(mode, zeropt, vecx, vecy);
+ verify(at2, at3, mode, vectorscale, zeropt,
+ "vector not invariant with 0,0 translate at ",
+ deg, " degrees");
+ }
+ }
+
+ for (int quad = -8; quad <= 8; quad++) {
+ double degrees = quad * 90.0;
+ double radians = Math.toRadians(degrees);
+ double vecx = quadxvec[quad & 3] * vectorscale;
+ double vecy = quadyvec[quad & 3] * vectorscale;
+
+ at1 = makeAT(mode, txpt, radians);
+ at2 = makeAT(mode, txpt, vecx, vecy);
+ verify(at1, at2, mode, vectorscale, txpt,
+ "quadrant vector and radians do not match for ",
+ degrees, " degrees");
+ at2 = makeQuadAT(mode, txpt, quad);
+ verify(at1, at2, mode, vectorscale, txpt,
+ "quadrant and radians do not match for ",
+ quad, " quadrants");
+ if (txpt == null) {
+ at3 = makeQuadAT(mode, zeropt, quad);
+ verify(at2, at3, mode, vectorscale, zeropt,
+ "quadrant not invariant with 0,0 translate at ",
+ quad, " quadrants");
+ }
+ }
+ }
+
+ public static AffineTransform makeRandomAT() {
+ AffineTransform at = new AffineTransform();
+ at.scale(Math.random() * -10.0, Math.random() * 100.0);
+ at.rotate(Math.random() * Math.PI);
+ at.shear(Math.random(), Math.random());
+ at.translate(Math.random() * 300.0, Math.random() * -20.0);
+ return at;
+ }
+
+ public static AffineTransform makeAT(Mode mode, Point2D txpt,
+ double radians)
+ {
+ AffineTransform at;
+ double tx = (txpt == null) ? 0.0 : txpt.getX();
+ double ty = (txpt == null) ? 0.0 : txpt.getY();
+ switch (mode) {
+ case GET:
+ if (txpt != null) {
+ at = AffineTransform.getRotateInstance(radians, tx, ty);
+ } else {
+ at = AffineTransform.getRotateInstance(radians);
+ }
+ break;
+ case SET:
+ at = makeRandomAT();
+ if (txpt != null) {
+ at.setToRotation(radians, tx, ty);
+ } else {
+ at.setToRotation(radians);
+ }
+ break;
+ case MOD:
+ at = makeRandomAT();
+ at.setToIdentity();
+ if (txpt != null) {
+ at.rotate(radians, tx, ty);
+ } else {
+ at.rotate(radians);
+ }
+ break;
+ default:
+ throw new InternalError("unrecognized mode: "+mode);
+ }
+
+ return at;
+ }
+
+ public static AffineTransform makeAT(Mode mode, Point2D txpt,
+ double vx, double vy)
+ {
+ AffineTransform at;
+ double tx = (txpt == null) ? 0.0 : txpt.getX();
+ double ty = (txpt == null) ? 0.0 : txpt.getY();
+ switch (mode) {
+ case GET:
+ if (txpt != null) {
+ at = AffineTransform.getRotateInstance(vx, vy, tx, ty);
+ } else {
+ at = AffineTransform.getRotateInstance(vx, vy);
+ }
+ break;
+ case SET:
+ at = makeRandomAT();
+ if (txpt != null) {
+ at.setToRotation(vx, vy, tx, ty);
+ } else {
+ at.setToRotation(vx, vy);
+ }
+ break;
+ case MOD:
+ at = makeRandomAT();
+ at.setToIdentity();
+ if (txpt != null) {
+ at.rotate(vx, vy, tx, ty);
+ } else {
+ at.rotate(vx, vy);
+ }
+ break;
+ default:
+ throw new InternalError("unrecognized mode: "+mode);
+ }
+
+ return at;
+ }
+
+ public static AffineTransform makeQuadAT(Mode mode, Point2D txpt,
+ int quads)
+ {
+ AffineTransform at;
+ double tx = (txpt == null) ? 0.0 : txpt.getX();
+ double ty = (txpt == null) ? 0.0 : txpt.getY();
+ switch (mode) {
+ case GET:
+ if (txpt != null) {
+ at = AffineTransform.getQuadrantRotateInstance(quads, tx, ty);
+ } else {
+ at = AffineTransform.getQuadrantRotateInstance(quads);
+ }
+ break;
+ case SET:
+ at = makeRandomAT();
+ if (txpt != null) {
+ at.setToQuadrantRotation(quads, tx, ty);
+ } else {
+ at.setToQuadrantRotation(quads);
+ }
+ break;
+ case MOD:
+ at = makeRandomAT();
+ at.setToIdentity();
+ if (txpt != null) {
+ at.quadrantRotate(quads, tx, ty);
+ } else {
+ at.quadrantRotate(quads);
+ }
+ break;
+ default:
+ throw new InternalError("unrecognized mode: "+mode);
+ }
+
+ return at;
+ }
+
+ public static boolean compare(AffineTransform at1, AffineTransform at2) {
+ maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX()));
+ maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY()));
+ maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX()));
+ maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY()));
+ maxtxulps = Math.max(maxtxulps,
+ ulps(at1.getTranslateX(), at2.getTranslateX()));
+ maxtxulps = Math.max(maxtxulps,
+ ulps(at1.getTranslateY(), at2.getTranslateY()));
+ return (getModifiedType(at1) == getModifiedType(at2) &&
+ (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) &&
+ (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) &&
+ (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) &&
+ (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) &&
+ (compare(at1.getTranslateX(),
+ at2.getTranslateX(), MAX_TX_ULPS)) &&
+ (compare(at1.getTranslateY(),
+ at2.getTranslateY(), MAX_TX_ULPS)));
+ }
+
+ public static int getModifiedType(AffineTransform at) {
+ int type = at.getType();
+ // Some of the vector methods can introduce a tiny uniform scale
+ // at some angles...
+ if ((type & AffineTransform.TYPE_UNIFORM_SCALE) != 0) {
+ maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0));
+ if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) {
+ // Really tiny - we will ignore it
+ type &= (~AffineTransform.TYPE_UNIFORM_SCALE);
+ }
+ }
+ return type;
+ }
+
+ public static boolean compare(double val1, double val2, double maxulps) {
+ return (ulps(val1, val2) <= maxulps);
+ }
+
+ public static double ulps(double val1, double val2) {
+ double diff = Math.abs(val1 - val2);
+ double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2));
+ return (diff / ulpmax);
+ }
+}
diff --git a/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java b/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java
new file mode 100644
index 00000000000..0e129367e6d
--- /dev/null
+++ b/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2005, 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 6213608
+ * @summary Test that AffineTransform can deserialize appropriate versions.
+ * @author flar
+ * @run main TestSerialization
+ */
+
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.awt.geom.AffineTransform;
+
+public class TestSerialization {
+ public static void main(String argv[]) {
+ if (argv.length > 0) {
+ System.out.println("Saving from: "+
+ System.getProperty("java.version"));
+ writeSer(argv[0]);
+ return;
+ }
+ System.out.println("Testing on: "+System.getProperty("java.version"));
+ testReadWrite();
+ readSer("serial.1.2", true);
+ }
+
+ public static AffineTransform testATs[] = {
+ new AffineTransform(),
+ AffineTransform.getScaleInstance(2.5, -3.0),
+ AffineTransform.getRotateInstance(Math.PI / 4.0),
+ AffineTransform.getShearInstance(1.0, -3.0),
+ AffineTransform.getTranslateInstance(25.0, 12.5),
+ makeComplexAT(),
+ };
+
+ public static AffineTransform makeComplexAT() {
+ AffineTransform at = new AffineTransform();
+ at.scale(2.5, -3.0);
+ at.rotate(Math.PI / 4.0);
+ at.shear(1.0, -3.0);
+ at.translate(25.0, 12.5);
+ return at;
+ };
+
+ public static void testReadWrite() {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ testWrite(oos);
+ oos.flush();
+ oos.close();
+ byte buf[] = baos.toByteArray();
+ ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ testRead(ois, true);
+ } catch (InvalidClassException ice) {
+ throw new RuntimeException("Object read failed from loopback");
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("IOException testing loopback");
+ }
+ }
+
+ public static String resolve(String relfilename) {
+ String dir = System.getProperty("test.src");
+ if (dir == null) {
+ return relfilename;
+ } else {
+ return dir+"/"+relfilename;
+ }
+ }
+
+ public static void readSer(String filename, boolean shouldsucceed) {
+ try {
+ FileInputStream fis = new FileInputStream(resolve(filename));
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ testRead(ois, shouldsucceed);
+ } catch (InvalidClassException ice) {
+ throw new RuntimeException("Object read failed from: "+filename);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("IOException reading: "+filename);
+ }
+ }
+
+ public static void testRead(ObjectInputStream ois, boolean shouldsucceed)
+ throws IOException
+ {
+ for (int i = 0; i < testATs.length; i++) {
+ AffineTransform at;
+ try {
+ at = (AffineTransform) ois.readObject();
+ if (!shouldsucceed) {
+ throw new RuntimeException("readObj did not fail");
+ }
+ } catch (ClassNotFoundException e) {
+ // Should never happen, but must catch declared exceptions...
+ throw new RuntimeException("AffineTransform not found!");
+ } catch (InvalidClassException e) {
+ if (shouldsucceed) {
+ throw e;
+ }
+ continue;
+ }
+ if (!testATs[i].equals(at)) {
+ throw new RuntimeException("wrong AT read from stream");
+ }
+ }
+ }
+
+ public static void writeSer(String filename) {
+ try {
+ FileOutputStream fos = new FileOutputStream(filename);
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
+ testWrite(oos);
+ oos.flush();
+ oos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("IOException writing: "+filename);
+ }
+ }
+
+ public static void testWrite(ObjectOutputStream oos)
+ throws IOException
+ {
+ for (int i = 0; i < testATs.length; i++) {
+ oos.writeObject(testATs[i]);
+ }
+ }
+}
diff --git a/jdk/test/java/awt/geom/AffineTransform/serial.1.2 b/jdk/test/java/awt/geom/AffineTransform/serial.1.2
new file mode 100644
index 00000000000..d6e7a737c16
--- /dev/null
+++ b/jdk/test/java/awt/geom/AffineTransform/serial.1.2
Binary files differ
diff --git a/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java b/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java
new file mode 100644
index 00000000000..36d4185a6f9
--- /dev/null
+++ b/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, 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 8028539
+ * @summary Test that drawing a scaled image terminates.
+ * @run main/othervm/timeout=60 DrawImageCoordsTest
+*/
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+public class DrawImageCoordsTest {
+
+ public static void main(String[] args) {
+
+ /* Create an image to draw, filled in solid red. */
+ BufferedImage srcImg =
+ new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+ Graphics srcG = srcImg.createGraphics();
+ srcG.setColor(Color.red);
+ int w = srcImg.getWidth(null);
+ int h = srcImg.getHeight(null);
+ srcG.fillRect(0, 0, w, h);
+
+ /* Create a destination image */
+ BufferedImage dstImage =
+ new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+ Graphics2D dstG = dstImage.createGraphics();
+ /* draw image under a scaling transform that overflows int */
+ AffineTransform tx = new AffineTransform(0.5, 0, 0, 0.5,
+ 0, 5.8658460197478485E9);
+ dstG.setTransform(tx);
+ dstG.drawImage(srcImg, 0, 0, null );
+ /* draw image under the same overflowing transform, cancelling
+ * out the 0.5 scale on the graphics
+ */
+ dstG.drawImage(srcImg, 0, 0, 2*w, 2*h, null);
+ if (Color.red.getRGB() == dstImage.getRGB(w/2, h/2)) {
+ throw new RuntimeException("Unexpected color: clipping failed.");
+ }
+ System.out.println("Test Thread Completed");
+ }
+}
diff --git a/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java b/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java
new file mode 100644
index 00000000000..901e6f79570
--- /dev/null
+++ b/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.VolatileImage;
+
+import static java.awt.Transparency.TRANSLUCENT;
+
+/**
+ * @test
+ * @bug 8062164
+ * @summary We should get correct alpha, when we draw to/from VolatileImage and
+ * bicubic interpolation is enabled
+ * @author Sergey Bylokhov
+ */
+public final class IncorrectAlphaConversionBicubic {
+
+ private static final Color RGB = new Color(200, 255, 7, 123);
+ private static final int SIZE = 100;
+
+ public static void main(final String[] args) {
+ final GraphicsEnvironment ge =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice gd = ge.getDefaultScreenDevice();
+ final GraphicsConfiguration gc = gd.getDefaultConfiguration();
+ final VolatileImage vi =
+ gc.createCompatibleVolatileImage(SIZE, SIZE, TRANSLUCENT);
+ final BufferedImage bi = makeUnmanagedBI(gc, TRANSLUCENT);
+ final int expected = bi.getRGB(2, 2);
+
+ int attempt = 0;
+ BufferedImage snapshot;
+ while (true) {
+ if (++attempt > 10) {
+ throw new RuntimeException("Too many attempts: " + attempt);
+ }
+ vi.validate(gc);
+ final Graphics2D g2d = vi.createGraphics();
+ g2d.setComposite(AlphaComposite.Src);
+ g2d.scale(2, 2);
+ g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ g2d.drawImage(bi, 0, 0, null);
+ g2d.dispose();
+
+ snapshot = vi.getSnapshot();
+ if (vi.contentsLost()) {
+ continue;
+ }
+ break;
+ }
+ final int actual = snapshot.getRGB(2, 2);
+ if (actual != expected) {
+ System.err.println("Actual: " + Integer.toHexString(actual));
+ System.err.println("Expected: " + Integer.toHexString(expected));
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ private static BufferedImage makeUnmanagedBI(GraphicsConfiguration gc,
+ int type) {
+ BufferedImage img = gc.createCompatibleImage(SIZE, SIZE, type);
+ Graphics2D g2d = img.createGraphics();
+ g2d.setColor(RGB);
+ g2d.fillRect(0, 0, SIZE, SIZE);
+ g2d.dispose();
+ final DataBuffer db = img.getRaster().getDataBuffer();
+ if (db instanceof DataBufferInt) {
+ ((DataBufferInt) db).getData();
+ } else if (db instanceof DataBufferShort) {
+ ((DataBufferShort) db).getData();
+ } else if (db instanceof DataBufferByte) {
+ ((DataBufferByte) db).getData();
+ } else {
+ try {
+ img.setAccelerationPriority(0.0f);
+ } catch (final Throwable ignored) {
+ }
+ }
+ return img;
+ }
+}
diff --git a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java
index 67ea6b5af99..e08bb9dec16 100644
--- a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java
+++ b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java
@@ -41,7 +41,7 @@ import static java.awt.image.BufferedImage.*;
/*
* @test
- * @bug 8029253
+ * @bug 8029253 8059941
* @summary Unmanaged images should be drawn fast.
* @author Sergey Bylokhov
*/
diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java
index bb955f2de20..b81853bd9ee 100644
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java
@@ -2269,9 +2269,10 @@ public class Basic {
fail("Test failed: Process exited prematurely");
}
long end = System.nanoTime();
- // give waitFor(timeout) a wide berth (200ms)
- // Old AIX machines my need a little longer.
- if ((end - start) > 200000000L * (AIX.is() ? 2 : 1))
+ // give waitFor(timeout) a wide berth (2s)
+ System.out.printf(" waitFor process: delta: %d%n",(end - start) );
+
+ if ((end - start) > TimeUnit.SECONDS.toNanos(2))
fail("Test failed: waitFor took too long (" + (end - start) + "ns)");
p.destroy();
@@ -2295,19 +2296,23 @@ public class Basic {
final Process p = new ProcessBuilder(childArgs).start();
long start = System.nanoTime();
- p.waitFor(1000, TimeUnit.MILLISECONDS);
+ p.waitFor(10, TimeUnit.MILLISECONDS);
long end = System.nanoTime();
- if ((end - start) < 500000000)
+ if ((end - start) < TimeUnit.MILLISECONDS.toNanos(10))
fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)");
p.destroy();
start = System.nanoTime();
- p.waitFor(1000, TimeUnit.MILLISECONDS);
+ p.waitFor(8, TimeUnit.SECONDS);
end = System.nanoTime();
- if ((end - start) > 900000000)
- fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)");
+
+ int exitValue = p.exitValue();
+
+ if ((end - start) > TimeUnit.SECONDS.toNanos(7))
+ fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)"
+ + ", exitValue: " + exitValue);
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
diff --git a/jdk/test/java/lang/reflect/Generics/ThreadSafety.java b/jdk/test/java/lang/reflect/Generics/ThreadSafety.java
new file mode 100644
index 00000000000..801bb9c23c4
--- /dev/null
+++ b/jdk/test/java/lang/reflect/Generics/ThreadSafety.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2014 Google Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8062771 8016236
+ * @summary Test publication of Class objects via a data race
+ * @run testng ThreadSafety
+ */
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeoutException;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+/**
+ * A test resulting from an attempt to repro this failure (in guice):
+ *
+ * java.lang.NullPointerException
+ * at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
+ * at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
+ * at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
+ * at java.lang.Class.getGenericSuperclass(Class.java:692)
+ * at com.google.inject.TypeLiteral.getSuperclassTypeParameter(TypeLiteral.java:99)
+ * at com.google.inject.TypeLiteral.<init>(TypeLiteral.java:79)
+ *
+ * However, as one would expect with thread safety problems in reflection, these
+ * are very hard to reproduce. This very test has never been observed to fail,
+ * but a similar test has been observed to fail about once in 2000 executions
+ * (about once every 6 CPU-hours), in jdk7 only. It appears to be fixed in jdk8+ by:
+ *
+ * 8016236: Class.getGenericInterfaces performance improvement.
+ * (by making Class.genericInfo volatile)
+ */
+public class ThreadSafety {
+ public static class EmptyClass {
+ public static class EmptyGenericSuperclass<T> {}
+ public static class EmptyGenericSubclass<T> extends EmptyGenericSuperclass<T> {}
+ }
+
+ /** published via data race */
+ private Class<?> racyClass = Object.class;
+
+ private URL[] urls = ((URLClassLoader) ThreadSafety.class.getClassLoader()).getURLs();
+
+ private Class<?> createNewEmptyGenericSubclassClass() throws Exception {
+ URLClassLoader ucl = new URLClassLoader(urls, null);
+ return Class.forName("ThreadSafety$EmptyClass$EmptyGenericSubclass", true, ucl);
+ }
+
+ @Test
+ public void testRacy_getGenericSuperclass() throws Exception {
+ final int nThreads = 10;
+ final int iterations = 30;
+ final int timeout = 10;
+ final CyclicBarrier newCycle = new CyclicBarrier(nThreads);
+ final Callable<Void> task = new Callable<Void>() {
+ public Void call() throws Exception {
+ for (int i = 0; i < iterations; i++) {
+ final int threadId;
+ try {
+ threadId = newCycle.await(timeout, SECONDS);
+ } catch (BrokenBarrierException e) {
+ return null;
+ }
+ for (int j = 0; j < iterations; j++) {
+ // one thread publishes the class object via a data
+ // race, for the other threads to consume.
+ if (threadId == 0) {
+ racyClass = createNewEmptyGenericSubclassClass();
+ } else {
+ racyClass.getGenericSuperclass();
+ }
+ }
+ }
+ return null;
+ }};
+
+ final ExecutorService pool = Executors.newFixedThreadPool(nThreads);
+ try {
+ for (Future<Void> future :
+ pool.invokeAll(Collections.nCopies(nThreads, task))) {
+ try {
+ future.get(iterations * timeout, SECONDS);
+ } catch (ExecutionException e) {
+ // ignore "collateral damage"
+ if (!(e.getCause() instanceof BrokenBarrierException)
+ &&
+ !(e.getCause() instanceof TimeoutException)) {
+ throw e;
+ }
+ }
+ }
+ } finally {
+ pool.shutdownNow();
+ assertTrue(pool.awaitTermination(2 * timeout, SECONDS));
+ }
+ }
+}
diff --git a/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java b/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java
new file mode 100644
index 00000000000..9d0cdca0766
--- /dev/null
+++ b/jdk/test/java/lang/reflect/Parameter/InnerClassToString.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, 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 8055063
+ * @summary javac should generate method parameters correctly.
+ * @clean InnerClassToString
+ * @compile -parameters InnerClassToString.java
+ * @run main InnerClassToString
+ * @clean InnerClassToString
+ * @compile InnerClassToString.java
+ * @run main InnerClassToString
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Parameter;
+import java.util.Set;
+
+// Test copied and expanded from webbug group report.
+public class InnerClassToString {
+ private static final Class<?>[] genericParamClasses = new Class<?>[] {
+ InnerClassToString.class, Set.class
+ };
+
+ private static final Class<?>[] nongenericParamClasses = new Class<?>[] {
+ InnerClassToString.class, String.class
+ };
+
+ private int errors = 0;
+
+ private void test(Constructor<MyEntity> constructor,
+ Class<?>[] paramClasses) {
+ final Parameter[] params = constructor.getParameters();
+
+ for (int i = 0; i < params.length; i++) {
+ final Parameter parameter = params[i];
+ System.out.println(parameter.toString());
+
+ if (!parameter.getType().equals(paramClasses[i])) {
+ errors++;
+ System.err.println("Expected type " + paramClasses[i] +
+ " but got " + parameter.getType());
+ }
+
+ System.out.println(parameter.getParameterizedType());
+ System.out.println(parameter.getAnnotatedType());
+ }
+
+ }
+
+ private void run() throws Exception {
+ final Constructor<MyEntity> genericConstructor =
+ MyEntity.class.getConstructor(InnerClassToString.class, Set.class);
+
+ test(genericConstructor, genericParamClasses);
+
+ final Constructor<MyEntity> nongenericConstructor =
+ MyEntity.class.getConstructor(InnerClassToString.class, String.class);
+
+ test(nongenericConstructor, nongenericParamClasses);
+
+ if (errors != 0)
+ throw new RuntimeException(errors + " errors in test");
+ }
+
+ public static void main(String[] args) throws Exception {
+ new InnerClassToString().run();
+ }
+
+ public class MyEntity {
+ public MyEntity(Set<?> names) {}
+ public MyEntity(String names) {}
+ }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java b/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java
new file mode 100644
index 00000000000..e1b5457bda8
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java
@@ -0,0 +1,1318 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.sql.rowset.serial.SerialArray;
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialRef;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubArray;
+import util.StubBaseRowSet;
+import util.StubBlob;
+import util.StubClob;
+import util.StubNClob;
+import util.StubRef;
+import util.StubRowId;
+import util.StubSQLXML;
+import util.TestRowSetListener;
+
+public class BaseRowSetTests extends BaseTest {
+
+ private StubBaseRowSet brs;
+ private StubBaseRowSet brs1;
+ private final String query = "SELECT * FROM SUPERHEROS";
+ private final String url = "jdbc:derby://localhost:1527/myDB";
+ private final String dsName = "jdbc/myDB";
+ private final String user = "Bruce Wayne";
+ private final String password = "The Dark Knight";
+ private final Date aDate = Date.valueOf(LocalDate.now());
+ private final Time aTime = Time.valueOf(LocalTime.now());
+ private final Timestamp ts = Timestamp.valueOf(LocalDateTime.now());
+ private final Calendar cal = Calendar.getInstance();
+ private final byte[] bytes = new byte[10];
+ private RowId aRowid;
+ private Ref aRef;
+ private Blob aBlob;
+ private Clob aClob;
+ private Array aArray;
+ private InputStream is;
+ private Reader rdr;
+ private Map<String, Class<?>> map = new HashMap<>();
+
+ public BaseRowSetTests() {
+ brs1 = new StubBaseRowSet();
+ is = new StringBufferInputStream(query);
+ rdr = new StringReader(query);
+ aRowid = new StubRowId();
+ try {
+ aBlob = new SerialBlob(new StubBlob());
+ aClob = new SerialClob(new StubClob());
+ aRef = new SerialRef(new StubRef("INTEGER", query));
+ aArray = new SerialArray(new StubArray("INTEGER", new Object[1]));
+ map.put("SUPERHERO", Class.forName("util.SuperHero"));
+ } catch (SQLException | ClassNotFoundException ex) {
+ Logger.getLogger(BaseRowSetTests.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ @BeforeMethod
+ @Override
+ public void setUpMethod() throws Exception {
+ brs = new StubBaseRowSet();
+ }
+
+ /*
+ * Validate that getCommand() returns null by default
+ */
+ @Test
+ public void test() {
+ assertTrue(brs.getCommand() == null);
+ }
+
+ /*
+ * Validate that getCommand() returns command specified to setCommand
+ */
+ @Test
+ public void test01() throws Exception {
+ brs.setCommand(query);
+ assertTrue(brs.getCommand().equals(query));
+ }
+
+ /*
+ * Validate that getCurrency() returns the correct default value
+ */
+ @Test
+ public void test02() throws Exception {
+ assertTrue(brs.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
+ }
+
+ /*
+ * Validate that getCurrency() returns the correct value
+ * after a call to setConcurrency())
+ */
+ @Test(dataProvider = "concurTypes")
+ public void test03(int concurType) throws Exception {
+ brs.setConcurrency(concurType);
+ assertTrue(brs.getConcurrency() == concurType);
+ }
+
+ /*
+ * Validate that getCurrency() throws a SQLException for an invalid value
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test04() throws Exception {
+ brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ }
+
+ /*
+ * Validate that getDataSourceName() returns null by default
+ */
+ @Test
+ public void test05() throws Exception {
+ assertTrue(brs.getDataSourceName() == null);
+ }
+
+ /*
+ * Validate that getDataSourceName() returns the value specified
+ * by setDataSourceName() and getUrl() returns null
+ */
+ @Test
+ public void test06() throws Exception {
+ brs.setUrl(url);
+ brs.setDataSourceName(dsName);
+ assertTrue(brs.getDataSourceName().equals(dsName));
+ assertTrue(brs.getUrl() == null);
+ }
+
+ /*
+ * Validate that setDataSourceName() throws a SQLException for an empty
+ * String specified for the data source name
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test07() throws Exception {
+ String dsname = "";
+ brs.setDataSourceName(dsname);
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns false by default
+ */
+ @Test
+ public void test08() throws Exception {
+ assertFalse(brs.getEscapeProcessing());
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns value set by
+ * setEscapeProcessing()
+ */
+ @Test(dataProvider = "trueFalse")
+ public void test09(boolean val) throws Exception {
+ brs.setEscapeProcessing(val);
+ assertTrue(brs.getEscapeProcessing() == val);
+ }
+
+ /*
+ * Validate that getFetchDirection() returns the correct default value
+ */
+ @Test
+ public void test10() throws Exception {
+ assertTrue(brs.getFetchDirection() == ResultSet.FETCH_FORWARD);
+ }
+
+ /*
+ * Validate that getFetchDirection() returns the value set by
+ * setFetchDirection()
+ */
+ @Test(dataProvider = "fetchDirection")
+ public void test11(int direction) throws Exception {
+ brs.setFetchDirection(direction);
+ assertTrue(brs.getFetchDirection() == direction);
+ }
+
+ /*
+ * Validate that setConcurrency() throws a SQLException for an invalid value
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test12() throws Exception {
+ brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ }
+
+ /*
+ * Validate that setFetchSize() throws a SQLException for an invalid value
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test13() throws Exception {
+ brs.setFetchSize(-1);
+ }
+
+ /*
+ * Validate that setFetchSize() throws a SQLException for a
+ * value greater than getMaxRows()
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test14() throws Exception {
+ brs.setMaxRows(5);
+ brs.setFetchSize(brs.getMaxRows() + 1);
+ }
+
+ /*
+ * Validate that getFetchSize() returns the correct value after
+ * setFetchSize() has been called
+ */
+ @Test
+ public void test15() throws Exception {
+ int maxRows = 150;
+ brs.setFetchSize(0);
+ assertTrue(brs.getFetchSize() == 0);
+ brs.setFetchSize(100);
+ assertTrue(brs.getFetchSize() == 100);
+ brs.setMaxRows(maxRows);
+ brs.setFetchSize(maxRows);
+ assertTrue(brs.getFetchSize() == maxRows);
+ }
+
+ /*
+ * Validate that setMaxFieldSize() throws a SQLException for an invalid value
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test16() throws Exception {
+ brs.setMaxFieldSize(-1);
+ }
+
+ /*
+ * Validate that getMaxFieldSize() returns the value set by
+ * setMaxFieldSize()
+ */
+ @Test
+ public void test17() throws Exception {
+ brs.setMaxFieldSize(0);
+ assertTrue(brs.getMaxFieldSize() == 0);
+ brs.setMaxFieldSize(100);
+ assertTrue(brs.getMaxFieldSize() == 100);
+ brs.setMaxFieldSize(50);
+ assertTrue(brs.getMaxFieldSize() == 50);
+ }
+
+ /*
+ * Validate that isReadOnly() returns value set by
+ * setReadOnly()
+ */
+ @Test(dataProvider = "trueFalse")
+ public void test18(boolean val) throws Exception {
+ brs.setReadOnly(val);
+ assertTrue(brs.isReadOnly() == val);
+ }
+
+ /*
+ * Validate that getTransactionIsolation() returns value set by
+ * setTransactionIsolation()
+ */
+ @Test(dataProvider = "isolationTypes")
+ public void test19(int val) throws Exception {
+ brs.setTransactionIsolation(val);
+ assertTrue(brs.getTransactionIsolation() == val);
+ }
+
+ /*
+ * Validate that getType() returns value set by setType()
+ */
+ @Test(dataProvider = "scrollTypes")
+ public void test20(int val) throws Exception {
+ brs.setType(val);
+ assertTrue(brs.getType() == val);
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns value set by
+ * setEscapeProcessing()
+ */
+ @Test(dataProvider = "trueFalse")
+ public void test21(boolean val) throws Exception {
+ brs.setShowDeleted(val);
+ assertTrue(brs.getShowDeleted() == val);
+ }
+
+ /*
+ * Validate that getTypeMap() returns same value set by
+ * setTypeMap()
+ */
+ @Test()
+ public void test22() throws Exception {
+ brs.setTypeMap(map);
+ assertTrue(brs.getTypeMap().equals(map));
+ }
+
+ /*
+ * Validate that getUsername() returns same value set by
+ * setUsername()
+ */
+ @Test()
+ public void test23() throws Exception {
+ brs.setUsername(user);
+ assertTrue(brs.getUsername().equals(user));
+ }
+
+ /*
+ * Validate that getPassword() returns same password set by
+ * setPassword()
+ */
+ @Test()
+ public void test24() throws Exception {
+ brs.setPassword(password);
+ assertTrue(brs.getPassword().equals(password));
+ }
+
+ /*
+ * Validate that getQueryTimeout() returns same value set by
+ * setQueryTimeout() and that 0 is a valid timeout value
+ */
+ @Test()
+ public void test25() throws Exception {
+ int timeout = 0;
+ brs.setQueryTimeout(timeout);
+ assertTrue(brs.getQueryTimeout() == timeout);
+ }
+
+ /*
+ * Validate that getQueryTimeout() returns same value set by
+ * setQueryTimeout() and that 0 is a valid timeout value
+ */
+ @Test()
+ public void test26() throws Exception {
+ int timeout = 10000;
+ brs.setQueryTimeout(timeout);
+ assertTrue(brs.getQueryTimeout() == timeout);
+ }
+
+ /*
+ * Validate that setQueryTimeout() throws a SQLException for a timeout
+ * value < 0
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test27() throws Exception {
+ brs.setQueryTimeout(-1);
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowSetChanged is called
+ */
+ @Test()
+ public void test28() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.notifyRowSetChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowChanged is called
+ */
+ @Test()
+ public void test29() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.notifyRowChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyCursorMoved is called
+ */
+ @Test()
+ public void test30() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowSetChanged,
+ * notifyRowChanged() and notifyCursorMoved are called
+ */
+ @Test()
+ public void test31() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.notifyRowSetChanged();
+ brs.notifyRowChanged();
+ brs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(
+ TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
+ | TestRowSetListener.ROW_CHANGED));
+ }
+
+ /*
+ * Create multiple RowSetListeners and validate that notifyRowSetChanged
+ * is called on all listeners
+ */
+ @Test()
+ public void test32() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ TestRowSetListener rsl2 = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.addRowSetListener(rsl2);
+ brs.notifyRowSetChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ assertTrue(rsl2.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ }
+
+ /*
+ * Create multiple RowSetListeners and validate that notifyRowChanged
+ * is called on all listeners
+ */
+ @Test()
+ public void test33() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ TestRowSetListener rsl2 = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.addRowSetListener(rsl2);
+ brs.notifyRowChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
+ assertTrue(rsl2.isNotified(TestRowSetListener.ROW_CHANGED));
+ }
+
+ /*
+ * Create multiple RowSetListeners and validate that notifyCursorMoved
+ * is called on all listeners
+ */
+ @Test()
+ public void test34() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ TestRowSetListener rsl2 = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.addRowSetListener(rsl2);
+ brs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
+ assertTrue(rsl2.isNotified(TestRowSetListener.CURSOR_MOVED));
+ }
+
+ /*
+ * Create multiple RowSetListeners and validate that notifyRowSetChanged,
+ * notifyRowChanged() and notifyCursorMoved are called on all listeners
+ */
+ @Test()
+ public void test35() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ TestRowSetListener rsl2 = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.addRowSetListener(rsl2);
+ brs.notifyRowSetChanged();
+ brs.notifyRowChanged();
+ brs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(
+ TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
+ | TestRowSetListener.ROW_CHANGED));
+ assertTrue(rsl2.isNotified(
+ TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
+ | TestRowSetListener.ROW_CHANGED));
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowSetChanged is called,
+ * remove the listener, invoke notifyRowSetChanged again and verify the
+ * listner is not called
+ */
+ @Test()
+ public void test36() throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ brs.addRowSetListener(rsl);
+ brs.notifyRowSetChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ // Clear the flag indicating the listener has been called
+ rsl.resetFlag();
+ brs.removeRowSetListener(rsl);
+ brs.notifyRowSetChanged();
+ assertFalse(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ }
+
+ /*
+ * Validate addRowSetListener does not throw an Exception when null is
+ * passed as the parameter
+ */
+ @Test()
+ public void test37() throws Exception {
+ brs.addRowSetListener(null);
+ }
+
+ /*
+ * Validate removeRowSetListener does not throw an Exception when null is
+ * passed as the parameter
+ */
+ @Test()
+ public void test38() throws Exception {
+ brs.removeRowSetListener(null);
+ }
+
+ /*
+ * Set two parameters and then validate clearParameters() will clear them
+ */
+ @Test()
+ public void test39() throws Exception {
+ brs.setInt(1, 1);
+ brs.setString(2, query);
+ assertTrue(brs.getParams().length == 2);
+ brs.clearParameters();
+ assertTrue(brs.getParams().length == 0);
+ }
+
+ /*
+ * Set the base parameters and validate that the value set is
+ * the correct type and value
+ */
+ @Test(dataProvider = "testBaseParameters")
+ public void test40(int pos, Object o) throws Exception {
+ assertTrue(getParam(pos, o).getClass().isInstance(o));
+ assertTrue(o.equals(getParam(pos, o)));
+ }
+
+ /*
+ * Set the complex parameters and validate that the value set is
+ * the correct type
+ */
+ @Test(dataProvider = "testAdvancedParameters")
+ public void test41(int pos, Object o) throws Exception {
+ assertTrue(getParam(pos, o).getClass().isInstance(o));
+ }
+
+ /*
+ * Validate setNull specifying the supported type values
+ */
+ @Test(dataProvider = "jdbcTypes")
+ public void test42(Integer type) throws Exception {
+ brs.setNull(1, type);
+ assertTrue(checkNullParam(1, type, null));
+ }
+
+ /*
+ * Validate setNull specifying the supported type values and that
+ * typeName is set internally
+ */
+ @Test(dataProvider = "jdbcTypes")
+ public void test43(Integer type) throws Exception {
+ brs.setNull(1, type, "SUPERHERO");
+ assertTrue(checkNullParam(1, type, "SUPERHERO"));
+ }
+
+ /*
+ * Validate that setDate sets the specified Calendar internally
+ */
+ @Test()
+ public void test44() throws Exception {
+ brs.setDate(1, aDate, cal);
+ assertTrue(checkCalendarParam(1, cal));
+ }
+
+ /*
+ * Validate that setTime sets the specified Calendar internally
+ */
+ @Test()
+ public void test45() throws Exception {
+ brs.setTime(1, aTime, cal);
+ assertTrue(checkCalendarParam(1, cal));
+ }
+
+ /*
+ * Validate that setTimestamp sets the specified Calendar internally
+ */
+ @Test()
+ public void test46() throws Exception {
+ brs.setTimestamp(1, ts, cal);
+ assertTrue(checkCalendarParam(1, cal));
+ }
+
+ /*
+ * Validate that getURL() returns same value set by
+ * setURL()
+ */
+ @Test()
+ public void test47() throws Exception {
+ brs.setUrl(url);
+ assertTrue(brs.getUrl().equals(url));
+ }
+
+ /*
+ * Validate that initParams() initializes the parameters
+ */
+ @Test()
+ public void test48() throws Exception {
+ brs.setInt(1, 1);
+ brs.initParams();
+ assertTrue(brs.getParams().length == 0);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test100() throws Exception {
+ brs1.setAsciiStream(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test101() throws Exception {
+ brs1.setAsciiStream("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test102() throws Exception {
+ brs1.setAsciiStream("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test103() throws Exception {
+ brs1.setBinaryStream(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test104() throws Exception {
+ brs1.setBinaryStream("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test105() throws Exception {
+ brs1.setBinaryStream("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test106() throws Exception {
+ brs1.setBigDecimal("one", BigDecimal.ONE);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test107() throws Exception {
+ brs1.setBlob(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test108() throws Exception {
+ brs1.setBlob("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test109() throws Exception {
+ brs1.setBlob("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test110() throws Exception {
+ brs1.setBlob("one", aBlob);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test111() throws Exception {
+ brs1.setBoolean("one", true);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test112() throws Exception {
+ byte b = 1;
+ brs1.setByte("one", b);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test113() throws Exception {
+ byte b = 1;
+ brs1.setBytes("one", bytes);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test114() throws Exception {
+ brs1.setCharacterStream("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test115() throws Exception {
+ brs1.setCharacterStream("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test116() throws Exception {
+ brs1.setCharacterStream(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test117() throws Exception {
+ brs1.setClob(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test118() throws Exception {
+ brs1.setClob("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test119() throws Exception {
+ brs1.setClob("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test120() throws Exception {
+ brs1.setClob("one", aClob);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test121() throws Exception {
+ brs1.setDate("one", aDate);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test122() throws Exception {
+ brs1.setDate("one", aDate, cal);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test123() throws Exception {
+ brs1.setTime("one", aTime);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test124() throws Exception {
+ brs1.setTime("one", aTime, cal);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test125() throws Exception {
+ brs1.setTimestamp("one", ts);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test126() throws Exception {
+ brs1.setTimestamp("one", ts, cal);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test127() throws Exception {
+ brs1.setDouble("one", 2.0d);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test128() throws Exception {
+ brs1.setFloat("one", 2.0f);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test129() throws Exception {
+ brs1.setInt("one", 21);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test130() throws Exception {
+ brs1.setLong("one", 21l);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test131() throws Exception {
+ brs1.setNCharacterStream("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test132() throws Exception {
+ brs1.setNCharacterStream("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test133() throws Exception {
+ brs1.setNCharacterStream(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test134() throws Exception {
+ brs1.setNCharacterStream(1, rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test135() throws Exception {
+ brs1.setClob("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test136() throws Exception {
+ brs1.setClob("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test137() throws Exception {
+ brs1.setNClob("one", new StubNClob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test138() throws Exception {
+ brs1.setNClob(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test139() throws Exception {
+ brs1.setNClob(1, rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test140() throws Exception {
+ brs1.setNClob(1, new StubNClob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test141() throws Exception {
+ brs1.setNString(1, query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test142() throws Exception {
+ brs1.setNull("one", Types.INTEGER);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test143() throws Exception {
+ brs1.setNull("one", Types.INTEGER, "my.type");
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test144() throws Exception {
+ brs1.setObject("one", query, Types.VARCHAR);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test145() throws Exception {
+ brs1.setObject("one", query, Types.VARCHAR, 0);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test146() throws Exception {
+ brs1.setObject("one", query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test147() throws Exception {
+ brs1.setRowId("one", aRowid);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test148() throws Exception {
+ brs1.setSQLXML("one", new StubSQLXML());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test149() throws Exception {
+ brs1.setSQLXML(1, new StubSQLXML());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test150() throws Exception {
+ brs1.setNString(1, query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test151() throws Exception {
+ brs1.setNString("one", query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void test152() throws Exception {
+ short val = 21;
+ brs1.setShort("one", val);
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for
+ * methods using transaction isolation types
+ */
+ @DataProvider(name = "isolationTypes")
+ private Object[][] isolationTypes() {
+ return new Object[][]{
+ {Connection.TRANSACTION_NONE},
+ {Connection.TRANSACTION_READ_COMMITTED},
+ {Connection.TRANSACTION_READ_UNCOMMITTED},
+ {Connection.TRANSACTION_REPEATABLE_READ},
+ {Connection.TRANSACTION_SERIALIZABLE}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for fetch direction
+ */
+ @DataProvider(name = "fetchDirection")
+ private Object[][] fetchDirection() {
+ return new Object[][]{
+ {ResultSet.FETCH_FORWARD},
+ {ResultSet.FETCH_REVERSE},
+ {ResultSet.FETCH_UNKNOWN}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for Concurrency
+ */
+ @DataProvider(name = "concurTypes")
+ private Object[][] concurTypes() {
+ return new Object[][]{
+ {ResultSet.CONCUR_READ_ONLY},
+ {ResultSet.CONCUR_UPDATABLE}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for Cursor Scroll Type
+ */
+ @DataProvider(name = "scrollTypes")
+ private Object[][] scrollTypes() {
+ return new Object[][]{
+ {ResultSet.TYPE_FORWARD_ONLY},
+ {ResultSet.TYPE_SCROLL_INSENSITIVE},
+ {ResultSet.TYPE_SCROLL_SENSITIVE}
+ };
+ }
+
+ /*
+ * DataProvider used to set parameters for basic types that are supported
+ */
+ @DataProvider(name = "testBaseParameters")
+ private Object[][] testBaseParameters() throws SQLException {
+ Integer aInt = 1;
+ Long aLong = Long.MAX_VALUE;
+ Short aShort = Short.MIN_VALUE;
+ BigDecimal bd = BigDecimal.ONE;
+ Double aDouble = Double.MAX_VALUE;
+ Boolean aBoolean = true;
+ Float aFloat = 1.5f;
+ Byte aByte = 1;
+
+ brs1.clearParameters();
+ brs1.setInt(1, aInt);
+ brs1.setString(2, query);
+ brs1.setLong(3, aLong);
+ brs1.setBoolean(4, aBoolean);
+ brs1.setShort(5, aShort);
+ brs1.setDouble(6, aDouble);
+ brs1.setBigDecimal(7, bd);
+ brs1.setFloat(8, aFloat);
+ brs1.setByte(9, aByte);
+ brs1.setDate(10, aDate);
+ brs1.setTime(11, aTime);
+ brs1.setTimestamp(12, ts);
+ brs1.setDate(13, aDate, cal);
+ brs1.setTime(14, aTime, cal);
+ brs1.setTimestamp(15, ts);
+ brs1.setObject(16, query);
+ brs1.setObject(17, query, Types.CHAR);
+ brs1.setObject(18, query, Types.CHAR, 0);
+
+ return new Object[][]{
+ {1, aInt},
+ {2, query},
+ {3, aLong},
+ {4, aBoolean},
+ {5, aShort},
+ {6, aDouble},
+ {7, bd},
+ {8, aFloat},
+ {9, aByte},
+ {10, aDate},
+ {11, aTime},
+ {12, ts},
+ {13, aDate},
+ {14, aTime},
+ {15, ts},
+ {16, query},
+ {17, query},
+ {18, query}
+
+ };
+ }
+
+ /*
+ * DataProvider used to set advanced parameters for types that are supported
+ */
+ @DataProvider(name = "testAdvancedParameters")
+ private Object[][] testAdvancedParameters() throws SQLException {
+
+ brs1.clearParameters();
+ brs1.setBytes(1, bytes);
+ brs1.setAsciiStream(2, is, query.length());
+ brs1.setRef(3, aRef);
+ brs1.setArray(4, aArray);
+ brs1.setBlob(5, aBlob);
+ brs1.setClob(6, aClob);
+ brs1.setBinaryStream(7, is, query.length());
+ brs1.setUnicodeStream(8, is, query.length());
+ brs1.setCharacterStream(9, rdr, query.length());
+
+ return new Object[][]{
+ {1, bytes},
+ {2, is},
+ {3, aRef},
+ {4, aArray},
+ {5, aBlob},
+ {6, aClob},
+ {7, is},
+ {8, is},
+ {9, rdr}
+ };
+ }
+
+ /*
+ * Method that returns the specified parameter instance that was set via setXXX
+ * Note non-basic types are stored as an Object[] where the 1st element
+ * is the object instnace
+ */
+ @SuppressWarnings("unchecked")
+ private <T> T getParam(int pos, T o) throws SQLException {
+ Object[] params = brs1.getParams();
+ if (params[pos - 1] instanceof Object[]) {
+ Object[] param = (Object[]) params[pos - 1];
+ return (T) param[0];
+ } else {
+ return (T) params[pos - 1];
+ }
+ }
+
+ /*
+ * Utility method to validate parameters when the param is an Object[]
+ */
+ private boolean checkParam(int pos, int type, Object val) throws SQLException {
+ boolean result = false;
+ Object[] params = brs.getParams();
+ if (params[pos - 1] instanceof Object[]) {
+ Object[] param = (Object[]) params[pos - 1];
+
+ if (param[0] == null) {
+ // setNull was used
+ if (param.length == 2 && (Integer) param[1] == type) {
+ result = true;
+ } else {
+ if (param.length == 3 && (Integer) param[1] == type
+ && val.equals(param[2])) {
+ result = true;
+ }
+ }
+
+ } else if (param[0] instanceof java.util.Date) {
+ // setDate/Time/Timestamp with a Calendar object
+ if (param[1] instanceof Calendar && val.equals(param[1])) {
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Wrapper method for validating that a null was set and the appropriate
+ * type and typeName if applicable
+ */
+ private boolean checkNullParam(int pos, int type, String typeName) throws SQLException {
+ return checkParam(pos, type, typeName);
+ }
+
+ /*
+ * Wrapper method for validating that a Calander was set
+ */
+ private boolean checkCalendarParam(int pos, Calendar cal) throws SQLException {
+ // 2nd param is ignored when instanceof java.util.Date
+ return checkParam(pos, Types.DATE, cal);
+ }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java
new file mode 100644
index 00000000000..a6756a13a4a
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SQLInputImplTests.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.Struct;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.rowset.serial.SQLInputImpl;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubArray;
+import util.StubBlob;
+import util.StubClob;
+import util.StubRef;
+import util.StubStruct;
+import util.SuperHero;
+import util.TestSQLDataImpl;
+
+public class SQLInputImplTests extends BaseTest {
+
+ // Copy of the array of data type values
+ private Object[] typeValues;
+ private TestSQLDataImpl impl;
+ private Map<String, Class<?>> map ;
+ private SuperHero hero;
+ private final String sqlType = "SUPERHERO";
+
+ @BeforeMethod
+ @Override
+ public void setUpMethod() throws Exception {
+ map = new HashMap<>();
+ impl = new TestSQLDataImpl("TestSQLData");
+ typeValues = Arrays.copyOf(TestSQLDataImpl.attributes,
+ TestSQLDataImpl.attributes.length);
+ hero = new SuperHero(sqlType, "Bruce", "Wayne",
+ 1939, "Batman");
+ }
+
+ /*
+ * Validate that a SQLException is thrown if the attribute value is
+ * null
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test() throws Exception {
+ SQLInputImpl x = new SQLInputImpl(null, map);
+ }
+
+ /*
+ * Validate that a SQLException is thrown if the map value is
+ * null
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test02() throws Exception {
+ SQLInputImpl x = new SQLInputImpl(typeValues, null);
+ }
+
+ /*
+ * Read in the various datatypes via readSQL (which will exercise the
+ * various readXXX methods and validate that results are as expected
+ */
+ @Test()
+ public void test03() throws Exception {
+ impl.readSQL(new SQLInputImpl(typeValues, map), "misc");
+ assertTrue(Arrays.equals(impl.toArray(), typeValues));
+ // Null out a field and make sure the arrays do not match
+ typeValues[2] = null;
+ assertFalse(Arrays.equals(impl.toArray(), typeValues));
+ }
+
+ /*
+ * Validate that wasNull indicates if a null was read in
+ */
+ @Test()
+ public void test04() throws Exception {
+ Object[] values = {"Hello", null, 1};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ String s = sqli.readString();
+ assertFalse(sqli.wasNull());
+ s = sqli.readString();
+ assertTrue(sqli.wasNull());
+ int i = sqli.readInt();
+ assertFalse(sqli.wasNull());
+ }
+
+ /*
+ * Validate that readObject returns the correct value
+ */
+ @Test()
+ public void test05() throws Exception {
+ Object[] values = {hero};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Object o = sqli.readObject();
+ assertTrue(hero.equals(o));
+
+ }
+
+ /*
+ * Validate a Array can be read
+ */
+ @Test(enabled = true)
+ public void test06() throws Exception {
+ Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast",
+ "Cappuccino"};
+ Array a = new StubArray("VARCHAR", coffees);
+ Object[] values = {a};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Array a2 = sqli.readArray();
+ assertTrue(Arrays.equals((Object[]) a2.getArray(), (Object[]) a.getArray()));
+ assertTrue(a.getBaseTypeName().equals(a2.getBaseTypeName()));
+ }
+
+ /*
+ * Validate a Blob can be read
+ */
+ @Test(enabled = true)
+ public void test07() throws Exception {
+ Blob b = new StubBlob();
+ Object[] values = {b};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Blob b2 = sqli.readBlob();
+ assertTrue(Arrays.equals(
+ b.getBytes(1, (int) b.length()),
+ b2.getBytes(1, (int) b2.length())));
+ }
+
+ /*
+ * Validate a Clob can be read
+ */
+ @Test(enabled = true)
+ public void test08() throws Exception {
+ Clob c = new StubClob();
+ Object[] values = {c};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Clob c2 = sqli.readClob();
+ assertTrue(c.getSubString(1,
+ (int) c.length()).equals(c2.getSubString(1, (int) c2.length())));
+ }
+
+ /*
+ * Validate a Ref can be read
+ */
+ @Test(enabled = true)
+ public void test09() throws Exception {
+ Ref ref = new StubRef(sqlType, hero);
+ Object[] values = {ref};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Ref ref2 = sqli.readRef();
+ assertTrue(ref.getObject().equals(ref2.getObject()));
+ assertTrue(ref.getBaseTypeName().equals(ref2.getBaseTypeName()));
+ }
+
+ /*
+ * Validate a URL can be read
+ */
+ @Test(enabled = true)
+ public void test10() throws Exception {
+ URL u = new URL("http://www.oracle.com/");;
+ Object[] values = {u};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ URL u2 = sqli.readURL();
+ assertTrue(u2.equals(u));
+ assertTrue(u2.sameFile(u));
+ }
+
+ /*
+ * Validate that readObject returns the correct value when a Struct is
+ * next on the stream
+ */
+ @Test()
+ public void test11() throws Exception {
+ Object[] attributes = new Object[]{"Bruce", "Wayne", 1939,
+ "Batman"};
+ map.put(sqlType, Class.forName("util.SuperHero"));
+ Struct struct = new StubStruct(sqlType, attributes);
+ Object[] values = {struct};
+ SQLInputImpl sqli = new SQLInputImpl(values, map);
+ Object o = sqli.readObject();
+
+ assertTrue(hero.equals(o));
+
+ }
+}
diff --git a/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java b/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java
new file mode 100644
index 00000000000..00f62df6f79
--- /dev/null
+++ b/jdk/test/javax/sql/testng/test/rowset/serial/SQLOutputImplTests.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.serial;
+
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.Struct;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import javax.sql.rowset.serial.SQLInputImpl;
+import javax.sql.rowset.serial.SQLOutputImpl;
+import javax.sql.rowset.serial.SerialArray;
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialDatalink;
+import javax.sql.rowset.serial.SerialRef;
+import javax.sql.rowset.serial.SerialStruct;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubArray;
+import util.StubBlob;
+import util.StubClob;
+import util.StubRef;
+import util.StubStruct;
+import util.SuperHero;
+import util.TestSQLDataImpl;
+
+public class SQLOutputImplTests extends BaseTest {
+
+ // Copy of the array of data type values
+ private Object[] typeValues;
+ private TestSQLDataImpl impl;
+ private Map<String, Class<?>> map = new HashMap<>();
+ private Vector results;
+ private final String sqlType = "SUPERHERO";
+ private SuperHero hero;
+ private SQLOutputImpl outImpl;
+
+ @BeforeMethod
+ @Override
+ public void setUpMethod() throws Exception {
+ results = new Vector();
+ impl = new TestSQLDataImpl("TestSQLData");
+ typeValues = Arrays.copyOf(TestSQLDataImpl.attributes,
+ TestSQLDataImpl.attributes.length);
+ hero = new SuperHero(sqlType, "Bruce", "Wayne", 1939, "Batman");
+ outImpl = new SQLOutputImpl(results, map);
+ }
+
+ /*
+ * Validate that a SQLException is thrown if the attribute value is
+ * null
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test() throws Exception {
+ SQLOutputImpl x = new SQLOutputImpl(null, map);
+ }
+
+ /*
+ * Validate that a SQLException is thrown if the map value is
+ * null
+ */
+ @Test(expectedExceptions = SQLException.class)
+ public void test02() throws Exception {
+ SQLOutputImpl x = new SQLOutputImpl(results, null);
+ }
+
+ /*
+ * Read in the various datatypes via readSQL (which will exercise the
+ * various readXXX methods and validate that results are as expected
+ */
+ @Test()
+ public void test03() throws Exception {
+ impl.readSQL(new SQLInputImpl(typeValues, map), "misc");
+ impl.writeSQL(outImpl);
+ assertTrue(Arrays.equals(results.toArray(), typeValues));
+ // Null out a field and make sure the arrays do not match
+ typeValues[2] = null;
+ assertFalse(Arrays.equals(results.toArray(), typeValues));
+ }
+
+ /*
+ * Validate a Array can be written and returned
+ */
+ @Test(enabled = true)
+ public void test04() throws Exception {
+ Object[] coffees = new Object[]{"Espresso", "Colombian", "French Roast",
+ "Cappuccino"};
+ Array a = new StubArray("VARCHAR", coffees);
+ outImpl.writeArray(a);
+ SerialArray sa = (SerialArray) results.get(0);
+ assertTrue(Arrays.equals(coffees, (Object[]) sa.getArray()));
+ assertTrue(a.getBaseTypeName().equals(sa.getBaseTypeName()));
+ }
+
+ /*
+ * Validate a Blob can be written and returned
+ */
+ @Test(enabled = true)
+ public void test05() throws Exception {
+ Blob b = new StubBlob();
+ outImpl.writeBlob(b);
+ SerialBlob sb = (SerialBlob) results.get(0);
+ assertTrue(Arrays.equals(
+ b.getBytes(1, (int) b.length()),
+ sb.getBytes(1, (int) sb.length())));
+ }
+
+ /*
+ * Validate a Clob can be written and returned
+ */
+ @Test(enabled = true)
+ public void test06() throws Exception {
+ Clob c = new StubClob();
+ outImpl.writeClob(c);
+ SerialClob sc = (SerialClob) results.get(0);
+ assertTrue(c.getSubString(1,
+ (int) c.length()).equals(sc.getSubString(1, (int) sc.length())));
+ }
+
+ /*
+ * Validate a Ref can be written and returned
+ */
+ @Test(enabled = true)
+ public void test07() throws Exception {
+ Ref ref = new StubRef(sqlType, hero);
+ outImpl.writeRef(ref);
+ SerialRef sr = (SerialRef) results.get(0);
+ assertTrue(hero.equals(sr.getObject()));
+ }
+
+ /*
+ * Validate a Struct can be written and returned
+ */
+ @Test(enabled = true)
+ public void test08() throws Exception {
+ Object[] attributes = new Object[]{"Bruce", "Wayne", 1939,
+ "Batman"};
+ Struct s = new StubStruct(sqlType, attributes);
+ outImpl.writeStruct(s);
+ SerialStruct ss = (SerialStruct) results.get(0);
+ assertTrue(Arrays.equals(attributes, (Object[]) ss.getAttributes()));
+ assertTrue(sqlType.equals(ss.getSQLTypeName()));
+ }
+
+ /*
+ * Validate a DataLink can be written and returned
+ */
+ @Test(enabled = true)
+ public void test09() throws Exception {
+ URL u = new URL("http://www.oracle.com/");
+ outImpl.writeURL(u);
+ SerialDatalink sdl = (SerialDatalink) results.get(0);
+ URL u2 = sdl.getDatalink();
+ assertTrue(u2.equals(u));
+ assertTrue(u2.sameFile(u));
+ }
+
+ /*
+ * Validate an Object implementing SQLData can be written and returned
+ */
+ @Test(enabled = true)
+ public void test10() throws Exception {
+ Object[] attributes = new Object[]{"Bruce", "Wayne", 1939,
+ "Batman"};
+ outImpl.writeObject(hero);
+ SerialStruct ss = (SerialStruct) results.get(0);
+ assertTrue(Arrays.equals(attributes, (Object[]) ss.getAttributes()));
+ assertTrue(sqlType.equals(ss.getSQLTypeName()));
+ }
+}
diff --git a/jdk/test/javax/sql/testng/util/StubBaseRowSet.java b/jdk/test/javax/sql/testng/util/StubBaseRowSet.java
new file mode 100644
index 00000000000..e003b522ed9
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubBaseRowSet.java
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+import javax.sql.RowSet;
+import javax.sql.rowset.BaseRowSet;
+
+public class StubBaseRowSet extends BaseRowSet implements RowSet {
+
+ public StubBaseRowSet() {
+ super();
+ // Must call initParams() as part of initialization
+ super.initParams();
+ }
+
+ public void notifyCursorMoved() throws SQLException {
+ super.notifyCursorMoved();
+ }
+
+ public void notifyRowChanged() throws SQLException {
+ super.notifyRowChanged();
+ }
+
+ public void notifyRowSetChanged() throws SQLException {
+ super.notifyRowSetChanged();
+ }
+
+ public void initParams() {
+ super.initParams();
+ }
+
+ // Methods required by RowSet interace, not used
+ @Override
+ public void execute() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean next() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void close() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean wasNull() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getString(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean getBoolean(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte getByte(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public short getShort(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public int getInt(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public long getLong(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public float getFloat(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public double getDouble(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte[] getBytes(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Date getDate(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Time getTime(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Timestamp getTimestamp(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getAsciiStream(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getBinaryStream(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getString(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean getBoolean(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte getByte(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public short getShort(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public int getInt(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public long getLong(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public float getFloat(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public double getDouble(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public byte[] getBytes(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Date getDate(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Time getTime(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Timestamp getTimestamp(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getAsciiStream(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getUnicodeStream(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getBinaryStream(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getCursorName() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public ResultSetMetaData getMetaData() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Object getObject(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Object getObject(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public int findColumn(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Reader getCharacterStream(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Reader getCharacterStream(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isBeforeFirst() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isAfterLast() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isFirst() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isLast() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void beforeFirst() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void afterLast() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean first() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean last() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public int getRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean absolute(int row) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean relative(int rows) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean previous() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean rowUpdated() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean rowInserted() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean rowDeleted() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNull(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateByte(int columnIndex, byte x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateShort(int columnIndex, short x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateInt(int columnIndex, int x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateLong(int columnIndex, long x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateFloat(int columnIndex, float x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateDouble(int columnIndex, double x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateString(int columnIndex, String x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateDate(int columnIndex, Date x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateTime(int columnIndex, Time x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateObject(int columnIndex, Object x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNull(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBoolean(String columnLabel, boolean x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateByte(String columnLabel, byte x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateShort(String columnLabel, short x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateInt(String columnLabel, int x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateLong(String columnLabel, long x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateFloat(String columnLabel, float x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateDouble(String columnLabel, double x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateString(String columnLabel, String x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBytes(String columnLabel, byte[] x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateDate(String columnLabel, Date x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateTime(String columnLabel, Time x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateObject(String columnLabel, Object x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void insertRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void deleteRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void refreshRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void cancelRowUpdates() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void moveToInsertRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void moveToCurrentRow() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Statement getStatement() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Ref getRef(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Blob getBlob(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Clob getClob(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Array getArray(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Object getObject(String columnLabel, Map<String, Class<?>> map) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Ref getRef(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Blob getBlob(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Clob getClob(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Array getArray(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Date getDate(String columnLabel, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Time getTime(String columnLabel, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public java.net.URL getURL(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public java.net.URL getURL(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateRef(int columnIndex, Ref x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateRef(String columnLabel, Ref x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(int columnIndex, Blob x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(String columnLabel, Blob x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(int columnIndex, Clob x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(String columnLabel, Clob x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateArray(int columnIndex, Array x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateArray(String columnLabel, Array x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public RowId getRowId(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public RowId getRowId(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateRowId(int columnIndex, RowId x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateRowId(String columnLabel, RowId x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public int getHoldability() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isClosed() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNString(int columnIndex, String nString) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNString(String columnLabel, String nString) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public NClob getNClob(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public NClob getNClob(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public SQLXML getSQLXML(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public SQLXML getSQLXML(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getNString(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getNString(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Reader getNCharacterStream(int columnIndex) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Reader getNCharacterStream(String columnLabel) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(int columnIndex, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateClob(String columnLabel, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
diff --git a/jdk/test/javax/sql/testng/util/StubNClob.java b/jdk/test/javax/sql/testng/util/StubNClob.java
new file mode 100644
index 00000000000..10682578b9a
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubNClob.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.sql.NClob;
+
+public class StubNClob extends StubClob implements NClob {
+
+}
diff --git a/hotspot/test/runtime/NMT/UnsafeMallocLimit.java b/jdk/test/javax/sql/testng/util/StubRowId.java
index 1df1f8eb37b..f8e90d49867 100644
--- a/hotspot/test/runtime/NMT/UnsafeMallocLimit.java
+++ b/jdk/test/javax/sql/testng/util/StubRowId.java
@@ -20,31 +20,15 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+package util;
-/*
- * @test
- * @bug 8055289
- * @library /testlibrary
- * @build UnsafeMallocLimit
- * @run main/othervm -Xmx32m -XX:NativeMemoryTracking=summary UnsafeMallocLimit
- */
+import java.sql.RowId;
-import com.oracle.java.testlibrary.*;
-import sun.misc.Unsafe;
+public class StubRowId implements RowId {
-public class UnsafeMallocLimit {
-
- public static void main(String args[]) throws Exception {
- if (Platform.is32bit()) {
- Unsafe unsafe = Utils.getUnsafe();
- try {
- unsafe.allocateMemory(1 << 30);
- throw new RuntimeException("Did not get expected OOME");
- } catch (OutOfMemoryError e) {
- // Expected exception
- }
- } else {
- System.out.println("Test only valid on 32-bit platforms");
- }
+ @Override
+ public byte[] getBytes() {
+ throw new UnsupportedOperationException("Not supported yet.");
}
+
}
diff --git a/jdk/test/javax/sql/testng/util/StubSQLXML.java b/jdk/test/javax/sql/testng/util/StubSQLXML.java
new file mode 100644
index 00000000000..44d1351b357
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/StubSQLXML.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+public class StubSQLXML implements SQLXML{
+
+ @Override
+ public void free() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getBinaryStream() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public OutputStream setBinaryStream() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Writer setCharacterStream() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getString() throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public void setString(String value) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public <T extends Source> T getSource(Class<T> sourceClass) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public <T extends Result> T setResult(Class<T> resultClass) throws SQLException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+}
diff --git a/jdk/test/javax/sql/testng/util/SuperHero.java b/jdk/test/javax/sql/testng/util/SuperHero.java
index 8588f5006f1..c8afb3831de 100644
--- a/jdk/test/javax/sql/testng/util/SuperHero.java
+++ b/jdk/test/javax/sql/testng/util/SuperHero.java
@@ -32,10 +32,14 @@ public class SuperHero implements SQLData, Serializable {
private String first;
private String last;
- private final String type;
+ private String type = "SUPERHERO";
private Integer firstYear;
private String secretIdentity;
+ public SuperHero() {
+
+ }
+
public SuperHero(String sqlType, String fname, String lname, Integer year,
String identity) {
first = fname;
diff --git a/jdk/test/javax/sql/testng/util/TestRowSetListener.java b/jdk/test/javax/sql/testng/util/TestRowSetListener.java
new file mode 100644
index 00000000000..069ade29ca2
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/TestRowSetListener.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import javax.sql.RowSetEvent;
+import javax.sql.RowSetListener;
+
+public class TestRowSetListener implements RowSetListener {
+
+ // Flags to indicate which listener events should have been notified
+ public final static int ROWSET_CHANGED = 1;
+ public final static int ROW_CHANGED = 2;
+ public final static int CURSOR_MOVED = 4;
+ private int flag;
+
+ @Override
+ public void rowSetChanged(RowSetEvent event) {
+ flag |= ROWSET_CHANGED;
+ }
+
+ @Override
+ public void rowChanged(RowSetEvent event) {
+ flag |= ROW_CHANGED;
+ }
+
+ @Override
+ public void cursorMoved(RowSetEvent event) {
+ flag |= CURSOR_MOVED;
+ }
+
+ /*
+ * Clear the flag indicating which events we were notified for
+ */
+ public void resetFlag() {
+ flag = 0;
+ }
+
+ /*
+ * Method used to validate that the correct event was notified
+ */
+ public boolean isNotified( int val) {
+ return flag == val;
+ }
+}
diff --git a/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java b/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java
new file mode 100644
index 00000000000..0694add3ef9
--- /dev/null
+++ b/jdk/test/javax/sql/testng/util/TestSQLDataImpl.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.SQLData;
+import java.sql.SQLException;
+import java.sql.SQLInput;
+import java.sql.SQLOutput;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Arrays;
+
+public class TestSQLDataImpl implements SQLData {
+
+ private final int stringPos = 0;
+ private final int datePos = 1;
+ private final int timePos = 2;
+ private final int timestampPos = 3;
+ private final int intPos = 4;
+ private final int longPos = 5;
+ private final int shortPos = 6;
+ private final int bigDecimalPos = 7;
+ private final int doublePos = 8;
+ private final int booleanPos = 9;
+ private final int floatPos = 10;
+ private final int bytePos = 11;
+ private final int bytesPos = 12;
+ private final int MAX_TYPES = bytesPos + 1;
+ private final Object[] types = new Object[MAX_TYPES];
+
+ private final static byte[] b = {1, 2, 3};
+
+ // attributes entries must line up with the ordering of the reading and
+ // writing of the fields in readSQL and writeSQL
+ public final static Object[] attributes = {"The Dark Knight",
+ Date.valueOf(LocalDate.now()), Time.valueOf(LocalTime.now()),
+ Timestamp.valueOf(LocalDateTime.now()), Integer.MAX_VALUE,
+ Long.MAX_VALUE, Short.MIN_VALUE, BigDecimal.ONE,
+ Double.MAX_VALUE, true, 1.5f, Byte.MAX_VALUE, b};
+
+ private String sqlType;
+
+ public TestSQLDataImpl(String type) {
+ sqlType = type;
+ }
+
+ @Override
+ public String getSQLTypeName() throws SQLException {
+ return sqlType;
+ }
+
+ @Override
+ public void readSQL(SQLInput stream, String typeName) throws SQLException {
+
+ sqlType = typeName;
+ types[stringPos] = stream.readString();
+ types[datePos] = stream.readDate();
+ types[timePos] = stream.readTime();
+ types[timestampPos] = stream.readTimestamp();
+ types[intPos] = stream.readInt();
+ types[longPos] = stream.readLong();
+ types[shortPos] = stream.readShort();
+ types[bigDecimalPos] = stream.readBigDecimal();
+ types[doublePos] = stream.readDouble();
+ types[booleanPos] = stream.readBoolean();
+ types[floatPos] = stream.readFloat();
+ types[bytePos] = stream.readByte();
+ types[bytesPos] = stream.readBytes();
+ }
+
+ @Override
+ public void writeSQL(SQLOutput stream) throws SQLException {
+
+ stream.writeString((String) types[stringPos]);
+ stream.writeDate((Date) types[datePos]);
+ stream.writeTime((Time) types[timePos]);
+ stream.writeTimestamp((Timestamp) types[timestampPos]);
+ stream.writeInt((Integer) types[intPos]);
+ stream.writeLong((Long) types[longPos]);
+ stream.writeShort((Short) types[shortPos]);
+ stream.writeBigDecimal((BigDecimal) types[bigDecimalPos]);
+ stream.writeDouble((Double) types[doublePos]);
+ stream.writeBoolean((Boolean) types[booleanPos]);
+ stream.writeFloat((Float) types[floatPos]);
+ stream.writeByte((Byte) types[bytePos]);
+ stream.writeBytes((byte[]) types[bytesPos]);
+ }
+
+ public Object[] toArray() {
+
+ Object[] result = Arrays.copyOf(types, types.length);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + sqlType + " " + types + "]";
+ }
+
+}
diff --git a/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java b/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java
new file mode 100644
index 00000000000..5f58d3dd664
--- /dev/null
+++ b/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.EventQueue;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+import sun.awt.SunToolkit;
+
+/**
+ * @test
+ * @bug 8057893
+ * @author Alexander Scherbatiy
+ * @summary JComboBox actionListener never receives "comboBoxEdited"
+ * from getActionCommand
+ * @run main bug8057893
+ */
+public class bug8057893 {
+
+ private static volatile boolean isComboBoxEdited = false;
+
+ public static void main(String[] args) throws Exception {
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ EventQueue.invokeAndWait(() -> {
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ JComboBox<String> comboBox = new JComboBox<>(new String[]{"one", "two"});
+ comboBox.setEditable(true);
+ comboBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if ("comboBoxEdited".equals(e.getActionCommand())) {
+ isComboBoxEdited = true;
+ }
+ }
+ });
+ frame.add(comboBox);
+ frame.pack();
+ frame.setVisible(true);
+ comboBox.requestFocusInWindow();
+ });
+
+ toolkit.realSync();
+
+ robot.keyPress(KeyEvent.VK_A);
+ robot.keyRelease(KeyEvent.VK_A);
+ robot.keyPress(KeyEvent.VK_ENTER);
+ robot.keyRelease(KeyEvent.VK_ENTER);
+ toolkit.realSync();
+
+ if(!isComboBoxEdited){
+ throw new RuntimeException("ComboBoxEdited event is not fired!");
+ }
+ }
+}
diff --git a/jdk/test/javax/swing/JTable/4222153/bug4222153.html b/jdk/test/javax/swing/JTable/4222153/bug4222153.html
new file mode 100644
index 00000000000..efa7e634c53
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.html
@@ -0,0 +1,31 @@
+<!--
+ Copyright (c) 1999, 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.
+-->
+
+<html>
+<body>
+Click in the upper-left cell and then press TAB two times.
+If table cell selection is not on the left cell of the second row
+then test fails.
+<applet code="bug4222153.class" width=200 height=200></applet>
+</body>
+</html>
diff --git a/jdk/test/javax/swing/JTable/4222153/bug4222153.java b/jdk/test/javax/swing/JTable/4222153/bug4222153.java
new file mode 100644
index 00000000000..75871c59974
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1999, 2014, 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 javax.swing.JApplet;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/**
+ * @test
+ * @bug 4222153
+ * @author Konstantin Eremin
+ * @run applet/manual=yesno bug4222153.html
+ */
+public class bug4222153 extends JApplet {
+
+ public void init() {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ UIManager.setLookAndFeel(
+ "javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ getContentPane().add(new JTable(2, 2));
+ });
+ }
+}
diff --git a/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html
new file mode 100644
index 00000000000..324f84be764
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html
@@ -0,0 +1,43 @@
+<!--
+ Copyright (c) 1999, 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.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>Keyboard Navigation in JTable</title>
+ </head>
+
+ <body>
+ <h1>Keyboard Navigation in JTable</h1>
+ <applet code=KeyBoardNavigation width=500 height=200>
+ </applet>
+
+ <p>
+ Refer to bug report 4112270 for spec of keyboard navigation. Check all combinations of navigational keys in all four modes shift and control verifying each change to the selection against the spec.
+ If it does, press "pass", otherwise press "fail".
+ <hr>
+ <address><a href="mailto:milne@taller">Philip Milne</a></address>
+
+ </body>
+</html>
+
diff --git a/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java
new file mode 100644
index 00000000000..39ce0acdf3f
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+
+/**
+ * @test
+ * @bug 4112270
+ * @summary
+ * Keyboard Navigation in JTable
+ * @author milne
+ * @run applet/manual=yesno KeyBoardNavigation.html
+ */
+public class KeyBoardNavigation extends JApplet
+{
+ static void initTest(Container contentPane)
+ {
+ // Take the dummy data from SwingSet.
+ final String[] names = {"First Name", "Last Name", "Favorite Color",
+ "Favorite Number", "Vegetarian"};
+ final Object[][] data = {
+ {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)},
+ {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)},
+ {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)},
+ {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)},
+ {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)},
+ {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)},
+ {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)},
+ {"David", "Karlton", "Red", new Integer(1), new Boolean(false)},
+ {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)},
+ {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)},
+ {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)},
+ {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)},
+ {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)},
+ {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)},
+ {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)},
+ {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)},
+ {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)},
+ {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)},
+ {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)},
+ {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)},
+ {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)}
+ };
+
+ // Create a model of the data.
+ TableModel dataModel = new AbstractTableModel() {
+ // These methods always need to be implemented.
+ public int getColumnCount() { return names.length; }
+ public int getRowCount() { return data.length;}
+ public Object getValueAt(int row, int col) {return data[row][col];}
+
+ // The default implementations of these methods in
+ // AbstractTableModel would work, but we can refine them.
+ public String getColumnName(int column) {return names[column];}
+ public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
+ public boolean isCellEditable(int row, int col) {return true;}
+ public void setValueAt(Object aValue, int row, int column) {
+ System.out.println("Setting value to: " + aValue);
+ data[row][column] = aValue;
+ }
+ };
+
+ // Create the table
+ JTable tableView = new JTable(dataModel);
+ // Turn off auto-resizing so that we can set column sizes programmatically.
+ // In this mode, all columns will get their preferred widths, as set blow.
+ tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+
+ // Create a combo box to show that you can use one in a table.
+ JComboBox comboBox = new JComboBox();
+ comboBox.addItem("Red");
+ comboBox.addItem("Orange");
+ comboBox.addItem("Yellow");
+ comboBox.addItem("Green");
+ comboBox.addItem("Blue");
+ comboBox.addItem("Indigo");
+ comboBox.addItem("Violet");
+
+ TableColumn colorColumn = tableView.getColumn("Favorite Color");
+ // Use the combo box as the editor in the "Favorite Color" column.
+ colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
+
+ // Set a pink background and tooltip for the Color column renderer.
+ DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer();
+ colorColumnRenderer.setBackground(Color.pink);
+ colorColumnRenderer.setToolTipText("Click for combo box");
+ colorColumn.setCellRenderer(colorColumnRenderer);
+
+ // Set a tooltip for the header of the colors column.
+ TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
+ if (headerRenderer instanceof DefaultTableCellRenderer)
+ ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!");
+
+ // Set the width of the "Vegetarian" column.
+ TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
+ vegetarianColumn.setPreferredWidth(100);
+
+ // Show the values in the "Favorite Number" column in different colors.
+ TableColumn numbersColumn = tableView.getColumn("Favorite Number");
+ DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() {
+ public void setValue(Object value) {
+ int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0;
+ setForeground((cellValue > 30) ? Color.black : Color.red);
+ setText((value == null) ? "" : value.toString());
+ }
+ };
+ numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
+ numbersColumn.setCellRenderer(numberColumnRenderer);
+ numbersColumn.setPreferredWidth(110);
+
+ // Finish setting up the table.
+ JScrollPane scrollpane = new JScrollPane(tableView);
+ scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
+ scrollpane.setPreferredSize(new Dimension(430, 200));
+
+ contentPane.add(scrollpane);
+ }
+
+
+ public void init() {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ UIManager.setLookAndFeel(
+ "javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ initTest(getContentPane());
+ });
+ }
+}
diff --git a/jdk/test/javax/swing/JTable/TAB/TAB.html b/jdk/test/javax/swing/JTable/TAB/TAB.html
new file mode 100644
index 00000000000..7c378253659
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/TAB/TAB.html
@@ -0,0 +1,43 @@
+<!--
+ Copyright (c) 1999, 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.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>Tabbing test</title>
+ </head>
+
+ <body>
+ <h1>Tabbing test</h1>
+ <applet code=TAB width=500 height=200>
+ </applet>
+
+ <p>
+ Select a cell by double clicking it, press tab. Check that the focus moves to the next cell.
+ If it does, press "pass", otherwise press "fail".
+ <hr>
+ <address><a href="mailto:milne@taller">Philip Milne</a></address>
+
+ </body>
+</html>
+
diff --git a/jdk/test/javax/swing/JTable/TAB/TAB.java b/jdk/test/javax/swing/JTable/TAB/TAB.java
new file mode 100644
index 00000000000..8c4f7035772
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/TAB/TAB.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+/**
+ * @test
+ * @bug 4128521
+ * @summary
+ * Tabbing test
+ * @author milne
+ * @run applet/manual=yesno TAB.html
+ */
+public class TAB extends JApplet
+{
+ static void initTest(Container contentPane)
+ {
+ // Take the dummy data from SwingSet.
+ final String[] names = {"First Name", "Last Name", "Favorite Color",
+ "Favorite Number", "Vegetarian"};
+ final Object[][] data = {
+ {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)},
+ {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)},
+ {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)},
+ {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)},
+ {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)},
+ {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)},
+ {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)},
+ {"David", "Karlton", "Red", new Integer(1), new Boolean(false)},
+ {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)},
+ {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)},
+ {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)},
+ {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)},
+ {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)},
+ {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)},
+ {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)},
+ {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)},
+ {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)},
+ {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)},
+ {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)},
+ {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)},
+ {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)}
+ };
+
+ // Create a model of the data.
+ TableModel dataModel = new AbstractTableModel() {
+ // These methods always need to be implemented.
+ public int getColumnCount() { return names.length; }
+ public int getRowCount() { return data.length;}
+ public Object getValueAt(int row, int col) {return data[row][col];}
+
+ // The default implementations of these methods in
+ // AbstractTableModel would work, but we can refine them.
+ public String getColumnName(int column) {return names[column];}
+ public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
+ public boolean isCellEditable(int row, int col) {return true;}
+ public void setValueAt(Object aValue, int row, int column) {
+ System.out.println("Setting value to: " + aValue);
+ data[row][column] = aValue;
+ }
+ };
+
+ // Create the table
+ JTable tableView = new JTable(dataModel);
+ // Turn off auto-resizing so that we can set column sizes programmatically.
+ // In this mode, all columns will get their preferred widths, as set blow.
+ tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+
+ // Create a combo box to show that you can use one in a table.
+ JComboBox comboBox = new JComboBox();
+ comboBox.addItem("Red");
+ comboBox.addItem("Orange");
+ comboBox.addItem("Yellow");
+ comboBox.addItem("Green");
+ comboBox.addItem("Blue");
+ comboBox.addItem("Indigo");
+ comboBox.addItem("Violet");
+
+ TableColumn colorColumn = tableView.getColumn("Favorite Color");
+ // Use the combo box as the editor in the "Favorite Color" column.
+ colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
+
+ // Set a pink background and tooltip for the Color column renderer.
+ DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer();
+ colorColumnRenderer.setBackground(Color.pink);
+ colorColumnRenderer.setToolTipText("Click for combo box");
+ colorColumn.setCellRenderer(colorColumnRenderer);
+
+ // Set a tooltip for the header of the colors column.
+ TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
+ if (headerRenderer instanceof DefaultTableCellRenderer)
+ ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!");
+
+ // Set the width of the "Vegetarian" column.
+ TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
+ vegetarianColumn.setPreferredWidth(100);
+
+ // Show the values in the "Favorite Number" column in different colors.
+ TableColumn numbersColumn = tableView.getColumn("Favorite Number");
+ DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() {
+ public void setValue(Object value) {
+ int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0;
+ setForeground((cellValue > 30) ? Color.black : Color.red);
+ setText((value == null) ? "" : value.toString());
+ }
+ };
+ numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
+ numbersColumn.setCellRenderer(numberColumnRenderer);
+ numbersColumn.setPreferredWidth(110);
+
+ // Finish setting up the table.
+ JScrollPane scrollpane = new JScrollPane(tableView);
+ scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
+ scrollpane.setPreferredSize(new Dimension(430, 200));
+
+ contentPane.add(scrollpane);
+ }
+
+
+ public void init() {
+ SwingUtilities.invokeLater(() -> {
+ try {
+ UIManager.setLookAndFeel(
+ "javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ initTest(getContentPane());
+ });
+ }
+}
diff --git a/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java b/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java
new file mode 100644
index 00000000000..36abd0c1458
--- /dev/null
+++ b/jdk/test/javax/xml/jaxp/testng/parse/XMLEntityScannerLoad.java
@@ -0,0 +1,52 @@
+package parse;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * JDK-8059327: XML parser returns corrupt attribute value
+ * https://bugs.openjdk.java.net/browse/JDK-8059327
+ *
+ * Also:
+ * JDK-8061550: XMLEntityScanner can corrupt corrupt content during parsing
+ * https://bugs.openjdk.java.net/browse/JDK-8061550
+ *
+ * @Summary: verify that the character cache in XMLEntityScanner is reset properly
+ */
+
+public class XMLEntityScannerLoad {
+
+ @Test(dataProvider = "xmls")
+ public void test(String xml) throws SAXException, IOException, ParserConfigurationException {
+ Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ChunkInputStream(xml));
+ String value = d.getDocumentElement().getAttribute("a1");
+ assertEquals(value, "w");
+ }
+
+ static class ChunkInputStream extends ByteArrayInputStream {
+ ChunkInputStream(String xml) {
+ super(xml.getBytes());
+ }
+
+ @Override
+ public synchronized int read(byte[] b, int off, int len) {
+ return super.read(b, off, 7);
+ }
+ }
+
+ @DataProvider(name = "xmls")
+ private Object[][] xmls() {
+ return new Object[][] {
+ {"<?xml version=\"1.0\"?><element a1=\"w\" a2=\"&quot;&quot;\"/>"},
+ {"<?xml version=\"1.1\"?><element a1=\"w\" a2=\"&quot;&quot;\"/>"}
+ };
+ }
+}
diff --git a/jdk/test/lib/testlibrary/ExtendedRobot.java b/jdk/test/lib/testlibrary/ExtendedRobot.java
index 725bd82c7a8..1e33c7d0d0c 100644
--- a/jdk/test/lib/testlibrary/ExtendedRobot.java
+++ b/jdk/test/lib/testlibrary/ExtendedRobot.java
@@ -23,9 +23,6 @@
* questions.
*/
-import sun.awt.ExtendedKeyCodes;
-import sun.awt.SunToolkit;
-
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.GraphicsDevice;
@@ -33,6 +30,7 @@ import java.awt.Toolkit;
import java.awt.Point;
import java.awt.MouseInfo;
import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
/**
* ExtendedRobot is a subclass of {@link java.awt.Robot}. It provides some convenience methods that are
@@ -178,8 +176,7 @@ public class ExtendedRobot extends Robot {
* dispatching thread
*/
public synchronized void waitForIdle(int delayValue) {
- SunToolkit.flushPendingEvents();
- ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+ super.waitForIdle();
delay(delayValue);
}
@@ -382,7 +379,7 @@ public class ExtendedRobot extends Robot {
* @see java.awt.event.KeyEvent
*/
public void type(char c) {
- type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c));
+ type(KeyEvent.getExtendedKeyCodeForChar(c));
}
/**
diff --git a/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java b/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java
index 1cd02b50e16..604d7dcf7a8 100644
--- a/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java
+++ b/jdk/test/sun/jvmstat/monitor/MonitoredVm/CR6672135.java
@@ -34,6 +34,7 @@ import sun.jvmstat.monitor.VmIdentifier;
* @bug 6672135
* @summary setInterval() for local MonitoredHost and local MonitoredVm
* @author Tomas Hurka
+ * @run main/othervm -XX:+UsePerfData CR6672135
*/
public class CR6672135 {
diff --git a/hotspot/test/runtime/NMT/UnsafeMallocLimit2.java b/jdk/test/sun/security/pkcs11/Cipher/JNICheck.java
index 003c8e8ca80..ecb12517abd 100644
--- a/hotspot/test/runtime/NMT/UnsafeMallocLimit2.java
+++ b/jdk/test/sun/security/pkcs11/Cipher/JNICheck.java
@@ -23,32 +23,42 @@
/*
* @test
- * @bug 8058818
- * @library /testlibrary
- * @build UnsafeMallocLimit2
- * @run main/othervm -Xmx32m -XX:NativeMemoryTracking=off UnsafeMallocLimit2
+ * @bug 8063700
+ * @run main/othervm -Xcheck:jni JNICheck
*/
-import com.oracle.java.testlibrary.*;
-import sun.misc.Unsafe;
+import javax.crypto.Cipher;
+import javax.crypto.SealedObject;
+import javax.crypto.SecretKey;
+import javax.crypto.KeyGenerator;
+import java.security.NoSuchProviderException;
-public class UnsafeMallocLimit2 {
+public class JNICheck {
- public static void main(String args[]) throws Exception {
- if (Platform.is32bit()) {
- Unsafe unsafe = Utils.getUnsafe();
+ /* This test is similar to the JCK test that found 8063700. */
+ static class SealedObjectTest {
+ Cipher c;
+
+ SealedObjectTest() throws Exception {
try {
- // Allocate greater than MALLOC_MAX and likely won't fail to allocate,
- // so it hits the NMT code that asserted.
- // Test that this doesn't cause an assertion with NMT off.
- // The option above overrides if all the tests are run with NMT on.
- unsafe.allocateMemory(0x40000000);
- System.out.println("Allocation succeeded");
- } catch (OutOfMemoryError e) {
- System.out.println("Allocation failed");
+ c = Cipher.getInstance("AES", "SunPKCS11-Solaris");
+ } catch (NoSuchProviderException nspe) {
+ System.out.println("No SunPKCS11-Solaris provider. Test skipped");
+ return;
}
- } else {
- System.out.println("Test only valid on 32-bit platforms");
+
+ String s = "Test string";
+ SealedObject so;
+ SecretKey key = KeyGenerator.getInstance("AES").generateKey();
+
+ c.init(Cipher.ENCRYPT_MODE, key);
+ so = new SealedObject(s, c);
+
+ so.getObject(key, "SunPKCS11-Solaris");
}
}
+
+ public static void main(String args[]) throws Exception {
+ new SealedObjectTest();
+ }
}
diff --git a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh
index e7e65cd01ba..6ab1be90065 100644
--- a/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh
+++ b/jdk/test/sun/security/tools/keytool/ListKeychainStore.sh
@@ -22,7 +22,7 @@
#
# @test
-# @bug 7133495 8041740 8062264
+# @bug 7133495 8041740 8062264 8046777
# @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry
if [ "${TESTJAVA}" = "" ] ; then
@@ -117,6 +117,26 @@ if [ $? -ne 0 ]; then
fi
echo "Imported keypairs from PKCS12 keystore into the keychain"
+# Generate a 2048-bit RSA keypair and import into the temporary keychain
+# (its private key is configured with non-default key usage settings)
+
+certtool c k=$TEMPORARY_KC <<EOF
+test
+r
+2048
+y
+b
+s
+y
+A
+US
+A
+A
+
+
+y
+EOF
+
# Adjust the keychain search order
echo "\"$TEMPORARY_KC\"" > $TEMPORARY_LIST
@@ -127,10 +147,11 @@ echo "Temporary keychain search order:"
security list-keychains
# Recount the number of private key entries in the Keychain keystores
+# (3 private keys imported from PKCS12, 1 private key generated by 'certtool')
RECOUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l`
echo "Found $RECOUNT private key entries in the Keychain keystore"
-if [ $RECOUNT -lt `expr $COUNT + 3` ]; then
+if [ $RECOUNT -lt `expr $COUNT + 4` ]; then
echo "Error: expected >$COUNT private key entries in the Keychain keystores"
RESULT=`$CLEANUP_P12`
RESULT=`$CLEANUP_KC`
@@ -141,7 +162,7 @@ fi
# Access controls have already been lowered (see 'security import ... -A' above)
${TESTJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/ExportPrivateKeyNoPwd.java || exit 6
-echo | ${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x
+${TESTJAVA}/bin/java ${TESTVMOPTS} ExportPrivateKeyNoPwd x
if [ $? -ne 0 ]; then
echo "Error exporting private key from the temporary keychain"
RESULT=`$CLEANUP_P12`
diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk
index 3ef60a4fc04..20ae9c9f073 100644
--- a/make/CompileJavaModules.gmk
+++ b/make/CompileJavaModules.gmk
@@ -245,7 +245,6 @@ java.sql.rowset_CLEAN_FILES := $(wildcard \
################################################################################
# Exclude building of IIOP transport for RMI Connector
-java.management_EXCLUDES := com/sun/jmx/remote/protocol/iiop
ifeq ($(RMICONNECTOR_IIOP), false)
java.management_EXCLUDES += com/sun/jmx/remote/protocol/iiop
@@ -264,11 +263,11 @@ java.corba_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS
java.corba_COPY := .prp
java.corba_CLEAN := .properties
-java.corba_EXCLUDES := \
+java.corba_EXCLUDES += \
com/sun/corba/se/PortableActivationIDL \
com/sun/tools/corba/se/logutil \
#
-java.corba_EXCLUDE_FILES := \
+java.corba_EXCLUDE_FILES += \
com/sun/corba/se/impl/presentation/rmi/JNDIStateFactoryImpl.java \
com/sun/corba/se/spi/presentation/rmi/StubWrapper.java \
com/sun/org/omg/CORBA/IDLTypeOperations.java \
@@ -350,12 +349,12 @@ SCTP_IMPL_CLASSES = \
$(JDK_TOPDIR)/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/Shutdown.java
ifeq ($(OPENJDK_TARGET_OS), macosx)
- jdk.sctp_EXCLUDE_FILES := $(SCTP_IMPL_CLASSES)
+ jdk.sctp_EXCLUDE_FILES += $(SCTP_IMPL_CLASSES)
endif
ifeq ($(OPENJDK_TARGET_OS),aix)
# These files are duplicated in AIX_SRC_DIRS
- jdk.sctp_EXCLUDE_FILES := $(SCTP_IMPL_CLASSES)
+ jdk.sctp_EXCLUDE_FILES += $(SCTP_IMPL_CLASSES)
endif
################################################################################
@@ -373,7 +372,7 @@ jdk.compiler_CLEAN_FILES := $(wildcard \
################################################################################
-jdk.jdi_EXCLUDES := \
+jdk.jdi_EXCLUDES += \
com/sun/tools/example/debug/bdi \
com/sun/tools/example/debug/event \
com/sun/tools/example/debug/gui \
@@ -414,7 +413,7 @@ sun.charsets_COPY := .dat
jdk.localedata_COPY := _dict _th
# Exclude BreakIterator classes that are just used in compile process to generate
# data files and shouldn't go in the product
-jdk.localedata_EXCLUDE_FILES := sun/text/resources/th/BreakIteratorRules_th.java
+jdk.localedata_EXCLUDE_FILES += sun/text/resources/th/BreakIteratorRules_th.java
################################################################################
# Setup the compilation of each module