Mercurial > hg > release > icedtea-1.9
changeset 1431:79e96b23cdd3
Merge with IcedTea6.
2008-11-17 Andrew John Hughes <ahughes@redhat.com>
Merge with IcedTea6.
* .hgignore,
* .hgtags,
* ChangeLog,
* HACKING,
* IcedTeaPlugin.cc,
* Makefile.am,
* contrib/mixtec-hacks.patch,
* fsg.sh,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/CHANGES.txt,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java,
* overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java,
* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java,
* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java,
* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java,
* patches/icedtea-6761856-freetypescaler.patch,
* patches/icedtea-alsa-default-device.patch,
* patches/icedtea-cc-interp-no-fer.patch,
* patches/icedtea-display-mode-changer.patch,
* patches/icedtea-f2i-overflow.patch: Merged.
* patches/icedtea-linker-libs-order.patch: Rebuilt.
* patches/icedtea-testenv.patch: Converted to work against TestUtil.
* patches/icedtea-uname.patch,
* patches/icedtea-visualvm.patch,
* plugin/icedtea/sun/applet/PluginAppletViewer.java,
* ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp,
* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp,
* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp,
* ports/hotspot/src/cpu/zero/vm/frame_zero.cpp,
* ports/hotspot/src/cpu/zero/vm/globals_zero.hpp,
* ports/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp,
* ports/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp,
* ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp,
* ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp,
* ports/hotspot/src/share/vm/shark/sharkBlock.cpp,
* ports/hotspot/src/share/vm/shark/sharkBlock.hpp,
* ports/hotspot/src/share/vm/shark/sharkRuntime.cpp,
* ports/hotspot/src/share/vm/shark/sharkRuntime.hpp,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java,
* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java,
* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c,
* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java,
* test/jtreg/README,
* test/jtreg/com/sun/javatest/diff/Diff.java,
* test/jtreg/com/sun/javatest/diff/Fault.java,
* test/jtreg/com/sun/javatest/diff/HTMLReporter.java,
* test/jtreg/com/sun/javatest/diff/HTMLWriter.java,
* test/jtreg/com/sun/javatest/diff/Main.java,
* test/jtreg/com/sun/javatest/diff/MultiMap.java,
* test/jtreg/com/sun/javatest/diff/ReportReader.java,
* test/jtreg/com/sun/javatest/diff/StandardDiff.java,
* test/jtreg/com/sun/javatest/diff/SuperDiff.java,
* test/jtreg/com/sun/javatest/diff/WorkDirectoryReader.java,
* test/jtreg/com/sun/javatest/diff/i18n.properties,
* test/jtreg/com/sun/javatest/regtest/Main.java,
* test/jtreg/com/sun/javatest/regtest/MainAction.java,
* test/jtreg/com/sun/javatest/regtest/RegressionSecurityManager.java,
* test/jtreg/com/sun/javatest/regtest/RegressionTestFinder.java,
* test/jtreg/com/sun/javatest/regtest/i18n.properties: Merged.
author | Andrew John Hughes <gnu_andrew@member.fsf.org> |
---|---|
date | Mon, 17 Nov 2008 15:26:51 +0000 |
parents | 4e8f60cd59d0 (current diff) 3d0cabbaa2b3 (diff) |
children | 79d3c8c363dc |
files | .hgignore .hgtags ChangeLog HACKING IcedTeaPlugin.cc Makefile.am NEWS acinclude.m4 configure.ac fsg.sh overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java patches/icedtea-copy-plugs.patch patches/icedtea-linker-libs-order.patch patches/icedtea-testenv.patch patches/icedtea-version.patch ports/hotspot/src/cpu/zero/vm/frame_zero.cpp ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp |
diffstat | 72 files changed, 3618 insertions(+), 857 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Mon Nov 17 12:41:07 2008 +0000 +++ b/.hgignore Mon Nov 17 15:26:51 2008 +0000 @@ -38,6 +38,7 @@ test/langtools test/jtreg.jar test/jtreg/classes +test/check-.*log rt/com/sun/jdi/AbsentInformationException.java rt/com/sun/jdi/Accessible.java rt/com/sun/jdi/ArrayReference.java
--- a/.hgtags Mon Nov 17 12:41:07 2008 +0000 +++ b/.hgtags Mon Nov 17 15:26:51 2008 +0000 @@ -10,3 +10,4 @@ 871b70407a139c6bd42c200762ee1d302b31168f icedtea6-1.2 8bbc4ffe2c7c542f9aa7d26f823e50f0dd036ce9 icedtea-1.7 3ef9c9c4e70b8204b73fa9b88243f49f59c2a23f icedtea6-1.3 +be368b1e3c7dca9b4dfe8e8f40be794ecfbef22e icedtea6-1.3.1
--- a/ChangeLog Mon Nov 17 12:41:07 2008 +0000 +++ b/ChangeLog Mon Nov 17 15:26:51 2008 +0000 @@ -1,5 +1,81 @@ -2008-11-14 Andrew John Hughes <ahughes@redhat.com> - +2008-11-17 Andrew John Hughes <ahughes@redhat.com> + + Merge with IcedTea6. + * .hgignore, + * .hgtags, + * ChangeLog, + * HACKING, + * IcedTeaPlugin.cc, + * Makefile.am, + * contrib/mixtec-hacks.patch, + * fsg.sh, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/CHANGES.txt, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java, + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java, + * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, + * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, + * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java, + * patches/icedtea-6761856-freetypescaler.patch, + * patches/icedtea-alsa-default-device.patch, + * patches/icedtea-cc-interp-no-fer.patch, + * patches/icedtea-display-mode-changer.patch, + * patches/icedtea-f2i-overflow.patch: Merged. + * patches/icedtea-linker-libs-order.patch: Rebuilt. + * patches/icedtea-testenv.patch: Converted to work against TestUtil. + * patches/icedtea-uname.patch, + * patches/icedtea-visualvm.patch, + * plugin/icedtea/sun/applet/PluginAppletViewer.java, + * ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp, + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp, + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp, + * ports/hotspot/src/cpu/zero/vm/frame_zero.cpp, + * ports/hotspot/src/cpu/zero/vm/globals_zero.hpp, + * ports/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp, + * ports/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp, + * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp, + * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp, + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp, + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp, + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp, + * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java, + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java, + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c, + * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java, + * test/jtreg/README, + * test/jtreg/com/sun/javatest/diff/Diff.java, + * test/jtreg/com/sun/javatest/diff/Fault.java, + * test/jtreg/com/sun/javatest/diff/HTMLReporter.java, + * test/jtreg/com/sun/javatest/diff/HTMLWriter.java, + * test/jtreg/com/sun/javatest/diff/Main.java, + * test/jtreg/com/sun/javatest/diff/MultiMap.java, + * test/jtreg/com/sun/javatest/diff/ReportReader.java, + * test/jtreg/com/sun/javatest/diff/StandardDiff.java, + * test/jtreg/com/sun/javatest/diff/SuperDiff.java, + * test/jtreg/com/sun/javatest/diff/WorkDirectoryReader.java, + * test/jtreg/com/sun/javatest/diff/i18n.properties, + * test/jtreg/com/sun/javatest/regtest/Main.java, + * test/jtreg/com/sun/javatest/regtest/MainAction.java, + * test/jtreg/com/sun/javatest/regtest/RegressionSecurityManager.java, + * test/jtreg/com/sun/javatest/regtest/RegressionTestFinder.java, + * test/jtreg/com/sun/javatest/regtest/i18n.properties: Merged. + +2008-11-17 Andrew John Hughes <ahughes@redhat.com> + * Makefile.am: Expand generated and pulseaudio. Lock patches to $(top_srcdir). Run jtreg with @@ -13,6 +89,16 @@ * test/jtreg/excludelist.langtools.jtx: Exclude broken tests. +2008-11-17 Matthias Klose <doko@ubuntu.com> + + * fsg.sh: Don't remove xml-stylesheet files. + +2008-11-15 Mark Wielaard <mark@klomp.org> + + * patches/icedtea-testenv.patch: New patch. + * Makefile.am (ICEDTEA_PATCHES): Add new patch. + * HACKING: Document new patch. + 2008-11-14 Andrew John Hughes <ahughes@redhat.com> * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/services/javax.sound.midi.spi.MidiDeviceProvider, @@ -28,6 +114,32 @@ * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/services/windows-ia64/javax.sound.sampled.spi.MixerProvider: Add property files missed by hg. +2008-11-15 Mark Wielaard <mark@klomp.org> + + * patches/icedtea-display-mode-changer.patch: New patch. + * Makefile.am (ICEDTEA_PATCHES): Add new patch. + * HACKING: Document new patch. + +2008-11-14 Omair Majid <omajid@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java + Removed useless SuppressWarnings. + (static): Delegate the loading of native libraries to SecurityWrapper. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java + (static): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java + (static): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java + (static): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java + (static): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java + (static): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java + New class. + (loadNativeLibrary): Loads libpulse-java.so in a privileged operation to + work when a security manager is installed. + 2008-11-14 Andrew John Hughes <ahughes@redhat.com> * HACKING: List new plugs patches. @@ -78,28 +190,151 @@ * javac.in: Convert to Perl script to avoid quoting errors. - + +2008-11-11 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp + (os::atomic_copy64): New method. + * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp + (_Copy_conjoint_jlongs_atomic): Use the above. + * ports/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp + (OrderAccess::load_acquire): Likewise. + (OrderAccess::release_store): Likewise. + (OrderAccess::store_fence): Likewise. + (OrderAccess::release_store_fence): Likewise. + +2008-11-11 Matthias Klose <doko@ubuntu.com> + + * patches/icedtea-uname.patch: Fix ARCH on powerpc-linux-gnu + 2008-11-10 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Fix make dist. +2008-11-10 Omair Majid <omajid@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java + New class containing debugging functions. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java + (run): Print some debugging info. + (update): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java + (ClipThread.writeFrames): Likewise. + (close): Likewise. + (open): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java + (PulseAudioMixer): Likewise. + (getLine): Likewise. + (close): Likewise. + (open): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java + (PulseAudioMixerProvider): Initialize Debug class. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java + (open): Print some debug info. + (close): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java + (open): Likewise. + (close): Likewise. + +2008-11-10 Omair Majid <omajid@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java + (close): Dont check for permission to play audio. Always granted. + Infact, checking it causes an AccessControlException for untrusted + applets. The ALSA based backend doesnt check this permission at all. + (open): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java + (getLine): Likewise. + (getSourceLines): Likewise. + (close): Likewise. + (open): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java + (open): Likewise. + (close): Likewise. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java + (open): Likewise. + (close): Likewise. + +2008-11-10 Omair Majid <omajid@redhat.com> + + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c + (Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1set_1sink_1volume): + Deallocate unused memory. + +2008-11-10 Mark Wielaard <mark@klomp.org> + + * overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/ + CHANGES.txt,SoftAudioPusher.java,SoftFilter.java, + SoftJitterCorrector.java,SoftMainMixer.java,SoftVoice.java: + Updated to new Gervill CVS. + 2008-11-09 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Bump to b39. * patches/icedtea-hotspot-use-idx_t.patch, * patches/icedtea-security-updates.patch: Remove parts applied/changed in b39. - -2008-11-07 Omair Majid <omajid@redhat.com> - - * patches/icedtea-jsoundhs.patch: Added two more diffs to remove all uses - of jsoundhs and Headspace libraries. + +2008-11-09 Mark Wielaard <mark@klomp.org> + + * Makefile.am (check-langtools): Run jtreg with -samevm. + +2008-11-09 Mark Wielaard <mark@klomp.org> + + * test/jtreg/README, + test/jtreg/com/sun/javatest/diff/HTMLReporter.java, + test/jtreg/com/sun/javatest/diff/Main.java, + test/jtreg/com/sun/javatest/diff/MultiMap.java, + test/jtreg/com/sun/javatest/diff/ReportReader.java, + test/jtreg/com/sun/javatest/diff/WorkDirectoryReader.java, + test/jtreg/com/sun/javatest/diff/i18n.properties, + test/jtreg/com/sun/javatest/regtest/Main.java, + test/jtreg/com/sun/javatest/regtest/MainAction.java, + test/jtreg/com/sun/javatest/regtest/RegressionSecurityManager.java, + test/jtreg/com/sun/javatest/regtest/RegressionTestFinder.java, + test/jtreg/com/sun/javatest/regtest/i18n.properties, + test/jtreg/com/sun/javatest/diff/Diff.java, + test/jtreg/com/sun/javatest/diff/Fault.java, + test/jtreg/com/sun/javatest/diff/HTMLWriter.java, + test/jtreg/com/sun/javatest/diff/StandardDiff.java, + test/jtreg/com/sun/javatest/diff/SuperDiff.java, + Upgrade to jtreg-4_0-src-b02-15_oct_2008. + +2008-11-09 Mark Wielaard <mark@klomp.org> + + * .hgignore: Add test/check-.*log. + +2008-11-08 Mark Wielaard <mark@klomp.org> + + * Makefile.am (ICEDTEA_ENV): Set MILESTONE to fcs. + * patches/icedtea-version.patch: Remove special casing of + MILESTONE in hotspot build, add special casing of milestone in + langtools build. + +2008-11-08 Mark Wielaard <mark@klomp.org> + + * Makefile.am (OPENJDK_MD5SUM): Fixed value. + +2008-11-08 Mark Wielaard <mark@klomp.org> + + * Makefile.am (OPENJDK_DATE, OPENJDK_MD5SUM, OPENJDK_VERSION): + Update for b13. + (ICEDTEA_PATCHES): Removed patches 6616825, 6651382, 6756202. + * patches/icedtea-6open-6616825.patch: Removed. + * patches/icedtea-6open-6651382.patch: Removed. + * patches/icedtea-6open-6756202.patch: Removed. + * NEWS: Add integration of b13. 2008-11-07 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Use 'node|short' instead of 'rev' for Mercurial revision number. +2008-11-07 Omair Majid <omajid@redhat.com> + + * patches/icedtea-jsoundhs.patch: Added two more diffs to remove all uses + of jsoundhs and Headspace libraries. + 2008-11-07 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Remove unneeded citypeflow fix, @@ -114,6 +349,165 @@ * ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp: Updated for HotSpot 14 b05. +2008-11-07 Gary Benson <gbenson@redhat.com> + + * patches/icedtea-cc-interp-no-fer.patch: New file. + * Makefile.am (ICEDTEA_PATCHES): Apply the above. + * HACKING: Document the above. + +2008-11-07 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp + (Atomic::store_ptr): Implemented. + +2008-11-07 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/frame_zero.cpp + (frame::interpreter_frame_result): Implemented. + +2008-11-06 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp + (JVM_handle_linux_signal): Added signal chaining, + abort_if_unrecognised, and stack overflow recognition. + +2008-11-06 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/globals_zero.hpp + (StackShadowPages): Increase for debug builds. + +2008-11-06 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::native_entry): Unwind correctly if an + exception is thrown while setting up the call. + +2008-11-06 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::native_entry): Add stack overflow check. + +2008-11-06 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp + (CppInterpreter::stack_overflow_imminent): New method. + + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::stack_overflow_imminent): New method. + (CppInterpreter::normal_entry): Add stack overflow check. + +2008-11-05 Deepak Bhole <dbhole@redhat.com> + + * patches/icedtea-copy-plugs.patch: Add netscape.* classes to rt.jar when + building with an alternate jar application. + +2008-11-05 Deepak Bhole <dbhole@redhat.com> + + * rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Correct + indentation from last commit, remove debug output. + +2008-11-05 Andrew Haley <aph@redhat.com> + Gary Benson <gbenson@redhat.com> + + * contrib/mixtec-hacks.patch: new file. + +2008-11-04 Deepak Bhole <dbhole@redhat.com> + + * rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Dynamically load + files from the index. + +2008-11-04 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp + (SharkRuntime::_f2i): New constant. + (SharkRuntime::_f2l): Likewise. + (SharkRuntime::_d2i): Likewise. + (SharkRuntime::_d2l): Likewise. + (SharkRuntime::f2i): New accessor. + (SharkRuntime::f2l): Likewise. + (SharkRuntime::d2i): Likewise. + (SharkRuntime::d2l): Likewise. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::_f2i): New constant. + (SharkRuntime::_f2l): Likewise. + (SharkRuntime::_d2i): Likewise. + (SharkRuntime::_d2l): Likewise. + (SharkRuntime::initialize): Initialize the above. + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::call_vm_leaf): New method. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse): Use runtime calls for f2i, f2l, d2i and d2l. + +2008-11-04 Omair Majid <omajid@redhat.com> + + * Makefile.am (stamps/pulse-java.stamp): Link in libpulse.so after all + the object files that use it. + * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java + (testWriteIntegralNumberFrames): New function. Tests that a SourceDataLine + will only write an integral number of frames. + (testWriteNegativeLength): New function. Tests that a + SourceDataLine.write() wont accept a negative length. + (testWriteNegativeOffset): New function. Tests that a + SourceDataLine.write() will not accept a negative offset. + (testWriteMoreThanArrayLength): New function. Tests that + SourceDataLine.write() wont write more than the length of the array. + (testWriteMoreThanArrayLength2): Likewise. + (testWriteWithoutStart): Added a check to avoid throwing an + IllegalStateException. + +2008-11-04 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse): Fix syntax errors. + +2008-11-04 Gary Benson <gbenson@redhat.com> + + PR icedtea/244: + * patches/icedtea-f2i-overflow.patch: New file. + * Makefile.am (ICEDTEA_PATCHES): Apply the above. + * HACKING: Document the above. + +2008-11-03 Nix <nix@esperi.org.uk> + Omair Majid <omajid@redhat.com> + + * Makefile.am (ICEDTEA_PATCHES): Added icedtea-linker-libs-order.patch. + * patches/icedtea-linker-libs-order.patch: Fixes icedtea bug#237. + +2008-11-03 Omair Majid <omajid@redhat.com> + + * patches/icedtea-alsa-default-device.patch: New patch. Use the ALSA + 'default' device if possible. Makes Java play nice with PulseAudio. + +2008-11-03 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse): Fix shift instructions to use only the + lower order bits of the second argument. + +2008-11-03 Gary Benson <gbenson@redhat.com> + + * ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp + (BytecodeInterpreter::VMintShl): Only shift by the lower five bits. + (BytecodeInterpreter::VMintShr): Likewise. + (BytecodeInterpreter::VMintUshr): Likewise. + +2008-10-31 Deepak Bhole <dbhole@redhat.com> + + * IcedTeaPlugin.cc: Fix potential DoS issue when dealing with very long + URL/target addresses. + * plugin/icedtea/sun/applet/PluginAppletViewer.java: Decode param values + correctly. + * rt/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java: Bypass + authentication check when origin matches. + * rt/net/sourceforge/jnlp/security/AccessWarningPane.java: Show proper + Name/Publisher/Origin values when no certificate is associated. + + +2008-10-31 Lillian Angel <langel@redhat.com> + + * Makefile.am: Updated for new visualvm 1.0.1. + * patches/icedtea-visualvm.patch: Updated. + 2008-10-30 Andrew John Hughes <ahughes@redhat.com> * Makefile.am: Add bootstrap-directory-symlink @@ -142,6 +536,23 @@ * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java: Merged. +2008-10-29 Mark Wielaard <mark@klomp.org> + + * patches/icedtea-6761856-freetypescaler.patch: New patch. + * Makefile.am (ICEDTEA_PATCHES): Add new patch. + * HACKING: Document new patch. + +2008-10-29 Gary Benson <gbenson@redhat.com> + + PR icedtea/238: + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse): Fix copy-and-paste error in f2l. + +2008-10-27 Deepak Bhole <dbhole@redhat.com> + + * rt/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java: Act on window + close events (Bug# 215) + 2008-10-27 Andrew John Hughes <ahughes@redhat.com> * acinclude.m4: @@ -153,6 +564,10 @@ 2008-10-27 Lillian Angel <langel@redhat.com> + * configure.ac: Updated version to 1.4. + +2008-10-27 Lillian Angel <langel@redhat.com> + * NEWS: Updated for 1.3.1 release. 2008-10-27 Andrew John Hughes <ahughes@redhat.com>
--- a/HACKING Mon Nov 17 12:41:07 2008 +0000 +++ b/HACKING Mon Nov 17 15:26:51 2008 +0000 @@ -63,8 +63,13 @@ * icedtea-arch.patch: Add support for additional architectures. * icedtea-alt-jar.patch: Add support for using an alternate jar tool in JDK building. * icedtea-hotspot7-tests.patch: Adds hotspot compiler tests from jdk7 tree. -* patches/icedtea-renderer-crossing.patch: Check whether crossing is - initialized in Pisces Renderer. +* icedtea-renderer-crossing.patch: Check whether crossing is initialized in Pisces Renderer. +* icedtea-f2i-overflow.patch: Replaces the code used by [fd]2[il] bytecodes to correctly handle overflows. (PR244) +* icedtea-cc-interp-no-fer.patch: Report that we cannot force early returns with the C++ interpreter. +* icedtea-6761856-freetypescaler.patch: Fix IcedTea bug #227, OpenJDK bug + #6761856, swing TextLayout.getBounds() returns shifted bounds. +* icedtea-display-mode-changer.patch: Add extra test class. +* icedtea-testenv.patch: Provide public reachable machines for net/nio tests. The following patches are only applied to OpenJDK6 in IcedTea6:
--- a/IcedTeaPlugin.cc Mon Nov 17 12:41:07 2008 +0000 +++ b/IcedTeaPlugin.cc Mon Nov 17 15:26:51 2008 +0000 @@ -1409,19 +1409,19 @@ NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE - GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target); + GetURLRunnable (nsIPluginInstancePeer* peer, nsCString url, nsCString target); ~GetURLRunnable (); private: nsIPluginInstancePeer* peer; - const char* url; - const char* target; + nsCString url; + nsCString target; }; NS_IMPL_ISUPPORTS1 (GetURLRunnable, nsIRunnable) -GetURLRunnable::GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target) +GetURLRunnable::GetURLRunnable (nsIPluginInstancePeer* peer, nsCString url, nsCString target) : peer(peer), url(url), target(target) @@ -1442,7 +1442,7 @@ nsIPluginInstanceOwner* owner = nsnull; ownerGetter->GetOwner (&owner); - return owner->GetURL ((const char*) url, (const char*) target, + return owner->GetURL ((const char*) url.get(), (const char*) target.get(), nsnull, 0, nsnull, 0); } @@ -2869,8 +2869,8 @@ ownerGetter->GetOwner (&owner); PLUGIN_DEBUG_2ARG ("Calling GetURL with %s and %s\n", nsCString (url).get (), nsCString (target).get ()); nsCOMPtr<nsIRunnable> event = new GetURLRunnable (instance->peer, - nsCString (url).get (), - nsCString (target).get ()); + nsCString (url), + nsCString (target)); current->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); } } @@ -4062,7 +4062,11 @@ { if (!factory->js_cleared_handles.Get(javascript_identifier, NULL)) { - PLUGIN_DEBUG_2ARG ("Calling Eval: %d, %d\n", javascript_identifier, strSize); + nsCString evStr(""); + for (int i=0; i < strSize; i++) + evStr += nameString[i]; + + PLUGIN_DEBUG_2ARG ("Calling Eval: %d, %s\n", javascript_identifier, evStr.get()); result = liveconnect->Eval(proxyEnv, javascript_identifier, nameString, strSize,
--- a/Makefile.am Mon Nov 17 12:41:07 2008 +0000 +++ b/Makefile.am Mon Nov 17 15:26:51 2008 +0000 @@ -1393,6 +1393,7 @@ "BUILD_NUMBER=$(OPENJDK_VERSION)" \ "JDK_UPDATE_VERSION=$(JDK_UPDATE_VERSION)" \ "JRE_RELEASE_VERSION=1.7.0_$(COMBINED_VERSION)" \ + "MILESTONE=fcs" \ "LANG=C" \ "PATH=$(abs_top_builddir)/bootstrap/jdk1.6.0/bin:/usr/bin:/bin:/usr/sbin:/sbin" \ "ALT_BOOTDIR=$(ICEDTEA_BOOT_DIR)" \ @@ -1462,6 +1463,7 @@ "BUILD_NUMBER=$(OPENJDK_VERSION)" \ "JDK_UPDATE_VERSION=$(JDK_UPDATE_VERSION)" \ "JRE_RELEASE_VERSION=1.7.0_$(COMBINED_VERSION)" \ + "MILESTONE=fcs" \ "LANG=C" \ "PATH=$(abs_top_builddir)/bootstrap/jdk1.6.0/bin:/usr/bin:/bin:/usr/sbin:/sbin" \ "ALT_BOOTDIR=$(ICEDTEA_BOOT_DIR)" \ @@ -1584,7 +1586,7 @@ if USE_ALT_VISUALVM_SRC_ZIP VISUALVM_SRC_ZIP = $(ALT_VISUALVM_SRC_ZIP) else - VISUALVM_SRC_ZIP = visualvm-20080728-src.tar.gz + VISUALVM_SRC_ZIP = visualvm-20081031-src.tar.gz endif stamps/download.stamp: stamps/hgforest.stamp @@ -1839,6 +1841,13 @@ patches/icedtea-snmp.patch \ patches/icedtea-sound.patch \ patches/icedtea-tests-jdk.patch \ + patches/icedtea-alsa-default-device.patch \ + patches/icedtea-linker-libs-order.patch \ + patches/icedtea-f2i-overflow.patch \ + patches/icedtea-cc-interp-no-fer.patch \ + patches/icedtea-6761856-freetypescaler.patch \ + patches/icedtea-display-mode-changer.patch \ + patches/icedtea-testenv.patch \ $(ZERO_PATCHES_COND) if WITH_RHINO @@ -2825,7 +2834,7 @@ $(CC) $(LIBPULSE_CFLAGS) $(CFLAGS) -fPIC -c -I$(ICEDTEA_BOOT_DIR)/include/linux -I$(ICEDTEA_BOOT_DIR)/include $(PULSE_JAVA_NATIVE_SRCDIR)/org_classpath_icedtea_pulseaudio_Stream.c $(CC) $(LIBPULSE_CFLAGS) $(CFLAGS) -fPIC -c -I$(ICEDTEA_BOOT_DIR)/include/linux -I$(ICEDTEA_BOOT_DIR)/include $(PULSE_JAVA_NATIVE_SRCDIR)/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c $(CC) $(LIBPULSE_CFLAGS) $(CFLAGS) -fPIC -c -I$(ICEDTEA_BOOT_DIR)/include/linux -I$(ICEDTEA_BOOT_DIR)/include $(PULSE_JAVA_NATIVE_SRCDIR)/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c - $(CC) $(LDFLAGS) -shared $(LIBPULSE_LIBS) -o libpulse-java.so org_*pulseaudio*.o jni-common.o + $(CC) $(LDFLAGS) -shared org_*pulseaudio*.o jni-common.o $(LIBPULSE_LIBS) -o libpulse-java.so mv org_classpath_icedtea_pulseaudio_*.o $(PULSE_JAVA_CLASS_DIR) mv jni-common.o $(PULSE_JAVA_CLASS_DIR) endif @@ -2935,7 +2944,7 @@ mkdir -p test/langtools/JTwork test/langtools/JTreport $(ICEDTEA_BOOT_DIR)/bin/java -jar test/jtreg.jar -v1 -a -ignore:quiet \ -w:test/langtools/JTwork -r:test/langtools/JTreport \ - -jdk:`pwd`/$(BUILD_OUTPUT_DIR)/j2sdk-image \ + -s -jdk:`pwd`/$(BUILD_OUTPUT_DIR)/j2sdk-image \ -exclude:$(abs_top_srcdir)/test/jtreg/excludelist.langtools.jtx \ `pwd`/openjdk/langtools/test \ | tee test/$@.log
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/mixtec-hacks.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,104 @@ +diff -r 4f4d268762d7 Makefile.am +--- a/Makefile.am Wed Aug 20 04:24:45 2008 -0400 ++++ b/Makefile.am Thu Aug 28 03:53:35 2008 -0400 +@@ -442,6 +442,13 @@ + endif + + ICEDTEA_FSG_PATCHES = ++ ++# Build with assertions and lowered optimization ++DISTRIBUTION_PATCHES = \ ++ patches/mixtec-assertions.patch \ ++ patches/mixtec-no-log-vm-output.patch \ ++ patches/mixtec-no-print-vm-options.patch \ ++ patches/mixtec-optimization.patch + + ICEDTEA_PATCHES = \ + $(ZERO_PATCHES_COND) \ +diff -r 4f4d268762d7 patches/mixtec-assertions.patch +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/patches/mixtec-assertions.patch Thu Aug 28 03:53:35 2008 -0400 +@@ -0,0 +1,14 @@ ++diff -r d384f5a5bd0c hotspot/build/linux/makefiles/product.make ++--- openjdk/hotspot/build/linux/makefiles/product.make Mon Aug 06 13:11:51 2007 +0100 +++++ openjdk/hotspot/build/linux/makefiles/product.make Fri Sep 14 09:58:33 2007 +0100 ++@@ -41,8 +41,8 @@ MAPFILE = $(GAMMADIR)/build/linux/makefi ++ MAPFILE = $(GAMMADIR)/build/linux/makefiles/mapfile-vers-product ++ ++ G_SUFFIX = ++-SYSDEFS += -DPRODUCT ++-VERSION = optimized +++SYSDEFS += -DASSERT +++VERSION = mixtec ++ ++ # use -g to strip library as -x will discard its symbol table; -x is fine for ++ # executables. +diff -r 4f4d268762d7 patches/mixtec-no-log-vm-output.patch +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/patches/mixtec-no-log-vm-output.patch Thu Aug 28 03:53:35 2008 -0400 +@@ -0,0 +1,11 @@ ++--- openjdk-ecj/hotspot/src/share/vm/runtime/globals.hpp 2007-11-13 09:19:54.000000000 -0500 +++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp 2007-11-13 17:13:24.000000000 -0500 ++@@ -2081,7 +2081,7 @@ ++ diagnostic(bool, DisplayVMOutput, true, \ ++ "Display all VM output on the tty, independently of LogVMOutput") \ ++ \ ++- diagnostic(bool, LogVMOutput, trueInDebug, \ +++ diagnostic(bool, LogVMOutput, false, \ ++ "Save VM output to hotspot.log, or to LogFile") \ ++ \ ++ diagnostic(ccstr, LogFile, NULL, \ +diff -r 4f4d268762d7 patches/mixtec-no-print-vm-options.patch +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/patches/mixtec-no-print-vm-options.patch Thu Aug 28 03:53:35 2008 -0400 +@@ -0,0 +1,12 @@ ++diff -r c5904941581b openjdk-ecj/hotspot/src/share/vm/runtime/globals.hpp ++--- openjdk/hotspot/src/share/vm/runtime/globals.hpp Tue Nov 13 14:09:56 2007 +0000 +++++ openjdk/hotspot/src/share/vm/runtime/globals.hpp Tue Nov 13 14:19:54 2007 +0000 ++@@ -2072,7 +2072,7 @@ class CommandLineFlags { ++ diagnostic(bool, DebugInlinedCalls, true, \ ++ "If false, restricts profiled locations to the root method only") \ ++ \ ++- product(bool, PrintVMOptions, trueInDebug, \ +++ product(bool, PrintVMOptions, false, \ ++ "print VM flag settings") \ ++ \ ++ diagnostic(bool, SerializeVMOutput, true, \ +diff -r 4f4d268762d7 patches/mixtec-optimization.patch +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/patches/mixtec-optimization.patch Thu Aug 28 03:53:35 2008 -0400 +@@ -0,0 +1,34 @@ ++diff -urN openjdk.orig/hotspot/build/linux/makefiles/gcc.make openjdk/hotspot/build/linux/makefiles/gcc.make ++--- openjdk.orig/hotspot/build/linux/makefiles/gcc.make 2007-10-12 03:46:25.000000000 -0400 +++++ openjdk/hotspot/build/linux/makefiles/gcc.make 2007-10-12 17:41:02.000000000 -0400 ++@@ -111,7 +111,7 @@ ++ CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) ++ ++ # The flags to use for an Optimized g++ build ++-OPT_CFLAGS += -O3 +++OPT_CFLAGS += -O0 ++ ++ # Hotspot uses very unstrict aliasing turn this optimization off ++ OPT_CFLAGS += -fno-strict-aliasing ++diff -urN openjdk.orig/j2se/make/common/Defs-linux.gmk openjdk/j2se/make/common/Defs-linux.gmk ++--- openjdk.orig/jdk/make/common/Defs-linux.gmk 2007-10-12 03:54:05.000000000 -0400 +++++ openjdk/jdk/make/common/Defs-linux.gmk 2007-10-12 17:41:02.000000000 -0400 ++@@ -97,6 +97,7 @@ ++ _OPT = $(CC_LOWER_OPT) ++ CPPFLAGS_DBG += -DLOGGING ++ endif +++_OPT = -O0 ++ ++ # For all platforms, do not omit the frame pointer register usage. ++ # We need this frame pointer to make it easy to walk the stacks. ++diff -r e847abdac6f6 openjdk/corba/make/common/Defs-linux.gmk ++--- openjdk/corba/make/common/Defs-linux.gmk Thu Nov 22 08:57:34 2007 +0000 +++++ openjdk/corba/make/common/Defs-linux.gmk Thu Nov 22 08:59:18 2007 +0000 ++@@ -87,6 +87,7 @@ else ++ _OPT = $(CC_LOWER_OPT) ++ CPPFLAGS_DBG += -DLOGGING ++ endif +++_OPT = -O0 ++ ++ # For all platforms, do not omit the frame pointer register usage. ++ # We need this frame pointer to make it easy to walk the stacks.
--- a/fsg.sh Mon Nov 17 12:41:07 2008 +0000 +++ b/fsg.sh Mon Nov 17 15:26:51 2008 +0000 @@ -82,11 +82,6 @@ rm -f \ openjdk/jdk/test/sun/net/idn/nfscis.spp -# has w3c copyright. license to be checked / needs checking after decoding -rm -f \ - openjdk/jdk/test/javax/xml/crypto/dsig/data/xml-stylesheet \ - openjdk/jdk/test/javax/xml/crypto/dsig/data/xml-stylesheet.b64 - # TODO #$ find openjdk -name '*.jar' -o -name '*.class'|grep -v test
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/CHANGES.txt Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/CHANGES.txt Mon Nov 17 15:26:51 2008 +0000 @@ -1,3 +1,14 @@ + - Fix: Throw IllegalArgumentException Exception on + invalid soundbank to: + SoftSynthesizer.unloadAllInstruments(Soundbank soundbank) + SoftSynthesizer.unloadInstruments(Soundbank soundbank, Patch[] patchList) + just like done in: + SoftSynthesizer.unloadInstrument(Instrument instrument). + - Change: SoftMainMixer, SoftVoice optimized for mono voices. + - Change: SoftFilter optimized. + - Fix: Turn SoftJitterCorrector, SoftAudioPusher threads into a daemon threads. + These threads prevented the VM to exit when synthesizer was open. + See: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=213 - Add: More JTreg tests added: EmergencySoundbank SoftFilter @@ -6,6 +17,8 @@ - Fix: ModelByteBuffer.skip called super.skip instead to call to RandomAccessFile directly. JTreg tests added: ModelByteBuffer/RandomFileInputStream/*.java + +Version 1.0.2 (released in OpenJDK 6 b12) - Fix: ModelByteBuffer.len was being modified in inner class RandomFileInputStream. The variable was made final and RandomFileInputStream.read methods where fixed. @@ -13,7 +26,7 @@ Keys array was to small, it couldn't hold all possible midi notes (0..127). -Version 1.0.1 +Version 1.0.1 (released as 1.0) - Fix: Created dummy SourceDataline so that following jtreg test can be tested without using a real Audio Device SourceDataLine.
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java Mon Nov 17 15:26:51 2008 +0000 @@ -54,6 +54,7 @@ return; active = true; audiothread = new Thread(this); + audiothread.setDaemon(true); audiothread.setPriority(Thread.MAX_PRIORITY); audiothread.start(); }
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java Mon Nov 17 15:26:51 2008 +0000 @@ -543,8 +543,6 @@ public void filter1(SoftAudioBuffer sbuffer) { - float[] buffer = sbuffer.array(); - if (dirty) { filter1calc(); dirty = false; @@ -559,6 +557,7 @@ if (wet > 0 || last_wet > 0) { + float[] buffer = sbuffer.array(); int len = buffer.length; float a0 = this.last_a0; float q = this.last_q; @@ -577,14 +576,16 @@ q += q_delta; gain += gain_delta; wet += wet_delta; - y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i]; - y2 = (1 - q * a0) * y2 + (a0) * y1; + float ga0 = (1 - q * a0); + y1 = ga0 * y1 + (a0) * (buffer[i] - y2); + y2 = ga0 * y2 + (a0) * y1; buffer[i] = y2 * gain * wet + buffer[i] * (1 - wet); } } else if (a0_delta == 0 && q_delta == 0) { + float ga0 = (1 - q * a0); for (int i = 0; i < len; i++) { - y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i]; - y2 = (1 - q * a0) * y2 + (a0) * y1; + y1 = ga0 * y1 + (a0) * (buffer[i] - y2); + y2 = ga0 * y2 + (a0) * y1; buffer[i] = y2 * gain; } } else { @@ -592,8 +593,9 @@ a0 += a0_delta; q += q_delta; gain += gain_delta; - y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i]; - y2 = (1 - q * a0) * y2 + (a0) * y1; + float ga0 = (1 - q * a0); + y1 = ga0 * y1 + (a0) * (buffer[i] - y2); + y2 = ga0 * y2 + (a0) * y1; buffer[i] = y2 * gain; } } @@ -611,4 +613,4 @@ this.last_gain = this.gain; this.last_wet = this.wet; } -} +} \ No newline at end of file
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java Mon Nov 17 15:26:51 2008 +0000 @@ -216,6 +216,7 @@ }; thread = new Thread(runnable); + thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.start(); }
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java Mon Nov 17 15:26:51 2008 +0000 @@ -48,16 +48,18 @@ public final static int CHANNEL_LEFT = 0; public final static int CHANNEL_RIGHT = 1; - public final static int CHANNEL_EFFECT1 = 2; - public final static int CHANNEL_EFFECT2 = 3; - public final static int CHANNEL_EFFECT3 = 4; - public final static int CHANNEL_EFFECT4 = 5; + public final static int CHANNEL_MONO = 2; + public final static int CHANNEL_EFFECT1 = 3; + public final static int CHANNEL_EFFECT2 = 4; + public final static int CHANNEL_EFFECT3 = 5; + public final static int CHANNEL_EFFECT4 = 6; public final static int CHANNEL_LEFT_DRY = 10; public final static int CHANNEL_RIGHT_DRY = 11; public final static int CHANNEL_SCRATCH1 = 12; public final static int CHANNEL_SCRATCH2 = 13; public final static int CHANNEL_CHANNELMIXER_LEFT = 14; public final static int CHANNEL_CHANNELMIXER_RIGHT = 15; + public final static int CHANNEL_CHANNELMIXER_MONO = 16; protected boolean active_sensing_on = false; private long msec_last_activity = -1; private boolean pusher_silent = false; @@ -485,8 +487,10 @@ // to channelmixer left,right input/output SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT]; SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT]; + SoftAudioBuffer monobak = buffers[CHANNEL_MONO]; buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT]; - buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_LEFT]; + buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_RIGHT]; + buffers[CHANNEL_MONO] = buffers[CHANNEL_CHANNELMIXER_MONO]; int bufferlen = buffers[CHANNEL_LEFT].getSize(); @@ -503,6 +507,7 @@ for (ModelChannelMixer cmixer : act_registeredMixers) { for (int i = 0; i < cbuffer.length; i++) Arrays.fill(cbuffer[i], 0); + buffers[CHANNEL_MONO].clear(); boolean hasactivevoices = false; for (int i = 0; i < voicestatus.length; i++) if (voicestatus[i].active) @@ -516,6 +521,26 @@ cur_registeredMixers = null; } } + + if(!buffers[CHANNEL_MONO].isSilent()) + { + float[] mono = buffers[CHANNEL_MONO].array(); + float[] left = buffers[CHANNEL_LEFT].array(); + if (nrofchannels != 1) { + float[] right = buffers[CHANNEL_RIGHT].array(); + for (int i = 0; i < bufferlen; i++) { + float v = mono[i]; + left[i] += v; + right[i] += v; + } + } + else + { + for (int i = 0; i < bufferlen; i++) { + left[i] += mono[i]; + } + } + } for (int i = 0; i < cbuffer.length; i++) { float[] cbuff = cbuffer[i]; @@ -539,6 +564,7 @@ buffers[CHANNEL_LEFT] = leftbak; buffers[CHANNEL_RIGHT] = rightbak; + buffers[CHANNEL_MONO] = monobak; } @@ -546,6 +572,27 @@ if (voicestatus[i].active) if (voicestatus[i].channelmixer == null) voicestatus[i].processAudioLogic(buffers); + + if(!buffers[CHANNEL_MONO].isSilent()) + { + float[] mono = buffers[CHANNEL_MONO].array(); + float[] left = buffers[CHANNEL_LEFT].array(); + int bufferlen = buffers[CHANNEL_LEFT].getSize(); + if (nrofchannels != 1) { + float[] right = buffers[CHANNEL_RIGHT].array(); + for (int i = 0; i < bufferlen; i++) { + float v = mono[i]; + left[i] += v; + right[i] += v; + } + } + else + { + for (int i = 0; i < bufferlen; i++) { + left[i] += mono[i]; + } + } + } // Run effects if (synth.chorus_on) @@ -665,7 +712,7 @@ / synth.getControlRate()); control_mutex = synth.control_mutex; - buffers = new SoftAudioBuffer[16]; + buffers = new SoftAudioBuffer[17]; for (int i = 0; i < buffers.length; i++) { buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat()); }
--- a/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java Mon Nov 17 15:26:51 2008 +0000 @@ -782,6 +782,7 @@ SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT]; SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT]; + SoftAudioBuffer mono = buffer[SoftMainMixer.CHANNEL_MONO]; SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1]; SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2]; SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY]; @@ -802,17 +803,26 @@ if (rightdry != null) mixAudioStream(rightdry, left, last_out_mixer_left, out_mixer_left); - } else { - mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left); - if (rightdry != null) - mixAudioStream(rightdry, right, last_out_mixer_right, + } else { + if(rightdry == null && + last_out_mixer_left == last_out_mixer_right && + out_mixer_left == out_mixer_right) + { + mixAudioStream(leftdry, mono, last_out_mixer_left, out_mixer_left); + } + else + { + mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left); + if (rightdry != null) + mixAudioStream(rightdry, right, last_out_mixer_right, out_mixer_right); - else - mixAudioStream(leftdry, right, last_out_mixer_right, + else + mixAudioStream(leftdry, right, last_out_mixer_right, out_mixer_right); + } } - if (rightdry == null) { + if (rightdry == null) { mixAudioStream(leftdry, eff1, last_out_mixer_effect1, out_mixer_effect1); mixAudioStream(leftdry, eff2, last_out_mixer_effect2,
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Mon Nov 17 15:26:51 2008 +0000 @@ -17,24 +17,44 @@ package net.sourceforge.jnlp.runtime; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.*; -import java.security.*; -import java.lang.reflect.*; -import javax.jnlp.*; -import javax.swing.JOptionPane; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Vector; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; - -import java.security.cert.Certificate; - -import net.sourceforge.jnlp.*; -import net.sourceforge.jnlp.cache.*; -import net.sourceforge.jnlp.security.*; -import net.sourceforge.jnlp.services.*; +import net.sourceforge.jnlp.ExtensionDesc; +import net.sourceforge.jnlp.JARDesc; +import net.sourceforge.jnlp.JNLPFile; +import net.sourceforge.jnlp.LaunchException; +import net.sourceforge.jnlp.ParseException; +import net.sourceforge.jnlp.PluginBridge; +import net.sourceforge.jnlp.ResourcesDesc; +import net.sourceforge.jnlp.SecurityDesc; +import net.sourceforge.jnlp.cache.CacheUtil; +import net.sourceforge.jnlp.cache.ResourceTracker; +import net.sourceforge.jnlp.cache.UpdatePolicy; +import net.sourceforge.jnlp.security.SecurityWarningDialog; import net.sourceforge.jnlp.tools.JarSigner; -import net.sourceforge.jnlp.tools.KeyTool; +import sun.misc.JarIndex; /** * Classloader that takes it's resources from a JNLP file. If the @@ -109,6 +129,8 @@ private JarSigner js = null; private boolean signing = false; + + private ArrayList<JarIndex> jarIndexes = new ArrayList<JarIndex>(); /** * Create a new JNLPClassLoader from the specified file. @@ -469,6 +491,11 @@ addURL(location); + // there is currently no mechanism to cache files per + // instance.. so only index cached files + if (localFile != null) + jarIndexes.add(JarIndex.getJarIndex(new JarFile(localFile.getAbsolutePath()), null)); + if (JNLPRuntime.isDebug()) System.err.println("Activate jar: "+location); } @@ -635,6 +662,7 @@ * extensions. */ public Class loadClass(String name) throws ClassNotFoundException { + Class result = findLoadedClassAll(name); // try parent classloader @@ -654,7 +682,60 @@ // search this and the extension loaders if (result == null) - result = loadClassExt(name); + try { + result = loadClassExt(name); + } catch (ClassNotFoundException cnfe) { + + // Not found in external loader either. As a last resort, look in any available indexes + + // Currently this loads jars directly from the site. We cannot cache it because this + // call is initiated from within the applet, which does not have disk read/write permissions + for (JarIndex index: jarIndexes) { + LinkedList<String> jarList = index.get(name.replace('.', '/')); + + if (jarList != null) { + for (String jarName: jarList) { + JARDesc desc; + try { + desc = new JARDesc(new URL(file.getCodeBase(), jarName), + null, null, false, true, false); + } catch (MalformedURLException mfe) { + throw new ClassNotFoundException(name); + } + + available.add(desc); + + tracker.addResource(desc.getLocation(), + desc.getVersion(), + JNLPRuntime.getDefaultUpdatePolicy() + ); + + URL remoteURL; + try { + remoteURL = new URL(file.getCodeBase() + jarName); + } catch (MalformedURLException mfe) { + throw new ClassNotFoundException(name); + } + + URL u; + + try { + u = tracker.getCacheURL(remoteURL); + System.out.println("URL = " + u); + } catch (Exception e) { + throw new ClassNotFoundException(name); + } + + if (u != null) + addURL(u); + + } + + // If it still fails, let it error out + result = loadClassExt(name); + } + } + } return result; }
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Mon Nov 17 15:26:51 2008 +0000 @@ -17,20 +17,24 @@ package net.sourceforge.jnlp.runtime; -import java.awt.*; -import java.awt.event.*; -import java.lang.ref.*; -import javax.swing.*; -import java.security.*; +import java.awt.Frame; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.ref.WeakReference; +import java.net.SocketPermission; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; +import javax.swing.JWindow; + +import net.sourceforge.jnlp.JNLPFile; import net.sourceforge.jnlp.security.SecurityWarningDialog; import net.sourceforge.jnlp.services.ServiceUtil; -import net.sourceforge.jnlp.util.*; - +import net.sourceforge.jnlp.util.WeakList; import sun.security.util.SecurityConstants; -import java.net.SocketPermission; - /** * Security manager for JNLP environment. This security manager * cannot be replaced as it always denies attempts to replace the @@ -122,6 +126,11 @@ public void windowDeactivated(WindowEvent e) { activeApplication = null; } + + public void windowClosing(WindowEvent e) { + System.err.println("Disposing window"); + e.getWindow().dispose(); + } }; @@ -278,6 +287,46 @@ if (perm instanceof SocketPermission) { tmpPerm = new SocketPermission(perm.getName(), SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION); + + // before proceeding, check if we are trying to connect to same origin + ApplicationInstance app = getApplication(); + JNLPFile file = app.getJNLPFile(); + + String srcHost = file.getSourceLocation().getAuthority(); + String destHost = name; + + // host = abc.xyz.com or abc.xyz.com:<port> + if (destHost.indexOf(':') >= 0) + destHost = destHost.substring(0, destHost.indexOf(':')); + + // host = abc.xyz.com + String[] hostComponents = destHost.split("\\."); + + int length = hostComponents.length; + if (length >= 2) { + + // address is in xxx.xxx.xxx format + destHost = hostComponents[length -2] + "." + hostComponents[length -1]; + + // host = xyz.com i.e. origin + boolean isDestHostName = false; + + // make sure that it is not an ip address + try { + Integer.parseInt(hostComponents[length -1]); + } catch (NumberFormatException e) { + isDestHostName = true; + } + + if (isDestHostName) { + // okay, destination is hostname. Now figure out if it is a subset of origin + if (srcHost.endsWith(destHost)) { + addPermission(tmpPerm); + return; + } + } + } + } else tmpPerm = perm;
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java Mon Nov 17 12:41:07 2008 +0000 +++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/security/AccessWarningPane.java Mon Nov 17 15:26:51 2008 +0000 @@ -84,18 +84,19 @@ //We don't worry about exceptions when trying to fill in //these strings -- we just want to fill in as many as possible. try { - name = file.getInformation().getTitle(); + name = file.getInformation().getTitle() != null ? file.getInformation().getTitle() : "<no associated certificate>"; } catch (Exception e) { } try { - publisher = file.getInformation().getVendor(); + publisher = file.getInformation().getVendor() != null ? file.getInformation().getVendor() : "<no associated certificate>"; } catch (Exception e) { } try { - from = file.getInformation().getHomepage().toString(); + from = !file.getInformation().getHomepage().toString().equals("") ? file.getInformation().getHomepage().toString() : file.getSourceLocation().getAuthority(); } catch (Exception e) { + from = file.getSourceLocation().getAuthority(); } //Top label
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-6761856-freetypescaler.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,47 @@ +# User igor +# Date 1225234342 -10800 +# Node ID 9cdababf6179bd03270d881740fbb5dcc405854f +# Parent 594c52582b21063bdbc36b38d9f73a3c46abe041 +6761856: OpenJDK: vertical text metrics may be significanly different from those returned by Sun JDK +Reviewed-by: bae, prr + +--- openjdk.orig/jdk/src/share/native/sun/font/freetypeScaler.c Tue Oct 28 14:47:14 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/font/freetypeScaler.c Wed Oct 29 01:52:22 2008 +0300 +@@ -1281,7 +1281,7 @@ Java_sun_font_FreetypeFontScaler_getGlyp + sunFontIDs.rect2DFloatClass, + sunFontIDs.rect2DFloatCtr4, + F26Dot6ToFloat(bbox.xMin), +- F26Dot6ToFloat(bbox.yMax), ++ F26Dot6ToFloat(-bbox.yMax), + F26Dot6ToFloat(bbox.xMax-bbox.xMin), + F26Dot6ToFloat(bbox.yMax-bbox.yMin)); + } +--- openjdk.orig/jdk/test/java/awt/font/TextLayout/TextLayoutBounds.java Tue Oct 28 14:47:14 2008 -0700 ++++ openjdk/jdk/test/java/awt/font/TextLayout/TextLayoutBounds.java Wed Oct 29 01:52:22 2008 +0300 +@@ -22,7 +22,7 @@ + */ + /* @test + * @summary verify TextLayout.getBounds() return visual bounds +- * @bug 6323611 ++ * @bug 6323611 6761856 + */ + + import java.awt.*; +@@ -39,10 +39,15 @@ public class TextLayoutBounds { + Rectangle2D tlBounds = tl.getBounds(); + GlyphVector gv = f.createGlyphVector(frc, s); + Rectangle2D gvvBounds = gv.getVisualBounds(); ++ Rectangle2D oBounds = tl.getOutline(null).getBounds2D(); + System.out.println("tlbounds="+tlBounds); + System.out.println("gvbounds="+gvvBounds); ++ System.out.println("outlineBounds="+oBounds); + if (!gvvBounds.equals(tlBounds)) { +- throw new RuntimeException("Bounds differ"); ++ throw new RuntimeException("Bounds differ [gvv != tl]"); ++ } ++ if (!tlBounds.equals(oBounds)) { ++ throw new RuntimeException("Bounds differ [tl != outline]"); + } + } + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-alsa-default-device.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,17 @@ +diff -uNr openjdk-orig/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c openjdk/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c +--- openjdk-orig/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c 2008-11-03 15:02:16.000000000 -0500 ++++ openjdk/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c 2008-11-03 15:08:07.000000000 -0500 +@@ -143,8 +143,12 @@ + ERROR1("snd_pcm_hw_params_malloc returned error %d\n", ret); + } else { + ret = snd_pcm_hw_params_any(handle, hwParams); +- if (ret != 0) { ++ /* snd_pcm_hw_params_any can return a positive value on success too */ ++ if (ret < 0) { + ERROR1("snd_pcm_hw_params_any returned error %d\n", ret); ++ } else { ++ /* for the logic following this code, set ret to 0 to indicate success */ ++ ret = 0; + } + } + snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-cc-interp-no-fer.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,15 @@ +diff -r 11b9bdd4bbd3 openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp +--- openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp Fri Nov 07 10:53:57 2008 +0000 ++++ openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp Fri Nov 07 11:29:34 2008 +0000 +@@ -116,7 +116,11 @@ jvmtiCapabilities JvmtiManageCapabilitie + + memset(&jc, 0, sizeof(jc)); + jc.can_pop_frame = 1; ++#ifdef CC_INTERP ++ jc.can_force_early_return = 0; ++#else + jc.can_force_early_return = 1; ++#endif // CC_INTERP + jc.can_get_source_debug_extension = 1; + jc.can_access_local_variables = 1; + jc.can_maintain_original_method_order = 1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-display-mode-changer.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,100 @@ +6733718: test /java/awt/FullScreen/UninitializedDisplayModeChangeTest/ fails +Reviewed-by: igor + +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/FullScreen/UninitializedDisplayModeChangeTest/DisplayModeChanger.java Tue Aug 05 09:37:03 2008 -0700 +@@ -0,0 +1,93 @@ ++/* ++ * Copyright 2006-2008 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, ++ * CA 95054 USA or visit www.sun.com if you need additional information or ++ * have any questions. ++ */ ++ ++import java.awt.DisplayMode; ++import java.awt.EventQueue; ++import java.awt.Frame; ++import java.awt.GraphicsDevice; ++import java.awt.GraphicsEnvironment; ++import java.lang.reflect.InvocationTargetException; ++ ++/** ++ * Used by the UninitializedDisplayModeChangeTest to change the ++ * display mode. ++ */ ++public class DisplayModeChanger { ++ ++ public static void main(String[] args) ++ throws InterruptedException, InvocationTargetException ++ { ++ final GraphicsDevice gd = ++ GraphicsEnvironment.getLocalGraphicsEnvironment(). ++ getDefaultScreenDevice(); ++ ++ EventQueue.invokeAndWait(new Runnable() { ++ public void run() { ++ Frame f = null; ++ if (gd.isFullScreenSupported()) { ++ try { ++ f = new Frame("DisplayChanger Frame"); ++ gd.setFullScreenWindow(f); ++ if (gd.isDisplayChangeSupported()) { ++ DisplayMode dm = findDisplayMode(gd); ++ if (gd != null) { ++ gd.setDisplayMode(dm); ++ } ++ } ++ try { ++ Thread.sleep(1000); ++ } catch (InterruptedException ex) { ++ ex.printStackTrace(); ++ } ++ gd.setFullScreenWindow(null); ++ } finally { ++ if (f != null) { ++ f.dispose(); ++ } ++ } ++ } ++ } ++ }); ++ } ++ ++ /** ++ * Finds a display mode that is different from the current display ++ * mode and is likely to cause a display change event. ++ */ ++ private static DisplayMode findDisplayMode(GraphicsDevice gd) { ++ DisplayMode dms[] = gd.getDisplayModes(); ++ DisplayMode currentDM = gd.getDisplayMode(); ++ for (DisplayMode dm : dms) { ++ if (!dm.equals(currentDM) && ++ dm.getRefreshRate() == currentDM.getRefreshRate()) ++ { ++ // different from the current dm and refresh rate is the same ++ // means that something else is different => more likely to ++ // cause a DM change event ++ return dm; ++ } ++ } ++ return null; ++ } ++ ++} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-f2i-overflow.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,96 @@ +diff -r dcb49b482348 -r f63a8dee04ae openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp +--- openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Nov 03 14:00:57 2008 +0000 ++++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Nov 03 15:56:17 2008 +0000 +@@ -173,64 +173,46 @@ JRT_END + + + JRT_LEAF(jint, SharedRuntime::f2i(jfloat x)) +- if (g_isnan(x)) {return 0;} +- jlong lltmp = (jlong)x; +- jint ltmp = (jint)lltmp; +- if (ltmp == lltmp) { +- return ltmp; +- } else { +- if (x < 0) { +- return min_jint; +- } else { +- return max_jint; +- } +- } ++ if (g_isnan(x)) ++ return 0; ++ if (x >= (jfloat) max_jint) ++ return max_jint; ++ if (x <= (jfloat) min_jint) ++ return min_jint; ++ return (jint) x; + JRT_END + + + JRT_LEAF(jlong, SharedRuntime::f2l(jfloat x)) +- if (g_isnan(x)) {return 0;} +- jlong lltmp = (jlong)x; +- if (lltmp != min_jlong) { +- return lltmp; +- } else { +- if (x < 0) { +- return min_jlong; +- } else { +- return max_jlong; +- } +- } ++ if (g_isnan(x)) ++ return 0; ++ if (x >= (jfloat) max_jlong) ++ return max_jlong; ++ if (x <= (jfloat) min_jlong) ++ return min_jlong; ++ return (jlong) x; + JRT_END + + + JRT_LEAF(jint, SharedRuntime::d2i(jdouble x)) +- if (g_isnan(x)) {return 0;} +- jlong lltmp = (jlong)x; +- jint ltmp = (jint)lltmp; +- if (ltmp == lltmp) { +- return ltmp; +- } else { +- if (x < 0) { +- return min_jint; +- } else { +- return max_jint; +- } +- } ++ if (g_isnan(x)) ++ return 0; ++ if (x >= (jdouble) max_jint) ++ return max_jint; ++ if (x <= (jdouble) min_jint) ++ return min_jint; ++ return (jint) x; + JRT_END + + + JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x)) +- if (g_isnan(x)) {return 0;} +- jlong lltmp = (jlong)x; +- if (lltmp != min_jlong) { +- return lltmp; +- } else { +- if (x < 0) { +- return min_jlong; +- } else { +- return max_jlong; +- } +- } ++ if (g_isnan(x)) ++ return 0; ++ if (x >= (jdouble) max_jlong) ++ return max_jlong; ++ if (x <= (jdouble) min_jlong) ++ return min_jlong; ++ return (jlong) x; + JRT_END + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-linker-libs-order.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,66 @@ +diff -Nru openjdk.orig/jdk/make/com/sun/java/pack/Makefile openjdk/jdk/make/com/sun/java/pack/Makefile +--- openjdk.orig/jdk/make/com/sun/java/pack/Makefile 2008-11-17 13:13:17.000000000 +0000 ++++ openjdk/jdk/make/com/sun/java/pack/Makefile 2008-11-17 14:25:44.000000000 +0000 +@@ -75,12 +75,12 @@ + $(ZIPOBJDIR)/infutil.$(OBJECT_SUFFIX) \ + $(ZIPOBJDIR)/inffast.$(OBJECT_SUFFIX) + +- OTHER_LDLIBS += -lz + else + OTHER_CXXFLAGS += -DNO_ZLIB -DUNPACK_JNI +- OTHER_LDLIBS += -lz $(JVMLIB) ++ OTHER_LDLIBS += $(JVMLIB) + endif + ++OTHER_LDLIBS += -lz + CXXFLAGS_DBG += -DFULL + CXXFLAGS_OPT += -DPRODUCT + CXXFLAGS_COMMON += -DFULL +@@ -97,12 +97,11 @@ + RES = $(OBJDIR)/$(PGRM).res + else + LDOUTPUT = -o #Have a space +- LDDFLAGS += -lz -lc +- OTHER_LDLIBS += $(LIBCXX) ++ OTHER_LDLIBS += $(LIBCXX) -lc + # setup the list of libraries to link in... + ifeq ($(PLATFORM), linux) + ifeq ("$(CC_VER_MAJOR)", "3") +- OTHER_LDLIBS += -lz -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic ++ OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic + endif + endif #LINUX + endif #PLATFORM +@@ -139,7 +138,7 @@ + + $(UNPACK_EXE): $(UNPACK_EXE_FILES_o) winres + $(prep-target) +- $(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX) ++ $(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(OTHER_LDLIBS) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX) + $(CP) $(TEMPDIR)/unpack200$(EXE_SUFFIX) $(UNPACK_EXE) + + +diff -Nru openjdk.orig/jdk/make/common/shared/Sanity.gmk openjdk/jdk/make/common/shared/Sanity.gmk +--- openjdk.orig/jdk/make/common/shared/Sanity.gmk 2008-11-06 08:44:09.000000000 +0000 ++++ openjdk/jdk/make/common/shared/Sanity.gmk 2008-11-17 14:25:44.000000000 +0000 +@@ -1345,7 +1345,7 @@ + ifdef ALSA_VERSION_CHECK + $(ALSA_VERSION_CHECK): $(ALSA_VERSION_CHECK).c + @$(prep-target) +- @$(CC) -lasound -o $@ $< ++ @$(CC) -o $@ $< -lasound + + $(ALSA_VERSION_CHECK).c: + @$(prep-target) +diff -Nru openjdk.orig/jdk/make/javax/sound/jsoundalsa/Makefile openjdk/jdk/make/javax/sound/jsoundalsa/Makefile +--- openjdk.orig/jdk/make/javax/sound/jsoundalsa/Makefile 2008-11-06 08:44:10.000000000 +0000 ++++ openjdk/jdk/make/javax/sound/jsoundalsa/Makefile 2008-11-17 14:25:44.000000000 +0000 +@@ -65,7 +65,7 @@ + $(MIDIFILES_export) \ + $(PORTFILES_export) + +-LDFLAGS += -lasound ++OTHER_LDLIBS += -lasound + + CPPFLAGS += \ + -DUSE_DAUDIO=TRUE \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/icedtea-testenv.patch Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,60 @@ +diff -Nru openjdk.orig/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java openjdk/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java +--- openjdk.orig/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java 2008-11-06 08:45:01.000000000 +0000 ++++ openjdk/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java 2008-11-17 14:46:05.000000000 +0000 +@@ -40,7 +40,7 @@ + InetAddress bogus = InetAddress.getByName("0.0.0.0"); + SocketChannel sc = SocketChannel.open(); + InetSocketAddress saddr = new InetSocketAddress( +- InetAddress.getByName(TestUtil.HOST), 23); ++ InetAddress.getByName(TestUtil.HOST), 7); + + //Test1: connect only + sc.connect(saddr); +diff -Nru openjdk.orig/jdk/test/java/nio/channels/SocketChannel/Shutdown.java openjdk/jdk/test/java/nio/channels/SocketChannel/Shutdown.java +--- openjdk.orig/jdk/test/java/nio/channels/SocketChannel/Shutdown.java 2008-11-06 08:45:01.000000000 +0000 ++++ openjdk/jdk/test/java/nio/channels/SocketChannel/Shutdown.java 2008-11-17 14:45:53.000000000 +0000 +@@ -35,7 +35,7 @@ + + public static void main(String args[]) throws Exception { + InetSocketAddress sa = new InetSocketAddress( +- InetAddress.getByName(TestUtil.HOST), 23); ++ InetAddress.getByName(TestUtil.HOST), 7); + SocketChannel sc = SocketChannel.open(sa); + boolean before = sc.socket().isInputShutdown(); + sc.socket().shutdownInput(); +diff -Nru openjdk.orig/jdk/test/java/nio/channels/TestUtil.java openjdk/jdk/test/java/nio/channels/TestUtil.java +--- openjdk.orig/jdk/test/java/nio/channels/TestUtil.java 2008-11-17 14:43:22.000000000 +0000 ++++ openjdk/jdk/test/java/nio/channels/TestUtil.java 2008-11-17 14:44:24.000000000 +0000 +@@ -36,9 +36,9 @@ + + // Test hosts used by the channels tests - change these when + // executing in a different network. +- public static final String HOST = "javaweb.sfbay.sun.com"; +- public static final String REFUSING_HOST = "jano1.sfbay.sun.com"; +- public static final String FAR_HOST = "irejano.ireland.sun.com"; ++ public static final String HOST = "icedtea.classpath.org"; ++ public static final String REFUSING_HOST = "ns1.gnu.org"; ++ public static final String FAR_HOST = "developer.classpath.org"; + public static final String UNRESOLVABLE_HOST = "blah-blah.blah-blah.blah"; + + private TestUtil() { } +diff -Nru openjdk.orig/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh openjdk/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh +--- openjdk.orig/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh 2008-11-06 08:45:08.000000000 +0000 ++++ openjdk/jdk/test/sun/net/InetAddress/nameservice/dns/cname.sh 2008-11-17 14:48:52.000000000 +0000 +@@ -26,14 +26,14 @@ + + # @test + # @bug 4763315 +-# @build CanonicalName Lookup ++# @build CanonicalName Lookup + # @run shell/timeout=120 cname.sh + # @summary Test DNS provider's handling of CNAME records + + + # The host that we try to resolve + +-HOST=webcache.sfbay.sun.com ++HOST=developer.classpath.org + + # fail gracefully if DNS is not configured or there + # isn't a CNAME record.
--- a/patches/icedtea-uname.patch Mon Nov 17 12:41:07 2008 +0000 +++ b/patches/icedtea-uname.patch Mon Nov 17 15:26:51 2008 +0000 @@ -5,7 +5,7 @@ # Arch and OS name/version mach := $(shell uname -m) + ifneq (,$(wildcard /usr/bin/dpkg-architecture)) -+ mach := $(shell dpkg-architecture -qDEB_BUILD_ARCH_CPU 2>/dev/null || echo $(mach)) ++ mach := $(shell (dpkg-architecture -qDEB_BUILD_ARCH_CPU 2>/dev/null || echo $(mach)) | sed 's/powerpc$$/ppc/') + endif archExpr = case "$(mach)" in \ i[3-9]86) \ @@ -27,7 +27,7 @@ # Arch and OS name/version mach := $(shell uname -m) + ifneq (,$(wildcard /usr/bin/dpkg-architecture)) -+ mach := $(shell dpkg-architecture -qDEB_BUILD_ARCH_CPU 2>/dev/null || echo $(mach)) ++ mach := $(shell (dpkg-architecture -qDEB_BUILD_ARCH_CPU 2>/dev/null || echo $(mach)) | sed 's/powerpc$$/ppc/') + endif archExpr = case "$(mach)" in \ i[3-9]86) \
--- a/patches/icedtea-visualvm.patch Mon Nov 17 12:41:07 2008 +0000 +++ b/patches/icedtea-visualvm.patch Mon Nov 17 15:26:51 2008 +0000 @@ -1,5 +1,5 @@ ---- oldplatform.properties 2008-09-29 13:52:36.000000000 -0400 -+++ visualvm/visualvm/jvm/nbproject/platform.properties 2008-09-29 13:53:33.000000000 -0400 +--- pp 2008-10-31 11:24:42.000000000 -0400 ++++ visualvm/visualvm/jvm/nbproject/platform.properties 2008-10-31 11:24:48.000000000 -0400 @@ -16,8 +16,8 @@ org.openide.compat,\ org.openide.util.enumerations @@ -8,12 +8,12 @@ - profiler2 + platform8,\ + profiler3 - nbjdk.active=Java_HotSpot_TM__Client_VM_1.6.0-b88-17-release + nbjdk.active=default nbplatform.active=NetBeans_Platform_Dev_(Build_200711261600) suite.dir=${basedir} ---- oldplatform.properties1 2008-09-29 13:52:46.000000000 -0400 -+++ visualvm/visualvm/nbproject/platform.properties 2008-09-29 13:53:41.000000000 -0400 -@@ -15,8 +15,8 @@ +--- pp2 2008-10-31 11:50:40.000000000 -0400 ++++ visualvm/visualvm/nbproject/platform.properties 2008-10-31 11:50:47.000000000 -0400 +@@ -14,8 +14,8 @@ org.openide.compat,\ org.openide.util.enumerations enabled.clusters=\
--- a/plugin/icedtea/sun/applet/PluginAppletViewer.java Mon Nov 17 12:41:07 2008 +0000 +++ b/plugin/icedtea/sun/applet/PluginAppletViewer.java Mon Nov 17 15:26:51 2008 +0000 @@ -1265,6 +1265,10 @@ skipSpace(in); val = buf.toString(); } + + val = val.replace(">", ">"); + val = val.replace("<", "<"); + val = val.replace("&", "&"); PluginDebug.debug("PUT " + att + " = '" + val + "'"); atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); while (true) {
--- a/ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -82,7 +82,6 @@ } inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) { - // CVM did this 0x3f mask, is the really needed??? QQQ return ((unsigned long long) op1) >> (op2 & 0x3F); } @@ -237,11 +236,11 @@ } inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) { - return op1 << op2; + return op1 << (op2 & 0x1F); } inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) { - return op1 >> op2; // QQ op2 & 0x1f?? + return op1 >> (op2 & 0x1F); } inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) { @@ -249,7 +248,7 @@ } inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) { - return ((juint) op1) >> op2; // QQ op2 & 0x1f?? + return ((juint) op1) >> (op2 & 0x1F); } inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Nov 17 15:26:51 2008 +0000 @@ -77,6 +77,13 @@ intptr_t *result = NULL; int result_slots = 0; + + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } + while (true) { // We can set up the frame anchor with everything we want at // this point as we are thread_in_Java and no safepoints can @@ -151,6 +158,8 @@ } } + unwind_and_return: + // Unwind the current frame thread->pop_zero_frame(); @@ -164,6 +173,9 @@ void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { + // Make sure method is native and not abstract + assert(method->is_native() && !method->is_abstract(), "should be"); + JavaThread *thread = (JavaThread *) THREAD; ZeroStack *stack = thread->zero_stack(); @@ -173,11 +185,15 @@ interpreterState istate = frame->interpreter_state(); intptr_t *locals = istate->locals(); - // Make sure method is native and not abstract - assert(method->is_native() && !method->is_abstract(), "should be"); + // Check we're not about to run out of stack + if (stack_overflow_imminent(thread)) { + CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); + goto unwind_and_return; + } // Lock if necessary - BasicObjectLock *monitor = NULL; + BasicObjectLock *monitor; + monitor = NULL; if (method->is_synchronized()) { monitor = (BasicObjectLock*) istate->stack_base(); oop lockee = monitor->obj(); @@ -190,81 +206,83 @@ } else { CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor)); - if (HAS_PENDING_EXCEPTION) { - thread->pop_zero_frame(); - return; - } + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; } } } // Get the signature handler - address handlerAddr = method->signature_handler(); - if (handlerAddr == NULL) { - CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method)); - if (HAS_PENDING_EXCEPTION) { - thread->pop_zero_frame(); - return; + InterpreterRuntime::SignatureHandler *handler; + { + address handlerAddr = method->signature_handler(); + if (handlerAddr == NULL) { + CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + + handlerAddr = method->signature_handler(); + assert(handlerAddr != NULL, "eh?"); } - handlerAddr = method->signature_handler(); - assert(handlerAddr != NULL, "eh?"); + if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) { + CALL_VM_NOCHECK(handlerAddr = + InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + handler = \ + InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); } - if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) { - CALL_VM_NOCHECK(handlerAddr = - InterpreterRuntime::slow_signature_handler(thread, method, NULL, NULL)); - if (HAS_PENDING_EXCEPTION) { - thread->pop_zero_frame(); - return; - } - } - InterpreterRuntime::SignatureHandler *handler = - InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr); // Get the native function entry point - address function = method->native_function(); + address function; + function = method->native_function(); assert(function != NULL, "should be set if signature handler is"); // Build the argument list if (handler->argument_count() * 2 > stack->available_words()) { Unimplemented(); } - void **arguments = - (void **) stack->alloc(handler->argument_count() * sizeof(void **)); - void **dst = arguments; - - void *env = thread->jni_environment(); - *(dst++) = &env; - - void *mirror = NULL; - if (method->is_static()) { - istate->set_oop_temp( - method->constants()->pool_holder()->klass_part()->java_mirror()); - mirror = istate->oop_temp_addr(); - *(dst++) = &mirror; - } - - intptr_t *src = locals; - for (int i = dst - arguments; i < handler->argument_count(); i++) { - ffi_type *type = handler->argument_type(i); - if (type == &ffi_type_pointer) { - if (*src) { - stack->push((intptr_t) src); - *(dst++) = stack->sp(); + void **arguments; + { + arguments = + (void **) stack->alloc(handler->argument_count() * sizeof(void **)); + void **dst = arguments; + + void *env = thread->jni_environment(); + *(dst++) = &env; + + void *mirror = NULL; + if (method->is_static()) { + istate->set_oop_temp( + method->constants()->pool_holder()->klass_part()->java_mirror()); + mirror = istate->oop_temp_addr(); + *(dst++) = &mirror; + } + + intptr_t *src = locals; + for (int i = dst - arguments; i < handler->argument_count(); i++) { + ffi_type *type = handler->argument_type(i); + if (type == &ffi_type_pointer) { + if (*src) { + stack->push((intptr_t) src); + *(dst++) = stack->sp(); + } + else { + *(dst++) = src; + } + src--; + } + else if (type->size == 4) { + *(dst++) = src--; + } + else if (type->size == 8) { + src--; + *(dst++) = src--; } else { - *(dst++) = src; + ShouldNotReachHere(); } - src--; - } - else if (type->size == 4) { - *(dst++) = src--; - } - else if (type->size == 8) { - src--; - *(dst++) = src--; - } - else { - ShouldNotReachHere(); } } @@ -318,6 +336,8 @@ } } + unwind_and_return: + // Unwind the current activation thread->pop_zero_frame(); @@ -536,6 +556,30 @@ stack->set_sp(stack->sp() + method->size_of_parameters()); } +bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) +{ + // How is the ABI stack? + address stack_top = thread->stack_base() - thread->stack_size(); + int free_stack = os::current_stack_pointer() - stack_top; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + // How is the Zero stack? + // Throwing a StackOverflowError involves a VM call, which means + // we need a frame on the stack. We should be checking here to + // ensure that methods we call have enough room to install the + // largest possible frame, but that's more than twice the size + // of the entire Zero stack we get by default, so we just check + // we have *some* space instead... + free_stack = thread->zero_stack()->available_words() * wordSize; + if (free_stack < StackShadowPages * os::vm_page_size()) { + return true; + } + + return false; +} + InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, const methodOop method, JavaThread* thread)
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -38,3 +38,7 @@ public: // Main loop of normal_entry static void main_loop(int recurse, TRAPS); + + private: + // Stack overflow checks + static bool stack_overflow_imminent(JavaThread *thread);
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Mon Nov 17 15:26:51 2008 +0000 @@ -133,7 +133,58 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) { - Unimplemented(); + assert(is_interpreted_frame(), "interpreted frame expected"); + methodOop method = interpreter_frame_method(); + BasicType type = method->result_type(); + intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address(); + oop obj; + + switch (type) { + case T_VOID: + break; + case T_BOOLEAN: + value_result->z = *(jboolean *) tos_addr; + break; + case T_BYTE: + value_result->b = *(jbyte *) tos_addr; + break; + case T_CHAR: + value_result->c = *(jchar *) tos_addr; + break; + case T_SHORT: + value_result->s = *(jshort *) tos_addr; + break; + case T_INT: + value_result->i = *(jint *) tos_addr; + break; + case T_LONG: + value_result->j = *(jlong *) tos_addr; + break; + case T_FLOAT: + value_result->f = *(jfloat *) tos_addr; + break; + case T_DOUBLE: + value_result->d = *(jdouble *) tos_addr; + break; + + case T_OBJECT: + case T_ARRAY: + if (method->is_native()) { + obj = get_interpreterState()->oop_temp(); + } + else { + oop* obj_p = (oop *) tos_addr; + obj = (obj_p == NULL) ? (oop) NULL : *obj_p; + } + assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); + *oop_result = obj; + break; + + default: + ShouldNotReachHere(); + } + + return type; } int frame::frame_size() const
--- a/ports/hotspot/src/cpu/zero/vm/globals_zero.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/globals_zero.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -48,7 +48,7 @@ define_pd_global(intx, StackYellowPages, 2); define_pd_global(intx, StackRedPages, 1); -define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+1)); +define_pd_global(intx, StackShadowPages, 3 DEBUG_ONLY(+3)); define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true);
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -174,7 +174,7 @@ inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { - Unimplemented(); + *dest = store_value; } inline jint Atomic::add(jint add_value, volatile jint* dest)
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -46,13 +46,28 @@ inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; } inline jshort OrderAccess::load_acquire(volatile jshort* p) { return *p; } inline jint OrderAccess::load_acquire(volatile jint* p) { return *p; } -inline jlong OrderAccess::load_acquire(volatile jlong* p) { return *p; } +inline jlong OrderAccess::load_acquire(volatile jlong* p) +{ + jlong tmp; + os::atomic_copy64(p, &tmp); + return tmp; +} inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { return *p; } inline jushort OrderAccess::load_acquire(volatile jushort* p) { return *p; } inline juint OrderAccess::load_acquire(volatile juint* p) { return *p; } -inline julong OrderAccess::load_acquire(volatile julong* p) { return *p; } +inline julong OrderAccess::load_acquire(volatile julong* p) +{ + julong tmp; + os::atomic_copy64(p, &tmp); + return tmp; +} inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { return *p; } -inline jdouble OrderAccess::load_acquire(volatile jdouble* p) { return *p; } +inline jdouble OrderAccess::load_acquire(volatile jdouble* p) +{ + jdouble tmp; + os::atomic_copy64(p, &tmp); + return tmp; +} inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) { return *p; } inline void* OrderAccess::load_ptr_acquire(volatile void* p) { return *(void* volatile *)p; } @@ -61,13 +76,13 @@ inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { *p = v; } inline void OrderAccess::release_store(volatile jshort* p, jshort v) { *p = v; } inline void OrderAccess::release_store(volatile jint* p, jint v) { *p = v; } -inline void OrderAccess::release_store(volatile jlong* p, jlong v) { *p = v; } +inline void OrderAccess::release_store(volatile jlong* p, jlong v) { os::atomic_copy64(&v, p); } inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { *p = v; } inline void OrderAccess::release_store(volatile jushort* p, jushort v) { *p = v; } inline void OrderAccess::release_store(volatile juint* p, juint v) { *p = v; } -inline void OrderAccess::release_store(volatile julong* p, julong v) { *p = v; } +inline void OrderAccess::release_store(volatile julong* p, julong v) { os::atomic_copy64(&v, p); } inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { *p = v; } -inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { *p = v; } +inline void OrderAccess::release_store(volatile jdouble* p, jdouble v) { os::atomic_copy64(&v, p); } inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { *p = v; } inline void OrderAccess::release_store_ptr(volatile void* p, void* v) { *(void* volatile *)p = v; } @@ -75,27 +90,27 @@ inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); } inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); } inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); } -inline void OrderAccess::store_fence(jlong* p, jlong v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); } inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); } inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); } inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); } -inline void OrderAccess::store_fence(julong* p, julong v) { *p = v; fence(); } +inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); } inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); } -inline void OrderAccess::store_fence(jdouble* p, jdouble v) { *p = v; fence(); } +inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); } inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); } inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); } -inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { *p = v; fence(); } +inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); } +inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); } -inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { *p = v; fence(); } -inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { *(void* volatile *)p = v; fence(); } +inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); } +inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Nov 17 15:26:51 2008 +0000 @@ -126,6 +126,60 @@ } if (info != NULL && thread != NULL) { + // Handle ALL stack overflow variations here + if (sig == SIGSEGV) { + address addr = (address) info->si_addr; + + // check if fault address is within thread stack + if (addr < thread->stack_base() && + addr >= thread->stack_base() - thread->stack_size()) { + // stack overflow + if (thread->in_stack_yellow_zone(addr)) { + thread->disable_stack_yellow_zone(); + Unimplemented(); + } + else if (thread->in_stack_red_zone(addr)) { + thread->disable_stack_red_zone(); + Unimplemented(); + } + else { + // Accessing stack address below sp may cause SEGV if + // current thread has MAP_GROWSDOWN stack. This should + // only happen when current thread was created by user + // code with MAP_GROWSDOWN flag and then attached to VM. + // See notes in os_linux.cpp. + if (thread->osthread()->expanding_stack() == 0) { + thread->osthread()->set_expanding_stack(); + if (os::Linux::manually_expand_stack(thread, addr)) { + thread->osthread()->clear_expanding_stack(); + return true; + } + thread->osthread()->clear_expanding_stack(); + } + else { + fatal("recursive segv. expanding stack."); + } + } + } + } + + /*if (thread->thread_state() == _thread_in_Java) { + Unimplemented(); + } + else*/ if (thread->thread_state() == _thread_in_vm && + sig == SIGBUS && thread->doing_unsafe_access()) { + Unimplemented(); + } + + // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC + // kicks in and the heap gets shrunk before the field access. + /*if (sig == SIGSEGV || sig == SIGBUS) { + address addr = JNI_FastGetField::find_slowcase_pc(pc); + if (addr != (address)-1) { + stub = addr; + } + }*/ + // Check to see if we caught the safepoint code in the process // of write protecting the memory serialization page. It write // enables the page immediately after protecting it so we can @@ -138,6 +192,16 @@ } } + // signal-chaining + if (os::Linux::chained_handler(sig, info, ucVoid)) { + return true; + } + + if (!abort_if_unrecognized) { + // caller wants another chance, so give it to him + return false; + } + #ifndef PRODUCT if (sig == SIGSEGV) { fatal("\n#" @@ -341,14 +405,14 @@ if (from > to) { jlong *end = from + count; while (from < end) - *(to++) = *(from++); + os::atomic_copy64(from++, to++); } else if (from < to) { jlong *end = from; from += count - 1; to += count - 1; while (from >= end) - *(to--) = *(from--); + os::atomic_copy64(from--, to--); } }
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -29,3 +29,16 @@ // Note: Currently only used in 64 bit Windows implementations static bool register_code_area(char *low, char *high) { return true; } + // Atomically copy 64 bits of data + static void atomic_copy64(volatile void *src, volatile void *dst) + { +#if defined(PPC) && !defined(_LP64) + double tmp; + asm volatile ("lfd %0, 0(%1)\n" + "stfd %0, 0(%2)\n" + : "=f"(tmp) + : "b"(src), "b"(dst)); +#else + *(jlong *) dst = *(jlong *) src; +#endif // PPC && !_LP64 + }
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Mon Nov 17 15:26:51 2008 +0000 @@ -486,19 +486,28 @@ b = pop(); a = pop(); push(SharkValue::create_jint( - builder()->CreateShl(a->jint_value(), b->jint_value()))); + builder()->CreateShl( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))))); break; case Bytecodes::_ishr: b = pop(); a = pop(); push(SharkValue::create_jint( - builder()->CreateAShr(a->jint_value(), b->jint_value()))); + builder()->CreateAShr( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))))); break; case Bytecodes::_iushr: b = pop(); a = pop(); push(SharkValue::create_jint( - builder()->CreateLShr(a->jint_value(), b->jint_value()))); + builder()->CreateLShr( + a->jint_value(), + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x1f))))); break; case Bytecodes::_iand: b = pop(); @@ -555,7 +564,9 @@ builder()->CreateShl( a->jlong_value(), builder()->CreateIntCast( - b->jint_value(), SharkType::jlong_type(), true)))); + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)))); break; case Bytecodes::_lshr: b = pop(); @@ -564,7 +575,9 @@ builder()->CreateAShr( a->jlong_value(), builder()->CreateIntCast( - b->jint_value(), SharkType::jlong_type(), true)))); + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)))); break; case Bytecodes::_lushr: b = pop(); @@ -573,7 +586,9 @@ builder()->CreateLShr( a->jlong_value(), builder()->CreateIntCast( - b->jint_value(), SharkType::jlong_type(), true)))); + builder()->CreateAnd( + b->jint_value(), LLVMValue::jint_constant(0x3f)), + SharkType::jlong_type(), true)))); break; case Bytecodes::_land: b = pop(); @@ -727,13 +742,11 @@ case Bytecodes::_f2i: push(SharkValue::create_jint( - builder()->CreateFPToSI( - pop()->jfloat_value(), SharkType::jint_type()))); + call_vm_leaf(SharkRuntime::f2i(), pop()->jfloat_value()))); break; case Bytecodes::_f2l: - push(SharkValue::create_jint( - builder()->CreateFPToSI( - pop()->jfloat_value(), SharkType::jlong_type()))); + push(SharkValue::create_jlong( + call_vm_leaf(SharkRuntime::f2l(), pop()->jfloat_value()))); break; case Bytecodes::_f2d: push(SharkValue::create_jdouble( @@ -743,13 +756,11 @@ case Bytecodes::_d2i: push(SharkValue::create_jint( - builder()->CreateFPToSI( - pop()->jdouble_value(), SharkType::jint_type()))); + call_vm_leaf(SharkRuntime::d2i(), pop()->jdouble_value()))); break; case Bytecodes::_d2l: push(SharkValue::create_jlong( - builder()->CreateFPToSI( - pop()->jdouble_value(), SharkType::jlong_type()))); + call_vm_leaf(SharkRuntime::d2l(), pop()->jdouble_value()))); break; case Bytecodes::_d2f: push(SharkValue::create_jfloat(
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -371,6 +371,12 @@ return call_vm_nocheck(callee, args, args + 4); } + llvm::CallInst* call_vm_leaf(llvm::Constant* callee, + llvm::Value* arg1) + { + return builder()->CreateCall(callee, arg1); + } + // Whole-method synchronization public: void acquire_method_lock();
--- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Mon Nov 17 15:26:51 2008 +0000 @@ -43,6 +43,11 @@ Constant* SharkRuntime::_throw_NullPointerException; Constant* SharkRuntime::_trace_bytecode; +Constant* SharkRuntime::_f2i; +Constant* SharkRuntime::_f2l; +Constant* SharkRuntime::_d2i; +Constant* SharkRuntime::_d2l; + Constant* SharkRuntime::_dump; Constant* SharkRuntime::_is_subtype_of; Constant* SharkRuntime::_should_not_reach_here; @@ -158,6 +163,29 @@ FunctionType::get(Type::VoidTy, params, false), "SharkRuntime__trace_bytecode"); + // Leaf calls + params.clear(); + params.push_back(SharkType::jfloat_type()); + _f2i = builder->make_function( + (intptr_t) SharedRuntime::f2i, + FunctionType::get(SharkType::jint_type(), params, false), + "SharedRuntime__f2i"); + _f2l = builder->make_function( + (intptr_t) SharedRuntime::f2l, + FunctionType::get(SharkType::jlong_type(), params, false), + "SharedRuntime__f2l"); + + params.clear(); + params.push_back(SharkType::jdouble_type()); + _d2i = builder->make_function( + (intptr_t) SharedRuntime::d2i, + FunctionType::get(SharkType::jint_type(), params, false), + "SharedRuntime__d2i"); + _d2l = builder->make_function( + (intptr_t) SharedRuntime::d2l, + FunctionType::get(SharkType::jlong_type(), params, false), + "SharedRuntime__d2l"); + // Non-VM calls params.clear(); params.push_back(SharkType::intptr_type());
--- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Mon Nov 17 12:41:07 2008 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Mon Nov 17 15:26:51 2008 +0000 @@ -162,6 +162,31 @@ return *(thread->zero_stack()->sp() + offset); } + // Leaf calls + private: + static llvm::Constant* _f2i; + static llvm::Constant* _f2l; + static llvm::Constant* _d2i; + static llvm::Constant* _d2l; + + public: + static llvm::Constant* f2i() + { + return _f2i; + } + static llvm::Constant* f2l() + { + return _f2l; + } + static llvm::Constant* d2i() + { + return _d2i; + } + static llvm::Constant* d2l() + { + return _d2l; + } + // Non-VM calls private: static llvm::Constant* _dump;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,104 @@ +/* EventLoop.java + Copyright (C) 2008 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea 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 for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. + */ + +package org.classpath.icedtea.pulseaudio; + +public class Debug { + + public enum DebugLevel { + Verbose, Debug, Info, Warning, Error, None + } + + private static DebugLevel currentDebugLevel = DebugLevel.None; + + public static void initialize() { + // System.out.println("PulseAudio: initializing Debug"); + + String systemSetting; + try { + systemSetting = System.getProperty("pulseaudio.debugLevel"); + } catch (SecurityException e) { + // sigh, we cant read that property + systemSetting = null; + } + + DebugLevel wantedLevel; + try { + wantedLevel = DebugLevel.valueOf(systemSetting); + + } catch (IllegalArgumentException e) { + wantedLevel = DebugLevel.Info; + } catch (NullPointerException e) { + wantedLevel = DebugLevel.None; + } + + currentDebugLevel = wantedLevel; + println(DebugLevel.Info, "Using debug level: " + currentDebugLevel); + } + + public static void println(String string) { + println(DebugLevel.Info, string); + } + + public static void print(DebugLevel level, String string) { + int result = level.compareTo(currentDebugLevel); + if (result >= 0) { + if (level.compareTo(DebugLevel.Error) >= 0) { + System.err.print(string); + } else { + System.out.print(string); + } + } else { + // do nothing + } + } + + public static void println(DebugLevel level, String string) { + + int result = level.compareTo(currentDebugLevel); + if (result >= 0) { + if (level.compareTo(DebugLevel.Error) >= 0) { + System.err.println("DEBUG: pulse-java: " + string); + } else { + System.out.println("DEBUG: pulse-java: " + string); + } + } else { + // do nothing + } + } + +}
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java Mon Nov 17 15:26:51 2008 +0000 @@ -42,6 +42,7 @@ import java.util.concurrent.Semaphore; import org.classpath.icedtea.pulseaudio.ContextEvent.Type; +import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; /* * any methods that can obstruct the behaviour of pa_mainloop should run @@ -55,7 +56,6 @@ /* * the threadLock object is the object used for synchronizing the * non-thread-safe operations of pulseaudio's c api - * */ public Object threadLock = new Object(); @@ -79,7 +79,6 @@ * * Do not synchronize the individual functions, synchronize * block/method/lines around the call - * */ private native void native_setup(String appName, String server); @@ -92,12 +91,8 @@ /* * These fields hold pointers - * - * */ - @SuppressWarnings("unused") private byte[] contextPointer; - @SuppressWarnings("unused") private byte[] mainloopPointer; /* @@ -105,7 +100,7 @@ */ static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } private EventLoop() { @@ -132,6 +127,8 @@ public void run() { native_setup(this.name, this.serverString); + Debug.println(DebugLevel.Info, "Eventloop.run(): eventloop starting"); + /* * Perhaps this loop should be written in C doing a Java to C call on * every iteration of the loop might be slow @@ -144,14 +141,15 @@ if (Thread.interrupted()) { native_shutdown(); - // System.out.println(this.getClass().getName() - // + ": shutting down"); // clean up the listeners synchronized (contextListeners) { contextListeners.clear(); } + Debug.println(DebugLevel.Info, + "EventLoop.run(): event loop terminated"); + return; } @@ -197,7 +195,8 @@ break; case 5: fireEvent(new ContextEvent(Type.FAILED)); - System.out.println("context failed"); + Debug.println(DebugLevel.Warning, + "EventLoop.update(): Context failed"); break; case 6: fireEvent(new ContextEvent(Type.TERMINATED));
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java Mon Nov 17 15:26:51 2008 +0000 @@ -58,7 +58,7 @@ } static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } private native void native_ref();
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Mon Nov 17 15:26:51 2008 +0000 @@ -41,12 +41,12 @@ import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; -import javax.sound.sampled.AudioPermission; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; +import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; import org.classpath.icedtea.pulseaudio.Stream.WriteListener; public class PulseAudioClip extends PulseAudioDataLine implements Clip, @@ -146,6 +146,9 @@ stream.addWriteListener(writeListener); + Debug.println(DebugLevel.Verbose, + "PulseAudioClip$ClipThread.writeFrames(): Writing"); + int remainingFrames = lastFrame - startingFrame - 1; while (remainingFrames > 0) { synchronized (eventLoop.threadLock) { @@ -231,10 +234,6 @@ @Override public void close() { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - if (!isOpen) { throw new IllegalStateException("line already closed"); } @@ -255,6 +254,9 @@ super.close(); + Debug.println(DebugLevel.Verbose, "PulseAudioClip.close(): " + + "Clip closed"); + } /* @@ -397,10 +399,6 @@ public void open(AudioFormat format, byte[] data, int offset, int bufferSize) throws LineUnavailableException { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - super.open(format); this.data = new byte[bufferSize]; System.arraycopy(data, offset, this.data, 0, bufferSize); @@ -425,6 +423,7 @@ mixer.addSourceLine(this); isOpen = true; + Debug.println(DebugLevel.Verbose, "PulseAudioClip.open(): Clip opened"); }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Mon Nov 17 15:26:51 2008 +0000 @@ -67,6 +67,8 @@ import javax.sound.sampled.AudioFormat.Encoding; import javax.sound.sampled.Control.Type; +import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; + public class PulseAudioMixer implements javax.sound.sampled.Mixer { // singleton @@ -92,6 +94,10 @@ private final List<LineListener> lineListeners = new ArrayList<LineListener>(); private PulseAudioMixer() { + + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " + + "Contructing PulseAudioMixer..."); + AudioFormat[] formats = getSupportedFormats(); staticSourceLineInfos.add(new DataLine.Info(SourceDataLine.class, @@ -107,6 +113,9 @@ refreshSourceAndTargetLines(); + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " + + "Finished constructing PulseAudioMixer"); + } synchronized public static PulseAudioMixer getInstance() { @@ -126,7 +135,9 @@ * frameSize = sample size (in bytes, not bits) x # of channels * * From PulseAudio's sources - * http://git.0pointer.de/?p=pulseaudio.git;a=blob;f=src/pulse/sample.c;h=93da2465f4301e27af4976e82737c3a048124a68;hb=82ea8dde8abc51165a781c69bc3b38034d62d969#l63 + * http://git.0pointer.de/?p=pulseaudio.git;a=blob + * ;f=src/pulse/sample.c;h=93da2465f4301e27af4976e82737c3a048124a68;hb= + * 82ea8dde8abc51165a781c69bc3b38034d62d969#l63 */ /* @@ -135,7 +146,6 @@ * * PA_CHANNEL_MAP_DEFAULT (=PA_CHANNEL_MAP_AIFF) supports 1,2,3,4,5 or 6 * channels only - * */ int[] channelSizes = new int[] { 1, 2, 3, 4, 5, 6 }; @@ -298,15 +308,11 @@ } if ((info.getLineClass() == SourceDataLine.class)) { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - return new PulseAudioSourceDataLine(formats, defaultFormat); } if ((info.getLineClass() == TargetDataLine.class)) { - /* check for permission to play audio */ + /* check for permission to record audio */ AudioPermission perm = new AudioPermission("record", null); perm.checkGuard(null); @@ -314,10 +320,6 @@ } if ((info.getLineClass() == Clip.class)) { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - return new PulseAudioClip(formats, defaultFormat); } @@ -330,6 +332,9 @@ } } + Debug.println(DebugLevel.Info, "PulseAudioMixer.getLine(): " + + "No matching line supported by PulseAudio"); + throw new IllegalArgumentException("No matching lines found"); } @@ -371,11 +376,6 @@ @Override public Line[] getSourceLines() { - - /* check for permmission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - return (Line[]) sourceLines.toArray(new Line[0]); } @@ -401,7 +401,7 @@ @Override public Line[] getTargetLines() { - /* check for permission to play audio */ + /* check for permission to record audio */ AudioPermission perm = new AudioPermission("record", null); perm.checkGuard(null); @@ -492,16 +492,6 @@ * is allowed */ - try { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - } catch (SecurityException e) { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); - } - if (!this.isOpen) { throw new IllegalStateException("Mixer is not open; cant close"); } @@ -509,11 +499,14 @@ List<Line> linesToClose = new LinkedList<Line>(); linesToClose.addAll(sourceLines); if (sourceLines.size() > 0) { + + Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " + + linesToClose.size() + + " source lines were not closed. closing them now."); + linesToClose.addAll(sourceLines); for (Line line : linesToClose) { if (line.isOpen()) { - System.out - .println("PulseAudioMixer: DEBUG: some source lines have not been closed"); line.close(); } } @@ -521,11 +514,13 @@ linesToClose.clear(); if (targetLines.size() > 0) { + Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " + + linesToClose.size() + + " target lines have not been closed"); + linesToClose.addAll(targetLines); for (Line line : linesToClose) { if (line.isOpen()) { - System.out - .println("PulseAudioMixer: DEBUG: some target lines have not been closed"); line.close(); } } @@ -544,12 +539,13 @@ + ": interrupted while waiting for eventloop to finish"); } - // System.out.println(this.getClass().getName() + ": closed"); - isOpen = false; refreshSourceAndTargetLines(); + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.close(): " + + "Mixer closed"); + } @Override @@ -617,16 +613,6 @@ * is allowed */ - try { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - } catch (SecurityException e) { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); - } - if (isOpen) { throw new IllegalStateException("Mixer is already open"); } @@ -724,6 +710,9 @@ targetLineInfos.add(new Port.Info(Port.class, portName, false)); } + Debug.println(DebugLevel.Debug, "PulseAudioMixer.open(): " + + "Mixer opened"); + } @Override @@ -738,7 +727,6 @@ * Cons: - eventListeners are run from other threads, if those then call * fireEvent while a method is waiting on a listener, this synchronized * block wont be entered: deadlock! - * */ private void fireEvent(final LineEvent e) { synchronized (lineListeners) {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java Mon Nov 17 15:26:51 2008 +0000 @@ -43,6 +43,10 @@ public class PulseAudioMixerProvider extends javax.sound.sampled.spi.MixerProvider { + public PulseAudioMixerProvider() { + Debug.initialize(); + } + @Override public Mixer getMixer(Info info) { // System.out.println("DEBUG: getMixer called");
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java Mon Nov 17 15:26:51 2008 +0000 @@ -63,7 +63,7 @@ private PulseAudioVolumeControl volumeControl; static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } public PulseAudioPort(String name) {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Mon Nov 17 15:26:51 2008 +0000 @@ -41,11 +41,12 @@ import javax.sound.sampled.AudioFormat; import javax.sound.sampled.DataLine; -import javax.sound.sampled.AudioPermission; import javax.sound.sampled.LineListener; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; +import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; + public class PulseAudioSourceDataLine extends PulseAudioDataLine implements SourceDataLine, PulseAudioPlaybackLine { @@ -68,10 +69,6 @@ synchronized public void open(AudioFormat format, int bufferSize) throws LineUnavailableException { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - super.open(format, bufferSize); volumeControl = new PulseAudioVolumeControl(this, eventLoop); @@ -82,6 +79,9 @@ PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); parentMixer.addSourceLine(this); + Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.open(): " + + "line opened"); + } @Override @@ -154,11 +154,14 @@ } if (offset < 0) { - throw new ArrayIndexOutOfBoundsException("offset is negative: " + offset); + throw new ArrayIndexOutOfBoundsException("offset is negative: " + + offset); } - + if (length + offset > data.length) { - throw new ArrayIndexOutOfBoundsException("writing data beyond the length of the array: " + (length + offset)); + throw new ArrayIndexOutOfBoundsException( + "writing data beyond the length of the array: " + + (length + offset)); } int position = offset; @@ -318,10 +321,6 @@ @Override synchronized public void close() { - /* check for permmission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - if (!isOpen) { throw new IllegalStateException("not open so cant close"); } @@ -332,8 +331,12 @@ parent.removeSourceLine(this); super.close(); + + Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.close():" + + " line closed"); + } - + public javax.sound.sampled.Line.Info getLineInfo() { return new DataLine.Info(SourceDataLine.class, supportedFormats, StreamBufferAttributes.MIN_VALUE,
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java Mon Nov 17 15:26:51 2008 +0000 @@ -45,7 +45,7 @@ /* aka mic */ static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } public PulseAudioSourcePort(String name) {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Mon Nov 17 15:26:51 2008 +0000 @@ -44,6 +44,8 @@ import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.TargetDataLine; +import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; + public class PulseAudioTargetDataLine extends PulseAudioDataLine implements TargetDataLine { @@ -84,6 +86,9 @@ parentMixer.removeTargetLine(this); super.close(); + + Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.close(): " + + "Line closed"); } @Override @@ -107,6 +112,9 @@ /* add this open line to the mixer */ PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); parentMixer.addTargetLine(this); + + Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.open(): " + + "Line opened"); } @Override
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java Mon Nov 17 15:26:51 2008 +0000 @@ -37,7 +37,6 @@ package org.classpath.icedtea.pulseaudio; -import javax.sound.sampled.AudioPermission; import javax.sound.sampled.Port; public class PulseAudioTargetPort extends PulseAudioPort { @@ -45,7 +44,7 @@ /* aka speaker */ static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } public PulseAudioTargetPort(String name) { @@ -55,10 +54,6 @@ public void open() { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - super.open(); PulseAudioMixer parent = PulseAudioMixer.getInstance(); @@ -67,10 +62,6 @@ public void close() { - /* check for permission to play audio */ - AudioPermission perm = new AudioPermission("play", null); - perm.checkGuard(null); - if (!isOpen) { throw new IllegalStateException("not open, so cant close Port"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,27 @@ +package org.classpath.icedtea.pulseaudio; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +class SecurityWrapper { + + public static void loadNativeLibrary() { + + if (System.getSecurityManager() != null) { + PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>() { + @Override + public Boolean run() { + System.loadLibrary("pulse-java"); + return true; + } + + }; + + AccessController.doPrivileged(action); + + } else { + System.loadLibrary("pulse-java"); + } + + } +}
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java Mon Nov 17 15:26:51 2008 +0000 @@ -104,11 +104,10 @@ public static final String DEFAULT_DEVICE = null; - @SuppressWarnings("unused") private byte[] streamPointer; static { - System.loadLibrary("pulse-java"); + SecurityWrapper.loadNativeLibrary(); } private Format format;
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c Mon Nov 17 15:26:51 2008 +0000 @@ -356,7 +356,8 @@ *new_volume = volume; int stream_id = pa_stream_get_index(stream); - pa_context_get_sink_input_info(context, stream_id,sink_input_change_volume, new_volume); + pa_operation* o = pa_context_get_sink_input_info(context, stream_id,sink_input_change_volume, new_volume); + pa_operation_unref(o); return; }
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java Mon Nov 17 12:41:07 2008 +0000 +++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java Mon Nov 17 15:26:51 2008 +0000 @@ -227,6 +227,66 @@ } + @Test(expected = IllegalArgumentException.class) + public void testWriteIntegralNumberFrames() throws LineUnavailableException { + sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + /* try writing an non-integral number of frames size */ + sourceDataLine.open(); + int frameSize = sourceDataLine.getFormat().getFrameSize(); + byte[] buffer = new byte[(frameSize * 2) - 1]; + sourceDataLine.write(buffer, 0, buffer.length); + } + + @Test(expected = IllegalArgumentException.class) + public void testWriteNegativeLength() throws LineUnavailableException { + sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + sourceDataLine.open(); + int frameSize = sourceDataLine.getFormat().getFrameSize(); + byte[] buffer = new byte[(frameSize * 2)]; + /* try writing a negative length */ + sourceDataLine.write(buffer, 0, -2); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void testWriteNegativeOffset() throws LineUnavailableException { + sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + sourceDataLine.open(); + int frameSize = sourceDataLine.getFormat().getFrameSize(); + byte[] buffer = new byte[(frameSize * 2)]; + /* try writing with a negative offset */ + sourceDataLine.write(buffer, -1, buffer.length); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void testWriteMoreThanArrayLength() throws LineUnavailableException { + sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + sourceDataLine.open(); + int frameSize = sourceDataLine.getFormat().getFrameSize(); + byte[] buffer = new byte[(frameSize * 2)]; + /* try writing more than the array length */ + sourceDataLine.write(buffer, 0, frameSize * 3); + } + + @Test(expected = ArrayIndexOutOfBoundsException.class) + public void testWriteMoreThanArrayLength2() throws LineUnavailableException { + sourceDataLine = (SourceDataLine) mixer.getLine(new Line.Info( + SourceDataLine.class)); + + sourceDataLine.open(); + int frameSize = sourceDataLine.getFormat().getFrameSize(); + byte[] buffer = new byte[(frameSize * 2)]; + /* try writing more than the array length */ + sourceDataLine.write(buffer, 1, buffer.length); + } + @Test public void testWriteWithoutStart() throws UnsupportedAudioFileException, IOException, LineUnavailableException, InterruptedException { @@ -253,11 +313,18 @@ int total = 0; while (bytesRead >= 0 && total < 50) { + bytesRead = audioInputStream.read(abData, 0, abData.length); if (bytesRead > 0) { sourceDataLine.write(abData, 0, bytesRead); } + + // when the line is closed (in tearDown), + // break out of the loop + if (!sourceDataLine.isOpen()) { + break; + } total++; } } catch (LineUnavailableException e) { @@ -273,7 +340,7 @@ Thread.sleep(100); - writer.join(1000); + writer.join(2000); /* assert that the writer is still waiting in write */ Assert.assertTrue(writer.isAlive());
--- a/test/jtreg/README Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/README Mon Nov 17 15:26:51 2008 +0000 @@ -20,7 +20,7 @@ This version is based on: - jtharness-oss-4_1_3a-dev -- jtreg-4_0-src-b01-29_apr_2008 +- jtreg-4_0-src-b02-15_oct_2008 IcedJTReg is distrubuted under the GPLv2.0, like jtreg and jtharness. See the documents in the legal directory included in this release.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jtreg/com/sun/javatest/diff/Diff.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright 2007 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.javatest.diff; + +import com.sun.javatest.Status; +import com.sun.javatest.TestResult; +import com.sun.javatest.TestSuite; +import com.sun.javatest.WorkDirectory; +import com.sun.javatest.util.I18NResourceBundle; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public abstract class Diff { + + public abstract boolean report(File outFile) throws Fault, InterruptedException; + + protected boolean diff(List<File> files, File outFile) + throws Fault, InterruptedException { + this.outFile = outFile; + List<DiffReader> list = new ArrayList<DiffReader>(); + for (File f: files) + list.add(open(f)); + + PrintWriter prevOut = out; + if (out == null && outFile != null) { + try { + out = new PrintWriter(new BufferedWriter(new FileWriter(outFile))); // FIXME don't want to use PrintWriter + } catch (IOException e) { + throw new Fault(i18n, "diff.cantOpenFile", outFile, e); + } + } + + try { + initComparator(); + + initReporter(); + reporter.setTitle(title); + reporter.setComparator(comparator); + reporter.setReaders(list); + + List<int[]> testCounts = new ArrayList<int[]>(); + MultiMap<String,TestResult> table = new MultiMap<String,TestResult>(); + for (DiffReader r: list) { + int index = table.addColumn(r.getFile().getPath()); + int[] counts = new int[Status.NUM_STATES]; + for (TestResult tr: r) { + table.addRow(index, tr.getTestName(), tr); + counts[tr.getStatus().getType()]++; + } + testCounts.add(counts); + } + reporter.setTestCounts(testCounts); + + try { + reporter.write(table); + } catch (IOException e) { + throw new Fault(i18n, "diff.ioError", e); + } + + return (reporter.diffs == 0); + } finally { + if (out != prevOut) { +// try { + out.close(); +// } catch (IOException e) { +// throw new Fault(i18n, "main.ioError", e); +// } + out = prevOut; + } + } + } + + protected void initFormat() { + if (format == null && outFile != null) { + String name = outFile.getName(); + int dot = name.lastIndexOf("."); + if (dot != -1) + format = name.substring(dot + 1).toLowerCase(); + } + } + + protected void initReporter() throws Fault { + if (reporter == null) { + try { + initFormat(); + if (format != null && format.equals("html")) + reporter = new HTMLReporter(out); + else + reporter = new SimpleReporter(out); + } catch (IOException e) { + throw new Fault(i18n, "diff.cantOpenReport", e); + } + } + } + + protected void initComparator() { + if (comparator == null) + comparator = new StatusComparator(includeReason); + } + + protected DiffReader open(File f) throws Fault { + if (!f.exists()) + throw new Fault(i18n, "main.cantFindFile", f); + + try { + if (WorkDirectoryReader.accepts(f)) + return new WorkDirectoryReader(f); + + if (ReportReader.accepts(f)) + return new ReportReader(f); + + throw new Fault(i18n, "main.unrecognizedFile", f); + + } catch (TestSuite.Fault e) { + throw new Fault(i18n, "main.cantOpenFile", f, e); + } catch (WorkDirectory.Fault e) { + throw new Fault(i18n, "main.cantOpenFile", f, e); + } catch (IOException e) { + throw new Fault(i18n, "main.cantOpenFile", f, e); + } + + } + + protected File outFile; + protected PrintWriter out; + protected Comparator<TestResult> comparator; + protected Reporter reporter; + protected boolean includeReason; + protected String format; + protected String title; + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(Diff.class); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jtreg/com/sun/javatest/diff/Fault.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright 2007 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.javatest.diff; + +import com.sun.javatest.util.I18NResourceBundle; + +/** + * Exception to report a problem while executing in Main. + */ +public class Fault extends Exception { + + static final long serialVersionUID = 1607979458544175906L; + + Fault(I18NResourceBundle i18n, String s, Object... args) { + super(i18n.getString(s, args)); + } +}
--- a/test/jtreg/com/sun/javatest/diff/HTMLReporter.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/HTMLReporter.java Mon Nov 17 15:26:51 2008 +0000 @@ -33,7 +33,6 @@ import com.sun.javatest.TestResult; import com.sun.javatest.Status; -import com.sun.javatest.util.HTMLWriter; import com.sun.javatest.util.I18NResourceBundle; import static com.sun.javatest.util.HTMLWriter.*; @@ -47,8 +46,8 @@ * Report differences to an HTML file. */ public class HTMLReporter extends Reporter { - - /** Creates a new instance of SimpleDiffReporter */ + + /** Creates a new instance of HTMLReporter */ public HTMLReporter(Writer out) throws IOException { this.out = new HTMLWriter(out, DOCTYPE); this.out.setI18NResourceBundle(i18n); @@ -56,10 +55,40 @@ public void write(MultiMap<String, TestResult> table) throws IOException { this.table = table; - size = table.getColumns(); - + + startReport(title); + + out.startTag(H1); + if (title == null) + out.writeI18N("html.head.notitle"); + else + out.writeI18N("html.head.title", title); + out.endTag(H1); + + writeIndexTable(); + writeMainTable(); + writeSummary(); + + endReport(); + } + + protected void startReport(String title) throws IOException { out.startTag(HTML); + writeHead(title); + out.startTag(BODY); + } + + protected void endReport() throws IOException { + out.startTag(HR); + out.writeI18N("html.generatedAt", new Date()); + out.endTag(BODY); + + out.endTag(HTML); + out.flush(); + } + + protected void writeHead(String title) throws IOException { out.startTag(HEAD); out.startTag(TITLE); if (title == null) @@ -74,40 +103,24 @@ out.write("tr.head { background-color:#dddddd }"); out.write("tr.odd { background-color:#eeeeee }"); out.write("tr.even { background-color:white } "); - out.write("td { padding: 0 1em }"); + out.write("td { padding: 0 .5em }"); out.write("td.pass { background-color:#ddffdd } "); out.write("td.fail { background-color:#ffdddd } "); out.write("td.error { background-color:#ddddff } "); out.write("td.notRun { background-color:#dddddd } "); + out.write("th { padding: 0 .5em }"); out.write("hr { margin-top:30px; }"); out.write("\n"); out.endTag(STYLE); out.endTag(HEAD); - - out.startTag(BODY); - out.startTag(H1); - if (title == null) - out.writeI18N("html.head.notitle"); - else - out.writeI18N("html.head.title", title); - out.endTag(H1); - writeHead(); - writeBody(); - writeSummary(); - - out.startTag(HR); - out.writeI18N("html.generatedAt", new Date()); - out.endTag(BODY); - - out.endTag(HTML); - out.flush(); + } - - private void writeHead() throws IOException { + + private void writeIndexTable() throws IOException { out.startTag(H2); out.writeI18N("html.head.sets"); out.endTag(H2); - + out.startTag(TABLE); out.writeAttr(FRAME, BOX); out.writeAttr(RULES, GROUPS); @@ -120,6 +133,7 @@ out.startTag(TH); out.writeI18N("html.th.location"); out.endTag(TH); + writeIndexTableInfoHeadings(); // out.startTag(TH); // out.writeI18N("html.th.type"); // out.endTag(TH); @@ -146,16 +160,17 @@ out.endTag(TH); out.endTag(TR); out.endTag(THEAD); - + out.startTag(TBODY); for (int i = 0; i < size; i++) { out.startTag(TR); out.writeAttr(CLASS, (i % 2 == 0 ? EVEN : ODD)); out.startTag(TD); - out.write(String.valueOf(i)); + out.write(String.valueOf(i + 1)); out.endTag(TD); out.startTag(TD); out.write(table.getColumnName(i)); + writeIndexTableInfoValues(table.getColumnName(i)); out.endTag(TD); // out.startTag(TD); // out.write("??"); @@ -166,7 +181,7 @@ out.startTag(TD); if (counts[c] > 0) out.write(String.valueOf(counts[c])); - else + else out.writeEntity(" "); total += counts[c]; out.endTag(TD); @@ -179,8 +194,14 @@ out.endTag(TBODY); out.endTag(TABLE); } - - private void writeBody() throws IOException { + + protected void writeIndexTableInfoHeadings() throws IOException { + } + + protected void writeIndexTableInfoValues(String name) throws IOException { + } + + private void writeMainTable() throws IOException { diffs = 0; for (Map.Entry<String, MultiMap.Entry<TestResult>> e: table.entrySet()) { String testName = e.getKey(); @@ -202,7 +223,10 @@ out.endTag(TH); for (int i = 0; i < result.getSize(); i++) { out.startTag(TH); - out.writeI18N("html.th.setN", i); + if (compact) + out.write(String.valueOf(i + 1)); + else + out.writeI18N("html.th.setN", i + 1); out.endTag(TH); } out.endTag(TR); @@ -222,36 +246,24 @@ if (wd != null) trFile = new File(wd, tr.getWorkRelativePath()); } + out.startTag(TD); Status s = (tr == null ? null : tr.getStatus()); - out.startTag(TD); - String classAttr; - String text; - switch (s == null ? Status.NOT_RUN : s.getType()) { - case Status.PASSED: - classAttr = PASS; - text = i18n.getString("html.pass"); - break; - case Status.FAILED: - classAttr = FAIL; - text = i18n.getString("html.fail"); - break; - case Status.ERROR: - classAttr = ERROR; - text = i18n.getString("html.error"); - break; - default: - classAttr = NOT_RUN; - text = i18n.getString("html.notRun"); - break; - } - out.writeAttr(CLASS, classAttr); + out.writeAttr(CLASS, getClassAttr(s)); + String text = getText(s); if (trFile != null && trFile.exists()) { out.startTag(A); out.writeAttr(HREF, trFile.toURI().toString()); - out.write(text); + if (text.startsWith("&")) + out.writeEntity(text); + else + out.write(text); out.endTag(A); - } else - out.write(text); + } else { + if (text.startsWith("&")) + out.writeEntity(text); + else + out.write(text); + } out.endTag(TD); } out.endTag(TR); @@ -262,7 +274,7 @@ out.endTag(TABLE); } } - + private void writeSummary() throws IOException { out.startTag(P); if (diffs == 0) @@ -271,27 +283,60 @@ out.writeI18N("html.diffs.count", diffs); out.endTag(P); } - + + protected String getClassAttr(Status s) { + switch (s == null ? Status.NOT_RUN : s.getType()) { + case Status.PASSED: + return PASS; + case Status.FAILED: + return FAIL; + case Status.ERROR: + return ERROR; + default: + return NOT_RUN; + } + } + + protected String getText(Status s) { + if (statusStrings == null) { + statusStrings = new String[Status.NUM_STATES]; + if (compact) { + statusStrings[Status.PASSED] = i18n.getString("html.pass.compact"); + statusStrings[Status.FAILED] = i18n.getString("html.fail.compact"); + statusStrings[Status.ERROR] = i18n.getString("html.error.compact"); + statusStrings[Status.NOT_RUN] = i18n.getString("html.notRun.compact"); + } else { + statusStrings[Status.PASSED] = i18n.getString("html.pass"); + statusStrings[Status.FAILED] = i18n.getString("html.fail"); + statusStrings[Status.ERROR] = i18n.getString("html.error"); + statusStrings[Status.NOT_RUN] = i18n.getString("html.notRun"); + } + } + return statusStrings[s == null ? Status.NOT_RUN : s.getType()]; + } + + private String[] statusStrings; + + protected final HTMLWriter out; private MultiMap<String, TestResult> table; private int size; - private HTMLWriter out; - - private static final String DOCTYPE = + + private static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\">"; - + // HTML tags private static final String THEAD = "thead"; private static final String TBODY = "tbody"; - + // HTML attribute names private static final String CLASS = "class"; private static final String FRAME = "frame"; private static final String RULES = "rules"; - + // HTML attribute values private static final String BOX = "box"; private static final String GROUPS = "groups"; - + // HTML class values private static final String HEAD = "head"; private static final String ODD = "odd"; @@ -300,6 +345,7 @@ private static final String FAIL = "fail"; private static final String ERROR = "error"; private static final String NOT_RUN = "notRun"; - + + private boolean compact = Boolean.TRUE.equals(Boolean.getBoolean("jtdiff.html.compact")); private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(HTMLReporter.class); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jtreg/com/sun/javatest/diff/HTMLWriter.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,558 @@ +/* + * Copyright 1996-2008 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.javatest.diff; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.net.URL; +import com.sun.javatest.util.I18NResourceBundle; + +/** + * A class to facilitate writing HTML via a stream. + */ +public class HTMLWriter +{ + /** + * Create an HTMLWriter object, using a default doctype for HTML 3.2. + * @param out a Writer to which to write the generated HTML + * @throws IOException if there is a problem writing to the underlying stream + */ + public HTMLWriter(Writer out) throws IOException { + this(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">"); + } + + /** + * Create an HTMLWriter object, using a specifed doctype header. + * @param out a Writer to which to write the generated HTML + * @param docType a string containing a doctype header for the HTML to be generetaed + * @throws IOException if there is a problem writing to the underlying stream + */ + public HTMLWriter(Writer out, String docType) throws IOException { + if (out instanceof BufferedWriter) + this.out = (BufferedWriter) out; + else + this.out = new BufferedWriter(out); + this.out.write(docType); + this.out.newLine(); + } + + /** + * Create an HTMLWriter object, using a specified bundle for l0calizing messages. + * @param out a Writer to which to write the generated HTML + * @param i18n a resource bundle to use to localize messages + * @throws IOException if there is a problem writing to the underlying stream + */ + public HTMLWriter(Writer out, I18NResourceBundle i18n) throws IOException { + this(out); + this.i18n = i18n; + } + + + /** + * Create an HTMLWriter object, using a specifed doctype header and + * using a specified bundle for l0calizing messages. + * @param out a Writer to which to write the generated HTML + * @param docType a string containing a doctype header for the HTML to be generetaed + * @param i18n a resource bundle to use to localize messages + * @throws IOException if there is a problem writing to the underlying stream + */ + public HTMLWriter(Writer out, String docType, I18NResourceBundle i18n) throws IOException { + this(out, docType); + this.i18n = i18n; + } + + /** + * Set the reource bundle to be used for localizing messages. + * @param i18n the resource bundle to be used for localizing messages + */ + public void setI18NResourceBundle(I18NResourceBundle i18n) { + this.i18n = i18n; + } + + /** + * Flush the stream, and the underlying output stream. + * @throws IOException if there is a problem writing to the underlying stream + */ + public void flush() throws IOException { + out.flush(); + } + + /** + * Close the stream, and the underlying output stream. + * @throws IOException if there is a problem closing the underlying stream + */ + public void close() throws IOException { + out.close(); + } + + /** + * Write a newline to the underlying output stream. + * @throws IOException if there is a problem writing to the underlying stream + */ + public void newLine() throws IOException { + out.newLine(); + } + + /** + * Start an HTML tag. If a prior tag has been started, it will + * be closed first. Once a tag has been opened, attributes for the + * tag may be written out, followed by body content before finally + * ending the tag. + * @param tag the tag to be started + * @throws IOException if there is a problem writing to the underlying stream + * @see #writeAttr + * @see #write + * @see #endTag + */ + public void startTag(String tag) throws IOException { + if (state == IN_TAG) { + out.write(">"); + state = IN_BODY; + } + newLine(); + out.write("<"); + out.write(tag); + state = IN_TAG; + } + + /** + * Finish an HTML tag. It is expected that a call to endTag will match + * a corresponding earlier call to startTag, but there is no formal check + * for this. + * @param tag the tag to be closed. + * @throws IOException if there is a problem writing to the underlying stream + */ + public void endTag(String tag) throws IOException { + if (state == IN_TAG) { + out.write(">"); + state = IN_BODY; + out.newLine(); + } + out.write("</"); + out.write(tag); + out.write(">"); + //out.newLine(); // PATCHED, jjg + state = IN_BODY; + } + + /** + * Finish an empty element tag, such as a META, BASE or LINK tag. + * This is expected to correspond with a startTag. + * @param tag the tag which is being closed. this is only useful for + * validation, it is not written out + * @throws IllegalStateException if this call does not follow startTag + * (stream is not currently inside a tag) + * @throws IOException if there is a problem writing to the underlying stream + */ + public void endEmptyTag(String tag) throws IOException { + if (state != IN_TAG) + throw new IllegalStateException(); + + out.write(">"); + state = IN_BODY; + out.newLine(); + } + + /** + * Write an attribute for a tag. A tag must previously have been started. + * All tag attributes must be written before any body text is written. + * The value will be quoted if necessary when writing it to the underlying + * stream. No check is made that the attribute is valid for the current tag. + * @param name the name of the attribute to be written + * @param value the value of the attribute to be written + * @throws IllegalStateException if the stream is not in a state to + * write attributes -- e.g. if this call does not follow startTag or other + * calls of writteAttr + * @throws IOException if there is a problem writing to the underlying stream + */ + public void writeAttr(String name, String value) throws IOException { + if (state != IN_TAG) + throw new IllegalStateException(); + + out.write(" "); + out.write(name); + out.write("="); + boolean alpha = true; + for (int i = 0; i < value.length() && alpha; i++) + alpha = Character.isLetter(value.charAt(i)); + if (!alpha) + out.write("\""); + out.write(value); + if (!alpha) + out.write("\""); + } + + /** + * Write an attribute for a tag. A tag must previously have been started. + * All tag attributes must be written before any body text is written. + * The value will be quoted if necessary when writing it to the underlying + * stream. No check is made that the attribute is valid for the current tag. + * @param name the name of the attribute to be written + * @param value the value of the attribute to be written + * @throws IllegalStateException if the stream is not in a state to + * write attributes -- e.g. if this call does not follow startTag or other + * calls of writteAttr + * @throws IOException if there is a problem writing to the underlying stream + */ + public void writeAttr(String name, int value) throws IOException { + writeAttr(name, Integer.toString(value)); + } + + /** + * Write a line of text, followed by a newline. + * The text will be escaped as necessary. + * @param text the text to be written. + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLine(String text) throws IOException { + write(text); + out.newLine(); + } + + /** + * Write body text, escaping it as necessary. + * If this call follows a call of startTag, the open tag will be + * closed -- meaning that no more attributes can be written until another + * tag is started. If the text value is null, the current tag will still + * be closed, but no other text will be written. + * @param text the text to be written, may be null or zero length. + * @throws IOException if there is a problem writing to the underlying stream + */ + public void write(String text) throws IOException { + if (state == IN_TAG) { + out.write(">"); + state = IN_BODY; + } + + if (text == null) + return; + + // check to see if there are any special characters + boolean specialChars = false; + for (int i = 0; i < text.length() && !specialChars; i++) { + switch (text.charAt(i)) { + case '<': case '>': case '&': + specialChars = true; + } + } + + // if there are special characters write the string character at a time; + // otherwise, write it out as is + if (specialChars) { + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + switch (c) { + case '<': out.write("<"); break; + case '>': out.write(">"); break; + case '&': out.write("&"); break; + default: out.write(c); + } + } + } + else + out.write(text); + } + + /** + * Write a basic HTML entity, such as or { . + * @param entity the entity to write + * @throws IOException if there is a problem writing to the underlying stream + */ + public void writeEntity(String entity) throws IOException { + if (state == IN_TAG) { + out.write(">"); + state = IN_BODY; + } + out.write(entity); + } + + /** + * Write an image tag, using a specified path for the image source attribute. + * @param imagePath the path for the image source + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeImage(String imagePath) throws IOException { + startTag(IMAGE); + writeAttr(SRC, imagePath); + } + + /** + * Write an image tag, using a specified path for the image source attribute. + * @param imageURL the url for the image source + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeImage(URL imageURL) throws IOException { + writeImage(imageURL.toString()); + } + + /** + * Write a hypertext link. + * @param anchor the target for the link + * @param body the body text for the link + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLink(String anchor, String body) throws IOException { + startTag(A); + writeAttr(HREF, anchor); + write(body); + endTag(A); + } + + /** + * Write a hypertext link. + * @param file the target for the link + * @param body the body text for the link + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLink(File file, String body) throws IOException { + startTag(A); + StringBuffer sb = new StringBuffer(); + String path = file.getPath().replace(File.separatorChar, '/'); + if (file.isAbsolute() && !path.startsWith("/")) + sb.append('/'); + sb.append(path); + writeAttr(HREF, sb.toString()); + write(body); + endTag(A); + } + + /** + * Write a hypertext link. + * @param file the target and body for the link + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLink(File file) throws IOException { + writeLink(file, file.getPath()); + } + + /** + * Write a hypertext link. + * @param url the target for the link + * @param body the body text for the link + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLink(URL url, String body) throws IOException { + startTag(A); + writeAttr(HREF, url.toString()); + write(body); + endTag(A); + } + + /** + * Write the destination marker for a hypertext link. + * @param anchor the destination marker for hypertext links + * @param body the body text for the marker + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeLinkDestination(String anchor, String body) throws IOException { + startTag(A); + writeAttr(NAME, anchor); + write(body); + endTag(A); + } + + /** + * Write a parameter tag. + * @param name the name of the parameter + * @param value the value of the parameter + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeParam(String name, String value) throws IOException { + startTag(PARAM); + writeAttr(NAME, name); + writeAttr(VALUE, value); + } + + /** + * Write a style attribute. + * @param value the value for the style atrtribute + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeStyleAttr(String value) throws IOException { + writeAttr(STYLE, value); + } + + /** + * Write a localized message, using a specified resource bundle. + * @param i18n the resource bundle used to localize the message + * @param key the key for the message to be localized + * @throws IOException if there is a problem closing the underlying stream + */ + public void write(I18NResourceBundle i18n, String key) throws IOException { + write(i18n.getString(key)); + } + + /** + * Write a localized message, using a specified resource bundle. + * @param i18n the resource bundle used to localize the message + * @param key the key for the message to be localized + * @param arg an argument to be formatted into the localized message + * @throws IOException if there is a problem closing the underlying stream + */ + public void write(I18NResourceBundle i18n, String key, Object arg) throws IOException { + write(i18n.getString(key, arg)); + } + + /** + * Write a localized message, using a specified resource bundle. + * @param i18n the resource bundle used to localize the message + * @param key the key for the message to be localized + * @param args arguments to be formatted into the localized message + * @throws IOException if there is a problem closing the underlying stream + */ + public void write(I18NResourceBundle i18n, String key, Object[] args) throws IOException { + write(i18n.getString(key, args)); + } + + /** + * Write a localized message, using the default resource bundle. + * @param key the key for the message to be localized + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeI18N(String key) throws IOException { + write(i18n.getString(key)); + } + + /** + * Write a localized message, using the default resource bundle. + * @param key the key for the message to be localized + * @param arg an argument to be formatted into the localized message + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeI18N(String key, Object arg) throws IOException { + write(i18n.getString(key, arg)); + } + + /** + * Write a localized message, using the default resource bundle. + * @param key the key for the message to be localized + * @param args arguments to be formatted into the localized message + * @throws IOException if there is a problem closing the underlying stream + */ + public void writeI18N(String key, Object[] args) throws IOException { + write(i18n.getString(key, args)); + } + + /** The HTML "a" tag. */ + public static final String A = "a"; + /** The HTML "align" attribute. */ + public static final String ALIGN = "align"; + /** The HTML "b" tag. */ + public static final String B = "b"; + /** The HTML "body" tag. */ + public static final String BODY = "body"; + /** The HTML "border" attribute. */ + public static final String BORDER = "border"; + /** The HTML "br" tag. */ + public static final String BR = "br"; + /** The HTML "classid" attribute. */ + public static final String CLASSID = "classid"; + /** The HTML "code" tag. */ + public static final String CODE = "code"; + /** The HTML "color" attribte. */ + public static final String COLOR = "color"; + /** The HTML "col" attribute value. */ + public static final String COL = "col"; + /** The HTML "font" tag. */ + public static final String FONT = "font"; + /** The HTML "h1" tag. */ + public static final String H1 = "h1"; + /** The HTML "h2" tag. */ + public static final String H2 = "h2"; + /** The HTML "h3" tag. */ + public static final String H3 = "h3"; + /** The HTML "h4" tag. */ + public static final String H4 = "h4"; + /** The HTML "head" tag. */ + public static final String HEAD = "head"; + /** The HTML "href" attribute. */ + public static final String HREF = "href"; + /** The HTML "html" tag. */ + public static final String HTML = "html"; + /** The HTML "hr" tag. */ + public static final String HR = "hr"; + /** The HTML "i" tag. */ + public static final String I = "i"; + /** The HTML "image" tag. */ + public static final String IMAGE = "image"; + /** The HTML "left" attribute value. */ + public static final String LEFT = "left"; + /** The HTML "li" tag. */ + public static final String LI = "li"; + /** The HTML "link" tag. */ + public static final String LINK = "link"; + /** The HTML "name" attribute. */ + public static final String NAME = "name"; + /** The HTML "object" tag. */ + public static final String OBJECT = "object"; + /** The HTML "p" tag. */ + public static final String PARAM = "param"; + /** The HTML "param" tag. */ + public static final String P = "p"; + /** The HTML "rel" attribute value. */ + public static final String REL = "rel"; + /** The HTML "right" attribute value. */ + public static final String RIGHT = "right"; + /** The HTML "row" attribute value. */ + public static final String ROW = "row"; + /** The HTML "small" tag. */ + public static final String SMALL = "small"; + /** The HTML "src" attribute. */ + public static final String SRC = "src"; + /** The HTML "scope" attribute. */ + public static final String SCOPE = "scope"; + /** The HTML "style" attribute. */ + public static final String STYLE = "style"; + /** The HTML "table" tag. */ + public static final String TABLE = "table"; + /** The HTML "td" tag. */ + public static final String TD = "td"; + /** The HTML "title"attribute. */ + public static final String TITLE = "title"; + /** The HTML "th" tag. */ + public static final String TH = "th"; + /** The HTML "top" attribute value. */ + public static final String TOP = "top"; + /** The HTML "tr" tag. */ + public static final String TR = "tr"; + /** The HTML "type" attribute. */ + public static final String TYPE = "type"; + /** The HTML "ul" tag. */ + public static final String UL = "ul"; + /** The HTML "valign" attribute. */ + public static final String VALIGN = "valign"; + /** The HTML "value" attribute. */ + public static final String VALUE = "value"; + + + private BufferedWriter out; + private int state; + private I18NResourceBundle i18n; + private static final int IN_TAG = 1; + private static final int IN_BODY = 2; +}
--- a/test/jtreg/com/sun/javatest/diff/Main.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/Main.java Mon Nov 17 15:26:51 2008 +0000 @@ -33,20 +33,12 @@ package com.sun.javatest.diff; import com.sun.javatest.regtest.BadArgs; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.List; -import com.sun.javatest.Status; -import com.sun.javatest.TestResult; -import com.sun.javatest.TestSuite; -import com.sun.javatest.WorkDirectory; import com.sun.javatest.regtest.AntOptionDecoder; import com.sun.javatest.regtest.Option; import com.sun.javatest.regtest.OptionDecoder; @@ -58,29 +50,24 @@ * Main entry point for jtdiff. */ public class Main { - - /** - * Exception to report a problem while executing in Main. - */ - public static class Fault extends Exception { - static final long serialVersionUID = 1607979458544175906L; - Fault(I18NResourceBundle i18n, String s, Object... args) { - super(i18n.getString(s, args)); - } - } //---------- command line option decoding ---------------------------------- - + private static final String COMPARE = "compare"; private static final String OUTPUT = "output"; private static final String DOC = "doc"; private static final String FILES = "files"; - + Option[] options = { - new Option(NONE, COMPARE, "r", "reason") { + new Option(NONE, COMPARE, "r", "r", "reason") { public void process(String opt, String arg) { includeReason = true; } }, + new Option(NONE, COMPARE, "s", "s", "super") { + public void process(String opt, String arg) { + superMode = true; + } + }, new Option(OLD, OUTPUT, "o", "o", "outFile") { public void process(String opt, String arg) { outFile = new File(arg); @@ -136,7 +123,7 @@ } finally { out.flush(); } - + if (!ok) { // take care not to exit if GUI might be around, // and take care to ensure JavaTestSecurityManager will @@ -159,16 +146,16 @@ exit(3); } } // main() - + public Main() { this(new PrintWriter(System.out, true), new PrintWriter(System.err, true)); } - + public Main(PrintWriter out, PrintWriter err) { this.out = out; this.err = err; } - + /** * Decode command line args and perform the requested operations. * @param args An array of args, such as might be supplied on the command line. @@ -178,141 +165,55 @@ */ public final boolean run(String[] args) throws BadArgs, Fault, InterruptedException { new OptionDecoder(options).decodeArgs(args); - + + if (superMode) { + if (fileArgs.size() != 1 || !fileArgs.get(0).isDirectory()) + throw new Fault(i18n, "main.bad.super.dir"); + if (format != null) + throw new Fault(i18n, "main.bad.super.format"); + } + return run(); } - + private boolean run() throws Fault, InterruptedException { - if (fileArgs.size() == 0 && help == null) { + if (fileArgs.size() == 0 && !superMode && help == null) { help = new Help(options); help.setCommandLineHelpQuery(null); } - + if (help != null) { help.show(out); return true; } - - List<DiffReader> list = new ArrayList<DiffReader>(); - for (File f: fileArgs) - list.add(open(f)); - - PrintWriter prevOut = out; - if (outFile != null) { - try { - out = new PrintWriter(new BufferedWriter(new FileWriter(outFile))); // FIXME don't want to use PrintWriter - } catch (IOException e) { - throw new Fault(i18n, "main.cantOpenFile", outFile, e); - } - } - - try { - initComparator(); - - initReporter(); - reporter.setTitle(title); - reporter.setComparator(comparator); - reporter.setReaders(list); - List<int[]> testCounts = new ArrayList<int[]>(); - MultiMap<String,TestResult> table = new MultiMap<String,TestResult>(); - for (DiffReader r: list) { - int index = table.add(r.getFile().getPath()); - int[] counts = new int[Status.NUM_STATES]; - for (TestResult tr: r) { - table.add(index, tr.getTestName(), tr); - counts[tr.getStatus().getType()]++; - } - testCounts.add(counts); - } - - reporter.setTestCounts(testCounts); - - try { - reporter.write(table); - } catch (IOException e) { - throw new Fault(i18n, "main.ioError", e); - } + Diff d; + if (superMode) + d = new SuperDiff(fileArgs.get(0)); + else + d = new StandardDiff(fileArgs); - return (reporter.diffs == 0); - } finally { - if (out != prevOut) { -// try { - out.close(); -// } catch (IOException e) { -// throw new Fault(i18n, "main.ioError", e); -// } - out = prevOut; - } - } - } - - private void initFormat() { - if (format == null && outFile != null) { - String name = outFile.getName(); - int dot = name.lastIndexOf("."); - if (dot != -1) - format = name.substring(dot + 1).toLowerCase(); - } + d.includeReason = includeReason; + d.format = format; + d.title = title; + + return d.report(outFile); } - - private void initReporter() throws Fault { - if (reporter == null) { - try { - initFormat(); - if (format != null && format.equals("html")) - reporter = new HTMLReporter(out); - if (reporter == null) - reporter = new SimpleReporter(out); - } catch (IOException e) { - throw new Fault(i18n, "main.cantOpenReport", e); - } - } - } - - private void initComparator() { - if (comparator == null) - comparator = new StatusComparator(includeReason); - } - - private DiffReader open(File f) throws Fault { - if (!f.exists()) - throw new Fault(i18n, "main.cantFindFile", f); - - try { - if (WorkDirectoryReader.accepts(f)) - return new WorkDirectoryReader(f); - - if (ReportReader.accepts(f)) - return new ReportReader(f); - - throw new Fault(i18n, "main.unrecognizedFile", f); - - } catch (TestSuite.Fault e) { - throw new Fault(i18n, "main.cantOpenFile", f, e); - } catch (WorkDirectory.Fault e) { - throw new Fault(i18n, "main.cantOpenFile", f, e); - } catch (IOException e) { - throw new Fault(i18n, "main.cantOpenFile", f, e); - } - - } - + private static void exit(int exitCode) { System.exit(exitCode); } - + private PrintWriter out; private PrintWriter err; - private Comparator<TestResult> comparator; - private Reporter reporter; - + private boolean includeReason; private String format; private String title; private File outFile; private List<File> fileArgs = new ArrayList<File>(); + private boolean superMode; private Help help; - + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(Main.class); }
--- a/test/jtreg/com/sun/javatest/diff/MultiMap.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/MultiMap.java Mon Nov 17 15:26:51 2008 +0000 @@ -38,26 +38,26 @@ */ public class MultiMap<K,V> implements Map<K, MultiMap.Entry<V>> { public static class Entry<V> { - + private Entry(MultiMap<?,?> t) { table = t; } - + V get(int index) { return (index < list.size() ? list.get(index) : null); } - + int getSize() { return table.getColumns(); } - + void put(int index, V value) { if (index >= table.getColumns()) throw new IndexOutOfBoundsException(); - + if (list == null) list = new ArrayList<V>(index); - + if (index < list.size()) list.set(index, value); else { @@ -66,7 +66,7 @@ list.add(value); } } - + boolean allEqual(Comparator<V> c) { if (list.size() == 0) return true; @@ -79,96 +79,95 @@ } return true; } - + private List<V> list; private MultiMap<?,?> table; } - - /** Creates a new instance of DiffTable */ + + /** Creates a new instance of MultiMap */ public MultiMap() { names = new ArrayList<String>(); map = new TreeMap<K, Entry<V>>(); } - + int getColumns() { return names.size(); } - + String getColumnName(int index) { return names.get(index); } - - int add(String name) { + + int addColumn(String name) { names.add(name); return names.size() - 1; } - - void add(int index, K k, V v) { + + void addColumn(String name, Map<K, V> map) { + addColumn(name, map.entrySet()); + } + + void addColumn(String name, Iterable<Map.Entry<K,V>> iter) { + int index = addColumn(name); + for (Map.Entry<K,V> e: iter) + addRow(index, e.getKey(), e.getValue()); + } + + void addRow(int index, K k, V v) { Entry<V> de = get(k); if (de == null) put(k, de = new Entry<V>(this)); de.put(index, v); - } - - void add(String name, Map<K, V> map) { - add(name, map.entrySet()); - } - - void add(String name, Iterable<Map.Entry<K,V>> iter) { - int index = add(name); - for (Map.Entry<K,V> e: iter) - add(index, e.getKey(), e.getValue()); - } - + public int size() { return map.size(); } - + public Entry<V> get(Object path) { return map.get(path); } - + public boolean isEmpty() { return map.isEmpty(); } - + public boolean containsKey(Object key) { return map.containsKey(key); } - + public boolean containsValue(Object value) { return map.containsValue(value); } - + public Entry<V> put(K key, Entry<V> value) { return map.put(key, value); } - + public Entry<V> remove(Object key) { return map.remove(key); } - + public void putAll(Map<? extends K, ? extends Entry<V>> t) { map.putAll(t); } - + public void clear() { map.clear(); } - + public Set<Map.Entry<K, Entry<V>>> entrySet() { return map.entrySet(); } - + public Set<K> keySet() { return map.keySet(); } - + public Collection<Entry<V>> values() { return map.values(); } - + private List<String> names; private TreeMap<K, Entry<V>> map; }
--- a/test/jtreg/com/sun/javatest/diff/ReportReader.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/ReportReader.java Mon Nov 17 15:26:51 2008 +0000 @@ -39,28 +39,28 @@ import java.util.List; /** - * Read a set of test results from summary.txt, possibly located in a + * Read a set of test results from summary.txt, possibly located in a * report directory. */ public class ReportReader implements DiffReader { - private static final String SUMMARY_TXT = "summary.txt"; - + private static final String SUMMARY_TXT = "summary.txt"; + public static boolean accepts(File f) { if (!f.exists()) return false; - + if (f.isFile() && f.getName().equals(SUMMARY_TXT)) return true; - + if (f.isDirectory() && new File(f, SUMMARY_TXT).exists()) return true; - + if (f.isDirectory() && new File(new File(f, "text"), SUMMARY_TXT).exists()) return true; - + return false; } - + /** Creates a new instance of SummaryReader */ public ReportReader(File file) { this.file = file; @@ -69,11 +69,7 @@ public File getFile() { return file; } - - public File getWorkDirectory() { - return null; - } - + public String getFileType() { if (file != null && file.isDirectory()) return i18n.getString("report.reportDir"); @@ -81,10 +77,14 @@ return i18n.getString("report.reportFile"); } + public File getWorkDirectory() { + return null; + } + public Iterator<TestResult> iterator() { return readSummary().iterator(); } - + private List<TestResult> readSummary() { List<TestResult> list = new ArrayList<TestResult>(); File root = getRoot(); @@ -97,7 +97,7 @@ f = new File(new File(file, "text"), SUMMARY_TXT); else throw new IllegalStateException(); - + try { BufferedReader in = new BufferedReader(new FileReader(f)); String line; @@ -113,14 +113,14 @@ } return list; } - + private File getRoot() { return UNKNOWN; } - + private static File UNKNOWN = new File("unknown"); - + private File file; - + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(WorkDirectoryReader.class); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jtreg/com/sun/javatest/diff/StandardDiff.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright 2008 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.javatest.diff; + +import java.io.File; +import java.util.List; + +public class StandardDiff extends Diff { + StandardDiff(List<File> files) { + this.files = files; + } + + @Override + public boolean report(File outFile) throws Fault, InterruptedException { + return diff(files, outFile); + } + + List<File> files; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jtreg/com/sun/javatest/diff/SuperDiff.java Mon Nov 17 15:26:51 2008 +0000 @@ -0,0 +1,342 @@ +/* + * Copyright 2008 Sun Microsystems, 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.javatest.diff; + +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.sun.javatest.util.I18NResourceBundle; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import static com.sun.javatest.util.HTMLWriter.*; + +class SuperDiff extends Diff { + SuperDiff(File dir) { + table = new SuperTable(dir, resultPath); + } + + @Override + public boolean report(File outDir) throws Fault, InterruptedException { + baseTitle = title; + boolean ok = true; + for (YearDay yearDay: table.getRecentKeys(historySize)) + ok &= diffPlatforms(yearDay, outDir); + for (String platform : table.platforms) { + ok &= diffHistory(platform, outDir); + } + writeIndex(outDir, baseTitle); + return ok; + } + + protected boolean diff(List<File> files, File outFile, String title) throws Fault, InterruptedException { + this.title = title; + reporter = null; + return diff(files, outFile); + } + + @Override + protected void initReporter() throws Fault { + try { + reporter = new SuperReporter(out); + } catch (IOException e) { + throw new Fault(i18n, "main.cantOpenReport", e); + } + } + + private boolean diffPlatforms(YearDay yearDay, File outDir) throws Fault, InterruptedException { + Map<String, File> pMap = table.get(yearDay); + List<File> pDirs = new ArrayList<File>(); + for (String platform : table.platforms) { + File dir = pMap.get(platform); + if (dir != null) { + pDirs.add(dir); + } + } + File file = new File(outDir, yearDay.year + "_" + yearDay.dayOfYear + ".html"); + platformIndex.put(yearDay.toDateString(monthDayFormat), file); + String prefix = baseTitle == null ? "" : baseTitle + ": "; + return diff(pDirs, file, prefix + yearDay.toDateString(mediumDateFormat)); // I18N a better title? + } + + private boolean diffHistory(String platform, File outDir) throws Fault, InterruptedException { + List<File> pDirs = new ArrayList<File>(); + for (YearDay yearDay: table.getRecentKeys(historySize, platform)) { + pDirs.add(table.get(yearDay).get(platform)); + } + File file = new File(outDir, platform + ".html"); + historyIndex.put(platform, file); + String prefix = baseTitle == null ? "" : baseTitle + ": "; + return diff(pDirs, file, prefix + platform);// I18N a better title? + } + + private void writeIndex(File outDir, String title) throws Fault { + PrintWriter out; + try { + out = new PrintWriter(new BufferedWriter(new FileWriter(new File(outDir, "index.html")))); + } catch (IOException e) { + throw new Fault(i18n, "main.cantOpenReport", e); + } + + try { + SuperReporter r = new SuperReporter(out); + r.writeMainIndex(title); + } catch (IOException e) { + throw new Fault(i18n, "main.ioError", e); + } finally { + out.close(); + } + } + + protected String resultPath = System.getProperty("jtdiff.super.testResults", "JTreport/text/summary.txt"); + protected int historySize = Integer.getInteger("jtdiff.super.history", 21); + + private SuperTable table; + private String baseTitle; + private Map<String,File> historyIndex = new LinkedHashMap<String,File>(); + private Map<String,File> platformIndex = new LinkedHashMap<String,File>(); + + private static DateFormat monthDayFormat = new SimpleDateFormat("MMM d"); + private static DateFormat mediumDateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(Main.class); + + static class Info { + Info(String platform, Date date) { + this.platform = platform; + this.date = date; + } + + final String platform; + final Date date; + } + + class SuperReporter extends HTMLReporter { + SuperReporter(Writer out) throws IOException { + super(out); + } + + protected void writeIndexTableInfoHeadings() throws IOException { + out.startTag(TH); + out.writeI18N("super.th.platform"); + out.endTag(TH); + out.startTag(TH); + out.writeI18N("super.th.date"); + out.endTag(TH); + } + + protected void writeIndexTableInfoValues(String path) throws IOException { + Info info = table.getInfo(path); + out.startTag(TD); + if (info != null) + out.write(info.platform); + out.endTag(TD); + out.startTag(TD); + if (info != null) + out.write(monthDayFormat.format(info.date)); + out.endTag(TH); + } + + void writeMainIndex(String title) throws IOException { + startReport(title); + + out.startTag(H1); + out.write(baseTitle); + out.endTag(H1); + + writeMainIndexList(i18n.getString("super.platforms"), platformIndex); + writeMainIndexList(i18n.getString("super.history"), historyIndex); + + endReport(); + } + + void writeMainIndexList(String head, Map<String,File> map) throws IOException { + out.startTag(H2); + out.write(head); + out.endTag(H2); + out.startTag(P); + String comma = ""; + for (Map.Entry<String,File> e: map.entrySet()) { + out.write(comma); + out.startTag(A); + out.writeAttr(HREF, e.getValue().getName()); + String nbsp = ""; + for (String s: e.getKey().split(" ")) { + out.writeEntity(nbsp); + out.write(s); + nbsp = " "; + } + out.endTag(A); + comma = ", "; + } + } + } + + static class SuperTable extends TreeMap<YearDay, Map<String, File>> { + + static final long serialVersionUID = 5933594140534747584L; + + SuperTable(File inDir, String resultPath) { + super(); + for (File pDir : inDir.listFiles()) { + if (!pDir.isDirectory()) { + continue; + } + for (File yDir : pDir.listFiles()) { + if (!yDir.isDirectory()) { + continue; + } + for (File dDir : yDir.listFiles()) { + if (!dDir.isDirectory()) { + continue; + } + File resultDir = new File(dDir, resultPath); + if (resultDir.exists()) { + add(pDir.getName(), yDir.getName(), dDir.getName(), resultDir); + } + } + } + } + } + + private void add(String platform, String year, String day, File dir) { + platforms.add(platform); + YearDay yd = new YearDay(year, day); + Map<String, File> pMap = get(yd); + if (pMap == null) { + pMap = new HashMap<String, File>(); + put(yd, pMap); + } + pMap.put(platform, dir); + + Date date; + try { + Calendar c = Calendar.getInstance(); + c.clear(); + c.set(Calendar.YEAR, Integer.parseInt(year)); + c.set(Calendar.DAY_OF_YEAR, Integer.parseInt(day)); + date = c.getTime(); + } catch (NumberFormatException e) { + date = null; + } + infoTable.put(dir.getPath(), new Info(platform, date)); + } + + List<YearDay> getRecentKeys(int n) { + return getRecentKeys(n, null); + } + + List<YearDay> getRecentKeys(int n, String platform) { + LinkedList<YearDay> results = new LinkedList<YearDay>(); + List<YearDay> keys = new ArrayList<YearDay>(keySet()); + for (ListIterator<YearDay> iter = keys.listIterator(keys.size()); + iter.hasPrevious() && results.size() < n; ) { + YearDay key = iter.previous(); + if (platform == null || get(key).get(platform) != null) + results.addFirst(key); + } + return results; + } + + Info getInfo(String path) { + return infoTable.get(path); + } + + final Set<String> platforms = new TreeSet<String>(); + final Map<String,Info> infoTable = new HashMap<String, Info>(); + } + + static class YearDay implements Comparable<YearDay> { + YearDay(String year, String dayOfYear) { + year.getClass(); + dayOfYear.getClass(); + this.year = year; + this.dayOfYear = dayOfYear; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof YearDay)) + return false; + YearDay ydo = (YearDay) o; + return year.equals(ydo.year) && dayOfYear.equals(ydo.dayOfYear); + } + + @Override + public int hashCode() { + return year.hashCode() * 37 + dayOfYear.hashCode(); + } + + //@Override + public int compareTo(YearDay o) { + int c = compare(year, o.year); + return (c == 0 ? compare(dayOfYear, o.dayOfYear) : c); + } + + public String toString() { + return year + ":" + dayOfYear; + } + + public Date asDate() { + try { + Calendar c = Calendar.getInstance(); + c.clear(); + c.set(Calendar.YEAR, Integer.parseInt(year)); + c.set(Calendar.DAY_OF_YEAR, Integer.parseInt(dayOfYear)); + return c.getTime(); + } catch (NumberFormatException e) { + return null; + } + } + + public String toDateString(DateFormat f) { + Date d = asDate(); + return (d == null ? toString() : f.format(d)); + } + + private int compare(String left, String right) { + return left.compareTo(right); + } + + final String year; + final String dayOfYear; + } + +}
--- a/test/jtreg/com/sun/javatest/diff/WorkDirectoryReader.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/WorkDirectoryReader.java Mon Nov 17 15:26:51 2008 +0000 @@ -48,12 +48,12 @@ public static boolean accepts(File f) { return WorkDirectory.isWorkDirectory(f); } - + /** Creates a new instance of WorkDirectoryReader */ - public WorkDirectoryReader(File file) + public WorkDirectoryReader(File file) throws FileNotFoundException, WorkDirectory.Fault, TestSuite.Fault { this.file = file; - + // Because regtest testsuites don't contain testsuite.jtt // files, we can't use the standard WorkDirectory.open call. File tsp = getTestSuitePath(file); @@ -63,31 +63,31 @@ } else wd = WorkDirectory.open(file); } - + + public File getFile() { + return file; + } + public String getFileType() { return i18n.getString("wd.name"); } - - public File getFile() { - return file; - } - + public File getWorkDirectory() { return wd.getRoot(); } - + @SuppressWarnings("unchecked") public Iterator<TestResult> iterator() { TestResultTable trt = wd.getTestResultTable(); trt.waitUntilReady(); return trt.getIterator(); } - + private static File getTestSuitePath(File workDir) { File f = new File(new File(workDir, "jtData"), "testsuite"); - if (!f.exists()) + if (!f.exists()) return null; - + InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(f)); @@ -105,9 +105,9 @@ return null; } } - + private File file;; private WorkDirectory wd; - + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(WorkDirectoryReader.class); }
--- a/test/jtreg/com/sun/javatest/diff/i18n.properties Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/diff/i18n.properties Mon Nov 17 15:26:51 2008 +0000 @@ -23,6 +23,10 @@ # have any questions. # +diff.cantOpenFile=Cannot open file {0}: {1} +diff.cantOpenReport=Cannot open report: {0} +diff.ioError=Error: {0} + help.cantFindReleaseNotes= help.onlineHelp.pleaseWait=Loading online help ... help.releaseNotes= @@ -42,8 +46,21 @@ help.compare.name=Compare Options help.compare.desc= -help.compare.reason.desc=Include the reason string in the comparison, as well as \ +help.compare.r.desc=Include the reason string in the comparison, as well as \ the type (i.e. Passed, Failed, etc.) +help.compare.s.desc=Perform a "super-diff" looking for result sets within \ + a directory hierarchy. The hierarchy must be arranged as \ + follows: PATH/PLATFORM/YEAR/DAY_OF_YEAR/TEST_RESULTS, where PATH is \ + given by the single directory argument, PLATFORM is the name of the \ + platform on which the tests were run, YEAR and DAY_OF_YEAR are numbers \ + identifying when the tests were run, and TESTSUITE_RESULTS is a fixed string \ + identifying when to find the result set in the hierarchy. The default \ + is "JTreport/text/summary.txt", but it can be set to a different value by \ + setting the system property "jtdiff.super.testResults". It may identify any \ + source of results acceptable to a standard invocation of jtdiff. \ + Set system property jtdiff.html.compact=true for a more output format, with \ + symbols replacing the words "pass" (check mark), "fail" (cross), "error" \ + (cross in a circle), and "not run" (horizontal bar). help.doc.name=Help Options help.doc.desc=Options for additional help and information @@ -76,6 +93,10 @@ html.fail=fail html.notRun=not run html.pass=pass +html.error.compact=⊗ +html.fail.compact=× +html.notRun.compact=— +html.pass.compact=√ html.head.differences=Differences html.head.notitle=jtdiff results @@ -94,6 +115,8 @@ html.th.type=Type main.badArgs=Error: {0} +main.bad.super.dir=Bad directory argument for "super" mode +main.bad.super.format=Cannot specify format in "super" mode main.cantFindFile=Cannot find file: {0} main.cantOpenFile=Cannot open file {0}: {1} main.cantOpenReport=Cannot open report: {0} @@ -123,3 +146,8 @@ {6,choice,0#|0<not run: {6,number}} wd.name=Work Directory + +super.history=Comparison of recent results by platform +super.platforms=Comparison across platforms by date +super.th.date=Date +super.th.platform=Platform
--- a/test/jtreg/com/sun/javatest/regtest/Main.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/regtest/Main.java Mon Nov 17 15:26:51 2008 +0000 @@ -83,7 +83,7 @@ * JavaTest entry point to be used to access regression extensions. */ public class Main { - + /** * Exception to report a problem while executing in Main. */ @@ -93,14 +93,14 @@ super(i18n.getString(s, args)); } } - + public static final String MAIN = "main"; // main set of options public static final String SELECT = "select"; // test selection options public static final String JDK = "jdk"; // specify JDK to use public static final String MODE = "mode"; // sameVM or otherVM public static final String VERBOSE = "verbose"; // verbose controls public static final String DOC = "doc"; // help or doc info - + Option[] options = { new Option(OPT, VERBOSE, "verbose", "v", "verbose") { @Override @@ -122,49 +122,49 @@ childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "v1") { public void process(String opt, String arg) { verbose = Verbose.SUMMARY; childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "va") { public void process(String opt, String arg) { verbose = Verbose.ALL; childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "vp") { public void process(String opt, String arg) { verbose = Verbose.PASS; childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "vf") { public void process(String opt, String arg) { verbose = Verbose.FAIL; childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "ve") { public void process(String opt, String arg) { verbose = Verbose.ERROR; childArgs.add(opt); } }, - + new Option(NONE, VERBOSE, "verbose", "vt") { public void process(String opt, String arg) { verbose = Verbose.TIME; childArgs.add(opt); } }, - + new Option(NONE, DOC, "", "t", "tagspec") { public void process(String opt, String arg) { if (help == null) @@ -172,7 +172,7 @@ help.setTagSpec(true); } }, - + new Option(NONE, DOC, "", "n", "relnote") { public void process(String opt, String arg) { if (help == null) @@ -180,15 +180,15 @@ help.setReleaseNotes(true); } }, - + new Option(OLD, MAIN, "", "w", "workDir") { public void process(String opt, String arg) { - + workDirArg = new File(arg); childArgs.add("-w:" + workDirArg.getAbsolutePath()); } }, - + new Option(OPT, MAIN, "", "retain") { @Override public String[] getChoices() { @@ -204,34 +204,40 @@ childArgs.add(opt); } }, - + new Option(OLD, MAIN, "", "r", "reportDir") { public void process(String opt, String arg) { reportDirArg = new File(arg); childArgs.add("-r:" + reportDirArg.getAbsolutePath()); } }, - - new Option(NONE, MAIN, null, "ro", "reportOnly") { + + new Option(NONE, MAIN, "ro-nr", "ro", "reportOnly") { public void process(String opt, String arg) { reportOnlyFlag = true; } }, - + + new Option(NONE, MAIN, "ro-nr", "nr", "noreport") { + public void process(String opt, String arg) { + noReportFlag = true; + } + }, + new Option(STD, MAIN, "", "timeout", "timeoutFactor") { public void process(String opt, String arg) { timeoutFactorArg = arg; childArgs.add(opt); } }, - + new Option(STD, MAIN, "", "dir") { public void process(String opt, String arg) { baseDirArg = new File(arg); childArgs.add("-dir:" + baseDirArg.getAbsolutePath()); } }, - + new Option(STD, SELECT, "", "status") { @Override public String[] getChoices() { @@ -242,29 +248,29 @@ childArgs.add(opt); } }, - + new Option(STD, SELECT, "", "exclude", "Xexclude") { public void process(String opt, String arg) { File f = new File(arg); excludeListArgs.add(f); - childArgs.add(f.getAbsolutePath()); + childArgs.add("-exclude:" + f.getAbsolutePath()); } }, - + new Option(NONE, MAIN, null, "startHttpd") { public void process(String opt, String arg) { httpdFlag = true; childArgs.add(opt); } }, - + new Option(OLD, MAIN, "", "o", "observer") { public void process(String opt, String arg) { observerClassName = arg; childArgs.add(opt); } }, - + new Option(OLD, MAIN, "", "od", "observerDir", "op", "observerPath") { public void process(String opt, String arg) { arg = arg.trim(); @@ -279,20 +285,20 @@ childArgs.add("-op:" + filesToAbsolutePath(pathToFiles(arg))); } }, - + new Option(NONE, MAIN, null, "g", "gui") { public void process(String opt, String arg) { guiFlag = true; childArgs.add(opt); } }, - + new Option(NONE, MAIN, null, "c", "check") { public void process(String opt, String arg) { checkFlag = true; } }, - + // deprecated new Option(NONE, MAIN, "ignore", "noignore") { public void process(String opt, String arg) { @@ -300,7 +306,7 @@ childArgs.add(opt); } }, - + new Option(STD, MAIN, "ignore", "ignore") { @Override public String[] getChoices() { @@ -323,69 +329,69 @@ throw new BadArgs(i18n, "main.unknownIgnore", arg); } }, - + new Option(NONE, SELECT, "a-m", "a", "automatic", "automagic") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, AUTOMATIC); childArgs.add(opt); } }, - + new Option(NONE, SELECT, "a-m", "m", "manual") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, MANUAL); childArgs.add(opt); } }, - + new Option(NONE, SELECT, "shell-noshell", "shell") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, "shell"); childArgs.add(opt); } }, - + new Option(NONE, SELECT, "shell-noshell", "noshell") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, "!shell"); childArgs.add(opt); } }, - + new Option(STD, SELECT, null, "bug") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, "bug" + arg); childArgs.add(opt); } }, - + new Option(STD, SELECT, null, "k", "keywords") { public void process(String opt, String arg) { keywordsExprArg = combineKeywords(keywordsExprArg, "(" + arg + ")"); childArgs.add(opt); } }, - + new Option(NONE, MODE, "svm-ovm", "ovm", "othervm") { public void process(String opt, String arg) { sameJVMFlag = false; childArgs.add(opt); } }, - + new Option(NONE, MODE, "svm-ovm", "s", "svm", "samevm") { public void process(String opt, String arg) { sameJVMFlag = true; childArgs.add(opt); } }, - + new Option(OLD, JDK, "", "jdk", "testjdk") { public void process(String opt, String arg) { jdk = new JDK(arg); } }, - + new Option(STD, JDK, "", "cpa", "classpathappend") { public void process(String opt, String arg) { arg = arg.trim(); @@ -398,73 +404,73 @@ } } }, - + new Option(NONE, JDK, "jit-nojit", "jit") { public void process(String opt, String arg) { jitFlag = true; } }, - + new Option(NONE, JDK, "jit-nojit", "nojit") { public void process(String opt, String arg) { jitFlag = false; } }, - + new Option(WILDCARD, JDK, null, "Xrunjcov") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(NONE, JDK, null, "classic", "green", "native", "hotspot", "client", "server", "d32", "d64") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(OPT, JDK, null, "enableassertions", "ea", "disableassertions", "da") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(NONE, JDK, null, "enablesystemassertions", "esa", "disablesystemassertions", "dsa") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(WILDCARD, JDK, null, "XX", "Xms", "Xmx") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(WILDCARD, JDK, null, "Xint", "Xmixed", "Xcomp") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(STD, JDK, null, "Xbootclasspath") { public void process(String opt, String arg) { testVMOpts.add("-Xbootclasspath:" + filesToAbsolutePath(pathToFiles(arg))); } }, - + new Option(STD, JDK, null, "Xbootclasspath/a") { public void process(String opt, String arg) { testVMOpts.add("-Xbootclasspath/a:" + filesToAbsolutePath(pathToFiles(arg))); } }, - + new Option(STD, JDK, null, "Xbootclasspath/p") { public void process(String opt, String arg) { testVMOpts.add("-Xbootclasspath/p:" + filesToAbsolutePath(pathToFiles(arg))); } }, - + new Option(WILDCARD, JDK, null, "X") { public void process(String opt, String arg) { // This is a change in spec. Previously. -X was used to tunnel @@ -473,20 +479,20 @@ testVMOpts.add(opt); } }, - + new Option(WILDCARD, JDK, null, "D") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(STD, JDK, null, "vmoption") { public void process(String opt, String arg) { if (arg.length() > 0) testVMOpts.add(arg); } }, - + new Option(STD, JDK, null, "vmoptions") { public void process(String opt, String arg) { arg = arg.trim(); @@ -495,7 +501,7 @@ testVMOpts.addAll(Arrays.asList(arg.split("\\s+"))); } }, - + new Option(OLD, JDK, null, "e") { public void process(String opt, String arg) { arg = arg.trim(); @@ -504,25 +510,25 @@ envVarArgs.addAll(Arrays.asList(arg.split(","))); } }, - + new Option(STD, JDK, null, "agentlib") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(STD, JDK, null, "agentpath") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(STD, JDK, null, "javaagent") { public void process(String opt, String arg) { testVMOpts.add(opt); } }, - + new Option(STD, JDK, null, "javacoption") { public void process(String opt, String arg) { arg = arg.trim(); @@ -532,7 +538,7 @@ childArgs.add(opt); } }, - + new Option(STD, JDK, null, "javacoptions") { public void process(String opt, String arg) { arg = arg.trim(); @@ -542,7 +548,7 @@ childArgs.add(opt); } }, - + new Option(STD, JDK, null, "javaoption") { public void process(String opt, String arg) { arg = arg.trim(); @@ -552,7 +558,7 @@ childArgs.add(opt); } }, - + new Option(STD, JDK, null, "javaoptions") { public void process(String opt, String arg) { arg = arg.trim(); @@ -562,7 +568,7 @@ childArgs.add(opt); } }, - + new Option(REST, DOC, "help", "h", "help", "usage") { public void process(String opt, String arg) { if (help == null) @@ -570,7 +576,7 @@ help.setCommandLineHelpQuery(arg); } }, - + new Option(REST, DOC, "help", "onlineHelp") { public void process(String opt, String arg) { if (help == null) @@ -578,7 +584,7 @@ help.setOnlineHelpQuery(arg); } }, - + new Option(NONE, DOC, "help", "version") { public void process(String opt, String arg) { if (help == null) @@ -586,7 +592,7 @@ help.setVersionFlag(true); } }, - + new Option(FILE, MAIN, null) { public void process(String opt, String arg) { File f= new File(arg); @@ -610,7 +616,7 @@ public static final int EXIT_FAULT = 4; /** Unexpected exception occurred. */ public static final int EXIT_EXCEPTION = 5; - + /** * Standard entry point. Only returns if GUI mode is initiated; otherwise, it calls System.exit * with an appropriate exit code. @@ -628,7 +634,7 @@ out.flush(); err.flush(); } - + if (!(m.guiFlag && rc == EXIT_OK)) { // take care not to exit if GUI might be around, // and take care to ensure JavaTestSecurityManager will @@ -654,21 +660,21 @@ exit(EXIT_EXCEPTION); } } // main() - + public Main() { this(new PrintWriter(System.out, true), new PrintWriter(System.err, true)); } - + public Main(PrintWriter out, PrintWriter err) { this.out = out; this.err = err; - + // FIXME: work around bug 6466752 File javatest_jar = findJar("javatest.jar", "lib/javatest.jar", com.sun.javatest.Harness.class); if (javatest_jar != null) System.setProperty("javatestClassDir", javatest_jar.getPath()); } - + /** * Decode command line args and perform the requested operations. * @param args An array of args, such as might be supplied on the command line. @@ -681,7 +687,7 @@ new OptionDecoder(options).decodeArgs(expandAtFiles(args)); return run(); } - + private int run() throws BadArgs, Fault, Harness.Fault, InterruptedException { if (help != null) { guiFlag = help.show(out); @@ -690,7 +696,7 @@ if (sameJVMFlag && !testJavaOpts.isEmpty()) throw new Fault(i18n, "main.cant.mix.samevm.java.options"); - + if (jdk == null) { String s = null; if (!sameJVMFlag) @@ -706,23 +712,23 @@ f = f.getParentFile(); jdk = new JDK(f); } - + if (jitFlag == false) { if (sameJVMFlag) testVMOpts.add("-Djava.compiler="); else envVarArgs.add("JAVA_COMPILER="); } - + if (classPathAppendArg.size() > 0) { // TODO: store this separately in RegressionParameters, instead of in envVars if (!sameJVMFlag) envVarArgs.add("CPAPPEND=" + filesToAbsolutePath(classPathAppendArg)); } - + if (!jdk.exists()) throw new Fault(i18n, "main.jdk.not.found", jdk); - + File baseDir; if (baseDirArg == null) { baseDir = new File(System.getProperty("user.dir")); @@ -731,9 +737,9 @@ throw new Fault(i18n, "main.cantFindFile", baseDirArg); baseDir = baseDirArg.getAbsoluteFile(); } - + List<File> absTestFileArgs = new ArrayList<File>(); - + for (File t: testFileArgs) { if (!t.isAbsolute()) t = new File(baseDir, t.getPath()); @@ -741,13 +747,13 @@ throw new Fault(i18n, "main.cantFindFile", t); absTestFileArgs.add(t); } - + testFileArgs = absTestFileArgs; - + String antFileList = System.getProperty(JAVATEST_ANT_FILE_LIST); if (antFileList != null) antFileArgs.addAll(readFileList(new File(antFileList))); - + if (testSuiteArg == null) { File t; if (testFileArgs.size() > 0) @@ -756,49 +762,57 @@ t = antFileArgs.iterator().next(); else throw new BadArgs(i18n, "main.noTestSuiteOrTests"); - + testSuiteArg = getTestSuite(t); if (testSuiteArg == null) throw new Fault(i18n, "main.cantDetermineTestSuite", t); } - + if (workDirArg == null) { workDirArg = new File("JTwork"); childArgs.add(0, "-w:" + workDirArg.getAbsolutePath()); } - - if (reportDirArg == null) { + + if (reportDirArg == null && !noReportFlag) { reportDirArg = new File("JTreport"); childArgs.add(0, "-r:" + reportDirArg.getAbsolutePath()); } - - makeDir(reportDirArg); + + if (!noReportFlag) + makeDir(reportDirArg); + makeDir(workDirArg); makeDir(new File(workDirArg, "scratch")); - + if (!isThisVMOK()) return execChild(); - + RegressionParameters params = createParameters(); - + checkLockFiles(params.getWorkDirectory().getRoot(), "start"); - + Harness.setClassDir(ProductInfo.getJavaTestClassDir()); - + // Allow keywords to begin with a numeric Keywords.setAllowNumericKeywords(true); - + // Before we install our own security manager (which will restrict access // to the system properties), take a copy of the system properties. TestEnvironment.addDefaultPropTable("(system properties)", System.getProperties()); - + // TODO: take SecurityManager into account for isThisVMOK - if (sameJVMFlag) + if (sameJVMFlag) { RegressionSecurityManager.install(); - + SecurityManager sc = System.getSecurityManager(); + if (sc instanceof RegressionSecurityManager) { + // experimental + ((RegressionSecurityManager) sc).setAllowSetIO(true); + } + } + if (httpdFlag) startHttpServer(); - + if (guiFlag) { showTool(params); return EXIT_OK; @@ -810,7 +824,7 @@ } } } - + /** * Process Win32-style command files for the specified command line * arguments and return the resulting arguments. A command file argument @@ -839,7 +853,7 @@ } return newArgs.toArray(new String[newArgs.size()]); } - + private static void loadCmdFile(String name, List<String> args) throws Fault { Reader r; @@ -871,7 +885,7 @@ } } } - + private static List<File> readFileList(File file) throws Fault { BufferedReader r; @@ -898,7 +912,7 @@ } } } - + private static void writeFileList(File file, List<File> list) throws Fault { try { BufferedWriter out = new BufferedWriter(new FileWriter(file)); @@ -912,21 +926,21 @@ throw new Fault(i18n, "main.cantWrite", file, e); } } - + public int[] getTestStats() { return testStats; } - + private boolean isThisVMOK() { if (reportOnlyFlag || checkFlag || !sameJVMFlag) return true; - + // sameVM tests can use this VM if // - the current directory is the required scratch directory // - the current VM is the required test VM // - there are no outstanding VM options // - there is no classpath append - + File scratchDir = canon(new File(workDirArg, "scratch")); File currDir = canon(new File("")); if (!currDir.equals(scratchDir)) { @@ -934,7 +948,7 @@ System.err.println("dir mismatch: " + currDir + " " + scratchDir); return false; } - + File currJDKHome = canon(new File(System.getProperty("java.home"))); if (currJDKHome.getName().toLowerCase().equals("jre")) currJDKHome = currJDKHome.getParentFile(); @@ -943,53 +957,53 @@ System.err.println("jdk mismatch: " + currJDKHome + " " + jdk + " (" + jdk.getCanonicalFile() + ")"); return false; } - + if (System.getProperty("javatest.child") == null && !testVMOpts.isEmpty()) { if (debugChild) System.err.println("need VM opts: " + testVMOpts); return false; } - + if (classPathAppendArg.size() > 0) { if (debugChild) System.err.println("need classPathAppend: " + classPathAppendArg); return false; } - + return true; } - + // TODO use @file for args? private int execChild() throws Fault { if (System.getProperty("javatest.child") != null) throw new AssertionError(); - + File javatest_jar = findJar("javatest.jar", "lib/javatest.jar", com.sun.javatest.Harness.class); if (javatest_jar == null) throw new Fault(i18n, "main.cantFind.javatest.jar"); - + File jtreg_jar = findJar("jtreg.jar", "lib/jtreg.jar", getClass()); if (jtreg_jar == null) throw new Fault(i18n, "main.cantFind.jtreg.jar"); - + File childJDKHome = jdk.getAbsoluteFile(); File childJava = new File(new File(childJDKHome, "bin"), "java"); File childTools = new File(new File(childJDKHome, "lib"), "tools.jar"); - + File scratchDir = canon(new File(workDirArg, "scratch")); - + List<String> c = new ArrayList<String>(); c.add(childJava.getPath()); - + c.add("-classpath"); List<File> classpath = new ArrayList<File>(); classpath.add(jtreg_jar); classpath.add(childTools); classpath.addAll(classPathAppendArg); c.add(filesToAbsolutePath(classpath)); - + c.addAll(testVMOpts); - + // Tunnel Ant file args separately from command line tests, so that // they can be treated specially in the child VM: invalid files // specified by the user on the command line give an error; @@ -1003,39 +1017,39 @@ throw new Fault(i18n, "main.cantWriteTempFile", e); } } - + for (Map.Entry<?,?> e: System.getProperties().entrySet()) { String name = (String) e.getKey(); if (name.startsWith("javatest.")) c.add("-D" + name + "=" + e.getValue()); } - + c.add("-Djavatest.child=true"); - + c.add(Main.class.getName()); - + for (String o: testVMOpts) c.add("-vmoption:" + o); - + if (baseDirArg == null) c.add("-dir:" + System.getProperty("user.dir")); - + c.addAll(childArgs); - + String[] cmd = c.toArray(new String[c.size()]); File execDir = scratchDir; - + if (debugChild) { System.err.println("Starting JavaTest child"); System.err.println("Dir " + execDir + "; Command " + c); } - + Runtime r = Runtime.getRuntime(); Process p = null; - + try { try { - + // strictly speaking, we do not need to set the CLASSPATH for the child VM, // but we do it to maximize the consistency between sameVM and otherVM env. // See similar code in MainAction for otherVM tests. @@ -1043,46 +1057,46 @@ // because it will not have (and cannot have) the test-specific values. String cp = "CLASSPATH=" + javatest_jar + PATHSEP + jtreg_jar + PATHSEP + jdk.getToolsJar(); - + String[] env = getEnvVars(); String[] env_cp = new String[env.length + 1]; System.arraycopy(env, 0, env_cp, 0, env.length); env_cp[env_cp.length - 1] = cp; - + p = r.exec(cmd, env_cp, execDir); } catch (IOException e) { err.println("cannot start child VM"); return EXIT_FAULT; } - + InputStream childOut = p.getInputStream(); // output stream from process StreamCopier childOutCopier = new StreamCopier(childOut, out); childOutCopier.start(); InputStream childErr = p.getErrorStream(); StreamCopier childErrCopier = new StreamCopier(childErr, err); childErrCopier.start(); - + OutputStream childIn = p.getOutputStream(); // input stream to process if (childIn != null) childIn.close(); - + // wait for the stream copiers to complete childOutCopier.waitUntilDone(); childErrCopier.waitUntilDone(); - + // wait for the process to complete; int exitCode = p.waitFor(); p = null; - + if (debugChild) { System.err.println("JavaTest child process: rc=" + exitCode); } - + childOut.close(); childErr.close(); - + return exitCode; - + } catch (IOException e) { // TODO handle exception return EXIT_EXCEPTION; @@ -1094,7 +1108,7 @@ p.destroy(); } } - + /** * A thread to copy an input stream to an output stream */ @@ -1109,7 +1123,7 @@ in = new BufferedReader(new InputStreamReader(from)); out = to; } - + /** * Set the thread going. */ @@ -1130,32 +1144,32 @@ notifyAll(); } } - + public synchronized boolean isDone() { return done; } - + /** * Blocks until the copy is complete, or until the thread is interrupted */ public synchronized void waitUntilDone() throws InterruptedException { boolean interrupted = false; - + // poll interrupted flag, while waiting for copy to complete while (!(interrupted = Thread.interrupted()) && !done) wait(1000); - + if (interrupted) throw new InterruptedException(); } - + private BufferedReader in; private PrintWriter out; private boolean done; private static int serial; - + } - + private File getTestSuite(File test) { File f = canon(test); if (f.isFile()) @@ -1168,7 +1182,7 @@ // TODO try and default from work directory return null; } - + private String getEnvVar(String name) { for (String arg: envVarArgs) { if (arg.startsWith(name + "=")) @@ -1176,7 +1190,7 @@ } return null; } - + private void makeDir(File dir) throws Fault { // FIXME: I18N if (dir.isDirectory()) @@ -1187,7 +1201,7 @@ throw new Fault(i18n, "main.cantCreateDir", dir); } } - + private static List<File> pathToFiles(String path) { List<File> files = new ArrayList<File>(); for (String f: path.split(File.pathSeparator)) { @@ -1196,7 +1210,7 @@ } return files; } - + private static String filesToAbsolutePath(List<File> files) { StringBuffer sb = new StringBuffer(); for (File f: files) { @@ -1206,7 +1220,7 @@ } return sb.toString(); } - + private static String join(Iterator<?> iter, String sep) { StringBuilder sb = new StringBuilder(); while (iter.hasNext()) { @@ -1216,7 +1230,7 @@ } return sb.toString(); } - + /** * Create a RegressionParameters object based on the values set up by decodeArgs. * @return a RegressionParameters object @@ -1224,26 +1238,26 @@ private RegressionParameters createParameters() throws BadArgs, Fault { File ts = testSuiteArg; File wd = workDirArg; - + try { // create a canonTestFile suite and work dir. RegressionTestSuite testSuite = new RegressionTestSuite(ts); RegressionParameters rp = (RegressionParameters) (testSuite.createInterview()); - + WorkDirectory workDir; if (WorkDirectory.isWorkDirectory(wd)) workDir = WorkDirectory.open(wd, testSuite); else workDir = WorkDirectory.convert(wd, testSuite); rp.setWorkDirectory(workDir); - + rp.setRetainArgs(retainArgs); - + // set up the tests mode, and if specified tests are used, pass in the canonTestFile list. // ensure the tests parameters are root-relative File root = testSuite.getRoot(); List<String> tests = new ArrayList<String>(); - + if (testFileArgs != null) { // In the command line, the canonTestFile args are filenames, probably absolute, // and possibly with non-canonical file separators (e.g. / on Windows). @@ -1261,7 +1275,7 @@ } } } - + // no need to scan ant tests if all test suite selected (i.e. tests == null) if (tests != null && antFileArgs != null && antFileArgs.size() > 0) { TestResultTable trt = workDir.getTestResultTable(); @@ -1279,10 +1293,10 @@ } } } - + if (tests != null && tests.size() > 0) rp.setTests(tests); - + if (keywordsExprArg != null) rp.setKeywordsExpr(keywordsExprArg); rp.setExcludeLists(excludeListArgs.toArray(new File[excludeListArgs.size()])); @@ -1296,7 +1310,7 @@ b[Status.NOT_RUN] = (priorStatusValuesArg.indexOf("notr") != -1); rp.setPriorStatusValues(b); } - + if (concurrencyArg != null) { try { rp.setConcurrency(Integer.parseInt(concurrencyArg)); @@ -1304,7 +1318,7 @@ throw new BadArgs(i18n, "main.badConcurrency"); } } - + if (timeoutFactorArg != null) { try { rp.setTimeoutFactor(Integer.parseInt(timeoutFactorArg)); @@ -1312,10 +1326,10 @@ throw new BadArgs(i18n, "main.badTimeoutFactor"); } } - + if (!rp.isValid()) throw new Fault(i18n, "main.badParams", rp.getErrorMessage()); - + for (String o: testVMOpts) { if (o.startsWith("-Xrunjcov")) { if (!testVMOpts.contains("-XX:+EnableJVMPIInstructionStartEvent")) @@ -1323,23 +1337,23 @@ break; } } - + if (testVMOpts.size() > 0) rp.setTestVMOptions(testVMOpts); - + if (testCompilerOpts.size() > 0) rp.setTestCompilerOptions(testCompilerOpts); - + if (testJavaOpts.size() > 0) rp.setTestJavaOptions(testJavaOpts); - + rp.setCheck(checkFlag); rp.setSameJVM(sameJVMFlag); rp.setEnvVars(getEnvVars()); rp.setJDK(jdk); if (ignoreKind != null) rp.setIgnoreKind(ignoreKind); - + return rp; } catch (TestSuite.Fault f) { f.printStackTrace(); @@ -1359,7 +1373,7 @@ return file.getAbsoluteFile(); } } - + private String getRelativePath(File base, File f) { StringBuilder sb = new StringBuilder(); for ( ; f != null; f = f.getParentFile()) { @@ -1371,18 +1385,18 @@ } return null; } - + /** * Initialize the harness. If we are in verbose mode, add our own observer. */ private Harness createHarness() throws Fault { - + // Set backup parameters; in time this might become more versatile. BackupPolicy backupPolicy = createBackupPolicy(); - + Harness h = new Harness(); h.setBackupPolicy(backupPolicy); - + if (observerClassName != null) { try { Class observerClass; @@ -1413,16 +1427,16 @@ throw new Fault(i18n, "main.obsvrFault", e); } } - + // add our own observer for verbose if (verbose != null) { Harness.Observer observer = new RegressionObserver(verbose, out, err); h.addObserver(observer); } - + return h; } // createHarness() - + /** * Run the harness in batch mode, using the specified parameters. */ @@ -1430,7 +1444,7 @@ throws Fault, Harness.Fault, InterruptedException { try { boolean ok; - + if (reportOnlyFlag) { testStats = new int[Status.NUM_STATES]; for (Iterator iter = getResultsIterator(params); iter.hasNext(); ) { @@ -1443,15 +1457,27 @@ harness.addObserver(new BatchObserver()); ok = harness.batch(params); } - + showResultStats(testStats); - - boolean reportRequired = !Boolean.getBoolean("javatest.noReportRequired"); + + boolean reportRequired = + !noReportFlag && !Boolean.getBoolean("javatest.noReportRequired"); + List<String> reportKinds = + Arrays.asList(System.getProperty("javatest.report.kinds", "html text").split("[ ,]+")); if (reportRequired) { try { Report r = new Report(); Report.Settings s = new Report.Settings(params); - s.setHtmlMainReport(true, true); + if (reportKinds.contains("html")) { + s.setEnableHtmlReport(true); + s.setHtmlMainReport(true, true); + } + if (reportKinds.contains("text")) { + s.setEnablePlainReport(true); + } + if (reportKinds.contains("xml")) { + s.setEnableXmlReport(true); + } s.setFilter(new CompositeFilter(params.getFilters())); r.writeReport(s, reportDirArg); File report = new File(reportDirArg, "report.html"); // std through version 3.* @@ -1463,15 +1489,15 @@ out.println("Error while writing report: " + e); } } - + if (!reportOnlyFlag) out.println("Results written to " + params.getWorkDirectory().getPath()); - + // report a brief msg to System.err as well, in case System.out has // been redirected. if (!ok) err.println(i18n.getString("main.testsFailed")); - + return (testStats[Status.ERROR] > 0 ? EXIT_TEST_ERROR : testStats[Status.FAILED] > 0 ? EXIT_TEST_FAILED : EXIT_OK); @@ -1480,11 +1506,11 @@ err.flush(); } } - + private Iterator getResultsIterator(InterviewParameters params) { TestResultTable trt = params.getWorkDirectory().getTestResultTable(); trt.waitUntilReady(); - + String[] tests = params.getTests(); TestFilter[] filters = params.getFilters(); if (tests == null) @@ -1492,10 +1518,10 @@ else return trt.getIterator(tests, filters); } - + private void showTool(final InterviewParameters params) throws BadArgs { Startup startup = new Startup(); - + try { EventQueue.invokeLater(new Runnable() { public void run() { @@ -1512,13 +1538,13 @@ startup.disposeLater(); } } // showTool() - + private void showResultStats(int[] stats) { int p = stats[Status.PASSED]; int f = stats[Status.FAILED]; int e = stats[Status.ERROR]; int nr = stats[Status.NOT_RUN]; - + String msg; if (p + f + e + nr == 0) msg = i18n.getString("main.noTests"); @@ -1536,7 +1562,7 @@ } out.println(msg); } - + private BackupPolicy createBackupPolicy() { return new BackupPolicy() { public int getNumBackupsToKeep(File file) { @@ -1555,7 +1581,7 @@ private String[] ignoreExtns = StringArray.split(System.getProperty("javatest.backup.ignore", ".jtr")); }; } - + private void startHttpServer() { // start the http server // do this as early as possible, since objects may check @@ -1563,9 +1589,9 @@ // register their handlers HttpdServer server = new HttpdServer(); Thread thr = new Thread(server); - + PageGenerator.setSWName(ProductInfo.getName()); - + // format the date for i18n DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); Date dt = ProductInfo.getBuildDate(); @@ -1574,15 +1600,15 @@ date = df.format(dt); else date = i18n.getString("main.nobDate"); - + PageGenerator.setSWBuildDate(date); PageGenerator.setSWVersion(ProductInfo.getVersion()); - + thr.start(); } - + private String[] getEnvVars() { - + Map<String,String> envVars = new TreeMap<String,String>(); String osName = System.getProperty("os.name").toLowerCase(); if (osName.startsWith("windows")) { @@ -1594,22 +1620,22 @@ addEnvVars(envVars, "PATH=/bin:/usr/bin"); } addEnvVars(envVars, envVarArgs); - + return envVars.values().toArray(new String[envVars.size()]); } - + private void addEnvVars(Map<String,String> table, String list) { addEnvVars(table, list.split(",")); } - + private void addEnvVars(Map<String,String> table, String[] list) { addEnvVars(table, Arrays.asList(list)); } - + private void addEnvVars(Map<String,String> table, List<String> list) { if (list == null) return; - + for (String s: list) { s = s.trim(); if (s.length() == 0) @@ -1625,24 +1651,24 @@ } } } - + private static String combineKeywords(String kw1, String kw2) { return (kw1 == null ? kw2 : kw1 + " & " + kw2); } - + private File findJar(String jarProp, String pathFromHome, Class<?> c) { if (jarProp != null) { String v = System.getProperty(jarProp); if (v != null) return new File(v); } - + if (pathFromHome != null) { String v = System.getProperty("jtreg.home"); if (v != null) return new File(v, pathFromHome); } - + if (c != null) { try { String className = c.getName().replace(".", "/") + ".class"; @@ -1659,10 +1685,10 @@ ignore.printStackTrace(); } } - + return null; } - + /** * Call System.exit, taking care to get permission from the * JavaTestSecurityManager, if it is installed. @@ -1675,7 +1701,7 @@ ((JavaTestSecurityManager) sc).setAllowExit(true); System.exit(exitCode); } - + // This is almost completely dead code; testStats appears unused // so the only use here is error handling, which perhaps can be // folded into RegressionObserver @@ -1683,24 +1709,24 @@ public void startingTestRun(Parameters params) { testStats = new int[Status.NUM_STATES]; } - + public void startingTest(TestResult tr) { } - + public void finishedTest(TestResult tr) { testStats[tr.getStatus().getType()]++; } - + public void stoppingTestRun() { } - + public void finishedTesting() { } - + public void finishedTestRun(boolean allOK) { } - + public void error(String msg) { err.println(i18n.getString("main.error", msg)); } } - + private void checkLockFiles(File workDir, String msg) { // String jc = System.getProperty("javatest.child"); // File jtData = new File(workDir, "jtData"); @@ -1712,12 +1738,12 @@ // } // } } - + //----------member variables----------------------------------------------- - + private PrintWriter out; private PrintWriter err; - + // this first group of args are the "standard" JavaTest args private File testSuiteArg; private File workDirArg; @@ -1732,13 +1758,14 @@ // TODO: consider making this a "pathset" to detect redundant specification // of directories and paths within them. private List<File> antFileArgs = new ArrayList<File>(); - + // these args are jtreg extras private File baseDirArg; private boolean sameJVMFlag; private JDK jdk; private boolean guiFlag; private boolean reportOnlyFlag; + private boolean noReportFlag; private static Verbose verbose; private boolean httpdFlag; private String observerClassName; @@ -1752,28 +1779,28 @@ private List<File> classPathAppendArg = new ArrayList<File>(); private boolean jitFlag = true; private Help help; - - + + // the list of args to be passed down to a child VM private List<String> childArgs = new ArrayList<String>(); - + private int[] testStats; - + private static final String AUTOMATIC = "!manual"; private static final String MANUAL = "manual"; - + private static final String[] DEFAULT_UNIX_ENV_VARS = { "DISPLAY", "HOME", "LANG", "LC_ALL", "LC_TYPE", "LPDEST", "PRINTER", "TZ", "XMODIFIERS" }; - + private static final String[] DEFAULT_WINDOWS_ENV_VARS = { "SystemDrive", "SystemRoot", "windir", "TMP", "TEMP" }; - + private static final String JAVATEST_ANT_FILE_LIST = "javatest.ant.file.list"; - + private static boolean debugChild = Boolean.getBoolean("javatest.regtest.debugChild"); private static final String PATHSEP = System.getProperty("path.separator"); - + private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(Main.class); }
--- a/test/jtreg/com/sun/javatest/regtest/MainAction.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/regtest/MainAction.java Mon Nov 17 15:26:51 2008 +0000 @@ -151,7 +151,7 @@ throw new ParseException(PARSE_SECURE_OTHERVM); } } // init() - + @Override public File[] getSourceFiles() { List<File> l = new ArrayList<File>(); @@ -244,11 +244,11 @@ // available to main and applet actions via the system properties // "test.src" and "test.classes", respectively" List<String> command = new ArrayList<String>(6); - + // some tests are inappropriately relying on the CLASSPATH environment // variable being set, so force the use here. final boolean useCLASSPATH = true; - + if (useCLASSPATH || script.isJDK11()) { command.add("CLASSPATH=" + script.getJavaTestClassPath() + PATHSEP + script.testClassPath()); @@ -263,10 +263,10 @@ command.add("-Dtest.src=" + script.absTestSrcDir()); command.add("-Dtest.classes=" + script.absTestClsDir()); - command.add("-Dtest.vm.opts=" + script.getTestVMOptions()); - command.add("-Dtest.tool.vm.opts=" + script.getTestToolVMOptions()); - command.add("-Dtest.javac.opts=" + script.getTestCompilerOptions()); - command.add("-Dtest.java.opts=" + script.getTestJavaOptions()); + command.add("-Dtest.vm.opts=" + join(script.getTestVMOptions())); + command.add("-Dtest.tool.vm.opts=" + join(script.getTestToolVMOptions())); + command.add("-Dtest.javac.opts=" + join(script.getTestCompilerOptions())); + command.add("-Dtest.java.opts=" + join(script.getTestJavaOptions())); String newPolicyFN; if (policyFN != null) { @@ -364,7 +364,7 @@ } // runOtherJVM() private static Hashtable savedSystemProperties; - + private Status runSameJVM() throws TestRunException { // TAG-SPEC: "The source and class directories of a test are made // available to main and applet actions via the system properties @@ -376,6 +376,11 @@ Properties p = System.getProperties(); if (savedSystemProperties == null) savedSystemProperties = copyProperties(p); + p.put("java.class.path", + script.absTestClsDir() + PATHSEP + + script.absTestSrcDir() + PATHSEP + + script.absClsLibListStr() + PATHSEP + + p.getProperty("java.class.path")); p.put("test.src", script.absTestSrcDir().getPath()); p.put("test.classes", script.absTestClsDir().getPath()); p.put("test.vm.opts", StringUtils.join(script.getTestVMOptions(), " ")); @@ -390,18 +395,18 @@ //return Status.error(MAIN_SECMGR_BAD); } } - + ByteArrayOutputStream newOut = new ByteArrayOutputStream(); ByteArrayOutputStream newErr = new ByteArrayOutputStream(); PrintStream psOut = new PrintStream(newOut); PrintStream psErr = new PrintStream(newErr); - + Status status; PrintStream saveOut = System.out; PrintStream saveErr = System.err; try { status = Status.passed(EXEC_PASS); - + String[] classpath = StringArray.splitSeparator(PATHSEP, script.testClassPath()); List<URL> urls = new ArrayList<URL>(); for (int i = 0; i < classpath.length; i++) { @@ -417,18 +422,18 @@ Class<?> c = loader.loadClass(buildFN); Class<?>[] argTypes = { String[].class }; Method method = c.getMethod("main", argTypes); - + // XXX 4/1 possible to use splitSeparator instead? String[] tmpArgs = StringArray.splitWS(mainArgs); Object[] runArgs = {tmpArgs}; - + Status stat = redirectOutput(psOut, psErr); if (!stat.isPassed()) { return stat; } - + // RUN JAVA IN ANOTHER THREADGROUP - + SameVMThreadGroup tg = new SameVMThreadGroup(); SameVMThread svmt = new SameVMThread(method, runArgs, psErr); Thread t = new Thread(tg, svmt, "SameVMThread"); @@ -443,7 +448,7 @@ } } tg.cleanup(); - + if (((svmt.t != null) || (tg.uncaughtThrowable != null)) && (error == null)) { if (svmt.t == null) error = tg.uncaughtThrowable; @@ -451,12 +456,12 @@ error = svmt.t; status = Status.failed(MAIN_THREW_EXCEPT + error.toString()); } - + // EVALUATE RESULTS if (status.getReason().endsWith("java.lang.SecurityException: System.exit() forbidden by JavaTest")) { status = Status.failed(UNEXPECT_SYS_EXIT); } else { - + boolean ok = status.isPassed(); int st = status.getType(); String sr; @@ -503,19 +508,20 @@ System.setProperties(newProperties(savedSystemProperties)); // System.err.println("reset properties"); } else { + System.setProperty("java.class.path", (String) savedSystemProperties.get("java.class.path")); // System.err.println("no need to reset properties"); } rsm.setAllowPropertiesAccess(false); } - + Status stat = redirectOutput(saveOut, saveErr); if (!stat.isPassed()) { return stat; } - + psOut.close(); psErr.close(); - + String outString = newOut.toString(); String errString = newErr.toString(); PrintWriter sysOut = section.createOutput("System.out"); @@ -528,7 +534,7 @@ if (sysErr != null) sysErr.close(); } } - + return status; } // runSameJVM() @@ -539,7 +545,7 @@ value = "novalue"; return value; } // parseMainManual() - + private static Hashtable<Object,Object> copyProperties(Properties p) { Hashtable<Object,Object> h = new Hashtable<Object,Object>(); for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements(); ) { @@ -548,7 +554,7 @@ } return h; } - + private static Properties newProperties(Hashtable<?,?> h) { Properties p = new Properties(); for (Enumeration<?> e = h.keys(); e.hasMoreElements(); ) { @@ -556,7 +562,17 @@ p.put(key, h.get(key)); } return p; - + + } + + private String join(List<String> list) { + StringBuffer sb = new StringBuffer(); + for (String s: list) { + if (sb.length() > 0) + sb.append(" "); + sb.append(s); + } + return sb.toString(); } //----------internal classes------------------------------------------------ @@ -630,27 +646,27 @@ private void cleanup() { cleanMode = true; - + final int CLEANUP_ROUNDS = 4; final long MAX_CLEANUP_TIME_MILLIS = 2 * 60 * 1000; final long CLEANUP_MILLIS_PER_ROUND = MAX_CLEANUP_TIME_MILLIS / CLEANUP_ROUNDS; final long NANOS_PER_MILLI = 1000L * 1000L; - + long startCleanupTime = System.nanoTime(); - + for (int i = 1; i <= CLEANUP_ROUNDS; i++) { long deadline = startCleanupTime + i * CLEANUP_MILLIS_PER_ROUND * NANOS_PER_MILLI; List<Thread> liveThreads = liveThreads(); - if (liveThreads.isEmpty()) { + if (liveThreads.isEmpty()) { // nothing left to cleanup cleanupOK = true; return; } - + // kick the remaining live threads for (Thread thread : liveThreads) thread.interrupt(); - + // try joining as many threads as possible before // the round times out for (Thread thread : liveThreads) { @@ -663,10 +679,10 @@ } } } - + cleanupOK = liveThreads().isEmpty(); } // cleanup() - + /** * Gets all the "interesting" threads in the thread group. * @see ThreadGroup#enumerate(Thread[])
--- a/test/jtreg/com/sun/javatest/regtest/RegressionSecurityManager.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/regtest/RegressionSecurityManager.java Mon Nov 17 15:26:51 2008 +0000 @@ -25,7 +25,6 @@ package com.sun.javatest.regtest; -import java.lang.RuntimePermission; import java.security.Permission; import java.util.PropertyPermission; @@ -55,7 +54,7 @@ System.err.println("execution of sameJVM tests"); System.err.println(); } - else + else System.setSecurityManager(new RegressionSecurityManager()); } catch (SecurityException e) { @@ -104,13 +103,13 @@ // allow most stuff, but limit as appropriate if (perm instanceof RuntimePermission) { if (perm.getName().equals("setIO")) { - if (!allowSetIO) + if (!allowSetIO) // is this right or should we really restrict this more? super.checkPermission(new java.lang.RuntimePermission("setIO")); } else if (perm.getName().equals("exitVM")) checkExit(0); - else if (perm.getName().equals("createSecurityManager")) + else if (perm.getName().equals("createSecurityManager")) super.checkPermission(new java.lang.RuntimePermission("createSecurityManager")); } else if (perm instanceof PropertyPermission) { @@ -118,21 +117,21 @@ checkPropertiesAccess(); } } - + private boolean propertiesAccessed; - + public synchronized void checkPropertiesAccess() { super.checkPropertiesAccess(); propertiesAccessed = true; } - + boolean isPropertiesAccessed() { return propertiesAccessed; } - + void resetPropertiesAccessed() { propertiesAccessed = false; - } + } public boolean setAllowSetIO(boolean bool) { boolean prev = allowSetIO;
--- a/test/jtreg/com/sun/javatest/regtest/RegressionTestFinder.java Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/regtest/RegressionTestFinder.java Mon Nov 17 15:26:51 2008 +0000 @@ -40,6 +40,7 @@ import com.sun.javatest.finder.TagTestFinder; import com.sun.javatest.finder.HTMLCommentStream; import com.sun.javatest.finder.ShScriptCommentStream; +import java.util.regex.Pattern; /** * This is a specific implementation of the TagTestFinder which is to be used @@ -169,36 +170,33 @@ } // force more key words based on actions - String name; String value = newTagValues.get("run"); String origKeywords = newTagValues.get("keywords"); String addKeywords = ""; - if (value.indexOf(name = "othervm") != -1) - addKeywords += "othervm "; + if (match(value, OTHERVM_OPTION)) + addKeywords += " othervm"; - if (value.indexOf(name = "manual") != -1) - addKeywords += "manual "; + if (match(value, MANUAL_OPTION)) + addKeywords += " manual"; - if (value.indexOf(name = "shell") != -1) - addKeywords += "shell "; + if (match(value, SHELL_ACTION)) + addKeywords += " shell"; - if (value.indexOf(name = "ignore") != -1) - addKeywords += "ignore "; + if (match(value, IGNORE_ACTION)) + addKeywords += " ignore"; if (!addKeywords.equals("")) { if (origKeywords == null) newTagValues.put("keywords", addKeywords.trim()); else - newTagValues.put("keywords", origKeywords + " " + addKeywords.trim()); + newTagValues.put("keywords", origKeywords + addKeywords); } /* - for (Enumeration e = newTagValues.keys(); e.hasMoreElements(); ) { - name = (String) e.nextElement(); - value = (String) newTagValues.get(name); - System.out.println("NAME: " + name + " VALUE: " + value); + for (Map.Entry<String,String> e: newTagValues.entrySet()) { + System.out.println("NAME: " + e.getKey() + " VALUE: " + e.getValue()); // if (name.equals("keywords")) // System.out.println(currFile + " " + "`" + value + "'"); } @@ -206,6 +204,10 @@ return newTagValues; } + + private static boolean match(CharSequence cs, Pattern p) { + return p.matcher(cs).matches(); + } /** * Make sure that the provide name-value pair is of the proper format as @@ -221,7 +223,6 @@ { Map<String,String> tagValues = (Map<String,String>) tv; - File currFile = getCurrentFile(); // check for valid tag name, don't produce error message for the // the SCCS sequence '%' 'W' '%' if (name.startsWith("(#)")) @@ -552,6 +553,12 @@ private static final boolean allowLocalKeys = Boolean.parseBoolean(System.getProperty("javatest.regtest.allowLocalKeys", "true")); + + private static final Pattern + OTHERVM_OPTION = Pattern.compile(".*/othervm[/ \t].*", Pattern.DOTALL), + MANUAL_OPTION = Pattern.compile(".*/manual[/= \t].*", Pattern.DOTALL), + SHELL_ACTION = Pattern.compile(".*[ \t]shell[/ \t].*", Pattern.DOTALL), + IGNORE_ACTION = Pattern.compile(".*[ \t]ignore[/ \t].*", Pattern.DOTALL); //----------member variables------------------------------------------------
--- a/test/jtreg/com/sun/javatest/regtest/i18n.properties Mon Nov 17 12:41:07 2008 +0000 +++ b/test/jtreg/com/sun/javatest/regtest/i18n.properties Mon Nov 17 15:26:51 2008 +0000 @@ -176,6 +176,7 @@ re-run any tests. A work directory containing the results of the executed \ tests must be provided. The default location is "./JTwork". To specify an \ alternate directory, use -workDir. +help.main.nr.desc=Do not generate a final report. help.main.startHttpd.desc=Start the http server to view test results help.main.timeout.desc=A scaling factor to extend the default timeout of all \ tests. Typically used when running on slow file systems.